Composed Runs
Show the whole prompt
Read https://intentius.io/chant/guide/composed-runs/.
Say which components of this repository a pull request run would plan as a group, with a preview or with a hole, and why, as the page's table shows.
Change no files.
Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.Optional: hand this page to your coding agent
Read https://intentius.io/chant/guide/composed-runs/.Say which components of this repository a pull request run would plan as a group, with a preview or with a hole, and why, as the page's table shows.Change no files.Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.A composed run is how chant handles a pull request that changes a component and one that reads its output. chant names the components the change reaches, plans them together, binds one digest, takes one approval and applies in one run, passing each new value on to the components that read it. It belongs to chant, not to a lexicon. Each lexicon takes part in the way its own plan and API allow (ws-108).
A value another component creates in the same run has no value when the plan is made. A reader of it is planned in one of three ways.
- A group. The capability plans and applies several components in one call (ws-107). The value reaches its readers inside the same apply, with no later round.
- A preview. The capability plans the waiting component with stand-ins for the unknown values and keeps the plan’s shape. After the upstream applies, the real plan is compared with that shape. If it matches, the round is covered by the first approval.
- A hole. The component is not planned until its upstream has applied. The note shows
inputs from <component>; re-checked on apply, and the round needs an approval of its own.
Where a composed run applies
Section titled “Where a composed run applies”Groups form in the pull-request run (pr-plan, pr-apply, pr-env), and at promote too. Under the default trunk-curated workflow a merge deploys nothing, and chant components promote --release deploys, so the release gate’s plan forms the same groups by the same rule (#4465). Each group plans with one planGroup call, its digest is folded into each member’s part of the release gate’s change set, and the promote applies it with one runGroup call, with no round between its members. The promote prints a line per group with its members, its wave and its digest, then how each member ended. A promote that stopped part way through a group writes its resume record, and running the same promote again plans only the members that did not apply, as a smaller group where they still join.
chant components fan-out and chant run --components form the same groups. Neither plans before it applies, so each group plans in its wave against the outputs standing then, and applies at once.
Under --wave-gate no group forms, at promote or in a fan-out. Each wave is planned component by component, so every component that would have joined a group falls back with kind wave-gate and the run goes wave by wave as before.
A member of a group has one step, gates counted, so it has no gate of its own. A component with a gated step has more than one step and never joins a group (#4481, ruling 5), so a group has no gate to wait at. At promote, a group applies at promote --release without waiting at the release gate, as an ungated component does. That is the ruled behaviour (#4491). The release gate is decided at the gates of the other components the promote deploys.
Per lexicon
Section titled “Per lexicon”| Capability | Lexicon | Composes as | Issue | What the API offers | Why |
|---|---|---|---|---|---|
terraform-apply | terraform | group | #4447 | terraform plan over a root of module calls, where a value one module creates is known after apply in the modules that read it | One apply carries a value from one root to another. Outside a group a waiting root is a hole (waitingRoot); a preview outside a group is #4463, not built in this epic. |
cfn-deploy | aws | preview | #4423, #4430 | a change set per stack, created and deleted without executing | Built. previewCfnDeploy creates the change set with cfnPlaceholder stand-ins for the unknown parameters and returns cfnPlanShape. CloudFormation has no change set over several stacks, so a group would run change sets in order, as covered rounds do. |
Fn::ImportValue | aws | preview | #4466 | the same change set; an import resolves only when the change set is created, and fails when the export does not exist yet | Built. The CDK shape. cfn-deploy’s declaredReads turns an import of a name another cfn-deploy step exports into a read of <component>.<output>, which orders the importer and lists it under unknownInputs. The importer is previewed from a copy of its template with the import as a stand-in parameter (cfnTemplateWithStandIns), and a plan that changes or removes an export another stack imports is refused. |
arm-deploy | azure | hole | none | ARM what-if (deployments/whatIf), for ARM deployments only | chant applies through azApply, one PUT per resource, and plans by reading each resource with a GET (readPlan). It makes no ARM deployment, so what-if has nothing to preview. ArmDeployInput takes no template parameters: an upstream output can only fill resourceGroup, location, endpoint, subscriptionId or template, and a stand-in there reads a different target. |
gcp-apply | gcp | hole | none | no preview on the REST APIs gcpApply writes to; Config Connector and Infrastructure Manager preview through their own controllers, which chant does not use | planGcpResources reads each resource and decides it with decideResource. GcpApplyStepInput takes no values into resources: an upstream output can only fill manifest, project, endpoint or stack, all of which name the target. |
kubectl-apply | k8s | hole | #4467 | server-side dry run (dryRun=All), which plan already uses against the live cluster | KubectlApplyInput takes no values into objects: an upstream output can only fill manifest, stack, context or delete, and a dry run needs a real cluster. plan does not read unresolvedInputs yet, so it plans against the missing value; #4467 makes it return a hole as the other two do. |
A hole becomes a preview when a step takes values into its resources. Until then none of the three is a group, since their applies write resource by resource and pass no value between members inside one call.
A lexicon without a preview
Section titled “A lexicon without a preview”A component whose capability has no preview, or no group, gets a hole. Its plan shows what is known and no more: the member lists inputs from <component>; re-checked on apply and the note shows ? for its counts. Nothing the approval saw covers it, so no later plan of it is covered.
When the upstream has applied, the component is planned again against the real values. That plan needs an approval of its own, at the pull request’s gate, or at <gate>-round-<n> in a promote. The first approval does not carry over. Planned outputs and rounds states the round rule.
The other components of the change still plan together. A change can group the components that are eligible and plan the rest wave by wave, all under one approval through the covered rounds. The report’s groups and fallbacks say which grouped and why the others did not. Components of another kind on a dependency path between two group members split the group, and only single-step deploys join one. Groups planned and applied as one lists the fields.
A change set that looks empty while a group has reads it does not know yet is not passed without an approval.
Nothing is atomic
Section titled “Nothing is atomic”A failure part way through a run leaves what applied, applied. chant rolls nothing back, and a lexicon’s own locks stay the lexicon’s. The report gives each member’s outcome (applied, partial, failed, not-started or no-changes), and a resume plans only the members that did not apply, against the outputs the others applied with.
Where each lexicon says more
Section titled “Where each lexicon says more”- Terraform: In a composed run covers the
terraform.composesetting and the files it writes to.chant-compose/. It also lists the reasons a group falls back. - AWS: Stacks that read each other’s outputs, the preview and what the real change set is checked against.
- The pull-request CI guide shows a group in a plan note and what a resume does.
- Plan previews lists what the note shows for each capability.
- Capabilities describes
PlanShapeand the conformance helper a lexicon runs on its own shapes.