From 7fa758e2fc539ac3723324c026b166c3f2b210c8 Mon Sep 17 00:00:00 2001 From: hsd-bot Date: Fri, 30 Oct 2026 12:46:00 -0400 Subject: [PATCH] docs: record the maintainer release checklist Co-Authored-By: Claude Opus 5.5 --- CONTRIBUTING.md | 116 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 892fd2a..51d9159 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,16 +19,122 @@ docs: trim local setup to the essentials ## Build outputs -`imagediff.js` and `imagediff.min.js` are generated by `npm run build` and committed for releases. Rebuild and commit them only when preparing a release; ordinary PRs change `js/imagediff.js` and leave the built files alone. `npm test` runs against the source, including the CLI, so nothing needs rebuilding to test a change. +`imagediff.js` and `imagediff.min.js` are generated by `npm run build` and committed for releases. Only the maintainer rebuilds them, as part of cutting a release; ordinary PRs change `js/imagediff.js` and leave the built files alone. `npm test` runs against the source, including the CLI, so nothing needs rebuilding to test a change. ## Releasing -In the release PR, run: +The maintainer cuts releases by hand, from `main`, with a signed commit and tag. Agents and ordinary PRs don't bump the version, rebuild the built files, tag, or publish. + +Run these on your own machine, replacing `X.Y.Z` with the new version. Each step says what to check before you move on. + +### 1. Check your identity and signing setup + +```sh +git config user.name; git config user.email # you, not hsd-bot +git config user.signingkey; git config gpg.format # a key is set (gpg, or ssh) +gh auth status # your account, not hsd-bot +``` + +For GitHub to show the commit and tag as **Verified**, the signing key must be added to your GitHub account as a *signing* key. + +### 2. Get main and check that X.Y.Z isn't out yet + +```sh +cd ~/js-imagediff # your clone +git checkout main +git pull --ff-only +git status # must be clean +git fetch --tags && git tag -l vX.Y.Z # expect nothing +npm view imagediff version # expect the previous version +``` + +### 3. Bump the version + +```sh +npm version X.Y.Z --no-git-tag-version +``` + +This updates `package.json` and `package-lock.json` without committing or tagging. You do both, signed, below. + +Bump before building: the build stamps the version into the header of the built files, and `VersionSpec` fails if it doesn't match. + +### 4. Build and test + +```sh +node -v # compare with: cat .nvmrc +npm ci +npx playwright install chromium +npm test # specs against the source +npm run release # build, then run the specs against both built files +head -3 imagediff.js # the header shows X.Y.Z +``` + +All tests must pass. + +### 5. Check the package contents and release notes + +```sh +npm pack --dry-run +``` + +Expect only `imagediff.js`, `imagediff.min.js`, `js/imagediff.js`, `bin/`, `browser/`, `package.json`, `README.md` and `LICENSE`. ```sh -npm run release +awk '$0 == "### X.Y.Z" { on = 1; next } on && /^### / { exit } on' README.md > /tmp/imagediff-X.Y.Z-notes.md +cat /tmp/imagediff-X.Y.Z-notes.md ``` -It builds `imagediff.js` and `imagediff.min.js` and runs `npm test` against each, through `require` in Node and in a page. Commit the built files once it passes. It doesn't bump the version, tag or publish. +Check that any breaking changes are listed first. + +### 6. Commit and tag, signed + +```sh +git status # only package.json, package-lock.json, imagediff.js, imagediff.min.js +git commit -S -am "chore(release): X.Y.Z" +git tag -s vX.Y.Z -m vX.Y.Z +git verify-commit HEAD && git verify-tag vX.Y.Z +``` + +### 7. Push the commit and let CI run + +```sh +git push origin main +``` + +Wait for CI on that commit to go green: + +```sh +gh run watch $(gh run list --commit $(git rev-parse HEAD) --limit 1 --json databaseId -q '.[0].databaseId') +``` + +If main is protected, push a branch instead, open a PR, and merge it with **Create a merge commit**. A squash or rebase merge would replace your signed commit. Then pull main and confirm that `vX.Y.Z` points at your commit. + +### 8. Publish to npm + +```sh +git status # clean +npm whoami # or: npm login +npm publish +npm view imagediff version # expect X.Y.Z +``` + +`prepublishOnly` checks the committed built files again before publishing: it refuses if they differ from what's committed or if the specs fail against them. It doesn't rebuild, so what's published is what's committed. + +npm requires two-factor authentication to publish. Log in with `npm login` on an account with 2FA set to "Authorization and writes", not with a saved token, and enter the code when npm prompts for it. + +### 9. Push the tag and create the GitHub release + +```sh +git push origin vX.Y.Z +gh release create vX.Y.Z --verify-tag --title vX.Y.Z --notes-file /tmp/imagediff-X.Y.Z-notes.md +``` + +### 10. Check that it's live + +- https://www.npmjs.com/package/imagediff +- https://github.com/HumbleSoftware/js-imagediff/releases/tag/vX.Y.Z (the tag shows **Verified**) +- https://cdn.jsdelivr.net/npm/imagediff@X.Y.Z/imagediff.min.js (shows the `X.Y.Z` header) + +### 11. Close the issues the release resolves -After merging, `npm publish` checks the committed built files again before publishing: it refuses if they differ from what's committed or if the specs fail against them. It doesn't rebuild, so what's published is what's committed. +Comment on each issue the release resolves, pointing at the release, and close it.