Skip to content

Let Release Candidate accept the generated MCP version file - #2679

Open
r3dbars wants to merge 2 commits into
mainfrom
claude/intfix-release-ci
Open

r3dbars wants to merge 2 commits into
mainfrom
claude/intfix-release-ci

Conversation

@r3dbars

@r3dbars r3dbars commented Nov 12, 2026 •

Copy link
Copy Markdown
Owner

Fixes a P1 the bug hunt found on the integration branch (#2530).

Problem

scripts/release/bump-release-version.py now writes two files: Info.plist and the generated Tools/TranscriptedMCP/Sources/TranscriptedMCP/BuildVersion.swift. But the Release Candidate pin step still rejects any prep branch that differs from main in anything other than Info.plist. So every release after 1.1.76 fails the guard. The only workaround is to revert the generated file, and that ships an MCP helper that still reports the old version.

Change

  • .github/workflows/release-candidate.yml: the diff guard now requires the changed paths to be exactly Info.plist plus BuildVersion.swift (sorted compare). After the guard passes, it runs bump-release-version.py --check. The guard ensures that's main's copy of the script, so the generated file has to match Info.plist byte for byte.
  • Tests/CIWorkflowContractTests.swift: a contract test pins the two-path allow list. It also checks that --check runs after the guard.
  • docs/release-packaging.md step 1, .github/AGENTS.md and scripts/README.md now describe the two-file bump.

Current state (2026-11-13, prep for 1.1.77)

  • Base: main @ 5a72538a991a9fba22d0a0375db3e2e4f32dcb91 (read from the GitHub API, no drift from expected).
  • Head: c86e8a330e31885c32f9265293c32bd1ce22c159, a merge commit of current main into this branch (no force-push). Original commit f89c6210b is unchanged.
  • Merge was clean. Merged tree 74329a73a matches the reviewer's merge-tree. git diff main... is still only the 5 files listed above, no unrelated source changes.
  • check-superseded.py --pr 2679: OK, scope not covered by any merged PR.

Independent review

GREEN (separate Opus read-only review). Not superseded, clean merge-tree, exact sorted set compare kept, --check runs after the ancestor and path guards so it's main's copy of the script, and it runs in build-unsigned with no secrets. sign-and-notarize / verify-candidate are untouched and the signer still checks out main, so signer isolation holds. Non-blocking nits: --name-only would also list a pure mode change or symlink swap on BuildVersion.swift (content is still pinned), and the contract test splits expected= on spaces, which is brittle but fine.

Tests run on the merged head (offline, this Mac)

  • bash check.sh quick: PASS (113 passed, 0 failed, 0 skipped; includes bump-release-version.py --check and --version 1.1.77 --dry-run).
  • python3 scripts/release/bump-release-version.py --check: Compiled MCP version matches Info.plist.
  • Guard simulation in a scratch worktree: ran bump-release-version.py --version 1.1.77, then the workflow's sorted compare. Changed paths were exactly Info.plist + BuildVersion.swift, so PASS. --check passed after the bump, and failed (exit 1) with a stale BuildVersion.swift, as intended.
  • release-candidate.yml parses as YAML. check-test-shape.py --self-test passes.
  • Not run here: Swift app build, run-tests.sh (the contract test is Swift), full bench, hardware or native smokes. Those are left to CI and the combined release candidate.

Still pending

  1. PR CI (checks, build-and-test, etc.) on head c86e8a330, which pushing it triggered. Not green until it reports.
  2. Full bench / native proof on the combined 1.1.77 release candidate (the parent coordinator owns that).
  3. The real proof is the first Release Candidate dispatch after this lands on main: cut the prep branch from the new main, run bump-release-version.py --version 1.1.77, commit both files, then run gh workflow run release-candidate.yml --ref main -f source_ref=<prep> -f version=1.1.77. That's owner dispatch and approval only. Nothing here dispatched an RC, published, notarized or merged.

Historical proof (on the old base, before the merge)

This is release flow, and it can't be fully proven without a real release-candidate run. I checked the --check path locally (Compiled MCP version matches Info.plist), the bump script self-test passes, and the new contract test runs in the fast tests (54248/54248 passed). The first real RC dispatch after this lands is the actual proof. Since the dispatch uses --ref main, the workflow change only takes effect once it's on main.

Local bash check.sh ended with deterministic proof FAIL. None of the failures come from this diff:

  • nightly-security-check.py --strict against the 1.1.75 fixtures fails on appcast/cask/digest drift (fixtures 1.1.75, Info.plist and cask 1.1.76). That's on the integration base and this PR doesn't touch those files.
  • test-live-claude-mod.py and test-capture-list-load-more-scroll.sh are sandbox/account blocks (pinned Claude Code fails at Bun startup; native smoke refuses to run in the owner's account).
  • source-stability: the Lab build_and_run.sh --verify step left an untracked Tools/TranscriptedLab/dist/ while the proof was running.
  • BLOCKED items need manual proof or operator input.

🤖 Generated with Claude Code

Exact-head CI verification — 2026-11-13

Verified on c86e8a330e31885c32f9265293c32bd1ce22c159: repo-hygiene, pick-runner, checks, spm-tests, app-build, and the build-and-test umbrella all passed. Independent review remains GREEN. The PR is ready for review; it has not been merged.

The full-bench/hardware/staged-update jobs in this normal PR run were intentionally skipped. This does not claim a completed 1.1.77 Release Candidate, notarization, native updater proof, or publication. The actual release-guard proof still requires the Release Candidate workflow after integration.

bump-release-version.py now writes both Info.plist and
Tools/TranscriptedMCP/Sources/TranscriptedMCP/BuildVersion.swift, but the
Release Candidate pin step still rejected any prep branch that changed more
than Info.plist. Every release after 1.1.76 would fail the guard, and the only
workaround shipped an MCP helper reporting the old version.

The guard now requires exactly those two paths, then runs
bump-release-version.py --check (main's copy, since nothing else may differ)
so the generated file must match Info.plist byte for byte. Docs and the
workflow contract test follow.
@r3dbars r3dbars added the needs owner review Owner must review before merge label Nov 12, 2026
@r3dbars
r3dbars changed the base branch from codex/integration-open-prs-20261110 to main November 12, 2026 22:46

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

needs owner review Owner must review before merge risk:high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant