Release with the shared toolchain instead of a local copy - #59
Merged
Conversation
added 2 commits
August 31, 2026 11:56
toolchain/publish.mjs here was one of four 88-97% identical copies of the same script, and this copy never got the fix that lets an interrupted release resume - the scenario the script exists for. @datocms/release-toolchain is that script, once. What is left behind is toolchain/release.mjs: the User-Agent version stamping and the rebuild it implies, passed as the shared script's one hook. The stamping now runs after the publish plan is read rather than before. That is safe - the plan is derived from package.json versions changeset version has already written, and setClientVersion.ts only rewrites source - and it drops the second 'npm install --package-lock-only', which the shared script already does right after the bump. Claude-Session: https://claude.ai/code/session_01XaYAhzmiJwysZeq1XC5xrQ
Rehearsing the resume against a real registry and a real GitHub repo turned up a bug that every copy of the old script had: killed between 'changeset publish' and 'git push', the next run reads an empty plan - the packages are on the registry and their tags are local, which is all changesets looks at - and aborts with 'there is nothing to release', leaving the commit unpushed and no GitHub release. v1.1.0 finishes that release. Claude-Session: https://claude.ai/code/session_01XaYAhzmiJwysZeq1XC5xrQ
@datocms/cma-client
@datocms/cma-client-analysis
@datocms/cma-client-browser
@datocms/cma-client-node
@datocms/cma-schema-types-generator
@datocms/dashboard-client
@datocms/rest-api-events
@datocms/rest-api-reference
@datocms/rest-client-utils
commit: |
v1.2.0 adds a guard a package runs from prepublishOnly to refuse a hand-typed 'npm publish'. This repo does not use it: the root package.json is private, so the same slip publishes nothing. The seven single-package repos carry it, where 'npm publish' at the repo root does reach npm. The lockfile is the substantive part of this commit. Changing the spec alone left the previous SHA resolved, so 'npm ci' kept installing v1.0.0 while package.json claimed otherwise. Claude-Session: https://claude.ai/code/session_01XaYAhzmiJwysZeq1XC5xrQ
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.
toolchain/publish.mjshere was one of four 88–97% identical copies of the same~280-line script, and this copy never got the fix that lets an interrupted
release resume (
git merge-base --is-ancestor) — the exact scenario the scriptexists for. It still fails with "have diverged. Pull (or push) first." on a
resumed release.
@datocms/release-toolchainisthat script, once, shared by all eleven DatoCMS repos that publish to npm, and
installed from its repository by git tag rather than published: the
@datocmsscope on npm is what customers install, and internal automation does not belong
there.
What changed
toolchain/publish.mjs(–283 lines) →toolchain/release.mjs(+24), which isthe User-Agent stamping and the rebuild it implies, and nothing else, passed as
the shared script's one hook:
beforeCommit, afterchangeset versionand thelockfile refresh, after the publish plan is read, before
git add -A && git commit.publish→release,publish-next→release:next(env prefix on thelatter unchanged). Harmless in this repo, where the root
package.jsonisprivate, but
publishis a name npm runs itself duringnpm publish; thesingle-package repos migrating next would re-enter their own release script if
they kept it.
@manypkg/get-packagesdropped — the deleted script was its only consumer.README.md,CLAUDE.mdand.changeset/README.md.Two behaviour changes, both deliberate
derived from the
package.jsonversionschangeset versionhas alreadywritten, and
setClientVersion.tsonly rewrites source. The rebuild stillhappens before the commit, so what is committed and what is published are
built from the stamped source, exactly as before.
npm install --package-lock-onlyis gone. The shared scriptalready refreshes the lockfile right after
changeset version, and nothingbetween the two touches a dependency.
A release moving packages to different versions also gets
release: 4 packagesplus the tag list in the commit body instead of all of them in the subject — but
@datocms/*is alinkedgroup, so in practice the subject staysrelease: v5.9.0, or the package's own name when only one moved.Two things the shared script adds
vX.Y.Zwhen the repo is one package,name@versionin aworkspace) rather than hard-coded, and a step between
changeset publishandgit pushchecks that its derivation and changesets' agree — while the onlything that has happened is a publish.
visible in the release log.
https://claude.ai/code/session_01XaYAhzmiJwysZeq1XC5xrQ