Skip to content

Stop stable releases from rewriting the community QR template - #8002

Merged
3mdistal merged 8 commits into
mainfrom
alice/release-leaves-qr-alone
Oct 23, 2026
Merged

3mdistal merged 8 commits into
mainfrom
alice/release-leaves-qr-alone

Conversation

@3mdistal

@3mdistal 3mdistal commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Every stable release edits a file it shouldn't: templates/community/qr/package.json, the QR app that Dispatch offers as a curated community install (#7924). Each edit broke something, and each fix added another step to release prep:

QR is the only workspace package with a regular dependency on an internal package through a plain npm range (^0.219.0) instead of workspace:*, because its files get copied into other people's workspaces. Several packages declare plain peer ranges on Core, such as Dispatch's >=0.209.1; Safety and operations covers those. Changesets rewrites those ranges on every release, even for packages it otherwise skips: QR has no version field, yet Changesets still adds it to the release plan as a none release and updates its range. Adding qr to ignore would not stop this, for the same reason.

Approach

Stable releases stop rewriting plain ranges. With Changesets' bumpVersionsWithWorkspaceProtocolOnly on, a release only updates workspace: ranges and leaves QR's Core range alone. QR's range then moves only in a deliberate PR, and Dispatch's pin test already makes that PR refresh the pins too. Since releases no longer touch QR, the lockfile sync and the pin rewrite have nothing left to do, so this PR removes them. #8046's guards stay, and release PRs take their "catalog unchanged" path.

The setting is on for stable release prep only. A small wrapper sets it in .changeset/config.json for the changeset version run and restores the original file afterward, even when versioning fails. Turning it on repo-wide would break nightly and dev snapshots. Those rely on Changesets rewriting open peer ranges, such as Dispatch's >=0.209.1 on Core, to the exact snapshot version, because a prerelease Core falls outside the open range. The published @agent-native/dispatch@nightly declares "@agent-native/core": "0.212.0-nightly-20261021093329".

Release prep also fails closed now. After versioning, it runs pnpm install --frozen-lockfile --lockfile-only --ignore-scripts. Release PRs are admin-merged without waiting for CI, so if a release ever leaves a manifest out of step with the lockfile again, release prep stops before it opens the PR instead of merging a lockfile that breaks every install.

What changed

  • scripts/changeset-version-stable.ts (new): runs changeset version with the stable override and restores the config.
  • package.json: changeset:version now runs the wrapper, so running it by hand can't rewrite QR either. changeset:release-version runs it, compacts changelogs, then runs the frozen-lockfile check.
  • scripts/sync-community-qr-core-lock.ts and its tests: removed.
  • scripts/verify-community-qr-release-pin.ts: gitBlobSha, the one helper ci: verify generated QR pin for release merges #8046's verifier imported from the removed script, now lives here.
  • pnpm-lock.yaml: QR now resolves @agent-native/core@0.219.0 from npm instead of a forced link: to the in-repo package, which is how pnpm resolves a plain range here by default. Only QR's Core entry was re-resolved. pnpm also pruned old published @agent-native/* versions that nothing referenced (Core 0.210.2 and 0.212.0 with their agentkit, core-corpus, and recap-cli versions).
  • scripts/package-release-workflow.test.ts: three new tests, listed under Verification, and an assertion that changeset:version runs the wrapper.

