ci: split the conformance leg and build the e2e images once - #371
Merged
Conversation
The conformance leg ran miroir's Go specs and the upstream external-storage suite back to back, which made it the longest lane by about fourteen minutes (38m against the next-longest 28m). Neither suite needs the other's state, so they get a leg each -- specs and local -- both against the miroir-local class. A fresh cluster costs about six minutes, so the split is a clear win. Every leg also rebuilt all three images itself, which meant six builds racing one GHA cache scope apiece and an ordering hack where only the replicated leg wrote each scope back. A new e2e-images job builds them once, exports all three in a single docker save (~135MB, since gateway shares every agent layer), and hands them to the matrix as an artifact. Each leg loads it into its own runner-local registry while its VMs boot, so the nodes still pull over loopback and every leg now installs identical bytes. The gateway image was being built by every leg and installed by one; building once removes that without a special case. Export uses shell: bash for the pipefail the implicit `bash -e` default lacks, or a failed save would pass the step on gzip's exit status and hand every leg a truncated tarball. Signed-off-by: Devin Buhl <devin@buhl.casa>
gabrielcosi
pushed a commit
to gabrielcosi/home-ops
that referenced
this pull request
Jul 29, 2026
….11.12 ➔ 0.11.13) (#185) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/home-operations/charts/miroir](https://github.com/home-operations/miroir) | patch | `0.11.12` → `0.11.13` | --- ### Release Notes <details> <summary>home-operations/miroir (ghcr.io/home-operations/charts/miroir)</summary> ### [`v0.11.13`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#01113-2026-07-29) [Compare Source](home-operations/miroir@0.11.12...0.11.13) ##### Bug Fixes - **csi:** refuse to reformat a restore whose device reads blank ([#​373](home-operations/miroir#373)) ([b7ab14b](home-operations/miroir@b7ab14b)) ##### Continuous Integration - split the conformance leg and build the e2e images once ([#​371](home-operations/miroir#371)) ([3d58054](home-operations/miroir@3d58054)) </details> --- ### Configuration 📅 **Schedule**: (in timezone Europe/Berlin) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4wLjAiLCJ1cGRhdGVkSW5WZXIiOiI0NC4wLjAiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbInJlbm92YXRlL2NvbnRhaW5lciIsInR5cGUvcGF0Y2giXX0=--> Reviewed-on: https://git.xcd.dev/gabrielcosi/home-ops/pulls/185
doonga
pushed a commit
to greyrock-labs/home-ops
that referenced
this pull request
Jul 30, 2026
….11.12 ➔ 0.11.13) (#211) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/home-operations/charts/miroir](https://github.com/home-operations/miroir) | patch | `0.11.12` → `0.11.13` | --- ### Release Notes <details> <summary>home-operations/miroir (ghcr.io/home-operations/charts/miroir)</summary> ### [`v0.11.13`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#01113-2026-07-29) [Compare Source](home-operations/miroir@0.11.12...0.11.13) ##### Bug Fixes - **csi:** refuse to reformat a restore whose device reads blank ([#​373](home-operations/miroir#373)) ([b7ab14b](home-operations/miroir@b7ab14b)) ##### Continuous Integration - split the conformance leg and build the e2e images once ([#​371](home-operations/miroir#371)) ([3d58054](home-operations/miroir@3d58054)) </details> --- ### Configuration 📅 **Schedule**: (in timezone America/New_York) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4wLjAiLCJ1cGRhdGVkSW5WZXIiOiI0NC4wLjAiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbInJlbm92YXRlL2NvbnRhaW5lciIsInR5cGUvcGF0Y2giXX0=--> Reviewed-on: https://git.greyrock.io/greyrock-labs/home-ops/pulls/211
eleboucher
pushed a commit
to eleboucher/homelab
that referenced
this pull request
Jul 31, 2026
….11.12 ➔ 0.11.15) (#1764) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/home-operations/charts/miroir](https://github.com/home-operations/miroir) | patch | `0.11.12` → `0.11.15` | --- ### Release Notes <details> <summary>home-operations/miroir (ghcr.io/home-operations/charts/miroir)</summary> ### [`v0.11.15`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#01115-2026-07-31) [Compare Source](home-operations/miroir@0.11.14...0.11.15) ##### Bug Fixes - **csi:** log retryable status codes below error level ([#​380](home-operations/miroir#380)) ([4774d21](home-operations/miroir@4774d21)) - **snapshot:** lift possibly-set barrier on failed suspend-io and sweep mid-runtime ([#​382](home-operations/miroir#382)) ([09e3aa7](home-operations/miroir@09e3aa7)) ### [`v0.11.14`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#01114-2026-07-30) [Compare Source](home-operations/miroir@0.11.13...0.11.14) ##### Features - **go:** update module google.golang.org/grpc (v1.82.1 → v1.83.0) ([#​375](home-operations/miroir#375)) ([572e629](home-operations/miroir@572e629)) ##### Bug Fixes - **ci:** key the lint cache on the toolchain and drop the prefix fallback ([#​374](home-operations/miroir#374)) ([789e990](home-operations/miroir@789e990)) ### [`v0.11.13`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#01113-2026-07-29) [Compare Source](home-operations/miroir@0.11.12...0.11.13) ##### Bug Fixes - **csi:** refuse to reformat a restore whose device reads blank ([#​373](home-operations/miroir#373)) ([b7ab14b](home-operations/miroir@b7ab14b)) ##### Continuous Integration - split the conformance leg and build the e2e images once ([#​371](home-operations/miroir#371)) ([3d58054](home-operations/miroir@3d58054)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/1764
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
conformanceleg ran miroir's Go specs and the upstream external-storage suite back to back, which made it the longest lane by about fourteen minutes. Neither suite needs the other's state, so they get a leg each.Every leg also rebuilt all three images itself, so a shared
e2e-imagesjob now builds them once and hands them to the matrix.Why
Timings from a green run on #364 (
30453357794):The conformance leg's 33m48 was 1m39 install + 13m47 Go specs + 18m09 upstream suite. Splitting those gives roughly a 20m leg and a 24m leg, so the critical path drops to about 28m and
zfsbecomes the new ceiling.There is no slack left inside a leg. Sum-of-spec-time against wall clock at
procs=4, from the JUnit artifacts:procscannot go higher either — the runner is 4 CPU / 15.61 GiB already hosting three VMs. More clusters is the only lever, which is what this change spends.Changes
Split —
conformancebecomesspecs(Go specs,conformance: "0") andlocal(upstream suite), both ontestdriver-local.yamlwith capacity on. This reuses theRUN_CONFORMANCEknob andconformance: "0"convention already intest.shfor the autodiskful leg, sotest.shis unchanged.Shared images — a new
e2e-imagesjob builds controller/agent/gateway withload: true, exports all three in onedocker save | gzip(~135MB, since gateway shares every agent layer) and uploads it as an artifact. Each leg downloads and loads it into its own runner-local registry while its VMs boot, so nodes still pull over loopback andpatches/registry.yamlis untouched.Fallout that cleaned up on its own:
cache-to: ${{ matrix.suite == 'replicated' && … }}ordering hack is gone. One job owns each scope, so eachcache-tois unconditional and the cache cannot go unwritten if that leg is renamed or fails early.setup-buildxand itsnetwork=hostare gone from the legs entirely.matrix.specs == '1', and the e2e.test download onmatrix.conformance != '0'.Verified
The image path was run locally end to end rather than assumed: built all three,
docker saveof the set is 135MB,docker loadrestores all threelocalhost:5000/…:e2etags, and pushing into a realregistry:3gives a catalog with all three.actionlint(with the shared workflow-lint action's own ignore flags),zizmor,shellcheck,go vet -tags e2eandgolangci-lintare clean.One bug caught while writing it: GitHub's implicit
runshell isbash -e {0}with nopipefail, so a faileddocker savewould have exited 0 viagzipand handed every leg a truncated tarball. That step setsshell: bash.Tradeoff
The shared build job adds its own duration to the front of every leg, since the per-leg builds were previously hidden behind the cluster boot. The wall-clock win here comes from the split; the build job buys identical bytes across legs and the cache-scope cleanup. It also scales — the more the matrix shards, the more a single build amortises.
Next
Sharding the heavy upstream legs by
[Testpattern: …]should take the critical path to roughly 14-16m.run.shalready readsFOCUS/SKIPfrom env, so it is matrix-only work — but settingSKIPin a matrix row overrides run.sh's default\[Disruptive\]|\[Serial\]|…, which would re-admit Serial specs into a parallel shard. That wants append semantics first.