ci: authenticate docs preview build (#2115)

This commit is contained in:
Carlos Florêncio
2026-07-31 21:52:05 +01:00
committed by GitHub
parent 9a3f224224
commit 9f7662d540
5 changed files with 356 additions and 6 deletions
+94
View File
@@ -0,0 +1,94 @@
import assert from "node:assert/strict";
import fs from "node:fs/promises";
import path from "node:path";
import test from "node:test";
import { fileURLToPath } from "node:url";
const repoRoot = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
"..",
);
const workflowPath = path.join(
repoRoot,
".github/workflows/notify-docs.yml",
);
function extractJob(workflow, name) {
const marker = ` ${name}:\n`;
const start = workflow.indexOf(marker);
assert.notEqual(start, -1, `workflow job not found: ${name}`);
const bodyStart = start + marker.length;
const remainder = workflow.slice(bodyStart);
const nextJob = remainder.search(/\n [a-z0-9-]+:\n/);
return remainder.slice(0, nextJob === -1 ? remainder.length : nextJob);
}
function extractStep(job, name) {
const marker = ` - name: ${name}\n`;
const start = job.indexOf(marker);
assert.notEqual(start, -1, `workflow step not found: ${name}`);
const bodyStart = start + marker.length;
const remainder = job.slice(bodyStart);
const nextStep = remainder.search(/\n - name: /);
return remainder.slice(0, nextStep === -1 ? remainder.length : nextStep);
}
const tokenExpression = String.raw`\$\{\{ secrets\.GITHUB_TOKEN \}\}`;
test("docs preview build uses an authenticated read-only token", async () => {
const workflow = await fs.readFile(workflowPath, "utf8");
const preview = extractJob(workflow, "preview");
const build = extractStep(preview, "Build preview from pull request docs");
const validate = extractJob(workflow, "validate");
const testStep = extractStep(validate, "Test public docs validator");
assert.match(
preview,
/permissions:\n contents: read\n\n steps:/,
"preview job permissions must be limited to contents: read",
);
assert.match(build, new RegExp(`GITHUB_TOKEN: ${tokenExpression}`));
assert.doesNotMatch(
preview.replace(build, ""),
/GITHUB_TOKEN/,
"GITHUB_TOKEN must remain scoped to the landing build step",
);
assert.match(testStep, /scripts\/validate-public-docs\.test\.mjs/);
assert.match(testStep, /scripts\/notify-docs-workflow\.test\.mjs/);
assert.match(workflow, /- "scripts\/notify-docs-workflow\.test\.mjs"/);
});
test("preview comment publication is isolated from pull request content", async () => {
const workflow = await fs.readFile(workflowPath, "utf8");
const preview = extractJob(workflow, "preview");
const publication = extractJob(workflow, "publish-preview-link");
const publishStep = extractStep(publication, "Publish docs preview link");
assert.match(
preview,
/outputs:\n enabled: \$\{\{ steps\.cloudflare\.outputs\.enabled \}\}\n deployment_url: \$\{\{ steps\.deploy\.outputs\.deployment-url \}\}\n alias_url: \$\{\{ steps\.deploy\.outputs\.pages-deployment-alias-url \}\}/,
);
assert.match(publication, /needs: preview/);
assert.match(
publication,
/if: needs\.preview\.outputs\.enabled == 'true'/,
);
assert.match(publication, /permissions:\n contents: read\n issues: write\n pull-requests: write\n/);
assert.match(
publishStep,
new RegExp(
`DEPLOYMENT_URL: ${String.raw`\$\{\{ needs\.preview\.outputs\.deployment_url \}\}`}`,
),
);
assert.match(
publishStep,
new RegExp(
`ALIAS_URL: ${String.raw`\$\{\{ needs\.preview\.outputs\.alias_url \}\}`}`,
),
);
assert.match(publishStep, /uses: actions\/github-script@/);
assert.doesNotMatch(publication, /actions\/checkout@/);
assert.doesNotMatch(publication, /pnpm run build:pages/);
});