merge-train-infra
Provides internal configuration and workflow details for the AztecProtocol merge-train automation system.
Install
mkdir -p .claude/skills/merge-train-infra && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/17440" && unzip -o skill.zip -d .claude/skills/merge-train-infra && rm skill.zipInstalls to .claude/skills/merge-train-infra
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Reference for merge-train automation internals -- workflows, scripts, CI integration, and configuration. Use when modifying or debugging merge-train infrastructure.Key capabilities
- →Understand the automation lifecycle of the merge-train system
- →Debug merge-train infrastructure workflows
- →Modify GitHub Actions for PR creation and body updates
- →Integrate `next` and `v5-next` branches into merge-trains
- →Configure CI mode selection based on labels and target branches
How it works
This skill describes the internal workings of the merge-train system, detailing GitHub Actions workflows for PR creation, body updates, branch integration, and auto-merging.
Inputs & outputs
When to use merge-train-infra
- →Debugging failed merge-train workflow triggers
- →Modifying GitHub Actions for PR body updates
- →Updating scripts for branch integration logic
- →Auditing configuration for merge-train CI jobs
About this skill
Merge-Train Infrastructure
This skill covers the automation internals of the merge-train system. For contributor-facing guidance (creating PRs, labels, handling failures), see the merge-trains skill.
Automation Lifecycle
The merge-train system is fully automated via GitHub Actions in .github/workflows/merge-train-*.yml:
-
PR Creation (
merge-train-create-pr.yml): Triggered on push tomerge-train/*branches. Creates a PR targetingnext(orv5-nextfor-v5trains such asmerge-train/spartan-v5andmerge-train/fairies-v5) with theci-no-squashlabel (plusprivate-port-nextfor any train that targetsv5-next, andci-full-no-test-cacheformerge-train/spartan,merge-train/spartan-v5, andmerge-train/ci). Skips merge commits and commits already in the base branch. -
Body Updates (
merge-train-update-pr-body.yml): Triggered on push tomerge-train/**,backport-to-*-staging, andport-to-next-stagingbranches. Updates the PR body with meaningful commits (those containing PR references like(#1234)). The body wraps the commit list inBEGIN_COMMIT_OVERRIDE/END_COMMIT_OVERRIDEmarkers. Backport/port staging PRs also callupdate-pr-body.shinline fromscripts/backport_to_staging.shto handle the first-push case (where the PR doesn't exist yet when the workflow fires). -
Next Integration (
merge-train-next-to-branches.yml): Triggered on push tonextandv5-next. A push tonextmergesnextinto eachnext-based train; a push tov5-nextmergesv5-nextinto the-v5trains (merge-train/spartan-v5,merge-train/fairies-v5). Both go throughscripts/merge-train/merge-next.sh, which takes an optional second argument for the source branch (defaults tonext). Usescontinue-on-error: trueso a conflict in one branch does not block others. Skips branches whose PR already has auto-merge enabled. -
Auto-Merge (
merge-train-auto-merge.yml): Runs hourly via cron (0 * * * *). Callsscripts/merge-train/auto-merge.shfor merge-train (4-hour inactivity), backport-train (BRANCH_PATTERN=backport-to-, 8-hour), and port-to-next (BRANCH_PATTERN=port-to-next, 8-hour) branches. Uses separate GitHub tokens:AZTEC_BOT_GITHUB_TOKENfor API calls andMERGE_TRAIN_GITHUB_TOKENfor approvals. Will not auto-merge if the last merge-queue CI run failed or was cancelled. -
Recreation & Wakeup (
merge-train-recreate.yml): Triggered when a PR is closed (merged). If the merged PR's head branch starts withmerge-train/, recreates the branch from the base branch (usuallynext). Then runsscripts/merge-train/wakeup-prs.shto add theci-wakeup-pr-after-mergelabel to all open PRs targeting the branch that have passed CI and have automerge enabled. This triggers a CI re-run (typically a no-op via tree-hash cache) so those PRs can proceed through the merge queue. The label is immediately removed by a step inci3.ymlso it can be re-applied on subsequent merges. -
Failure Notification (
merge-queue-dequeue-notify.yml): Triggered when a PR is dequeued from the merge queue. If the PR's head branch starts withmerge-train/and the PR was NOT merged, sends a Slack notification viaci3/merge_train_failure_slack_notify. That script also kicks off a ClaudeBox session to investigate/fix the dequeued PR (ci3/slack_notify_with_claudebox_kickoff), passing--repo "$GITHUB_REPOSITORY"so the session runs in the mode matching the repo the train lives on. When the train is on a private mirror (…-private),claudebox.ymlselects private mode; otherwise it stays public. Without that repo hint a private-train fix session lands in public mode and cannot read the PR or open the fix.
Label-Driven Ports (backport.yml)
backport.yml (triggered on pull_request_target labeled/closed) cherry-picks a merged PR onto an accumulating staging branch, then opens/updates one staging PR into a target branch. It handles two label families, both driven by scripts/backport_to_staging.sh:
backport-to-<branch>(e.g.backport-to-v5-next): target is<branch>(derived from the label), staging branchbackport-to-<branch>-staging. Directionnext→ release line.port-to-next(fixed, generic): target isnext, staging branchport-to-next-staging. Direction: forward-port an already-merged PR straight intonext. The workflow passesSTAGING_BRANCH/STAGING_PR_TITLE/STAGING_PR_LABELSenv overrides into the script; the staging PR carriesci-no-squash(required becausenextenforces squashed PRs).port-to-nexttakes precedence if both label families are present.
On cherry-pick conflict the workflow comments on the PR, posts to #backports, and dispatches ClaudeBox (.claude/claudebox/backport.md) with the staging branch to resolve manually. Staging PRs are auto-merged by the 8-hour jobs in merge-train-auto-merge.yml.
Scheduled Forward-Port (port-v5-next-to-next.yml)
A daily bulk sweep (distinct from the per-PR port-to-next label) that keeps next fed with everything on the v5-next release line. port-v5-next-to-next.yml runs at 06:30 UTC (and on workflow_dispatch) and calls scripts/port_to_next.sh <source> (default v5-next). The port-<source>-to-next branch is long-lived: each run checks it out and merges both next and the source into it, then opens/updates one ci-no-squash PR into next. Accumulating (rather than rebuilding) means any conflict resolution pushed to the branch is preserved across runs. Once the PR is merged (the branch becomes an ancestor of next) the next run rebuilds the branch fresh from next with a --force-with-lease push; while accumulating it fast-forwards. If a run produces no delta over next it closes the stale PR. A merge conflict does not abandon the run: the conflicted merge is committed with markers (so the PR is still opened/updated as a resolution target), the script emits conflicts / pr_url step outputs, and the workflow posts the PR link and conflicted files to #backports. Resolve by checking out the port branch, fixing the markers, and pushing. This PR is intentionally left for human review — it is not added to the auto-merge patterns.
CI Integration Details
CI Mode Selection (.github/ci3_labels_to_env.sh)
Merge-train branches influence CI mode:
merge_groupevents orci-merge-queuelabel →merge-queuemode- If the merge-group event is for
merge-train/spartan-v5→ upgraded tomerge-queue-heavymode (10 parallel grind runs instead of 4) - Target branch
merge-train/docs→ci-docsmode - Target branch
merge-train/barretenberg→ci-barretenbergmode
CI Concurrency (.github/workflows/ci3.yml)
group: ci3-${{ (startsWith(github.event.pull_request.head.ref, 'merge-train/') && github.run_id) || ... }}
Merge-train PRs get full concurrency (each run has its own unique group via github.run_id), while non-merge-train PRs share a group by branch name with cancel-in-progress.
Instance Postfix (.github/ci3.sh)
if [[ "${PR_HEAD_REF:-}" == merge-train/* ]]; then
export INSTANCE_POSTFIX=${PR_COMMITS:-}
fi
Merge-train PRs get a unique instance postfix (commit count) to allow parallel EC2 instances.
CI Modes in bootstrap.sh
ci-docs: Only builds and tests documentationci-barretenberg: Only builds and tests barretenberg (AVM disabled)ci-barretenberg-full: Full barretenberg CI including acir_testsmerge-queue: 4x AMD64 full + 1x ARM64 fast in parallelmerge-queue-heavy: 10x AMD64 full + 1x ARM64 fast in parallel (used formerge-train/spartanandmerge-train/spartan-v5)
Test History Tracking (ci3/run_test_cmd)
if [[ "$is_merge_queue" -eq 1 || ("${TARGET_BRANCH:-}" =~ ^v[0-9]) || ("${TARGET_BRANCH:-}" == merge-train/*) ]]; then
track_test_history=1
fi
Failure Notification (ci3/bootstrap_ec2)
When a CI run fails on an EC2 instance, it calls merge_train_failure_slack_notify to send failure notifications to the appropriate Slack channel based on the branch name.
Creating a New Merge Train
- Create a branch from the desired base (
nextfor most trains; a release line likev5-nextfor a release-specific train) with naming patternmerge-train/{team}. For a v5-release train use the-v5suffix (merge-train/{team}-v5):merge-train-create-pr.ymlroutes any*-v5branch to av5-nextbase automatically and adds theprivate-port-nextlabel. - Add the branch to the loop in
.github/workflows/merge-train-next-to-branches.yml. If it tracks a base branch other thannext, also add that base to the workflow'spushtrigger and pass it as the second argument tomerge-next.sh(see thev5-next→-v5trains wiring) - For a base other than
nextthat the*-v5convention does not already cover, set the PR base in.github/workflows/merge-train-create-pr.yml. Either way, add a stale-check job that passesBASE_BRANCHin.github/workflows/merge-train-stale-check.yml - Add the branch-to-Slack-channel mapping in
ci3/merge_train_failure_slack_notify - Optionally add CI mode overrides in
.github/ci3_labels_to_env.shandbootstrap.sh - Push code to the branch -- automation handles PR creation from there
Key Files Reference
Workflows
| File | Purpose |
|---|---|
.github/workflows/merge-train-readme.md | User-facing documentation |
.github/workflows/merge-train-create-pr.yml | Auto-creates PRs for train branches |
.github/workflows/merge-train-auto-merge.yml | Hourly cron to auto-merge inactive trains |
.github/workflows/merge-train-next-to-branches.yml | Syncs next into all train branches; defines active branches |
.github/workflows/merge-train-recreate.yml | Recreates branch after merge |
.github/workflows/merge-train-update-pr-body.yml | Updates PR body with commit list (merge-train and backport branches) |
| `.github/workflows/merge-queue-dequeue-notify.yml |
Content truncated.
When not to use it
- →When seeking contributor-facing guidance on creating PRs or handling failures
- →When the task is not related to modifying or debugging merge-train infrastructure
Limitations
- →Focuses on automation internals, not contributor-facing guidance
- →Requires understanding of GitHub Actions and shell scripting
- →Does not cover creating a new merge train from scratch
How it compares
This skill provides a detailed reference for the merge-train's internal automation, offering specific workflow and script details that are not available in general documentation.
Compared to similar skills
merge-train-infra side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| merge-train-infra (this skill) | 0 | 23d | Review | Advanced |
| github-workflow-automation | 11 | 2mo | Review | Advanced |
| github-actions-templates | 7 | 3mo | No flags | Intermediate |
| hooks-automation | 3 | 3mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by AztecProtocol
View all by AztecProtocol →You might also like
github-workflow-automation
ruvnet
Advanced GitHub Actions workflow automation with AI swarm coordination, intelligent CI/CD pipelines, and comprehensive repository management
github-actions-templates
wshobson
Create production-ready GitHub Actions workflows for automated testing, building, and deploying applications. Use when setting up CI/CD with GitHub Actions, automating development workflows, or creating reusable workflow templates.
hooks-automation
ruvnet
Automated coordination, formatting, and learning from Claude Code operations using intelligent hooks with MCP integration. Includes pre$post task hooks, session management, Git integration, memory coordination, and neural pattern training for enhanced development workflows.
cli-commands
windmill-labs
MUST use when using the CLI.
dev
atopile
LLM-focused workflow for working in this repo: compile Zig, run the orchestrated test runner, consume test-report.json/html artifacts, and discover/debug ConfigFlags.
toolhive-release
stacklok
Creates ToolHive release PRs by analyzing commits since the last release, categorizing changes, recommending semantic version bump type (major/minor/patch), and triggering the release workflow. Use when cutting a release, preparing a new version, checking what changed since last release, or when the user mentions "release", "version bump", or "cut a release".