Skip to content

ci: split ci.yml into reusable build + test workflows#172

Draft
robtaylor wants to merge 5 commits into
mainfrom
ci-macos-xlarge
Draft

ci: split ci.yml into reusable build + test workflows#172
robtaylor wants to merge 5 commits into
mainfrom
ci-macos-xlarge

Conversation

@robtaylor

@robtaylor robtaylor commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

What & why

The organically-grown ci.yml had reached 2056 lines with build and test
logic interleaved per backend. This splits it into a build → test pipeline
behind a thin orchestrator, so every target configuration is compiled once on a
cheap standard runner and the resulting binary is handed to the test jobs on the
appropriate runners. Full design in docs/plans/ci-build-test-split.md.

ci.yml (orchestrator) ── changes ── build.yml ── test.yml
                                  └─ docs (Pages, ungated)
  • build.yml (reusable, workflow_call): a 4-way matrix producing one
    artifact per config — jacquard-{cpu,cuda,hip,metal}, all carrying the
    synth on-ramp. CUDA is all-major SASS so one build feeds both the T4 and
    the self-hosted Blackwell runner.
  • test.yml (reusable): the full test batch run against those prebuilt
    artifacts. CPU/compile-in-place jobs on ubuntu-latest; CUDA/HIP on the
    GitHub-hosted T4; Metal + MCU-SoC + JTAG on macos-latest-xlarge.
  • ci.yml is now a 129-line orchestrator. It passes code (docs-only
    gate) and build_result into test.yml so a failed build surfaces as a
    failed required check
    (via each artifact job's explicit build-gate step)
    rather than a silently-passing skip.
  • Divergent toolchain setup and the artifact download+chmod are factored into
    composite actions under .github/actions/ (setup-{cuda,hip,metal},
    init-submodules, download-jacquard), shared between build and test.

Scope: faithful move

Each backend keeps its current test content (Metal its rich suite, CUDA/HIP
the shared gpu_test_suite.sh). Unifying the batch across backends is a tracked
follow-up, not part of this PR — it would run new tests on CUDA/HIP for the
first time and needs GPU-runner triage.

Decisions baked in

  • synth is uniform on every artifact (published + test binaries).
  • Runner strategy: functional gating on GitHub-hosted runners (parallel);
    self-hosted nvidia1 reserved for perf. cuda-blackwell is non-gating
    it skips (not fails) when the build didn't succeed, so an offline box never
    blocks a merge.
  • CVC MCU-SoC path is an advisory guide, not a gate: mcu-soc-comparison
    gains continue-on-error so a CVC↔Metal mismatch is surfaced in the step
    summary without blocking merges.

Validation

Green on the first run — every job passed, including the artifact reuse
(one CUDA build → T4 + Blackwell), the new cosim-cpu artifact-consume path,
and backend equivalence:
https://github.com/gpu-eda/Jacquard/actions/runs/28785097079

⚠️ Required before merge: update branch-protection check names

The test jobs now run inside the reusable test.yml, so their check names gain
a Test / prefix. The 7 currently-required checks must be renamed:

Old (remove) New (add)
Lint Test / Lint
Unit Tests Test / Unit Tests
Metal Tests (macOS) Test / Metal Tests (macOS)
CUDA Tests Test / CUDA Tests
HIP Tests (NVIDIA backend) Test / HIP Tests (NVIDIA backend)
Benchmarks Test / Benchmarks
MCU SoC Metal Simulation Test / MCU SoC Metal Simulation

Because this PR reports the new names, it can't satisfy the old required
checks — merge it via admin override, then immediately update the required set
(other in-flight PRs will pick up the new names on rebase).

Follow-ups (separate PRs, build on this)

  1. Unify the test batch across backends (gpu_test_suite.sh).
  2. release.yml reuse of build.yml → publish Linux CUDA binaries; move
    release-metal off self-hosted macos-runner-1.
  3. Single fat CUDA+HIP binary (jacquard-only; ulib already supports it).
  4. Real AMD/ROCm runner on nvidia1.

robtaylor added 2 commits July 6, 2026 10:28
Introduce the build half of the planned build/test split (see
docs/plans/ci-build-test-split.md): a reusable `build.yml` (on:
workflow_call) that compiles jacquard for each target config on a cheap
standard runner and uploads one artifact per config —
jacquard-{cpu,cuda,hip,metal}, all carrying the `synth` on-ramp.

The divergent toolchain setup is extracted into composite actions so it
is shared between the build job and the matching test job later:
  - init-submodules: parameterised submodule init
  - setup-cuda:      CUDA toolkit (compile) or cudart (runtime-only)
  - setup-hip:       composes setup-cuda + ROCm/HIP (NVIDIA backend)
  - setup-metal:     Homebrew LLVM (clang+OpenMP), or runtime dylibs only

Nothing triggers build.yml yet (workflow_call is dormant); the thin
ci.yml orchestrator and test.yml follow in subsequent commits. The
cuda/hip artifacts are separate for now but ulib already supports both
backends in one binary, so the matrix can later collapse them into one
fat cuda,hip artifact without reshaping the workflow.

Co-developed-by: Claude Code v2.1.201 (claude-opus-4-8)
Cut the monolithic 2056-line ci.yml over to the build/test pipeline from
docs/plans/ci-build-test-split.md:

  ci.yml (orchestrator) → changes → build.yml → test.yml
                                  → docs (Pages, ungated)

- test.yml (reusable): the full test batch against the prebuilt artifacts
  from build.yml, on the appropriate runners — CPU/compile-in-place jobs
  on ubuntu, CUDA/HIP on the GitHub-hosted T4, Metal + MCU-SoC + JTAG on
  macos-latest-xlarge. Faithful move: each backend keeps its current test
  content (Metal its rich suite, CUDA/HIP the shared gpu_test_suite.sh);
  unifying the batch across backends is a tracked follow-up.
- ci.yml is now a thin orchestrator. It passes `code` (docs-only gate) and
  `build_result` into test.yml so a FAILED build surfaces as a FAILED
  required check via each artifact job's explicit build-gate step, rather
  than a silently-passing skip. docs stays inline (Pages deploy needs
  contents:write and must run on docs-only pushes).
- Self-hosted nvidia1 (cuda-blackwell) is non-gating: it skips — not fails
  — when the build didn't succeed, so an offline box never blocks a merge.
- CVC mcu-soc path is now an advisory guide, not a gate: mcu-soc-comparison
  gains continue-on-error so a CVC<->Metal mismatch is surfaced in the step
  summary without blocking merges (mcu-soc-cvc was already advisory).
- New download-jacquard composite action single-sources the artifact
  download+chmod (jacquard-<backend>) across the 8 GPU/downstream jobs.

The old per-job build steps are gone — GPU jobs consume build.yml's
artifacts. cuda/hip stay separate artifacts for now; the matrix is shaped
so a future fat cuda,hip binary collapses them without reshaping the flow.

Co-developed-by: Claude Code v2.1.201 (claude-opus-4-8)
@robtaylor robtaylor changed the title Test CI just on macos xlarge runners ci: split ci.yml into reusable build + test workflows Jul 6, 2026
Co-developed-by: Claude Code v2.1.201 (claude-opus-4-8)
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