Run your pre-commit hooks in CI
Optional: hand this page to your coding agentThe steps work by hand too.Show the whole prompt
Read https://intentius.io/terragucci/guides/run-pre-commit-hooks/.
Set check.pre_commit: true in terragucci.yml, run `npx terragucci init`, and check that the job's image carries pre-commit and every tool .pre-commit-config.yaml names; if it does not, say which are missing.
Open a pull request with the changed files, and tell me the hook runs in tf-check once that pull request merges.
Never apply, approve (a pull request review or `terragucci approve`), override a policy denial (`terragucci override`), use `--mode apply`, or merge; never touch `.chant/allowed_signers` or `chant/lifecycle`.Result
Section titled “Result”Every change runs the checks your .pre-commit-config.yaml already names. They run in tf-check after its own format check and validate. terragucci adds no linter and no rule of its own, so the tools and their versions are the ones in your file. A failure fails the check, and the check report lists it:
### Check hooks (read at origin/main)
- failed: `terragucci-pre-commit`, exit 1
- a check hook failed: terragucci-pre-commitPrerequisites
Section titled “Prerequisites”| You need | Why |
|---|---|
a .pre-commit-config.yaml at the repo’s root |
pre-commit reads it; pre-commit-terraform is the usual source of Terraform checks |
an image with pre-commit and the tools the file names |
terragucci’s image carries none of them. Build one FROM terragucci’s and name it under image.name |
Turn it on
Section titled “Turn it on”-
Set the key in
terragucci.yml:check:pre_commit: true -
Run
npx terragucci init. The check job gets one more step after the policy tests, and it now clones with full history to compare the change with its base. -
Commit the files
initchanged and open a pull request.
init never turns the key on by itself. When the key is off and the repo has .pre-commit-config.yaml, init prints a tip.
The step
Section titled “The step”The step runs pre-commit run --from-ref <base> --to-ref HEAD --show-diff-on-failure, so only the files the change touches are checked. On the default branch the base is the commit itself, and the step runs --all-files instead.
| Setting | Value | Why |
|---|---|---|
PCT_TFPATH |
the path of binary |
pre-commit-terraform runs the repo’s own binary. choudoufu works too, since its checks run init -backend=false as tf-check does |
SKIP |
terraform_fmt, then any SKIP the job already sets |
tf-check and the fmt job already check formatting |
The step holds no forge token and no cloud credential.
With a chant release that reads ci.hooks.check, init writes the step into chant.workspace.json under the name terragucci-pre-commit and raises minReader to match. tf-check reads it from the declaration at the base, as it reads the stage hooks, so a pull request cannot change the command it is checked with. The pull request that turns the key on adds the entry, and pre-commit runs from the next change after that merge. Entries of your own under ci.hooks.check run in the same step. Turning the key off removes only terragucci-pre-commit at the next init. An older chant gets no entry, and the step runs the same command from the pipeline.
Checks that write files
Section titled “Checks that write files”terraform_docs, terraform_providers_lock and tfupdate change files. In CI a changed file fails the run, which is pre-commit’s own behavior, and --show-diff-on-failure prints the difference. Run them locally and commit what they write, or set SKIP for them in the job’s environment.
A job of your own
Section titled “A job of your own”To keep pre-commit out of tf-check, give it a job of its own with own_jobs. The job can run in the pre-commit-terraform image pinned by its digest. It can also run in an image you build FROM terragucci’s with pre-commit added. This one is for GitHub:
pre-commit:
runs-on: ubuntu-latest
container: ghcr.io/antonbabenko/pre-commit-terraform:<tag>@sha256:<digest>
env:
PCT_TFPATH: tofu
SKIP: terraform_fmt
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- if: github.event_name == 'pull_request'
run: pre-commit run --from-ref "origin/${{ github.base_ref }}" --to-ref HEAD --show-diff-on-failure --color never
- if: github.event_name != 'pull_request'
run: pre-commit run --all-files --show-diff-on-failure --color neverown_jobs: ci/own-jobs.ymlPCT_TFPATH names a binary the image carries. With a path of your own, pre-commit-terraform’s --tool-version does not apply. GitLab and Forgejo take the same commands in their own syntax.
terragucciHelp setting it up: Intentius
These docs count page views and clicks with PostHog. They set no cookies, store nothing in your browser, and send nothing when your browser asks not to be tracked.