Skip to content

feat(generate): fan out per-component promote workflows with isolated concurrency - #518

Merged
joshua-temple merged 1 commit into
mainfrom
feat/promote-fanout
Jul 8, 2026
Merged

joshua-temple merged 1 commit into
mainfrom
feat/promote-fanout

Conversation

@joshua-temple

Copy link
Copy Markdown
Collaborator

Problem

With per-component promotion state recorded (#517), the generator must emit per-component promote workflows, each isolated so one component's promote never cancels or serializes another's. Two collision hazards exist: a component's resolved config carries the orchestrate concurrency group, and a manifest-global concurrency.group would collapse every component onto one lane.

Fix

  • When a manifest declares components:, generate one promote-<name>.yaml per component (mirroring the orchestrate fan-out), each emitting --component <name>.
  • Each promote workflow uses a dedicated promote-<name> concurrency namespace, distinct from the orchestrate-<name> lane.
  • When a global concurrency.group is set, the per-component promote composes it as <global>-promote-<name> so component identity is always present and isolation never collapses onto one literal lane.
  • No components: block generates a byte-identical single promote.yaml (no --component, original group).
  • The generate and verify (Plan) paths share one fan-out helper, so they cannot disagree.

Verification

go build ./..., go test ./... (2584 pass), go test -race on changed packages (1065 pass), golangci-lint run ./... clean; e2e module build+vet clean. Single-component byte-identical baseline gate green. New e2e scenario 50-component-promote-fanout.yaml (Per-Component Promote Generation) passes locally in the act+gitea harness (23s): asserts each promote-<name>.yaml exists, carries its own promote-<name> group and --component, and that no repo-wide promote.yaml exists for a components manifest.

Refs #291.

… concurrency

When a manifest declares components, generate one promote-<name>.yaml per component, mirroring the per-component orchestrate fan-out, each emitting --component so promotion computes and records that component's state. Each promote workflow gets its own concurrency namespace, promote-<name>, distinct from the orchestrate lane, so a component's promote never shares a repo-global lane with its orchestrate run. When a manifest sets a global concurrency group, the per-component promote composes it as <global>-promote-<name> so component identity is always present and isolation never collapses onto one literal lane. A manifest with no components generates a byte-identical single promote.yaml with no --component and the original group. The generate and verify paths share one fan-out helper so they cannot disagree.

Refs #291.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
@joshua-temple
joshua-temple merged commit ca775dd into main Jul 8, 2026
20 checks passed
@joshua-temple
joshua-temple deleted the feat/promote-fanout branch July 8, 2026 06:22
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