Skip to content

feat(ci): pin a single torch-spyre commit across all jobs in a run - #463

Open
BenjSz wants to merge 8 commits into
mainfrom
benjams/issue_449
Open

feat(ci): pin a single torch-spyre commit across all jobs in a run#463
BenjSz wants to merge 8 commits into
mainfrom
benjams/issue_449

Conversation

@BenjSz

@BenjSz BenjSz commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #449. A single CI run installed different torch-spyre commits across its jobs, because torch-spyre is a git checkout baked into each runner pod image at /home/senuser/torch-spyre and matrix jobs land on pods built at different times (the issue's example: 75 weekly-scan jobs spread across 6 commits). Results within one run were therefore not comparable or reproducible.

This resolves the torch-spyre revision once per run and pins it everywhere:

  • build-hf-adapters/action.yaml — new optional torch_spyre_sha input. When set, the baked checkout is fetched + checked out at exactly that commit before uv add (repurposes the previously-dead INPUT_REF branch). Empty (default) = today's behaviour, so other callers are unaffected.
  • gather-runner-info/action.yml — new pinned_torch_spyre_sha / hf_adapters_sha inputs. Asserts each job's checked-out torch-spyre HEAD equals the pinned SHA (fails the job on mismatch — the per-shard "verify it's pinned" check) and reports both SHAs in the run summary.
  • _test_matrix.yaml (PR / daily / integration) — new resolve-torch-spyre job resolves origin/main to one SHA on a spyre runner, threaded into all 24 suite + retry jobs and guarded by the run spyre unit tests gate so a resolve failure can't produce a false green.
  • push-to-clickhouse.yaml (the weekly scan — the issue's example run) — its own resolve-torch-spyre job (its generate-matrix runs on a backend runner without the checkout), threaded into the three weekly-model-scan-x1/-x2/-x4 fan-out jobs with a post-build pin-verify step.

hf-adapters SHA is already deterministic per run (PR head / github.sha); this change reports it alongside the pinned torch-spyre SHA rather than re-pinning it. Recording either commit in ClickHouse is a schema change and is out of scope.

Test plan

  • actionlint passes on both workflows and the full .github/workflows dir
  • pre-commit (check-yaml, whitespace, EOF, uv.lock) passes on all four files
  • Dispatch a push-to-clickhouse run (small top_k, clickhouse_db: dev) and a test_pull_request run; confirm every job's --- torch-spyre HEAD --- marker shows the identical SHA and the run summary shows the pinned SHA once

🤖 Generated with Claude Code

torch-spyre is baked into each runner pod image, so matrix jobs landed
on pods at different HEADs and one run mixed several torch-spyre commits,
making results incomparable (#449). Resolve origin/main to one SHA per
run, check that exact commit out before uv add in every job, assert each
job's HEAD matches, and report the pinned + hf-adapters SHAs in the run
summary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Benjamin Sznajder <benjams@il.ibm.com>
@BenjSz
BenjSz marked this pull request as ready for review September 3, 2026 10:22
@BenjSz
BenjSz requested a review from kmehant as a code owner September 3, 2026 10:22
@BenjSz
BenjSz enabled auto-merge September 3, 2026 10:22
@BenjSz
BenjSz disabled auto-merge September 3, 2026 10:24
Signed-off-by: Benjamin Sznajder <benjams@il.ibm.com>

@arielge arielge left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, this would break the integration test workflow - the integration infrastructure ensures that tests run on an image with a specific torch-spyre version (e.g., of a torch-spyre PR that triggers it), but then here we do git checkout --force "$SHA" which overrides that with a different torch-spyre version

@BenjSz

BenjSz commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

IIUC, this would break the integration test workflow - the integration infrastructure ensures that tests run on an image with a specific torch-spyre version (e.g., of a torch-spyre PR that triggers it), but then here we do git checkout --force "$SHA" which overrides that with a different torch-spyre version

I see - thus, the logic should be that the torch-spyre version "that is triggerring" the weekly should be passed to the different shard, afterthat...

@HarikrishnanBalagopal

HarikrishnanBalagopal commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

IIUC, this would break the integration test workflow - the integration infrastructure ensures that tests run on an image with a specific torch-spyre version (e.g., of a torch-spyre PR that triggers it), but then here we do git checkout --force "$SHA" which overrides that with a different torch-spyre version

yup we can use the same pattern as the torch-spyre repo prebaked_image https://github.com/torch-spyre/torch-spyre/blob/ffa47c1f06b94d000de90d4e93a3afb0727ae9f0/.github/workflows/integration-tests.yaml#L93-L101 and spyre-inference repo https://github.com/torch-spyre/spyre-inference/blob/a3044981f5c78b96eed4916c066f9c3ccf6711cd/.github/workflows/integration-tests.yaml#L89-L93
to avoid the checkout and rebuild/reinstall steps in the case of a prebaked-image that already contains the correct packages and source code

BenjSz and others added 2 commits September 8, 2026 13:24
The issue #449 pin unconditionally checked out origin/main into the baked
torch-spyre, clobbering the version the integration image was built to
test. Add a prebaked_image opt-out: integration-tests passes it true, which
skips resolve-torch-spyre, the per-job checkout, and the torch-spyre
reinstall entirely, so the run uses the image's baked-in venv as-is.
PR/daily/weekly keep pinning origin/main (default false).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Benjamin Sznajder <benjams@il.ibm.com>
Comment thread .github/actions/build-hf-adapters/action.yaml Outdated

@HarikrishnanBalagopal HarikrishnanBalagopal left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the full diff (5 files, all .github/). This is a solid, well-documented fix for #449 and it directly answers @arielge's CHANGES_REQUESTED concern: integration-tests.yaml now passes prebaked_image: true, which skips resolve-torch-spyre and the git checkout --force, so an integration run keeps the exact torch-spyre baked into its (per-PR) image instead of overwriting it with origin/main. Verified on the branch head:

  • .github/workflows/integration-tests.yaml:225 sets prebaked_image: true; every other caller omits it (default false = pin origin/main once).
  • resolve-torch-spyre.if: !inputs.skip_tests && !inputs.prebaked_image skips the job on that path, so its torch_spyre_sha output is '', build-hf-adapters takes its unpinned/prebaked branch, and gather-runner-info's pin assertion no-ops.

One substantive gap and two smaller points.

1. spyre-model-components-tests is left unpinned on the default path (partial #449 miss).
_test_matrix.yaml:791 spyre-model-components-tests (and its -retry at :1982) pass prebaked_image but NOT torch_spyre_sha, and the job has needs: [resolve-test-type] only (no resolve-torch-spyre), no pinned_torch_spyre_sha verify. It runs on ${{ inputs.image_label }} (the spyre runner that has the baked /home/senuser/torch-spyre) and is in the unit / integration / regression / trunk tiers (_test_matrix.yaml:794). So on the default pinned path, this one suite still installs whatever HEAD its pod's image baked in, while every sibling suite installs the resolved SHA. That is the exact within-run inconsistency #449 sets out to remove. The inline comment ("This job does not pin torch-spyre... runs on the image's baked-in torch-spyre") states the behavior but not why this suite is exempt. Could you either pin it like the others (add resolve-torch-spyre to needs, pass torch_spyre_sha + pinned_torch_spyre_sha/hf_adapters_sha), or, if it genuinely must stay on baked-in torch-spyre, spell out the reason so a reader does not read it as an oversight?

2. Retry jobs use a different gate than the primary jobs, worth confirming it is intentional.
The primary suite jobs guard with (needs.resolve-torch-spyre.result == 'success' || 'skipped') && ... so a pin FAILURE skips the matrix rather than running on baked-in torch-spyre. The -retry jobs instead keep if: !cancelled() && needs.collect-failed-suites.outputs.has_failed_* == 'true' with resolve-torch-spyre only added to needs. With !cancelled(), a retry job is not implicitly success()-gated, so if resolve-torch-spyre failed a retry could still fire on baked-in torch-spyre. In practice the primary jobs skip on pin failure, so nothing runs, so has_failed_* stays false and the retries do not fire, but the fail-closed property here is emergent from collect-failed-suites rather than explicit. A one-line comment noting that (or mirroring the result == guard) would make the two paths read consistently. Not a blocker.

3. git fetch ... origin "${TORCH_SPYRE_SHA}" relies on server-side fetch-by-SHA.
build-hf-adapters/action.yaml fetches the bare 40-char SHA, with a full-fetch fallback (|| git fetch --tags --force origin). Fetch-by-SHA needs uploadpack.allowReachableSHA1InWant/allowAnySHA1InWant on the remote; if the server rejects it the fallback covers it, so this is fine. Just flagging that the fallback is load-bearing, not cosmetic, in case someone trims it later.

Nits already left inline: uv pip show --active / uv pip freeze --active on the prebaked path (--active should be harmless for a show/freeze but is not needed).

Test plan question: the PR body's test plan is unchecked-in-spirit for the integration path. Since the biggest behavioral change is the new prebaked_image=true branch that #449's original patch did not have, has an actual integration-tests run been dispatched on a per-PR image to confirm the suites use the image's torch-spyre and do NOT re-resolve? A dispatched push-to-clickhouse (small top_k, dev db) plus one integration-tests run, with the per-job torch-spyre HEAD markers pasted, would close the loop on the exact regression @arielge raised.

BenjSz and others added 3 commits September 8, 2026 16:23
remove useless --active in uv pip freeze | show
…fail-closed

Address PR #463 review (issue #449):

1. spyre-model-components-tests (+ -retry) was the one suite left unpinned
   on the default path -- it ran on its pod's baked-in torch-spyre HEAD while
   every sibling suite installed the resolved SHA, the exact within-run
   inconsistency #449 removes. The suite exercises torch-spyre (moves tensors
   to Spyre, requires_spyre), so there is no reason to exempt it. Pin it like
   the others: add resolve-torch-spyre to needs, gate on its result, pass
   torch_spyre_sha to build, and add the pinned_torch_spyre_sha/hf_adapters_sha
   pin-verify to gather-runner-info. On the prebaked integration path
   resolve-torch-spyre is skipped, torch_spyre_sha is '' and the verify no-ops,
   matching token_compare/embed_compare exactly.

2. Document why the *-retry jobs use !cancelled() rather than the primary
   jobs' result == guard: fail-closed on a pin failure is emergent (a failed
   pin skips every primary, so nothing runs, so has_failed_* stays false and
   the retry never fires). Full note on spyre-load-tests-retry; short pointer
   on spyre-model-components-tests-retry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@BenjSz

BenjSz commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review @HarikrishnanBalagopal. Addressed in 129a3f4:

1. spyre-model-components-tests unpinned on the default path — fixed by pinning it like the others.
test_model_components_spyre.py is requires_spyre and moves tensors onto Spyre / exercises the compiled RoPE path, so it genuinely runs against torch-spyre — there was no reason to exempt it; it was an oversight. Both the primary suite (:861) and its retry (:2155) now:

  • add resolve-torch-spyre to needs,
  • gate the primary on (needs.resolve-torch-spyre.result == 'success' || 'skipped') (same guard as token_compare/embed_compare),
  • pass torch_spyre_sha to build-hf-adapters (id: build),
  • pass pinned_torch_spyre_sha + hf_adapters_sha to gather-runner-info for the per-shard pin-verify.

On the prebaked integration path (prebaked_image: true) resolve-torch-spyre is skipped, so torch_spyre_sha is '', the build takes its prebaked branch, and the pin assertion no-ops — identical to every sibling suite.

2. Retry gate vs. primary gate — documented rather than changed.
The retries stay on !cancelled() && has_failed_* == 'true'; the fail-closed property is emergent, as you noted. I added the full explanation on spyre-load-tests-retry (a pin failure skips every primary → nothing runs → has_failed_* stays false → the retry never fires; !cancelled() only survives the expected failure() of the primary) and a one-line pointer to it on spyre-model-components-tests-retry, so the two paths read consistently.

3. Load-bearing git fetch-by-SHA fallback — agreed, no change; leaving as-is with the full-fetch fallback.

actionlint (whole .github/workflows dir) and pre-commit pass.

On the test-plan question: I haven't dispatched the integration-tests + push-to-clickhouse runs yet to paste the per-job torch-spyre HEAD markers. I'll kick those off and post the marker output here to close the loop on the integration regression.

Signed-off-by: Benjamin Sznajder <benjams@il.ibm.com>
@BenjSz
BenjSz enabled auto-merge September 10, 2026 12:00
@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

⚙️ Auto-merge enabled — dispatched /spyre-test for db0d481d because the required Spyre Test gate had not run on this commit.

Automated: enabling auto-merge requests the gate, so the PR is not left waiting on a check nobody asked for. Re-enabling auto-merge on this same commit will not dispatch again.

@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

✅ spyre-test: success

Triggered by: /spyre-test comment

Plan (build waves + dependencies, per arch)

amd64

flowchart LR
  subgraph Lamd64_0["amd64 L0 · 1 parallel"]
    n_amd64_torch_spyre_torch_spyre_dev["torch-spyre/torch-spyre-dev 🟢<br/>image · a39b59f6076f"]
  end
  subgraph Lamd64_1["amd64 L1 · 1 parallel"]
    n_amd64_hf_adapters_hf_adapters_dev["hf-adapters/hf-adapters-dev 🟢<br/>image · a225402a774e"]
  end
  subgraph Lamd64_2["amd64 L2 · 1 parallel"]
    n_amd64_spyre_inference_spyre_inference_dev["spyre-inference/spyre-inference-dev 🟢<br/>image · 2fa8181dccc9"]
  end
  n_amd64_torch_spyre_torch_spyre_dev --> n_amd64_hf_adapters_hf_adapters_dev
  n_amd64_hf_adapters_hf_adapters_dev --> n_amd64_spyre_inference_spyre_inference_dev
  classDef sPending fill:#eceff1,stroke:#90a4ae,color:#37474f
  classDef sBuilding fill:#fff8e1,stroke:#f9a825,color:#5d4037,stroke-width:2px
  classDef sOk fill:#e8f5e9,stroke:#43a047,color:#1b5e20
  classDef sReused fill:#e3f2fd,stroke:#1e88e5,color:#0d47a1
  classDef sFailed fill:#ffebee,stroke:#e53935,color:#b71c1c,stroke-width:2px
  classDef sDropped fill:#f5f5f5,stroke:#bdbdbd,color:#9e9e9e
  class n_amd64_torch_spyre_torch_spyre_dev sOk;
  class n_amd64_hf_adapters_hf_adapters_dev sOk;
  class n_amd64_spyre_inference_spyre_inference_dev sOk;
Loading

✅ orch trigger-pr-validationgreen · arches amd64 · fp amd64=8a452b82

level component arch build smoke unit integration trunk regression perf
L0 torch-spyre/torch-spyre-dev amd64 ✅ ok · 🟢 gha · · ·
L1 hf-adapters/hf-adapters-dev amd64 ✅ ok 🟢 · 🟢 gha · · ·
L2 spyre-inference/spyre-inference-dev amd64 ✅ ok 🟢 · 🟢 gha · · ·

GHA test runs:


✅ safe to merge

Build: built 3

Tests: passed 6 · blocking 0 · advisory 0 · infra/inconclusive 0 · no signal 0

Before merging, consider:

  • Every leg that ran passed, and no leg was left without a signal, and every build cell settled.

@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

GHA test runs:

@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

GHA test runs:

@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

GHA test runs:

@BenjSz
BenjSz added this pull request to the merge queue Sep 10, 2026
@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

❌ merge-queue-integration: failure

Plan (build waves + dependencies, per arch)

amd64

flowchart LR
  subgraph Lamd64_0["amd64 L0 · 1 parallel"]
    n_amd64_torch_spyre_torch_spyre_dev["torch-spyre/torch-spyre-dev 🔴<br/>image · 16ec4926d4c8"]
  end
  subgraph Lamd64_1["amd64 L1 · 1 parallel"]
    n_amd64_hf_adapters_hf_adapters_dev["hf-adapters/hf-adapters-dev<br/>image · 9e02b8719045"]
  end
  subgraph Lamd64_2["amd64 L2 · 1 parallel"]
    n_amd64_spyre_inference_spyre_inference_dev["spyre-inference/spyre-inference-dev<br/>image · 86eca61204b1"]
  end
  n_amd64_torch_spyre_torch_spyre_dev --> n_amd64_hf_adapters_hf_adapters_dev
  n_amd64_hf_adapters_hf_adapters_dev --> n_amd64_spyre_inference_spyre_inference_dev
  classDef sPending fill:#eceff1,stroke:#90a4ae,color:#37474f
  classDef sBuilding fill:#fff8e1,stroke:#f9a825,color:#5d4037,stroke-width:2px
  classDef sOk fill:#e8f5e9,stroke:#43a047,color:#1b5e20
  classDef sReused fill:#e3f2fd,stroke:#1e88e5,color:#0d47a1
  classDef sFailed fill:#ffebee,stroke:#e53935,color:#b71c1c,stroke-width:2px
  classDef sDropped fill:#f5f5f5,stroke:#bdbdbd,color:#9e9e9e
  class n_amd64_torch_spyre_torch_spyre_dev sOk;
  class n_amd64_hf_adapters_hf_adapters_dev sFailed;
  class n_amd64_spyre_inference_spyre_inference_dev sDropped;
Loading

⚠️ orch trigger-pr-validationyellow · arches amd64 · fp amd64=24e53221

level component arch build smoke unit integration trunk regression perf
L0 torch-spyre/torch-spyre-dev amd64 ✅ ok · 🟡 gha · · ·
L1 hf-adapters/hf-adapters-dev amd64 ❌ failed ⏭️ · · · ⏭️ ·
L2 spyre-inference/spyre-inference-dev amd64 ⛔ dropped ⏭️ · ⏭️ · · ·

GHA test runs:


❌ build failed (1) — do not merge

Build: built 1 · failed 1 · dropped 1

  • build · hf-adapters/hf-adapters-dev/amd64: failed
    • depends on: torch-spyre

Tests: passed 0 · blocking 0 · advisory 2 · infra/inconclusive 0 · no signal 0

Failures by kind
  • ⚠️ advisory (does not block) · torch-spyre/amd64 integration: UNSTABLE
  • ⚠️ advisory (does not block) · torch-spyre/amd64 gha:integration: FAILURE

Before merging, consider:

  • hf-adapters/hf-adapters-dev/amd64 failed to BUILD — this blocks the merge. No test result below says anything about this change: those legs never dispatched. Fix the build first, then re-run.

@arielge
arielge removed this pull request from the merge queue due to a manual request Sep 10, 2026
@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

GHA test runs:

@BenjSz
BenjSz added this pull request to the merge queue Sep 10, 2026
@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

❌ merge-queue-integration: failure

Plan (build waves + dependencies, per arch)

amd64

flowchart LR
  subgraph Lamd64_0["amd64 L0 · 1 parallel"]
    n_amd64_torch_spyre_torch_spyre_dev["torch-spyre/torch-spyre-dev 🔴 ↺<br/>image · fc1752087216"]
  end
  subgraph Lamd64_1["amd64 L1 · 1 parallel"]
    n_amd64_hf_adapters_hf_adapters_dev["hf-adapters/hf-adapters-dev 🟢<br/>image · 5e4624f9f429"]
  end
  subgraph Lamd64_2["amd64 L2 · 1 parallel"]
    n_amd64_spyre_inference_spyre_inference_dev["spyre-inference/spyre-inference-dev 🔴<br/>image · 75f3523c474b"]
  end
  n_amd64_torch_spyre_torch_spyre_dev --> n_amd64_hf_adapters_hf_adapters_dev
  n_amd64_hf_adapters_hf_adapters_dev --> n_amd64_spyre_inference_spyre_inference_dev
  classDef sPending fill:#eceff1,stroke:#90a4ae,color:#37474f
  classDef sBuilding fill:#fff8e1,stroke:#f9a825,color:#5d4037,stroke-width:2px
  classDef sOk fill:#e8f5e9,stroke:#43a047,color:#1b5e20
  classDef sReused fill:#e3f2fd,stroke:#1e88e5,color:#0d47a1
  classDef sFailed fill:#ffebee,stroke:#e53935,color:#b71c1c,stroke-width:2px
  classDef sDropped fill:#f5f5f5,stroke:#bdbdbd,color:#9e9e9e
  class n_amd64_torch_spyre_torch_spyre_dev sReused;
  class n_amd64_hf_adapters_hf_adapters_dev sOk;
  class n_amd64_spyre_inference_spyre_inference_dev sOk;
Loading

✅ orch trigger-pr-validationgreen · arches amd64 · fp amd64=add923f9

level component arch build smoke unit integration trunk regression perf
L0 torch-spyre/torch-spyre-dev amd64 ✅ ok (reused) 🟢 · 🟡 gha · · ·
L1 hf-adapters/hf-adapters-dev amd64 ✅ ok 🟢 · · · 🟢 gha ·
L2 spyre-inference/spyre-inference-dev amd64 ✅ ok 🟢 · 🟡 gha · · ·

GHA test runs:


⚠️ advisory failures only — mergeable, see below

Build: built 2 · reused 1

Tests: passed 3 · blocking 0 · advisory 2 · infra/inconclusive 0 · no signal 0

Failures by kind
  • ⚠️ advisory (does not block) · torch-spyre/amd64 integration: UNSTABLE
  • ⚠️ advisory (does not block) · torch-spyre/amd64 gha:integration: FAILURE
  • ℹ️ informational · spyre-inference/amd64 gha:integration: FAILURE

Before merging, consider:

  • torch-spyre/amd64 gha:integration, torch-spyre/amd64 integration failed with gating: "unstable" — advisory. It set the build UNSTABLE but does not block the merge. Worth a look, not a stop.
  • spyre-inference/amd64 gha:integration failed with gating: false — informational only, no merge impact.

@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

GHA test runs:

@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

GHA test runs:

@spyre-ci

spyre-ci Bot commented Sep 10, 2026

Copy link
Copy Markdown

GHA test runs:

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 10, 2026
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.

Pin a single torch-spyre commit across all jobs in a workflow run

3 participants