Skip to content

Commit f76190f

Browse files
authored
feat(ci): add merge-train/spartan-v5 targeting v5-next (#23831)
## Summary Wires up a new merge-train branch, `merge-train/spartan-v5`, that behaves exactly like `merge-train/spartan` but tracks the **v5 release line**: it is fed from and targets `v5-next` instead of `next`. Scoped by grepping every `merge-train` reference repo-wide (all file types, not just workflows) and adding the `spartan-v5` equivalent wherever spartan-specific behavior is hard-coded. ## Changes **Workflows** - `merge-train-create-pr.yml` — base branch is resolved per train (`v5-next` for `merge-train/spartan-v5`, `next` otherwise); the "already merged" ancestor check and the `ci-full-no-test-cache` label list both use it. - `merge-train-next-to-branches.yml` — now also triggers on push to `v5-next`. A push to `v5-next` merges `v5-next` into `merge-train/spartan-v5`; pushes to `next` continue feeding the other six trains. - `merge-train-stale-check.yml` — added a `spartan-v5` job running the stale check with `BASE_BRANCH=v5-next`, alerting `#team-alpha`. **Scripts** - `scripts/merge-train/merge-next.sh` — takes an optional second arg for the source branch (defaults to `next`); all `next` references (fetch, diff, merge message, conflict comment + the commit it's posted on) now use it. **CI plumbing** - `.github/ci3_labels_to_env.sh` — `merge-train/spartan-v5` merge-group runs map to `merge-queue-heavy` (10 grind runs), same as spartan. - `ci3/run_test_cmd` — flake notifications and the `#team-alpha-ci` channel mapping include `spartan-v5`. - `ci3/merge_train_failure_slack_notify` — `merge-train/spartan-v5` failures route to `#team-alpha`. - `ci.sh` — comment updated. **Docs / skills / base-branch guidance** - `merge-trains` + `merge-train-infra` skills (branch table, CI behavior, automation lifecycle, and "create a new merge train" steps now cover non-`next` base branches). - Root `CLAUDE.md` base-branch mapping notes `merge-train/spartan-v5` (→ `v5-next`) as the v5-line alternative to `merge-train/spartan`. - `.claude/skills/fix/SKILL.md` notes branching/PR-basing off `merge-train/spartan-v5` for v5-scoped fixes. ## Verified branch-agnostic — no change needed These already match `merge-train/*` or capture the subsystem generically, so they cover `spartan-v5` automatically: - `merge-train-recreate.yml`, `merge-train-update-pr-body.yml`, `merge-queue-dequeue-notify.yml` (`startsWith('merge-train/')`) - `scripts/merge-train/auto-merge.sh` (`BRANCH_PATTERN=merge-train/`), `update-pr-body.sh` (reads the PR's real base) - `ci3.sh` instance-postfix + `ci3.yml` concurrency (`merge-train/*`) - `ci3/dashboard/ci-metrics/github_data.py` and `rk.py` (regex `merge-train/([^\s]+)`) - `scripts/commits`, `scripts/filter_history`, `scripts/find_orphaned_issues_in_prs.py` (`merge-train/` prefix) No in-repo CODEOWNERS / ruleset / branch-protection config exists (those live in the GitHub UI). Remaining literal `merge-train/spartan` strings are illustrative `Example:`/usage comments with no behavior. ## Follow-up needed (cannot be done from this PR) The `merge-train/spartan-v5` branch itself must be created from `v5-next` and pushed — branch creation can't go through PR tooling. Once it exists the automation here takes over (PR creation, integration from `v5-next`, stale checks, auto-merge, recreation). `v5-next` already exists as a protected branch. ## CI Labeled `ci-skip` — workflow/script/docs config only. Shell scripts pass `bash -n`; workflow YAML parses cleanly.
2 parents 0dde9fa + 0c3abc1 commit f76190f

12 files changed

Lines changed: 83 additions & 44 deletions

File tree

.claude/skills/fix/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ For each issue number provided:
2929

3030
Work through each confirmed issue **sequentially** in the main checkout:
3131

32-
1. **Stash & branch**: Stash any uncommitted changes, then create a branch from `merge-train/spartan` using the issue's `gitBranchName` from Linear.
32+
1. **Stash & branch**: Stash any uncommitted changes, then create a branch from `merge-train/spartan` using the issue's `gitBranchName` from Linear. For a fix scoped to the v5 release line, branch from `merge-train/spartan-v5` (which targets `v5-next`) instead.
3333
```
3434
git stash
3535
git checkout -B <gitBranchName> origin/merge-train/spartan
@@ -43,7 +43,7 @@ Work through each confirmed issue **sequentially** in the main checkout:
4343
- Message format: `fix: <short description> (A-XXX)`
4444
- Include `Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>`
4545

46-
5. **Push & PR**: Push the branch and create a draft PR.
46+
5. **Push & PR**: Push the branch and create a draft PR. Use `--base merge-train/spartan-v5` for v5-scoped fixes.
4747
```
4848
git push -u origin <gitBranchName>
4949
gh pr create --draft --base merge-train/spartan --title "fix: ..." --body "..."

.claude/skills/merge-train-infra/SKILL.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ This skill covers the automation internals of the merge-train system. For contri
1111

1212
The merge-train system is fully automated via GitHub Actions in `.github/workflows/merge-train-*.yml`:
1313

14-
1. **PR Creation** (`merge-train-create-pr.yml`): Triggered on push to `merge-train/*` branches. Creates a PR targeting `next` with the `ci-no-squash` label (and `ci-full-no-test-cache` for spartan). Skips merge commits and commits already in `next`.
14+
1. **PR Creation** (`merge-train-create-pr.yml`): Triggered on push to `merge-train/*` branches. Creates a PR targeting `next` (or `v5-next` for `merge-train/spartan-v5`) with the `ci-no-squash` label (and `ci-full-no-test-cache` for `merge-train/spartan`, `merge-train/spartan-v5`, and `merge-train/ci`). Skips merge commits and commits already in the base branch.
1515

1616
2. **Body Updates** (`merge-train-update-pr-body.yml`): Triggered on push to `merge-train/**` and `backport-to-*-staging` branches. Updates the PR body with meaningful commits (those containing PR references like `(#1234)`). The body wraps the commit list in `BEGIN_COMMIT_OVERRIDE` / `END_COMMIT_OVERRIDE` markers. Backport staging PRs also call `update-pr-body.sh` inline from `scripts/backport_to_staging.sh` to handle the first-push case (where the PR doesn't exist yet when the workflow fires).
1717

18-
3. **Next Integration** (`merge-train-next-to-branches.yml`): Triggered on push to `next`. Merges `next` into each active merge-train branch via `scripts/merge-train/merge-next.sh`. Uses `continue-on-error: true` so a conflict in one branch does not block others. Skips branches whose PR already has auto-merge enabled.
18+
3. **Next Integration** (`merge-train-next-to-branches.yml`): Triggered on push to `next` and `v5-next`. A push to `next` merges `next` into each `next`-based train; a push to `v5-next` merges `v5-next` into `merge-train/spartan-v5`. Both go through `scripts/merge-train/merge-next.sh`, which takes an optional second argument for the source branch (defaults to `next`). Uses `continue-on-error: true` so a conflict in one branch does not block others. Skips branches whose PR already has auto-merge enabled.
1919

2020
4. **Auto-Merge** (`merge-train-auto-merge.yml`): Runs hourly via cron (`0 * * * *`). Calls `scripts/merge-train/auto-merge.sh` for both merge-train (4-hour inactivity) and backport-train (8-hour inactivity) branches. Uses separate GitHub tokens: `AZTEC_BOT_GITHUB_TOKEN` for API calls and `MERGE_TRAIN_GITHUB_TOKEN` for approvals. Will not auto-merge if the last merge-queue CI run failed or was cancelled.
2121

@@ -29,7 +29,7 @@ The merge-train system is fully automated via GitHub Actions in `.github/workflo
2929

3030
Merge-train branches influence CI mode:
3131
- `merge_group` events or `ci-merge-queue` label → `merge-queue` mode
32-
- If the merge-group event is for `merge-train/spartan` → upgraded to `merge-queue-heavy` mode (10 parallel grind runs instead of 4)
32+
- If the merge-group event is for `merge-train/spartan` or `merge-train/spartan-v5` → upgraded to `merge-queue-heavy` mode (10 parallel grind runs instead of 4)
3333
- Target branch `merge-train/docs``ci-docs` mode
3434
- Target branch `merge-train/barretenberg``ci-barretenberg` mode
3535

@@ -57,7 +57,7 @@ Merge-train PRs get a unique instance postfix (commit count) to allow parallel E
5757
- `ci-barretenberg`: Only builds and tests barretenberg (AVM disabled)
5858
- `ci-barretenberg-full`: Full barretenberg CI including acir_tests
5959
- `merge-queue`: 4x AMD64 full + 1x ARM64 fast in parallel
60-
- `merge-queue-heavy`: 10x AMD64 full + 1x ARM64 fast in parallel (used for `merge-train/spartan`)
60+
- `merge-queue-heavy`: 10x AMD64 full + 1x ARM64 fast in parallel (used for `merge-train/spartan` and `merge-train/spartan-v5`)
6161

6262
### Test History Tracking (`ci3/run_test_cmd`)
6363

@@ -73,11 +73,12 @@ When a CI run fails on an EC2 instance, it calls `merge_train_failure_slack_noti
7373

7474
## Creating a New Merge Train
7575

76-
1. Create a branch from `next` with naming pattern `merge-train/{team}`
77-
2. Add the branch to the matrix in `.github/workflows/merge-train-next-to-branches.yml`
78-
3. Add the branch-to-Slack-channel mapping in `ci3/merge_train_failure_slack_notify`
79-
4. Optionally add CI mode overrides in `.github/ci3_labels_to_env.sh` and `bootstrap.sh`
80-
5. Push code to the branch -- automation handles PR creation from there
76+
1. Create a branch from the desired base (`next` for most trains; a release line like `v5-next` for a release-specific train) with naming pattern `merge-train/{team}`
77+
2. Add the branch to the loop in `.github/workflows/merge-train-next-to-branches.yml`. If it tracks a base branch other than `next`, also add that base to the workflow's `push` trigger and pass it as the second argument to `merge-next.sh` (see the `merge-train/spartan-v5` → `v5-next` wiring)
78+
3. If the base is not `next`, set the PR base in `.github/workflows/merge-train-create-pr.yml` and pass `BASE_BRANCH` to the stale check in `.github/workflows/merge-train-stale-check.yml`
79+
4. Add the branch-to-Slack-channel mapping in `ci3/merge_train_failure_slack_notify`
80+
5. Optionally add CI mode overrides in `.github/ci3_labels_to_env.sh` and `bootstrap.sh`
81+
6. Push code to the branch -- automation handles PR creation from there
8182

8283
## Key Files Reference
8384

.claude/skills/merge-trains/SKILL.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ A merge train is an automated batching system (inspired by [Rust rollups](https:
1919
| `merge-train/docs` | Documentation | `#dev-rels` |
2020
| `merge-train/fairies` | aztec-nr | `#team-fairies` |
2121
| `merge-train/spartan` | Spartan / infra / yarn-project sequencer and prover orchestration | `#team-alpha` |
22+
| `merge-train/spartan-v5` | Same as `merge-train/spartan` but for the v5 release line (targets `v5-next` instead of `next`) | `#team-alpha` |
23+
24+
> Every train targets `next` except `merge-train/spartan-v5`, which targets `v5-next`.
2225
2326
## How to Use a Merge Train
2427

@@ -39,7 +42,7 @@ A merge train is an automated batching system (inspired by [Rust rollups](https:
3942
## CI Behavior for Merge Trains
4043

4144
- **Specialized CI modes**: PRs targeting `merge-train/docs` run docs-only CI. PRs targeting `merge-train/barretenberg` run barretenberg-only CI. This avoids running the full test suite for domain-specific changes.
42-
- **Merge-queue mode**: When the merge-train PR enters GitHub's merge queue, it runs the full `merge-queue` CI mode (4 parallel grind runs on AMD64 + 1 ARM64). `merge-train/spartan` uses the heavier `merge-queue-heavy` mode (10 grind runs).
45+
- **Merge-queue mode**: When the merge-train PR enters GitHub's merge queue, it runs the full `merge-queue` CI mode (4 parallel grind runs on AMD64 + 1 ARM64). `merge-train/spartan` and `merge-train/spartan-v5` use the heavier `merge-queue-heavy` mode (10 grind runs).
4346
- **Full concurrency**: Merge-train PRs get unique CI concurrency groups (using `github.run_id`), so multiple CI runs can proceed in parallel without cancelling each other.
4447
- **Test history tracking**: Test results are tracked for merge-train PRs, same as merge-queue runs.
4548

.github/ci3_labels_to_env.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ function main {
107107
ci_mode="skip"
108108
elif [ "${GITHUB_EVENT_NAME:-}" == "merge_group" ] || has_label "ci-merge-queue"; then
109109
ci_mode="merge-queue"
110-
# Check if this is a merge-train/spartan PR entering the merge queue.
110+
# Check if this is a spartan merge-train PR entering the merge queue.
111111
# If so, use the heavier merge-queue-heavy mode (10 grind runs).
112112
if [ "${GITHUB_EVENT_NAME:-}" == "merge_group" ] && [ -n "${GITHUB_TOKEN:-}" ]; then
113113
# GITHUB_REF_NAME in merge_group is like: gh-readonly-queue/next/pr-XXX-SHA
@@ -116,7 +116,7 @@ function main {
116116
if [ -n "$pr_number" ]; then
117117
local head_branch
118118
head_branch=$(GH_TOKEN="$GITHUB_TOKEN" gh pr view "$pr_number" --json headRefName -q '.headRefName' 2>/dev/null || true)
119-
if [ "$head_branch" == "merge-train/spartan" ]; then
119+
if [ "$head_branch" == "merge-train/spartan" ] || [ "$head_branch" == "merge-train/spartan-v5" ]; then
120120
ci_mode="merge-queue-heavy"
121121
elif [ "$head_branch" == "merge-train/ci" ]; then
122122
ci_mode="merge-queue-ci"

.github/workflows/merge-train-create-pr.yml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,23 @@ jobs:
2323
run: |
2424
branch="${{ github.ref_name }}"
2525
26+
# Determine base branch. Most trains target next; the spartan-v5
27+
# train targets the v5 release line (v5-next) instead.
28+
base_branch="next"
29+
if [[ "$branch" == "merge-train/spartan-v5" ]]; then
30+
base_branch="v5-next"
31+
fi
32+
2633
# Skip if this is a merge commit (check for multiple parents)
2734
parent_count=$(git rev-list --parents -n 1 "${{ github.sha }}" | wc -w)
2835
if [[ $parent_count -gt 2 ]]; then
2936
echo "Skipping: This is a merge commit."
3037
exit 0
3138
fi
3239
33-
# Skip if this commit is already in the next branch
34-
if git merge-base --is-ancestor "${{ github.sha }}" origin/next; then
35-
echo "Skipping: This commit is already in the next branch"
40+
# Skip if this commit is already in the base branch
41+
if git merge-base --is-ancestor "${{ github.sha }}" "origin/$base_branch"; then
42+
echo "Skipping: This commit is already in the $base_branch branch"
3643
exit 0
3744
fi
3845
@@ -42,12 +49,9 @@ jobs:
4249
if [[ -z "$existing_pr" ]]; then
4350
echo "No PR exists for $branch, creating one"
4451
45-
# Determine base branch (default to next)
46-
base_branch="next"
47-
4852
# Create PR with ci-no-squash label
4953
labels="ci-no-squash"
50-
if [[ "$branch" == "merge-train/spartan" || "$branch" == "merge-train/ci" ]]; then
54+
if [[ "$branch" == "merge-train/spartan" || "$branch" == "merge-train/spartan-v5" || "$branch" == "merge-train/ci" ]]; then
5155
labels="$labels,ci-full-no-test-cache"
5256
fi
5357
gh pr create --base "$base_branch" --head "$branch" \

.github/workflows/merge-train-next-to-branches.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ on:
44
push:
55
branches:
66
- next
7+
- v5-next
78

89
jobs:
910
merge-to-trains:
10-
name: Merge next to merge-train branches
11+
name: Merge base branch into merge-train branches
1112
runs-on: ubuntu-latest
1213
steps:
1314
- name: Checkout
@@ -26,7 +27,14 @@ jobs:
2627
GH_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }}
2728
COMMIT_SHA: ${{ github.sha }}
2829
run: |
29-
for branch in merge-train/avm merge-train/barretenberg merge-train/ci merge-train/docs merge-train/fairies merge-train/spartan; do
30-
./scripts/merge-train/merge-next.sh "$branch" || true
31-
done
30+
# The spartan-v5 train tracks the v5 release line (v5-next); every
31+
# other train tracks next. Sync only the trains fed by the branch
32+
# that was just pushed.
33+
if [[ "${{ github.ref_name }}" == "v5-next" ]]; then
34+
./scripts/merge-train/merge-next.sh merge-train/spartan-v5 v5-next || true
35+
else
36+
for branch in merge-train/avm merge-train/barretenberg merge-train/ci merge-train/docs merge-train/fairies merge-train/spartan; do
37+
./scripts/merge-train/merge-next.sh "$branch" || true
38+
done
39+
fi
3240

.github/workflows/merge-train-stale-check.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,18 @@ jobs:
2020
GH_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }}
2121
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
2222
run: ./ci3/merge_train_stale_check merge-train/spartan '#team-alpha'
23+
24+
spartan-v5:
25+
name: Check merge-train/spartan-v5
26+
runs-on: ubuntu-latest
27+
permissions:
28+
contents: read
29+
pull-requests: read
30+
steps:
31+
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
32+
- name: Run stale check
33+
env:
34+
GH_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }}
35+
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
36+
BASE_BRANCH: v5-next
37+
run: ./ci3/merge_train_stale_check merge-train/spartan-v5 '#team-alpha'

CLAUDE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ Otherwise infer from the component being worked in:
4040
| `barretenberg/cpp/src/barretenberg/vm2/**` | `merge-train/avm` |
4141
| everything else | `next` |
4242

43+
The bases above target the `next` line. For work scoped to the v5 release line, use `merge-train/spartan-v5` (which targets `v5-next`) in place of `merge-train/spartan`.
44+
4345
Use the discovered base in `git diff origin/<base>...HEAD` and `git log origin/<base>..HEAD`. Always `git fetch` before creating branches so the base is not stale.
4446
</critical_never_assume_master>
4547

ci.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ case "$cmd" in
165165
'a1-fast arm64 ci-fast'
166166
;;
167167
merge-queue-heavy)
168-
# Heavy merge queue with 10 parallel grind runs, used for merge-train/spartan PRs.
168+
# Heavy merge queue with 10 parallel grind runs, used for merge-train/spartan and merge-train/spartan-v5 PRs.
169169
multi_job_run \
170170
'x'{1..10}'-full amd64 ci-full-no-test-cache' \
171171
'a1-fast arm64 ci-fast'

ci3/merge_train_failure_slack_notify

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ elif [[ "$REF_NAME" == "merge-train/fairies" ]]; then
3535
channel="#team-fairies"
3636
elif [[ "$REF_NAME" == "merge-train/spartan" ]]; then
3737
channel="#team-alpha"
38+
elif [[ "$REF_NAME" == "merge-train/spartan-v5" ]]; then
39+
channel="#team-alpha"
3840
else
3941
exit 0
4042
fi

0 commit comments

Comments
 (0)