Safety and operations

  • Stable releases: the override stops Changesets from rewriting every plain internal range, not just QR's. The 13 plain peer ranges, such as Dispatch's >=0.209.1 on Core, are all open >= ranges that the next patch, minor, or major bump still satisfies, so stable releases never rewrote them and nothing changes for them. A future closed peer range, such as ^0.219.0, would stop moving with stable releases and would need a hand update.
  • Release auto-merge: release PRs no longer change the catalog or QR's manifest, so ci: verify generated QR pin for release merges #8046's QR verifier reports the catalog unchanged and the path allowlist sees only manifests, changelogs, changesets, and the lockfile.
  • Snapshots: unchanged by this PR. Nightly and dev versioning call changeset version --snapshot directly with the shared config. Nightly publishes were failing on main for a related reason: snapshot versioning rewrites QR's range to the unpublished snapshot, and the lockfile refresh can't find it on npm. Unblock nightly publishes that fail on the community QR template #8006 fixed that separately and has merged; this branch includes it.
  • QR: QR now builds against published Core instead of the in-repo copy, as an installed community app would. Its range will go stale as Core moves (^0.219.0 stops matching at 0.220), so someone needs to bump it, together with the pins, from time to time. Installs already receive only the last reviewed files.
  • Interrupted release: a cancelled stable job stops before changesets/action commits or opens the release PR, so the override is discarded with the runner's checkout. A cancelled pnpm changeset:version run by hand can leave the override in the working tree, where git status shows it. If it were ever committed into a release PR, the auto-merge guard would refuse that PR, because .changeset/config.json isn't on its list.
  • Rollback: reverting this PR brings back the QR rewrite, the lockfile sync, and Fix stale QR template pin and refresh it on release #7978's pin rewrite, which ci: verify generated QR pin for release merges #8046's guards already accept.

Verification

  • pnpm test:package-release-workflow plus scripts/ci-change-scope.test.ts, after merging main at 845e327 (which includes Unblock nightly publishes that fail on the community QR template #8006): 184 of 189 passed. The 5 failures are the tests that put an extensionless gh stub on PATH: Fix paginated release PR file verification #8066's "runs both release verifier CLIs through the shared file request" and four that arrived from main (two required-check tests, a coordinator test, and the versionless-manifest CLI test). They fail only on Windows, where gh.exe wins over the stub and the test reaches the real API. CI runs them on Linux. The new tests show that:
    • Changesets' own release planner, run on this workspace with a Core patch, leaves QR out under the stable config and adds it as a none release without the override. With the override removed from the wrapper, this test fails.
    • the shared config doesn't enable the setting, so snapshot peer rewrites keep working.
    • the wrapper restores the config when versioning fails.
  • Stable release dry run from an earlier head (ddd20a0, after merging main at 0de9529, with a real release changeset): exit 0. A pending Toolkit minor carries Core 0.216.0 → 0.217.0 through the fixed group, so this is the case where QR's ^0.216.0 stops matching Core. QR's manifest, Dispatch's pins, the Changesets config, and the lockfile were unchanged, the frozen-lockfile check passed, and ci: verify generated QR pin for release merges #8046's assertReleaseOnlyPullRequestFiles accepted all 46 changed paths. Because neither the catalog nor QR's manifest changed, the QR pin verifier would report the catalog unchanged. Not rerun after the later merges of main: they moved QR's lockfile entry from npm Core 0.216.0 to 0.219.0, resolved the same way, and pnpm install --frozen-lockfile --lockfile-only passes at the PR head.
  • Drift dry run (on 58cd1e4, before merging main): with QR's manifest out of step with the lockfile, release prep exits 1 with ERR_PNPM_OUTDATED_LOCKFILE and restores the config.
  • Before merging main, pnpm --filter qr typecheck passed against npm Core 0.214.0, with QR's action spec (4) and community-apps.spec.ts (17) passing. CI reruns QR's typecheck against 0.219.0, because the lockfile changed.
  • CI: pending on 8e97468, which merges main after Fix the reaped-run tracking spec's db mock on main #8120 fixed the reaped-run tracking spec that failed Fast tests on main.

Review focus

  • Writing .changeset/config.json for the length of one command, rather than a repo-wide setting: is restoring it in finally enough, and is there a snapshot or release path that versions without going through the shared config?
  • QR's Core range now moves only by hand. Is that the intended model for the curated catalog?
  • Removing the link to the in-repo Core: was there a reason beyond release prep for QR to build against unpublished Core?

Follow-ups

  • Optional: Dispatch fetches QR's files from main, so a deliberate QR change still invalidates the pins in Dispatch builds already deployed. Pinning the catalog to a commit would fix that; the loader accepts only main today.

🤖 Generated with Claude Code

3mdistal and others added 2 commits October 21, 2026 20:52
Stable release prep now runs Changesets with bumpVersionsWithWorkspaceProtocolOnly,
so a release no longer edits QR's plain npm range on @agent-native/core. That
rewrite broke the lockfile and Dispatch's QR blob pins after every release, and
the release-time pin rewrite would make the auto-merge guard refuse the next
release PR. Snapshot releases keep the shared config, so their peer ranges still
move to each snapshot.

Remove the QR lock and pin sync script, resolve QR's Core from npm, and stop
release prep with a frozen-lockfile check when a manifest and the lockfile
disagree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Here's a visual recap of what changed:

Visual recap

Open the full interactive recap

@greptile-apps

greptile-apps Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no blocking issues were found.

Summary

Stable releases leave QR's plain Core range alone without changing snapshot release settings.

  • Stable releases leave the QR template and its Dispatch pins unchanged.
  • Stable release prep stops when the lockfile is out of step.

No actionable new issues were found in the changes since the previous review. No previous review threads were supplied.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Stable release prep] --> B[Save shared config]
  B --> C[Enable workspace-only range updates]
  C --> D[Run Changesets version]
  D --> E[Restore shared config on success or failure]
  E --> F{Versioning succeeded?}
  F -->|Yes| G[Compact changelogs]
  G --> H[Check frozen lockfile]
  F -->|No| I[Stop release prep]
  J[Nightly or dev release] --> K[Run Changesets snapshot directly]
  K --> L[Use unchanged shared config]
Loading

Reviews (2) · Last reviewed commit: "Route changeset:version through the stab..." · Reviewed by Greptile

builder-io-integration[bot]

This comment was marked as outdated.

Running the alias by hand still rewrote the QR template's Core range, so it
now runs the stable wrapper and release prep reuses it. Snapshot jobs call
`pnpm changeset version --snapshot` directly and keep the shared config.

Regenerate the lockfile by re-resolving only QR's Core entry, so tsx keeps
its existing esbuild resolution.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
builder-io-integration[bot]

This comment was marked as outdated.

Main gained two stable releases and #8046, whose QR pin verifier imported
gitBlobSha from the sync script this branch deletes. The helper now lives in
the verifier, and the release workflow tests import it from there.

The lockfile starts from main's and re-resolves only the QR template's Core
entry, as before, now at ^0.216.0. The consumed QR changeset stays deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
builder-io-integration[bot]

This comment was marked as outdated.

Keep #8066's new list-release-pr-package-files import next to this branch's
changeset-version-stable and check-changeset imports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
builder-io-integration[bot]

This comment was marked as outdated.

Conflicts:
- scripts/package-release-workflow.test.ts: keep main's new release
  coordinator, version policy and required-check imports; drop the import
  from the removed sync-community-qr-core-lock.ts.
- pnpm-lock.yaml: take main's lockfile, then re-resolve only QR's
  @agent-native/core (^0.219.0) from npm instead of the forced link: to
  packages/core, as this branch intends. pnpm pruned the published
  @agent-native/* versions nothing references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
builder-io-integration[bot]

This comment was marked as outdated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
builder-io-integration[bot]

This comment was marked as outdated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@builder-io-integration builder-io-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder reviewed your changes — looks good ✅

Review Details

Incremental Code Review Summary

Reviewed the latest PR #8002 head. The lockfile now resolves the QR template’s Core dependency at 0.219.0, matching its declared ^0.219.0 range; the release wrapper and QR pin verifier otherwise remain unchanged. The stable-only Changesets override continues to separate the stable path from snapshot workflows.

One additional low-severity edge case was found in withStableChangesetConfig: the override write occurs before entering the try/finally, so a rejected or interrupted write is not covered by the restoration path and may leave the shared config truncated or modified. This is distinct from the previously noted SIGINT/SIGTERM-during-versioning and dropped-CLI-arguments concerns; those remain unchanged and are not resubmitted. No high- or medium-severity issues were identified. Standard-risk release tooling; browser testing is not applicable.

🧪 Browser testing: Skipped — PR only modifies release scripts/config/lockfile/tests, no UI impact.

@3mdistal
3mdistal merged commit 0eaa9d2 into main Oct 23, 2026
149 of 152 checks passed
@3mdistal
3mdistal deleted the alice/release-leaves-qr-alone branch October 23, 2026 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants