A Forgejo Action that posts tofu plan output on a pull request as one
comment, updated in place on every run instead of stacking a new one.
Written for Forgejo Actions. It talks to /repos/{repo}/issues/{n}/comments
with curl and jq, which is the same shape GitHub serves, so it also runs on
GitHub Actions.
- name: Plan
id: plan
working-directory: tofu
run: |
set +e
tofu plan -input=false -no-color -lock-timeout=5m > plan-output.txt 2>&1
rc=$?
cat plan-output.txt
exit $rc
- name: Comment the plan on the PR
if: always() # a failed plan belongs on the PR, not only in the log
uses: ndreno/tofu-plan-comment@v1
with:
plan-file: tofu/plan-output.txt
status: ${{ steps.plan.outcome }}
token: ${{ github.token }}if: always() and capturing the plan to a file with set +e are the point:
the comment is most useful exactly when the plan fails.
On GitHub, add permissions: pull-requests: write to the job.
| Input | Required | Default | Meaning |
|---|---|---|---|
plan-file |
yes | File holding the captured plan output | |
status |
yes | Outcome of the plan step, e.g. ${{ steps.plan.outcome }} |
|
token |
yes | Token allowed to comment on the pull request | |
marker |
no | tofu-plan |
Identifier of the comment to update |
title |
no | OpenTofu plan |
Comment heading |
max-body |
no | 60000 |
Comment length cap, in characters |
Two plans in one repository (say a staging and a production workspace) need two
marker values, otherwise they overwrite each other.
Plan: 2 to add, 1 to change, 0 to destroy.
Full plan output
…
The summary line is lifted from the plan itself (Plan:, No changes,
Apply complete), so it stays whatever OpenTofu decided to say.
A plan longer than max-body keeps its head and tail and loses the middle: the
head carries the errors, the tail carries the summary, and the job log still
has the whole thing.
curlandjqin the job container.- A
pull_requestevent. On any other event the action prints a note and exits 0, so it can sit in a workflow that also runs on push.
Canonical repository: github.com/ndreno/tofu-plan-comment,
where CI runs. code.forgejo.org/ndreno/tofu-plan-comment
mirrors it, so a Forgejo instance whose DEFAULT_ACTIONS_URL points there
resolves the bare uses: form. Issues and pull requests go to GitHub.
post-comment.sh is the whole action. The suite stubs curl and asserts on the
requests the script makes, so it needs no network and no forge.
bats tests/
shellcheck post-comment.sh tests/stub-curl.sh
yamllint .MIT