Skip to content

ci: verify the binary builds before tagging a release - #20

Merged
llbbl merged 3 commits into
mainfrom
ci/verify-build-before-tag
Aug 21, 2026
Merged

ci: verify the binary builds before tagging a release#20
llbbl merged 3 commits into
mainfrom
ci/verify-build-before-tag

Conversation

@llbbl

@llbbl llbbl commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • PR CI now compiles the binary, so a bun build --compile break fails review instead of merging silently
  • The release workflow no longer tags before every binary has built and been packaged
  • Actions and the Bun version are pinned across all three workflow steps

Closes #18

The problem

Nothing verified that the CLI binary compiles until after a version bump and tag were already pushed. auto-release.yml's version job pushed the bump and tag (git push origin main --follow-tags), and only then did build run. ci.yml never built at all -- just lint, typecheck, tests. So a change that typechecks and passes tests but breaks bun build --compile could merge, bump the version, push a tag, and only then fail, leaving a bumped main, an orphan tag, and no release assets -- meaning brew install llbbl/tap/upkeep 404s for that version. This nearly bit us on the TypeScript 7 upgrade (#15), caught only because build:all was run locally by hand.

The fix, three layers of defense

  1. PR CI now runs bun run build, so a compile break fails review before merge.
  2. The release Verify step now also runs just build, so a break fails before the bump commit is even pushed.
  3. The tag is no longer created by the version job. version pushes only the bump commit and outputs its SHA; build and release check out that SHA; the tag is created and pushed by the release job after all five binaries are built and packaged. Tagging is the first irreversible act, so it now happens last.

Recovery paths added

Both matter because the restructure introduced these failure modes:

  • If a run pushes the bump but fails before tagging, the version files on main are already correct, so the next run's git commit would be empty and fail -- permanently wedging releases. The commit step now detects an empty stage, reuses the existing commit, and proceeds.
  • The tag step is idempotent, so a re-run after a partial failure completes instead of dying on an already-existing tag.

Changes

CI

  • .github/workflows/ci.yml: Add a Build binary step (bun run build) after tests
  • .github/workflows/auto-release.yml: Restructure so version pushes only the bump commit and outputs its SHA (steps.bump.outputs.sha); build and release check out that SHA instead of the tag; release creates and pushes the tag only after all binaries are packaged; version's Verify step also runs just build; commit step tolerates an empty stage; tag step is idempotent

Pins

  • .github/workflows/ci.yml, .github/workflows/auto-release.yml: bun-version: latest replaced with 1.4.0 in all three setup-bun steps -- latest already resolves to 1.4.0, so this changes nothing today but makes the build reproducible. Actions bumped to clear Node 20 deprecation warnings: actions/checkout v4 to v7, actions/upload-artifact v4 to v7, actions/download-artifact v4 to v8, softprops/action-gh-release v2 to v3, extractions/setup-just v2 to v4. Breaking changes were checked against actual usage: download-artifact v5's path change only affects downloads by artifact ID (we download all artifacts, so unaffected), and v8's digest-mismatch-errors and skip-decompress changes don't affect our flow
  • package.json: engines.bun tightened from >=1.0.0 to >=1.3.0

Verification

  • actionlint clean on both workflows (also validates the new needs.version.outputs.sha expression references)
  • just check passes locally (lint, typecheck, 405 tests)
  • just build -- the newly added CI step -- succeeds locally

Note for the reviewer

The restructured release path cannot be fully exercised until the next real release runs. The first merge to main after this lands will be its live test.

Test plan

  • Confirm PR CI runs and passes the new Build binary step
  • actionlint clean on both workflows
  • On the next merge to main, watch the release run: bump commit pushed, all five binaries build, tag created only after packaging, GitHub Release published with correct assets

llbbl added 3 commits August 21, 2026 18:23
Lint, typecheck, and tests all pass on code that `bun build --compile`
cannot bundle, so a compile break could previously merge undetected.
Add a build step to PR CI so that failure surfaces before merge
instead of during the release run.
Previously the version job pushed both the bump commit and the tag
before build even ran, so a compile failure left a bumped main and an
orphan tag with no release attached -- brew install would 404 for
that version. The version job now pushes only the bump commit and
outputs its SHA; build and release check out that SHA; the tag is
created and pushed by the release job after all five binaries have
built and been packaged. Tagging is the first irreversible act, so it
now happens last.

Also add just build to the version job's Verify step, so a compile
break fails before the bump commit is even pushed.

Two recovery paths introduced by this restructure:
- If a run pushes the bump but fails before tagging, the version
  files on main are already correct on the next run, so the commit
  step now detects an empty stage, reuses the existing commit, and
  proceeds instead of dying and wedging releases permanently.
- The tag step is idempotent, so a re-run after a partial failure
  completes instead of dying on an already-existing tag.
Replace bun-version: latest with 1.4.0 in all three setup-bun steps.
latest already resolves to 1.4.0, so this changes nothing today, but
it makes the build reproducible: an upstream Bun release can no
longer break CI or a release run with no change on our side.

Bump actions to clear Node 20 deprecation warnings: checkout v4 to
v7, upload-artifact v4 to v7, download-artifact v4 to v8,
action-gh-release v2 to v3, setup-just v2 to v4. Breaking changes were
checked against our actual usage: download-artifact v5's path change
only affects downloads by artifact ID (we download all artifacts, so
unaffected), and v8's digest-mismatch-errors and skip-decompress
changes don't affect our flow.

Also tighten engines.bun from >=1.0.0 to >=1.3.0 in package.json to
match the pinned version.
@llbbl
llbbl merged commit 7c82a89 into main Aug 21, 2026
3 checks passed
@llbbl
llbbl deleted the ci/verify-build-before-tag branch August 21, 2026 23:44
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.

ci: verify the binary builds before tagging a release

1 participant