Repository navigation
Release workflow: gated dry-run, candidate and publish with checked artifacts - #524
Draft
raiseCatError wants to merge 5 commits into
Draft
raiseCatError wants to merge 5 commits into
raiseCatError wants to merge 5 commits into
Conversation
GitHub's default bash runs without pipefail, so 'prepare.mjs | tee' would report success even when prepare failed. The workflow now declares 'shell: bash' (-eo pipefail), and prepare records its blockers in provenance.json, which publish refuses unless the list is empty.
- An untagged draft release is not resumable: create the annotated tag first and pin target_commitish, so GitHub never makes a lightweight tag. - The archive digest reaches publish as a prepare-job output, outside the artifact; release-notes.md is covered by SHA256SUMS and uploaded. - A resumed draft must carry exactly the verified assets. - Pull-request dry runs use their own concurrency group. - HOMEBREW_TAP_TOKEN is scoped to the one step that opens the tap PR. - The dispatched version is validated before it reaches step outputs. - The CI gate counts only GitHub Actions' own check runs.
This branch has not been deployed
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 free
to 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.
A release workflow for NMSh's existing source-release model: an annotated tag on the master merge commit, a GitHub Release, and a Homebrew source formula updated by a tap PR. Merging this publishes nothing. Publishing needs a manual dispatch from
masterwithmode: publish, the confirmationpublish vX.Y.Z, and approval in thenmsh-productionenvironment.What's added
scripts/release/:prepare.mjs: clean tree, semver, package/lockfile/changelog consistency, ref and approval checks, a physical-QA gate (docs/releases/vX.Y.Z-qa.json), build/typecheck/test:fast/npm audit, provenance (commit, tree, Node/npm, lockfile digest, dependencies) and release notes. Prints a blocker list.package.mjs: agit archiveof the exact commit, plusSHA256SUMS.verify-artifact.mjs: checks the checksums, then installs the archive the way the formula does, under a private HOME (npm ci, build, prune,--version, node-pty spawn).check-ci.mjs: exact-commitVerify (22.x)andVerify (26.x)check runs plus a successful dispatched CI run.publish.mjs: annotated tag at the commit → draft release → upload → re-download and verify → publish. A rerun resumes a tag at the same commit with only a draft. It refuses a published release, a tag at another commit, provenance that records blockers, an archive digest that doesn't match the prepare job's output, and a draft with unexpected assets.homebrew.mjs: changes the formula'surlandsha256only, with the digest taken from GitHub's tag archive. It opens the tap PRnmsh X.Y.Zonly if aHOMEBREW_TAP_TOKENsecret exists. Otherwise it uploads the formula as an artifact. The tap's ownbrew test-botandbrew pr-pullstay in charge of testing and bottles..github/workflows/release.yml:workflow_dispatch, and pull requests that touch release files. Pull requests are always dry runs.{}at the top, least privilege per job, and onlypublishcan write.bash -eo pipefail.env.docs/development/release-workflow.md: how to run the workflow, plus recovery for failed CI, packaging, an unverifiable asset, a partial GitHub Release, a Homebrew PR failure, an existing release, and a failed local install.tests/releaseWorkflow.test.ts: version mismatches, invalid refs, missing approvals and QA, missing artifacts, checksum failures, duplicate and resumable releases, and static checks of the workflow's triggers, pinning, gating, permissions and pipefail.Website deployment is unchanged and stays a separate PR plus the manual Publish NMSh website dispatch.
Verification
tests/releaseWorkflow.test.tsandtests/buildInfo.test.ts: 19/19 pass.tscclean,git diff --checkclean.--version 0.23.0reportsrelease-existsandqa-missing.--version 0.24.0reports version-mismatch, changelog-missing and qa-missing.npm audit --omit=dev: 0 vulnerabilities.Not verified
publish.mjsand the tap-PR path have never run against GitHub, because no dispatch or publish was executed. The first real release should runmode: dry-runfrommasterfirst.build unknown.nmsh-productionallows self-approval (prevent_self_reviewis off).