Lockstep release tooling for the three packages - #2296
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (7)
Disabled knowledge base sources:
WalkthroughThe pull request adds centralized lockstep release automation for three packages. It validates version sites, updates release metadata, publishes packages in dependency order, exposes npm commands, enables public access, and adds CI and contributor documentation. ChangesLockstep release workflow
Estimated code review effort: 4 (Complex) | ~45 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant Maintainer
participant ReleaseScript as scripts/release.js
participant PackageFiles
participant NpmRegistry
Maintainer->>ReleaseScript: run release:bump VERSION
ReleaseScript->>PackageFiles: update versions and peer pins
ReleaseScript->>PackageFiles: update React Hooks constant and lockfile
ReleaseScript->>ReleaseScript: re-check version sites
Maintainer->>ReleaseScript: run release:publish
ReleaseScript->>NpmRegistry: check published package versions
ReleaseScript->>NpmRegistry: pack and publish remaining packages
Suggested reviewers: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. A rabbit checks each version line, Comment |
None of the three package.json files set publishConfig.access, and npm publishes a scoped package as restricted by default on its first publish. The first lockstep release would therefore have published @ably/pubsub-core, @ably/pubsub-device and @ably/pubsub-server as private packages (or failed outright, depending on the org's plan). Declare access: public explicitly in all three. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rollout plan requires that one command releases core + device + server at the same version, with partial release impossible or failing reversibly. The release process was a manual checklist with three hand-edited version sites and three separate npm publish invocations — plenty of room for a drifted peer pin or a half-published release. scripts/release.js owns the mechanics, one command per step: - check: verifies all seven version sites agree (root and workspace package.json files, the wrappers' exact @ably/pubsub-core peer pins, and the react-hooks agent version constant). Wired into the lint CI job, so a drifted site cannot merge. - bump <version>: moves every site at once and refreshes the lockfile. The package.json files are rewritten directly rather than via npm version --workspaces, which was observed (npm 11) to rewrite the files and still exit non-zero, and then to fail on re-run with 'Version not changed' — exactly the partial state this tool exists to prevent. bump is deterministic and safely re-runnable. - publish [--dry-run] [--otp]: refuses to start unless the sites agree and every build artifact the packages' files globs reference exists (npm pack silently omits missing files, so a stale checkout would otherwise ship broken tarballs). Dry-run packs everything before publishing anything, publishes in dependency order (core before the wrappers that pin it), skips versions already on the registry so a failed run resumes by re-running, and prints rollback guidance (unpublish within 72 hours) if a release is abandoned partway. CONTRIBUTING's release process shrinks accordingly (three version steps become one, two publish steps become one). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
76ce7d6 to
19c4595
Compare
Stacked on #2294 (base:
uts-per-side) — implements the rollout plan's release-tooling step: "One command releases core + device + server at the same version. Partial release is impossible or fails reversibly."What
scripts/release.js, one command per release step, replacing the manual checklist's three hand-edited version sites and three separate publishes:npm run check:versions— verifies all seven version sites agree (root + three workspacepackage.jsons, both wrappers' exact@ably/pubsub-corepeer pins, and the react-hooks agent version constant). Now runs in the lint CI job, so a drifted site cannot merge.npm run release:bump <version>— moves every site at once and refreshes the lockfile. It rewrites thepackage.jsonfiles directly rather than usingnpm version --workspaces --include-workspace-root, which was observed (npm 11) to rewrite the files and still exit non-zero, then fail on re-run withVersion not changed— exactly the partial state this tooling exists to prevent.bumpis deterministic and re-runnable at any version.npm run release:publish [-- --dry-run] [-- --otp <code>]— the lockstep publish:filesglobs reference exists on disk (npm packsilently omits missing files, so a stale checkout would otherwise ship broken tarballs);npm unpublishwithin 72h) if a release is abandoned instead.Also fixes a first-release landmine found while building this: none of the three scoped packages set
publishConfig.access, and npm publishes scoped packages asrestrictedby default on first publish — so the first release would have shipped them private (or failed, depending on org plan). All three now declareaccess: public.CONTRIBUTING's release process shrinks accordingly (steps 4–6 → one bump command; 10–11 → one publish command).
Verification
checkpasses at 2.28.0 and correctly reports a deliberately drifted site with the full table.bumpround-tripped 2.28.0 → 2.99.0 → 2.28.0 with all seven sites moving together.publish --dry-runruns the full preflight against the real registry (all three names correctly detected as not yet published), dry-run packs all three, and reports the publish order.packages/server/dist/index.mjs: publish refuses with the exact path.Out of scope, flagged
First-time npm provisioning: trusted publishing can only be configured per package after its first publish, so release one of the new packages is necessarily an authenticated manual publish (OTP) — this tooling supports exactly that; the trusted-publishing binding (and its later re-binding for the repo rename) is registry-side configuration outside this repo.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation