Skip to content

fix(release): unblock release train (derived version-file allowlist) + surface missing Slack config - #132

Draft
LukasParke wants to merge 1 commit into
mainfrom
fix/release-train-derived-version-allowlist
Draft

LukasParke wants to merge 1 commit into
mainfrom
fix/release-train-derived-version-allowlist

Conversation

@LukasParke

Copy link
Copy Markdown
Contributor

Warning

⚠️ Merging this unblocks an automatic MAJOR release. The next release-train run (Tue/Thu 09:23 UTC) after this merges will auto-merge Version Packages PR #119 and publish @openrouter/agent 1.0.0 (a major bump from 0.11.0, driven by the major changeset .changeset/drop-preliminary-results.md from #110), plus @openrouter/mcp 1.1.2.

Before merging, either confirm 1.0.0 is intended, or add the release:hold label to #119. release:hold is the train's real pause mechanism: the find step reads HOLD_LABEL: release:hold and skips the scope/merge steps when it's present, and pr-gate.sh re-checks it (BLOCK_LABEL) on every poll and just before merging, so a hold added mid-gate still stops it. Remove the label to resume.

Why

The release train has failed all 15 runs since 2026-09-01 with:

##[error]path outside allowlist: packages/agent/src/mcp/version.ts

#104 allowlisted the hard-coded pattern packages/[^/]+/src/version.ts, then #102 moved the generated file to packages/agent/src/mcp/version.ts. Nobody was paged because the Slack alert secrets are empty, so each failure only logged (slack not configured; would have posted).

What changed

  • .github/scripts/verify-version-pr-scope.sh: allowed generated version files are now derived, not hard-coded. For each packages/*/package.json with "gen:version": "node <script>.mjs", the script reads the path that generator passes to writeFileSync(join(root, '<path>')). Today that resolves to packages/agent/src/mcp/version.ts. The derivation reads the trusted checkout (the train checks out main, not the PR branch), and a PR that edits a generator falls outside the allowlist anyway. If a generator can't be parsed, its output stays disallowed (fail closed). The per-line content check on the version file and on package.json is unchanged. An out-of-allowlist *version.ts error now lists the derived paths to make debugging easier.
  • --self-test mode (offline, no gh): checks that the derived paths exist, that a legitimate bump passes, and that a smuggled statement, a postinstall injection, a source edit, a non-generated version.ts and a generator edit all fail. It runs in CI's lint job, so a future generator move breaks the PR that causes it instead of the unattended train.
  • release-train.yaml: a new early step, Check Slack alerting config, emits a ::warning:: annotation and a job-summary note whenever CI_RELEASE_ALERT_SLACK_BOT_TOKEN / CI_RELEASE_ALERT_SLACK_CHANNEL_ID are empty. A final step, Flag unalerted failure (if: failure() with Slack unconfigured), adds an ::error:: and a summary saying nobody was paged. A missing Slack config doesn't fail runs by itself, so releases aren't blocked on it.
  • Updated stale paths: turbo.json gen:version outputs (src/version.ts → src/mcp/version.ts) and a comment in publish.yaml.

Verification

  • bash .github/scripts/verify-version-pr-scope.sh --self-test: all cases pass.
  • Ran the real check read-only against chore: version packages #119 (PR=119, head 41931d1): Diff scope OK. It failed before this change.

Manual action for maintainers

  1. Decide on 1.0.0 (see the warning above). Confirm it's intended, or label chore: version packages #119 release:hold before merging this.
  2. Configure the Slack alert secrets (repo or org Actions secrets): CI_RELEASE_ALERT_SLACK_BOT_TOKEN and CI_RELEASE_ALERT_SLACK_CHANNEL_ID. Inside the steps these are exposed as SLACK_BOT_TOKEN / SLACK_CHANNEL_ID. bump-openrouter-sdk.yaml uses the same secrets. Until they're set, the train only produces run annotations and summaries.

🤖 Generated with Claude Code

…ing Slack config

The release train has failed every run since 2026-09-01 with
"path outside allowlist: packages/agent/src/mcp/version.ts": #104
hard-coded packages/*/src/version.ts, then #102 moved the generated file.

- verify-version-pr-scope.sh now derives the allowed generated version
  files from each package's `gen:version` script (the writeFileSync path
  in the generator), read from the trusted main checkout. Fails closed if
  a generator can't be parsed.
- Add `--self-test` (offline) and run it in CI's lint job.
- release-train: warn + job summary when the Slack alert secrets are
  empty, and an error + summary when a run fails without alerting.
- Fix stale version.ts paths in turbo.json outputs and a publish.yaml note.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant