Skip to content

feat(cli): add the reconcile command - #476

Merged
joshua-temple merged 10 commits into
mainfrom
feat/reconcile-command
Jul 6, 2026
Merged

joshua-temple merged 10 commits into
mainfrom
feat/reconcile-command

Conversation

@joshua-temple

Copy link
Copy Markdown
Collaborator

Problem

When an action pin in a cascade-generated workflow is bumped externally, there was no supported way to fold that change back into the manifest so the whole pipeline agrees again. The only options were to hand-edit generated files (drift that regeneration overwrites) or to edit the manifest by hand.

Fix

Adds the reconcile command: it reads the incoming ref from the changed workflow files as data, adopts it verbatim into the manifest's action_pins, and regenerates so every generated file agrees. Generation stays a pure offline function of the manifest; a pin is never read back out of a generated file.

Three modes:

  • default user-repo reconcile: a surgical yaml.Node edit of the user manifest (comments and key order preserved), then regenerate. Idempotent; a converged second pass is a no-op.
  • --check: a read-only detector that writes a data-only relevance artifact.
  • --own-repo: cascade's own repo mode, which reconciles the disk action_pins.yaml (including composite-action pins) and regenerates, preserving its header comment block.

The command never pushes or merges. Both tag and sha adoptions are supported; a sha keeps its trailing # <version>.

Verification

  • go build ./..., go test ./... (all green), go test ./... -race, golangci-lint run ./... all clean.
  • New e2e scenario TestReconcileAdoptsBumpAndSurvivesRegen ran under Docker and proves a bump survives reconcile and regenerate with a clean cascade verify.
  • Docs updated in this PR: cli-reference.md (the command), configuration.md (action_pins as the write target), CONTRIBUTING.md (governed-pin standard). Docs site builds.
  • Independent review passed.

Closes #442. Part of #440.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
…nd regenerate

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
Adds a reconcile step to the multi-step harness DSL and a scenario that
stages a real two-environment pipeline, mutates the generated
orchestrate.yaml's checkout pin in place to simulate an external bump,
runs cascade reconcile, and requires both that the regenerated file
carries the adopted pin and that a subsequent cascade verify stays
clean.

Running the scenario under Docker surfaced a real bug: Run and
RunOwnRepo resolved the default manifest path relative to Root, while
verify's auto-detect always resolves through the working directory to
an absolute path. Since generate.Plan embeds that path verbatim in the
generated header's "Regenerate with" comment, the two commands wrote
different header text for the same file, so a reconcile-then-verify
cycle reported spurious drift on that line alone. Both now resolve the
default manifest path the same way, through a shared helper.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
Adds a reconcile section alongside verify: the three modes (default
user-repo reconcile, --check read-only detector, --own-repo for
cascade's own repo), the real flags, what it reads and writes, and
that it never pushes, commits, or merges.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
Extends the action_pins table row and the Action pinning prose to name
action_pins as the storage target cascade reconcile writes an adopted
external pin bump into, verbatim, keyed by action path, under both
pin_mode: tag and pin_mode: sha. Notes that a sha adoption's trailing
"# <version>" comment is part of a YAML-quoted scalar value so it
survives being re-parsed, and that the generator still emits it
correctly.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
Adds a Governed action pins standard: pins are single-source in the
manifest, a spliced pin value must be charset-validated and never
carry a newline, path-shaped manifest fields must reject .. traversal,
a machine-authored commit stages an explicit pathspec allowlist rather
than git add -A, and generated files are targets never sources so
generation stays a pure offline function of the manifest.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
@joshua-temple
joshua-temple merged commit 6f93361 into main Jul 6, 2026
21 checks passed
@joshua-temple
joshua-temple deleted the feat/reconcile-command branch July 6, 2026 02:10
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.

reconcile a governed action pin update into the manifest and regenerate

1 participant