fix(terraform-isolation): do not treat terraform markdown as a mixed change

This commit is contained in:
Adam Moussa 2026-09-10 20:16:51 -04:00
parent ddb45c7960
commit fc54afd421
No known key found for this signature in database
3 changed files with 26 additions and 12 deletions

View file

@ -33,6 +33,13 @@ export function isTerraformPath(file) {
return file.startsWith("terraform/");
}
// Markdown under terraform/ does not queue an HCP VCS run (workspace triggers
// are terraform/live/dev/** and terraform/live/modules/**), so it is not a
// Terraform change for the mixed-PR check.
export function isTerraformInfrastructurePath(file) {
return isTerraformPath(file) && !file.endsWith(".md");
}
export function mayAccompanyTerraform(file) {
if (isTerraformPath(file)) return true;
if (file.endsWith(".md")) return true;
@ -47,7 +54,7 @@ export function mayAccompanyTerraform(file) {
*/
export function classifyChangedFiles(files) {
const unique = [...new Set(files.map((file) => file.trim()).filter(Boolean))].sort();
const terraform = unique.filter(isTerraformPath);
const terraform = unique.filter(isTerraformInfrastructurePath);
const application = unique.filter((file) => !mayAccompanyTerraform(file));
return {
terraform,

View file

@ -8,6 +8,7 @@ import { fileURLToPath } from "node:url";
import {
OVERRIDE_LABEL,
classifyChangedFiles,
isTerraformInfrastructurePath,
mayAccompanyTerraform,
} from "./check-terraform-isolation.mjs";
@ -72,6 +73,18 @@ test("terraform-only and application-only changes are not mixed", () => {
assert.equal(classifyChangedFiles([]).mixed, false);
});
test("terraform documentation does not mix with application or workflow changes", () => {
assert.equal(isTerraformInfrastructurePath("terraform/README.md"), false);
assert.equal(isTerraformInfrastructurePath("terraform/live/dev/main.tf"), true);
assert.equal(
classifyChangedFiles(["terraform/README.md", ".github/workflows/ci.yaml"]).mixed,
false,
);
const docsOnly = runGate(["terraform/README.md", ".github/workflows/ci.yaml"]);
assert.equal(docsOnly.status, 0, docsOnly.stdout + docsOnly.stderr);
assert.match(docsOnly.stdout, /PASS/);
});
test("terraform plus application is mixed and lists the offending files", () => {
const result = classifyChangedFiles([
"terraform/live/dev/main.tf",
@ -115,11 +128,7 @@ test("removing the override fails a mixed change that was previously green", ()
const previouslyGreen = runGate(files, {
TERRAFORM_ISOLATION_OVERRIDE: "true",
});
assert.equal(
previouslyGreen.status,
0,
previouslyGreen.stdout + previouslyGreen.stderr,
);
assert.equal(previouslyGreen.status, 0, previouslyGreen.stdout + previouslyGreen.stderr);
assert.match(previouslyGreen.stdout, /WARNING/);
// CI sets TERRAFORM_ISOLATION_OVERRIDE from contains(...labels), which is
@ -128,11 +137,7 @@ test("removing the override fails a mixed change that was previously green", ()
const afterLabelRemoved = runGate(files, {
TERRAFORM_ISOLATION_OVERRIDE: "false",
});
assert.equal(
afterLabelRemoved.status,
1,
afterLabelRemoved.stdout + afterLabelRemoved.stderr,
);
assert.equal(afterLabelRemoved.status, 1, afterLabelRemoved.stdout + afterLabelRemoved.stderr);
assert.match(afterLabelRemoved.stdout, /FAIL/);
assert.match(afterLabelRemoved.stdout, /deploy\.yml/);
});

View file

@ -226,7 +226,9 @@ the labels. Push-to-`dev` releases return behind the repository variable
labels currently on the PR; the other CI jobs skip on those events so a
label change does not re-run the suite. Removing the label fails a mixed
PR that had previously passed with the override, so a stale green check
cannot merge. The label is the approval record. The override is temporary:
cannot merge. Markdown under `terraform/` does not count as a Terraform
change for this gate; it does not match the workspace trigger patterns.
The label is the approval record. The override is temporary:
a follow-up PR after PR C removes the label path from the checker and
workflow so the gate has no exception.
- **Every Terraform merge produces a VCS run.** A human confirms or discards