Documentation · Use it

Running an estate from CI

A choudoufu pipeline is six jobs. Three only read. The three that write run on a push, and all three stop for an approval first.

JobRuns onWhat it does
live-checkpull requestRefuses the pull request if the configuration would be refused. No cloud call and no credential
live-planpull requestPlans, and reports drift and live resources that match a block and carry no marker
live-applypush to mainPlans to a file, waits for approval of the rendered plan, then applies that file
live-adoptpush to stagingShows what it would adopt, waits for approval, then writes the two tags on each resource
live-discovera scheduleLists what carries this estate’s marker that nobody declares
backend-preparepush to bootstrapBuilds the record store bucket’s template, waits for approval of it, then creates or updates the bucket and checks it against the bucket contract

Give each job the narrowest role that works. live-check needs none. The plan and discover jobs need a role that can read, including the estate’s records. Only live-apply and live-adopt need to write to the estate. backend-prepare gets a role of its own, because creating the bucket and writing its policy is more than any other job may do: a role that can rewrite the bucket policy can lock every run out of its own records.

An apply that finds the live system changed since its plan was approved refuses with exit status 3, and the job should send it back for review and not page anyone.

examples/ci-pipelines is a working project that generates these six jobs for GitHub, Forgejo and GitLab, with the generated workflows checked in. PIPELINE.md beside it has what differs per forge, the variables and secrets each needs before its first run, and what was tested where. examples/pipeline-governance has the branch rules that require the two pull-request jobs and put the apply behind a reviewer.