Repository navigation
Add a tag-driven release process - #9
Merged
Merged
Conversation
Releases were cut by hand: a version bump commit, an npm publish from a laptop, no tag, and no release page. Nothing tied the published tarball to a commit that had passed CI. A push of a `v*` tag now runs release.yml, which refuses the tag unless it is an ancestor of main and unless package.json matches it, runs the suite on real Chromium, publishes with npm trusted publishing (OIDC, no stored token), and creates the release page from the merged PRs. The plugin manifest carries its own version that `npm version` does not touch, and it had already drifted to 0.1.0 against a published 0.1.1. A `version` lifecycle script syncs it into the same commit, and a test asserts the two agree so the drift surfaces on a PR rather than on a tag push.
Semver lets a 0.x line ship additive changes as a patch, and the 0.1.x releases have done exactly that. Left as written, the rules would be contradicted by the first release cut under them.
npm does allow unpublishing within 72 hours; it is the permanent block on reuse afterwards that makes fixing forward the only option. The advice was right, the reason given for it was not. The 0.x clause claimed minor marks a break. Semver says nothing of the kind for 0.x, and this package has not done that - 0.1.1 carried new flags and the BROWSE_* to VERDICT_* rename together, as a patch.
The backfill section gave only 0.1.1's target, leaving 0.1.0's to be derived. Both now come from npm's own gitHead rather than from reading the log, which is the only source that actually knows what was published. Says outright that the backfill is optional and not a prerequisite for the next release, so nobody sequences work around it.
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.
Releases are cut by hand today: a version bump commit,
npm publishfrom a laptop, no tag, no release page. Nothing links a published tarball to a commit that passed CI, and 0.1.0 / 0.1.1 have no tags at all.This makes a
v*tag push the whole release..github/workflows/release.ymlon: push: tags: ['v*']- verify, publish, release pageRELEASING.mdscripts/sync-plugin-version.mjsversionlifecycle script: copies the version into.claude-plugin/plugin.jsonand stages ittest/version-sync.test.mjs.claude-plugin/plugin.json0.1.0->0.1.1(existing drift, see below)package.jsonversionscriptCutting a release
npm version patch && git push origin main --follow-tagsThe three jobs
main(so the code went through PR CI) and unlesspackage.jsonand the plugin manifest both match it. Then the full suite on real Chromium, reusing pr-ci.yml's Chromium cache and its fail-on-skip guard, andnpm pack --dry-runso the tarball is visible before it is permanent.npm publish --provenance. Holdsid-token: writeand nothing else, and deliberately runs nonpm ci: there is noprepackorprepublishOnly, so no dependency code executes in the job that holds the OIDC token. Skipped when the version is already on the registry, so a rerun after a flake is not a 403.gh release create --generate-notes. Runs when publish succeeded or was skipped.Ordering is deliberate: everything that can say "do not ship this" runs before any job holds a credential. A verify failure costs a deleted tag; a failure after publish costs a version number npm will never let you reuse.
The manifest drift
.claude-plugin/plugin.jsonhas its ownversionandnpm versiondoes not touch it, so it reads0.1.0against a published0.1.1. The lifecycle script puts it in the same commit as the bump; the test means a future drift fails a PR rather than a tag push.One thing needed from a maintainer before the first release
The workflow uses npm trusted publishing, so no token is stored here - but the publisher has to be registered once on npmjs.com:
verdict-cli-> Settings -> Trusted publishertuandm, repositoryverdict-cli, workflow filenamerelease.yml, environment blankUntil that exists the publish step 401s. The workflow asserts npm >= 11.5.1 (the trusted-publishing floor) rather than assuming the
node-version: '24'pin provides it.Testing
actionlintclean.version-sync.test.mjspasses, and fails as expected against the pre-fix manifest.npm pack --dry-runconfirmsscripts/andRELEASING.mdstay out of the tarball. The browser suite was not run locally - PR CI runs it here.Follow-up, not in this PR
The README build badge points at
ci.yml; the workflow ispr-ci.yml, so the badge renders as unknown.