From da6d7f26d833b5d35346de053a38eec354c59726 Mon Sep 17 00:00:00 2001 From: Ryan Lee Date: Mon, 12 Oct 2026 19:24:31 +0000 Subject: [PATCH 1/3] ci(release): decide changeset coverage from turbo's build hashes The release gate moves from `paths` to `{ strategy: turbo, task: build }`. `main` has carried turbo.json since b7e907a, so the comment saying the turbo gate refuses this repository's base is stale. A publishable package now needs an intent when its turbo `build` hash moves between base and head (pnpm-release-management b9b4a1d change-verdict.ts verdictTouched), the gate systemfsoftware and pnpm-release-management use. .changeset/README.md states the same rule and keys the 0.0.0 `none` caveat on the tarball. --- .changeset/README.md | 9 +++++---- release.jsonc | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.changeset/README.md b/.changeset/README.md index 7a9658d..810b7a9 100644 --- a/.changeset/README.md +++ b/.changeset/README.md @@ -7,14 +7,15 @@ one with: pnpm change --bump --summary "" [...] ``` -- A pull request that changes a publishable package's path ships an intent - here; the changeset check fails without one. +- A pull request whose head moves a publishable package's turbo `build` hash + from the base ships an intent naming that package (`release.jsonc` `gate`); + the changeset check fails without one. - `none` records a change that needs no release. A `none` on a change a consumer can see is the silent non-release the check exists to catch. - `@systemfsoftware/api-extractor` is at 0.0.0 and the tag `@systemfsoftware/api-extractor@v0.0.0` exists. While both hold, a pull - request that changes `packages/api-extractor` ships a non-`none` intent for - it, because a `none` on a change to its tarball makes Release refuse with + request that changes its tarball ships a non-`none` intent for it, because a + `none` on a change to its tarball makes Release refuse with `tag-integrity-mismatch`. The tag is deleted only in the change that moves the version off 0.0.0. - The release PR consumes pending intents with `pnpm version -r`, writes each diff --git a/release.jsonc b/release.jsonc index 29ed7d7..f30ea69 100644 --- a/release.jsonc +++ b/release.jsonc @@ -8,7 +8,7 @@ "versioning": { "strategy": "changesets", }, - // A change under a package's directory needs an intent naming it. The turbo - // gate dry-runs turbo at the base, which a base without turbo.json refuses. - "gate": { "strategy": "paths" }, + // A pull request whose head moves a publishable package's turbo `build` hash + // away from the base ships an intent naming that package. + "gate": { "strategy": "turbo", "task": "build" }, } From 12e09feec840b27e3770027579d75d4330d5ca84 Mon Sep 17 00:00:00 2001 From: Ryan Lee Date: Tue, 13 Oct 2026 09:02:10 +0000 Subject: [PATCH 2/3] docs(changeset): name the root inputs that move the build hash The turbo gate asks for an intent when a package's `build` hash moves, and files outside the package can move it. turbo 2.10.12's dry run moved @systemfsoftware/api-extractor#build on a change to turbo.json's `build` task, to `globalEnv`, and to the root package.json's dependencies, and not on root metadata, a lockfile comment or another task's settings. The README now names those inputs, so a contributor can see why such a pull request owes an intent (`none` when the tarball is unchanged). --- .changeset/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.changeset/README.md b/.changeset/README.md index 810b7a9..c12813c 100644 --- a/.changeset/README.md +++ b/.changeset/README.md @@ -9,7 +9,10 @@ pnpm change --bump --summary "" [ - A pull request whose head moves a publishable package's turbo `build` hash from the base ships an intent naming that package (`release.jsonc` `gate`); - the changeset check fails without one. + the changeset check fails without one. Files outside the package move that + hash too: `turbo.json`'s `build` task or `globalEnv`, and the root + `package.json`'s dependencies. Such a pull request names the package, with + `none` when its tarball does not change. - `none` records a change that needs no release. A `none` on a change a consumer can see is the silent non-release the check exists to catch. - `@systemfsoftware/api-extractor` is at 0.0.0 and the tag From 0a72fe466b7851d3392b5bc1232eeec4e55a90d4 Mon Sep 17 00:00:00 2001 From: Ryan Lee Date: Tue, 13 Oct 2026 09:30:11 +0000 Subject: [PATCH 3/3] docs(changeset): give the hash-input list as examples The list of outside-package inputs that move a package's `build` hash named only the three that turbo 2.10.12's dry run was measured on, but read as complete. Review named other inputs turbo also folds in (lockfile resolutions, other root dependency fields). The sentence now gives the measured inputs as examples; the gate itself compares turbo's hashes. --- .changeset/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.changeset/README.md b/.changeset/README.md index c12813c..feee433 100644 --- a/.changeset/README.md +++ b/.changeset/README.md @@ -9,10 +9,10 @@ pnpm change --bump --summary "" [ - A pull request whose head moves a publishable package's turbo `build` hash from the base ships an intent naming that package (`release.jsonc` `gate`); - the changeset check fails without one. Files outside the package move that - hash too: `turbo.json`'s `build` task or `globalEnv`, and the root - `package.json`'s dependencies. Such a pull request names the package, with - `none` when its tarball does not change. + the changeset check fails without one. Files outside the package can move + that hash too, for example `turbo.json`'s `build` task or `globalEnv`, or the + root `package.json`'s dependencies. Such a pull request names the package, + with `none` when its tarball does not change. - `none` records a change that needs no release. A `none` on a change a consumer can see is the silent non-release the check exists to catch. - `@systemfsoftware/api-extractor` is at 0.0.0 and the tag