Uh oh!
There was an error while loading. Please reload this page.
feat(release): scripted draft/publish release flow, plus release CI fixes - #2952
Merged
Conversation
Three independent bugs in the release pipeline: - cli-release passed `github.ref` to the Sentry release action, producing releases named `devbox@refs/tags/0.17.5` instead of `devbox@0.17.5`. The edge job already used the bare version; use `github.ref_name` here too. - docker-image-release moved the `latest` tag unconditionally, so publishing a prerelease overwrote jetpackio/devbox:latest with it. Both 0.17.0-dev and 0.17.0-deva did exactly that. Gate the `latest` steps on the release not being a prerelease, with a `push_latest` input for manual dispatch. - The cli-tests `test` matrix ran with the default fail-fast, so a single failing macOS shard cancelled every other macOS shard. That matrix gates releases via cli-release, so when it goes red we want the full picture rather than the first shard to fail. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Releasing meant pushing a tag, hand-writing a draft, and publishing from the GitHub UI. That ordering is fragile: publishing from the UI creates the tag and publishes in one action, so docker-image-release starts downloading the release tarballs before goreleaser has uploaded them. It failed that way on both 0.17.3 and 0.17.5. And with no draft to attach to, goreleaser writes its default body -- the bare list of commit SHAs that shipped as 0.17.5's notes. scripts/release.ts encodes the order that avoids both: draft, then tag, then wait for the build, then publish. Two entry points, `devbox run draft-release` and `devbox run publish-release`, each walking every step and prompting for the tag, title and description. publish-release can also finish a draft that already exists. Every step is idempotent, so a run that fails partway resumes instead of duplicating work. Preflight also catches the flake.nix version drift that left lastTag at 0.17.3 across both the 0.17.4 and 0.17.5 releases. Node runs the script directly via type stripping, so there's no build step and no node_modules. nodejs-slim is added with its plugin disabled -- the nodejs plugin installs a Corepack init_hook that would otherwise run on every `devbox run` in this repo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ease-workflow-audit
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Releasing meant pushing a tag, hand-writing a draft, then publishing from the GitHub UI — an ordering that races the build, because publishing from the UI creates the tag and publishes in one action, so
docker-image-releasestarts downloading the release tarballs before goreleaser has uploaded them (it failed that way on both 0.17.3 and 0.17.5), and with no draft to attach to goreleaser writes its default body, the bare commit-SHA list that shipped as 0.17.5's notes.scripts/release.tsencodes the order that avoids both — draft → tag → wait for the build → publish — behinddevbox run draft-releaseanddevbox run publish-release, each walking every step, prompting for the tag/title/description, and resuming rather than duplicating work if a run fails partway;publish-releasecan also finish a draft that already exists. Preflight additionally catches theflake.nixversion drift that leftlastTagat 0.17.3 across both the 0.17.4 and 0.17.5 releases. Separately, this fixes three release-pipeline bugs found while auditing: Sentry releases nameddevbox@refs/tags/Xinstead ofdevbox@X, prereleases overwriting the Dockerlatesttag (0.17.0-dev and 0.17.0-deva both did), and a fail-fast test matrix where one failing macOS shard cancelled every other shard.Node runs the script directly via type stripping, so there's no build step and no
node_modules;nodejs-slimis added with its plugin disabled, since the nodejs plugin would otherwise install a Corepackinit_hookthat runs on everydevbox runin this repo.How was it tested?
All four
devbox runscripts were exercised end to end against the live repo:release-changesanalyses the 5 commits since 0.17.5 and recommends 0.18.0 (minor, 4 breaking),release-statusreads back 0.17.5's real state (published, 7 assets,cli-releasesuccess), and bothdraft-releaseandpublish-releaseare correctly stopped by preflight on the dirty tree and redmain. Workflow changes were validated withactionlint, which reports no new warnings.The mutating steps — draft creation, tag push, publish — have not been exercised, because no release can currently be cut:
mainhas been red since 2026-07-02 on the macOSzig-hello-worldexample test (build.ziguses the pre-Zig-0.12 API whiledevbox.lockpins zig 0.11.0), whichcli-releasegates on. That test is not fixed here and remains the blocker for 0.18.0.Community Contribution License
All community contributions in this pull request are licensed to the project
maintainers under the terms of the
Apache 2 License.
By creating this pull request, I represent that I have the right to license the
contributions to the project maintainers under the Apache 2 License as stated in
the
Community Contribution License.
🤖 Generated with Claude Code