feat: matrix mode — plan command + release --only / --pin-version#7
Merged
Conversation
Split deciding from building so CI can fan one runner out per build group (#5): - stevedore plan: resolves per-image versions, runs change detection (marker refs / --changed-since / --only-changed), applies build-once grouping, and prints the plan as compact JSON without building. The include array is GitHub Actions matrix shape — one entry per group, carrying ids, only (csv), per-member versions, ready-made --pin-version flags, and the build reason; skips are listed with their reason. Progress goes to stderr, stdout is only the document. - release --only <ids>: build exactly those images, unconditionally — selection was the planner's decision. Unknown ids fail fast. - release --pin-version id=ver (repeatable): tag exactly what the plan resolved; pinned images skip remote version resolution entirely, so matrix jobs need no registry read for versioning. - Release markers now advance after ANY real push (previously only in marker-detection mode), so --only matrix jobs and --changed-since runs keep every image's baseline current. - action.yml: plan output wired for strategy.matrix consumption. The eval/group pre-pass is extracted from Release and shared with Plan (internal/pipeline/plan.go); behavior is unchanged for existing modes. Verified against real multi-image configs: a 5-member identical-spec group plans as one entry with per-member ECR versions; 13 build-arg- distinct images plan as 13 entries with .csproj-graph change reasons.
release --only resolved every config image's version before filtering, so a matrix job still issued a registry read per excluded image — and the release-level version anchored on cfg.Images[0], reading a repo the job may not even have access to once per-service push roles land. - resolvePlans now takes the --only selection and skips excluded images before version resolution (filterPlans folded in). - resolveVersion anchors on the first *selected* image; when that image is pinned in per-image registry mode the pin is the release version, so a fully-pinned matrix job performs no registry read at all. - validateImageIDs moved ahead of version resolution so an unknown --only id fails fast with the intended error. Verified against the real dis config: `release --only dis --pin-version dis=0.0.160 --dry-run` and a full 5-way group replay from `plan` output both run with no AWS credentials. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Closes #5.
What
Splits deciding from building so CI can fan one runner out per build group — almost like a matrix build, because it is one:
stevedore plan— resolves per-image versions, runs change detection (marker refs /--changed-since/--only-changed), applies build-once grouping, and prints the plan as one compact JSON line without building.includeis GitHub Actions matrix shape: one entry per build group withids,only(csv), per-memberversions, ready-madepinsflags, and the buildreason. Skipped images are listed with their reason. Progress → stderr; stdout carries only the document.release --only <ids>— builds exactly those images, unconditionally (selection was the planner's decision). Unknown ids fail fast.release --pin-version id=ver(repeatable) — tags exactly what the plan resolved. Pinned images skip remote version resolution entirely, so a matrix job needs no registry read for versioning.--onlymatrix jobs and--changed-sinceruns now keep every image's baseline current (the marker records last released, not last marker-diffed).command: planexposes the document as theplanoutput forstrategy.matrix.How
The eval/group pre-pass is extracted from
ReleaseintoevaluateImages/groupPlans(internal/pipeline/plan.go) and shared by both paths — existing modes behave identically.Verified
make checkgreen (lint + race tests); new table tests for grouping, plan rendering,--onlyfiltering/validation, pin parsing and precedence..csproj-graph change reasons;release --only dis --pin-version dis=X --dry-runbuilds just that image with the pinned tag and no registry access.