Skip to content

Publish pre-built binaries and packages with each release - #55

Open
bkeepers wants to merge 1 commit into
beetlebugorg:mainfrom
bkeepers:release/prebuilt-binaries
Open

Publish pre-built binaries and packages with each release#55
bkeepers wants to merge 1 commit into
beetlebugorg:mainfrom
bkeepers:release/prebuilt-binaries

Conversation

@bkeepers

Copy link
Copy Markdown

This adds a release workflow so that pushing a vX.Y.Z tag produces downloadable binaries for macOS, Linux and Windows on both architectures, plus a Homebrew formula and a .deb.

Adding a tag via git tag v0.4.0 && git push origin v0.4.0 or the GitHub Releases UI runs .github/workflows/release.yml, which:

  1. Builds ReleaseFast for six targets and packages each one as tile57-<version>-<arch>-<os>.tar.gz, or .zip on Windows, carrying bin/tile57, lib/libtile57.a, include/tile57.h, and the licenses.
  2. Builds tile57_<version>_{amd64,arm64}.deb from the same payload.
  3. Creates the GitHub release with --generate-notes, all the archives, and a SHA256SUMS file.
  4. Regenerates Formula/tile57.rb in the Homebrew tap and pushes it.

A tag carrying a suffix, v0.4.0-rc1, publishes as a prerelease and skips the tap, so the whole matrix can be exercised without shipping anything.

Before any of that, each build leg checks the tag against the version in build.zig.zon, src/tile57.zig and tools/common.zig. A mismatch fails the build rather than shipping a binary whose tile57 version contradicts the file it arrived in.

Two target choices

macOS builds run natively per arch instead of cross-compiling from one runner. scripts/macho-align.sh calls ld -r and libtool without -arch, so it can only repack libtile57.a for the host. Threading the target arch through that script would allow a single-runner build, but native runners cost no code. That threading is the fix if the macos-15-intel runner is ever retired.

Linux uses the -gnu targets rather than -musl. build.zig already retargets the CLI to static musl on a glibc host, so the -gnu archives carry a portable tile57 and a libtile57.a that a glibc C host can still link. Building -musl would give up the second half of that.

Packages

Homebrew covers macOS and Linux from one formula, generated by scripts/brew-formula.sh out of the checksums of the archives that were just built. The formula installs the binary, the static library and the header, and its test do block runs tile57 version. Generating it beats hand-editing because all four checksums change every release. It does need a tap repo and a token, which is the checklist below.

The .deb is a release asset, not an apt repository. sudo apt install ./tile57_0.4.0_amd64.deb works, apt install tile57 does not. A real repository needs a signing key in secrets and somewhere to host the index, which seemed worth deferring until someone asks for it. Scoop, winget and AUR are out for the same reason.

Docs

Installation leads with binaries and keeps building from source below them. Its note about zig fetch being broken is gone: .paths in build.zig.zon covers vendor/, include/ and tools/, and I confirmed that a fetched package builds libtile57.a with no submodules initialised, so the lazy s101_portrayal dependency is doing its job. The same stale note in Zig API is replaced with the zig fetch --save line. Contributing gains the release steps.

Tested

The .deb was built and inspected with dpkg-deb, so root ownership, the control fields, and the layout under /usr are all confirmed. Tarball layout checked. Formula generation checked, including its non-zero exit when an archive is missing. actionlint and shellcheck are clean, and a zig fetched package built to libtile57.a without submodules.

The macOS legs are the untested part. CI has never built Darwin, so an -rc1 tag should come before the real one.

TODO

Before the first tag:

  • Create the tap repository beetlebugorg/homebrew-tap. Public, and empty is fine, since the workflow creates Formula/.
  • Create a token with contents: write on that repository, either a fine-grained PAT scoped to it or a GitHub App installation token.
  • Add the token to this repository as the actions secret HOMEBREW_TAP_TOKEN.
  • Confirm Actions is allowed to create releases. The workflow declares contents: write, but the repository's workflow-permissions setting has to allow it.
  • Decide on the tap name, homebrew-tap or homebrew-tile57. The URL is written into the workflow and into docs/docs/installation.md.

Without the secret the tap step logs a warning and exits, and the release still publishes.

First release:

  • Push v0.3.0-rc1 and confirm all six build legs go green, especially the two macOS ones.
  • Download one archive and one .deb and check they run on a clean machine.
  • Push the real tag.
  • Verify brew install beetlebugorg/tap/tile57 on macOS and on Linux.
  • Update the version numbers written out in the download commands in docs/docs/installation.md.

Not in this PR, worth considering later:

  • Notarize the macOS binaries so they don't need xattr -d com.apple.quarantine. Needs an Apple Developer account and certificates in secrets.
  • An apt repository, if apt install tile57 is wanted.
  • Add macos-latest to ci.yml so Darwin breakage surfaces on PRs instead of at tag time.

Pushing a vX.Y.Z tag builds macOS, Linux and Windows on x86-64 and arm64,
attaches the archives, .debs and SHA256SUMS to the release, and regenerates
the Homebrew tap formula.

macOS builds run natively per arch because macho-align.sh repacks
libtile57.a for the host only. Linux uses -gnu targets so libtile57.a stays
glibc-linkable while build.zig retargets the CLI to static musl.
@beetlebugorg

Copy link
Copy Markdown
Owner

Is there a good way to test this without merging and tagging? I've found I always need to iterate a little on GHA and it creates a lot of clutter in the build pipeline/tags/commits.

Maybe cloning the repo, merging there and testing, then pull any changes back into this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants