ci: publish a feat-cmux-next PR's cmux-tui merge tree from main (cx-73f2)
Summary
cmux-next's same-tree cmux-tui check failed 55 times on 33 feat-cmux-next PRs in one day (2026-10-10/11), all with the same reason: no cmux-tui artifacts run can publish tree <key>.
- A PR that changes a cmux-tui tree input has a merge tree that no push has published.
- Its own
pull_requestrun can't start that publish: its token gets 403 on thecmux-tui-pin-<sha12>ref and on the dispatch. cmux-tui-artifacts.yml'spull_request_targettrigger never fires, because GitHub readspull_request_targetworkflows only from main.
This adds a small publisher on main, cmux-next-pr-merge-tree.yml. It runs as pull_request_target on feat-cmux-next PRs, from the same-repository author only, filtered to the tree-input paths.
What it runs (no PR code with secrets):
- It checks out main only: the default branch, a sparse checkout of the publisher script, no credentials kept.
scripts/ci/publish_pr_merge_tree.pyuses only the API:- waits for GitHub to compute the merge commit;
- does nothing on a conflict or a newer head;
- skips the dispatch when an artifacts run for that commit already ran or is running;
- otherwise points
cmux-tui-pin-<sha12>at the merge commit and dispatchescmux-tui-artifacts.ymlthere.
- That dispatched run is the same one a push of that branch starts, which the author can already start by hand (
pin-cmux-tui.sh --help). Fork PRs start nothing. - It runs on a GitHub-hosted runner, as
test_ci_fork_runner_routingrequires forpull_request_target. Permissions arecontents: write,actions: writeandpull-requests: read, all scoped to this job. An API failure fails the job loudly with::error.
The feat-cmux-next side is the companion PR (linked below). There, the probe waits a bounded time for this publisher instead of failing on its own 403.
Testing
python3 tests/test_cmux_next_pr_merge_tree.py, 9 cases:
- Red at 7260ce0c584f: no publisher.
- Green after.
- The publisher runs against a fake GitHub API and covers:
- the merge commit appearing only after a few polls;
- an active or already-successful run (no new dispatch);
- a failed run (dispatched again);
- an existing pin at the merge commit (reused) or at another commit (error);
- a conflict or a newer head (nothing published);
- a refused dispatch (
::error).
- Checks on the workflow itself:
pull_request_targetonly, same repository only, the one checkout is the default branch, no PR refs.
Also run: test_ci_workflow_guards_are_wired, test_ci_fork_runner_routing, test_ci_linux_guard_routing and actionlint, all green. scripts/verify-local.py: 16 of 17 checks pass. The failing one is swift-syntax, on scripts/generate-computer-use-helper-icon.swift, which this PR doesn't touch, so it's already failing on main.
Changelog
none
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.
Summary by cubic
Fixes the same-tree cmux-tui check for feat-cmux-next pull requests, which failed 55 times on 33 PRs in a day because no run could start publishing a changed merge tree. Adds a pull_request_target workflow that does that publish from main.
- Runs only for same-repository feat-cmux-next PRs changing a cmux-tui tree input; it checks out main and never runs the PR's code.
- Waits for GitHub's merge commit and points
cmux-tui-pin-<sha12>at it with the FFI release App's token (GITHUB_TOKEN gets 403 on refs at feat-cmux-next commits), dispatchingcmux-tui-artifacts.ymlunless a run for that commit is already active or succeeded. - Does nothing on conflicts or newer heads; fork PRs start nothing and API failures fail loudly.
- Runs on a GitHub-hosted runner and is recorded as a
github-hosted-requiredguard exception, sincepull_request_targetwith a write token cannot use a self-hosted runner. - Adds
scripts/ci/publish_pr_merge_tree.pywith 9 tests against a fake GitHub API, plus CI-guard wiring.
Summary by CodeRabbit
- Chores
- Added automated merge-build artifact handling for eligible
cmux-nextpull requests from the same repository. - Existing successful or in-progress builds are reused when the merge commit matches; conflicting pull requests and pull requests whose source changes during processing are skipped.
- Added coverage for the automation and included it in CI guard checks.
- Added automated merge-build artifact handling for eligible