Repository navigation
Add a release skill, and put every release command in RELEASING.md - #710
ryanwelcher wants to merge 7 commits into
Conversation
…, and order the notes before the release
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
## Why `v2.0.0-beta.1` shipped on 13 October. Ten commits have reached trunk since then (#667 to #707), and milestone `v2.0.0` has 8 closed issues and none open. This is a stable release: it takes `releases/latest` from `v1.2.1`. `electron-builder` names the artifacts after `package.json`, so the version has to move before the tag and artifacts exist. ## What changes - **The version.** The three root version fields in `package.json` and `package-lock.json` move from `2.0.0-beta.1` to `2.0.0`. No dependency versions change. - **Translations.** `npm run i18n:download` refreshed the seven existing catalogs and added `lo`, `sr` and `tr`. None was removed, and no right-to-left locale was held back. - **Chromium locales.** Since #707 the same script keeps `build.electronLanguages` in line with the shipped catalogs, so it added `sr` and `tr` there. `lo` has no Chromium locale of its own. | Locale | Translated | Strings | | --- | --- | --- | | cs | 94% | 1037 | | en-ca | 95% | 1050 | | en-gb | 100% | 1100 | | gl | 96% | 1066 | | hu | 95% | 1050 | | lo | 95% | 1050 | | nl | 100% | 1100 | | pl | 99% | 1090 | | sr | 100% | 1100 | | tr | 100% | 1100 | ## How to test this **Platforms:** any for steps 1 to 3. Step 4 needs macOS for `Info.plist` and Windows for the `.exe`. Steps 4 and 5 use the Buildkite build for the current head. **Starting state:** this branch checked out with `node_modules` installed. Run every command from the repository root. 1. `npm run lint` is clean and `npm test` passes. 2. `node -e "console.log(require('./package.json').version)"` prints `2.0.0`. 3. `python3 -c "import json;d=json.load(open('package-lock.json'));print(d['version'], d['packages']['']['version'])"` prints `2.0.0 2.0.0`. 4. On the Buildkite build for the current head, the artifacts are named `wordpress-contributor-toolkit-2.0.0-*`. The `app.asar` root holds exactly `node_modules`, `package.json` and `src`, with npm 11 under `node_modules/npm` and no `.codesigning`. On macOS, `CFBundleShortVersionString` reads `2.0.0`. 5. In the installed app, set the language to Turkish in the settings and relaunch. The interface is in Turkish. **What must not have happened:** no dependency version may change. `git diff trunk -- . ':!src/languages'` shows five changed lines: the three root version fields and the two new `electronLanguages` entries. ## Risks and limitations None known. RELEASING.md still says to expect exactly three changed lines outside `src/languages/`. Since #707 a release that adds a locale with a Chromium locale changes `electronLanguages` too. #710 rewrites RELEASING.md and can update that line. ## Related Milestone `v2.0.0`. Release notes follow on the release. --- <details> <summary>Review outcome (required — see AGENTS.md)</summary> 0 [fix here] · 0 [follow-up]. Automatic checks only, as in #681: this change has no logic to review. - **Review:** completed, deterministic layer, in session; head `9df142b` / base `630253f` (trunk). `npm run lint` passes, `npm test` passes (2214 tests, 0 failures, 2 skipped), both files are valid JSON, and the diff outside `src/languages/` is the three root version fields plus the two `electronLanguages` entries. Outcome: nothing to fix. - **Since review:** none. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code)
- Allow the build.electronLanguages lines in the bump diff, which i18n:download rewrites since #707. - Check the signatures in section 2: codesign, spctl and stapler on macOS, and the Authenticode certificate of the Windows installer. - Say that Buildkite reports nothing to the pull request, so the person confirms the build's commit. - Merge with --match-head-commit, and let the skill merge when the person asks. - Check the docs site's Download button from a new tab, since it keeps the release it read for the tab's session.
There was a problem hiding this comment.
🟡 Changes recommended
The Windows signature check does not verify artifact integrity, and publication instructions need repository-selection and path-quoting corrections.
3 open issues
What changed in this PR
Centralizes the Contributor Toolkit’s release procedure in RELEASING.md and adds agent wrappers that require confirmation before public release actions.
Changes:
- Adds commands for artifact checks, guarded merging, publication, and post-release verification.
- Defines stable-versus-beta handling for release notes, docs deployment, and milestones.
- Adds matching release skills and links them from
AGENTS.md.
Review outcome: 3 [fix here] · 0 [follow-up]. GitHub Copilot reviewed the supplied four-file diff; reported head 43fdd1b, merge base 630253f. Lint and tests were not run.
| File | Description |
|---|---|
RELEASING.md |
Expands release commands and verification steps. |
AGENTS.md |
Links the canonical release procedure and skills. |
.claude/skills/release/SKILL.md |
Adds the release wrapper with confirmation checkpoints. |
.agents/skills/release/SKILL.md |
Provides the equivalent open-standard skill wrapper. |
Review effort: Balanced
| The Windows signature can be checked on Windows, with `Get-AuthenticodeSignature <dir>\wordpress-contributor-toolkit-X.Y.Z-win-x64.exe` in PowerShell (`Status` is `Valid` and the signer names Automattic Inc.), or on a Mac with `openssl`, which reads the certificates out of the installer's signature: | ||
|
|
||
| ```bash | ||
| node -e 'const fs=require("fs");const b=fs.readFileSync(process.argv[1]);const o=b.readUInt32LE(0x3c)+24;const d=o+(b.readUInt16LE(o)===0x20b?112:96)+32;const at=b.readUInt32LE(d),n=b.readUInt32LE(d+4);if(!n)throw new Error("not signed");process.stdout.write(b.subarray(at+8,at+n))' "<dir>/wordpress-contributor-toolkit-X.Y.Z-win-x64.exe" | openssl pkcs7 -inform DER -print_certs -noout | grep subject | ||
| ``` | ||
|
|
||
| It prints a `subject` line naming `O=Automattic Inc.`, and fails with `not signed` when the installer has no signature. |
| Then create the tag and the release together, on the bump commit. Every file is named by its path, so the command can run from anywhere: | ||
|
|
||
| ```bash | ||
| gh release create vX.Y.Z \ |
| --notes-file <path>/notes.md \ | ||
| <dir>/wordpress-contributor-toolkit-X.Y.Z-win-x64.exe \ | ||
| <dir>/wordpress-contributor-toolkit-X.Y.Z-mac-arm64.dmg \ | ||
| <dir>/wordpress-contributor-toolkit-X.Y.Z-linux-x86_64.AppImage |
…ver from a mismatch, and list open pull requests in the milestone

Why
RELEASING.mddescribed each step but left most of the commands to the person: how to check the macOS artifact, how to find the merged commit, which tag the release notes start from, how to tell the docs deploy actually ran. That makes a release slow to do by hand and easy for an agent to get wrong.What changes
RELEASING.mdgets the commands. Start-state checks and therelease/X.Y.Zbranch name, the bump diff check, the macOS artifact checks (mount the.dmg, list theapp.asarroot, read npm's version andCFBundleShortVersionString), re-checking after a branch update, confirming the merged commit matches the checked build, the base tag and commit count for the notes,--latestfor a stable release, checking the docs deploy job succeeded, the milestone commands, and a new section 7 that checks the result.A
releaseskill in.claude/skills/release/(/release X.Y.Zin Claude Code) and.agents/skills/release/. It is a thin wrapper overRELEASING.md, likeself-reviewis over the review standard. It adds five stops where it waits for a yes (branch, push and PR, a branch update,gh release create, docs and milestone), and merges only when the person asks, guarded by the checked head.AGENTS.mdpoints atRELEASING.mdand the skill under "Where things are".What the 2.0.0 release turned up (
c5ef531): the bump diff allows thebuild.electronLanguageslines thati18n:downloadwrites since Trim the packaged app by about 350 MB: unused PHP builds, renderer libraries and Chromium locales #707; section 2 checks the macOS signature, notarization and staple, and the Windows installer's Authenticode signer; Buildkite's commit is confirmed by the person, because the build reports nothing to the pull request; the merge uses--match-head-commit; and section 7 checks the docs site's Download button from a new tab, because the button keeps the release it read for the tab's session.Third review round (
43fdd1b): onlyX.Y.ZandX.Y.Z-beta.Nare accepted, so an rc is never published with--latest, and the stable notes base excludes every pre-release tag (--exclude '*-*'); section 3 checks the branch contains trunk before the merge and says to stop without tagging if the merged commit differs; a beta skips the docs deploy, asdocs.ymlandCONTRIBUTING.mdintend; and section 2 notes that the pipeline asks for commit statuses that never reach the pull request.Fourth review round (
72c3f69): the skill runs the check after the merge whichever way the bump was merged, not only when it merged it; a mismatch there says how to recover (check the trunk build of the merged commit with section 2, then tag); and the milestone check lists open pull requests as well as issues.Semantic Versioning (
140a866): a paragraph at the top ofRELEASING.mdsays versions follow semver and what major, minor and patch mean for an app with no public API.Not in it: downloading artifacts from Buildkite. The person downloads them; the skill checks them.
How to test this
Platforms: macOS for the artifact checks (they use
hdiutilandplutil); anything else works on either.Starting state: this branch checked out,
npm cidone, and a macOS build indist/(npm run dist), or a.dmgdownloaded from any Buildkite build.RELEASING.mdwithX.Y.Z=2.1.0. The tworev-parselines match, and the other two commands print nothing..dmg. It printssigned;acceptedwithsource=Notarized Developer IDandoriginnaming Automattic (an unsigned local build fails these three);The validate action worked!;/node_modules,/package.json,/src; a version starting with11.; then the build's version. Then run the Windows signature command against a Buildkite.exe. It prints asubjectline namingO=Automattic Inc../release 2.1.0and stop it at the first question. It runs the start checks and asks before creatingrelease/2.1.0.What must not have happened:
git statusshows no change topackage.json. An earlier draft usedasar extract-file, which writes into the current directory.Risks and limitations
RELEASING.md, and what it turned up is folded in here (c5ef531).Related
Released with trunk's process: v2.0.0 (#711).
Design decisions and alternatives considered
RELEASING.md, behaviour in the skill. The first draft put the commands in the skill. The review flagged that a person releasing by hand would never see them and that the two would drift, so they moved toRELEASING.md, and the skill keeps only what is agent-specific: the stops, leaving the merge to the person, and where the notes draft lives.Review outcome (required — see AGENTS.md)
Four rounds, 24 findings, all fixed.
code-review.instructions.md. First round on heada31b25d, base630253f(trunk, no PR yet): 9 findings (6 fix here, 3 follow-up), all fixed in5fb565e, includingasar extract-fileoverwritingpackage.jsonfrom the repo root, an unconditional milestone close that contradicted the beta rule, unfetched refs in the start checks, and procedure living only in the skill. Second round on5fb565e: 8 findings, all fixed infb32bc6, including the docs check reading the previous run and not failing on a failed run, notes commands placed after the command that needs the notes, ambiguous step references, and missing milestone commands.npm run lintandnpm testpass (2212 pass, 2 skipped).5fb565e → fb32bc6: the second round's fixes only, not re-reviewed by a third pass. The newghcommands were run against this repository (milestone listing, the deploy-job query on the last docs dispatch) and the artifact commands against a local macOS build.fb32bc6 → c5ef531: the 2.0.0 findings, not reviewed. Every new command was run against the signed 2.0.0 files and printed what the text says, and the Windows command was also run against a copy with its signature entry cleared, where it fails withnot signed.npm run lintpasses.c5ef531, basetrunk, merge base630253f: 4 findings (2 fix here, 2 follow-up), all fixed in43fdd1b. One, that Buildkite posts commit statuses to the pull request, was checked against GitHub and did not hold: the 2.0.0 bump head9df142bhas only CodeRabbit's status, so the fix is a note, not the suggestedgh api …/statuscheck. The new up-to-date check and the--exclude '*-*'base were run against this repository.npm run lintpasses;npm testwas not run, since only Markdown changed.43fdd1b, basetrunk, merge base630253f: fresh Explore subagent with the diff andcode-review.instructions.md. 3 findings (3 fix here, 0 follow-up), all fixed in72c3f69: the skill tied the check after the merge only to the path where it merges itself, so a merge done by the person went straight to tagging; the stop on a mismatched merge left no way forward; andgh issue list --milestonemisses open pull requests (gh pr list --search 'milestone:…'added, run againstv2.0.0).npm run lintandnpm testpass on43fdd1b(2212 pass, 2 skipped).43fdd1b → 72c3f69: the fourth round's fixes only, Markdown inRELEASING.mdand bothSKILL.mdcopies, not re-reviewed.72c3f69 → 140a866: one paragraph inRELEASING.mdon Semantic Versioning, not reviewed.passbut the message says automatic reviews are disabled; the pre-PR review above is the review of record, covering head43fdd1b.Screenshots or recording
Nothing on screen changed; this is documentation and an agent skill.
🤖 Generated with Claude Code