Conversation
- Turn an arbitrary string into an artifact-safe slug - Append a short digest so two different values never collide
- Run `terraform plan -out` with `-detailed-exitcode` and expose whether the workspace has changes - Build the summary from `terraform show -json`, never from the log text, and render it as a Markdown table of resource actions - Truncate the resource list at `max_resources` so one workspace cannot fill a pull request comment - Fall back to a plan without `-out` when the backend refuses to save one, which is what a workspace with remote execution does, and say so
- Apply a saved plan file, so the applied change is the reviewed change - Report a stale plan separately from a real failure, since it means the state moved after the plan and needs a fresh plan rather than a retry - Expose added, changed, and destroyed counts and a Markdown summary
- Resolve the merged pull request behind a commit and the completed run of a given workflow against that pull request's head - Lets a job triggered by the merge download artifacts the pull request run uploaded, such as a Terraform plan file
- Add a `details` input rendered as a collapsed block per row, for content too long for a table cell such as a Terraform plan - Add a `pr_number` input so the report can be posted from events without a pull request context, such as the push that follows a merge
- Reuse the integration resolver to find the changed workspaces - Plan each workspace in parallel and upload its plan file as an artifact - Publish one sticky comment holding a per-workspace collapsed plan, so a re-run updates the same comment instead of adding another
- Resolve the merged pull request and download the plan files its run saved - Apply one workspace at a time, each under its own concurrency group - Publish the result as its own comment on the merged pull request, kept separate from the plan comment
….apply - Guard the job summary steps with `always()`. A bare `if:` is implicitly combined with `success()`, so a step conditioned only on another step's failure never runs once that step has failed - Add a summary step that runs whatever happened, carrying the tail of the command that failed, so the caller never reports a bare failure with no reason
- Export `KEY=value` lines into the job environment - Mask every value, and skip a line whose value is empty, which is what an unset secret looks like - Reject a malformed line, an invalid variable name, and any name the runner owns, so the input cannot change how later steps run
…d apply workflows - Add a `provider_env` secret carrying `KEY=value` lines - Export it before planning or applying, so providers that read credentials from the environment, such as Okta, work without the reusable workflow needing an input per provider
…pply - Replace the `tee` pipeline of the init step with `shell.run`, as `terraform.validate` does, and point the failure summary and the plan summary fallback at its `log_file` output
GitHub Actions Integration
✅ All 1 passed. |
… diagnostics - Run the plan as `terraform plan -json -detailed-exitcode -out=<file>` with the message stream going to a file, then render the readable plan into the log with `terraform show -no-color <file>`. One plan run yields both the log a plain `terraform plan` would have printed and the typed message stream - Add `drift_count`, `warning_count`, and `error_count`, and the JSON outputs `changes`, `drift`, `output_changes`, and `diagnostics`, each truncated to `max_resources`. They carry addresses, actions, and reasons, never attribute values, so they stay far below the 1 MB limit on step outputs - Pass the bulky renderings as paths instead: `plan_json_file` and `stream_file` - Add `annotations_enabled` (default `true`). Diagnostics only exist in the message stream, not in the plan file, so warnings on a successful plan were previously dropped; they are now annotated and listed in the summary - Report drift in the summary as a collapsed list - Stop reporting `plan_file` and `plan_file_saved` when the plan failed and no file was written, which made the caller's artifact upload fail instead of skip
posquit0
force-pushed
the
test/plan-json-demo
branch
from
September 21, 2026 04:52
6243951 to
bd7622c
Compare
posquit0
force-pushed
the
test/plan-json-demo
branch
from
September 21, 2026 05:20
bd7622c to
e06694e
Compare
Terraform Plan
fixtures/plan-demo 🟢 +1 🟡 ~1 🔴 -1 🟠 ±1 · 🌀 1 drifted · |
- Move the summary rendering into `scripts/render-summary.py`, following the `web.s3.delivery` precedent, since slicing the plan text, diffing drift and laying out Markdown outgrew an inline `jq` program - Show each changed resource as a collapsed block titled with an emoji for the action (➕ create, 📝 update, 🗑️ destroy, ♻️ replace) and the reason, holding the attribute diff sliced out of `terraform show` so it reads exactly as Terraform prints it and keeps its redaction of sensitive values - Give drift the same treatment, diffed from `resource_drift` in the plan JSON because Terraform renders no drift section of its own - Link every diagnostic to its line on the commit being planned, using the pull request head rather than the merge commit - Add `diff_enabled`, `diff_max_lines` and `summary_max_bytes`. The last one keeps one workspace from spending the whole 65,536 character budget of the shared pull request comment, closing any open fence or block when it cuts - Report each target under its own heading in `github.matrix-report`, and fall back to the table alone when the comment would exceed the GitHub limit
posquit0
force-pushed
the
test/plan-json-demo
branch
from
September 21, 2026 05:26
e06694e to
7267588
Compare
…eport - Replace the pictographic emoji with Terraform's own notation, coloured so a block can be placed at a glance: 🟩 `+`, 🟨 `~`, 🟥 `-`, 🟧 `±`, 🟪 for drift - Add a `headline` output to `terraform.plan`, a single line such as `🟩 +1 · 🟨 ~1 · 🟪 1 drifted ·⚠️ 1 warning`, and take the counts out of the body so they are read next to the workspace name instead of above the diffs - Give `github.matrix-report` a `headline` input and render each target as a collapsed section headed by `<h3>`, with ✅ or ❌ and the headline on the same line, a rule between targets, and the section left open when it failed - Add `table_enabled`, so a report whose targets each carry their own section can drop the table that would only repeat the headings
posquit0
force-pushed
the
test/plan-json-demo
branch
from
September 21, 2026 05:43
7267588 to
2328d60
Compare
…eated counts - Remove the fixed `terraform plan failed` banner. It never varied, and the target's heading already carries ❌ and the error count. A failure with no diagnostics at all now says so instead - Head every part of the body: `Resource changes`, `Changed outside of Terraform`, `Errors`, `Warnings`. The counts stay on the target heading, so a section only needs a name - Settle the levels: the report title drops to `##`, each target keeps its `<h3>`, and the sections inside one sit at `####` - Divide the target headline into groups, so the resource counts, the drift and the diagnostics read as three things rather than one run-on list
posquit0
force-pushed
the
test/plan-json-demo
branch
from
September 21, 2026 05:54
2328d60 to
e76aecc
Compare
…ic row - Take the report title to `#`, each target to `<h2>` and the sections inside a target to `###`, so the three levels are told apart by size - Set the verdict above the targets as a quote - Separate the headline groups with a middle dot carrying space on both sides - Read a diagnostic location first, `main.tf:5 — Reference to undeclared input variable`, with the whole row as the link to that line
posquit0
force-pushed
the
test/plan-json-demo
branch
from
September 21, 2026 06:06
e76aecc to
d0c4eb1
Compare
…piral - 🟢 `+`, 🟡 `~`, 🔴 `-`, 🟠 `±` for the planned actions - 🌀 for drift, deliberately outside that family: it is not a change Terraform planned, so it reads as a different kind of thing and the headline groups separate on colour as well as on the divider
posquit0
force-pushed
the
test/plan-json-demo
branch
from
September 21, 2026 06:24
d0c4eb1 to
70c6abc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Demo for the
terraform.planrewrite in #5. Two fixtures fail or change on purpose:fixtures/plan-demohas a committedterraform.tfstatestanding in for a previous apply, andmanaged.txtis deliberately absent. The plan therefore reports a create, an update, a replace, a destroy, drift onlocal_file.managed, and a warning from acheckblock that fails on purpose.fixtures/plan-demo-errorreferences an undeclared variable, so the plan fails.What to look at:
terraform planprints it, rendered byterraform showfrom the saved plan file. The JSON message stream never reaches the log.summary.Not meant to be merged.