Skip to content

Commit 11ae73c

Browse files
committed
ci: add required test gate
1 parent 9887e0e commit 11ae73c

5 files changed

Lines changed: 56 additions & 95 deletions

File tree

.github/workflows/main.yml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,30 @@ jobs:
283283
if: github.event_name == 'push'
284284
run: node scripts/check-repo-security.mjs --changed-files .changed-files
285285

286+
test:
287+
runs-on: ubuntu-latest
288+
if: github.event_name == 'pull_request' || github.event_name == 'push'
289+
steps:
290+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
291+
with:
292+
fetch-depth: 1
293+
persist-credentials: false
294+
295+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
296+
with:
297+
node-version: 20
298+
299+
- name: Enable pnpm
300+
run: |
301+
corepack enable
302+
corepack prepare pnpm@10.20.0 --activate
303+
304+
- name: Install dependencies
305+
run: pnpm install --frozen-lockfile
306+
307+
- name: Run tests
308+
run: pnpm test
309+
286310
awesome-lint:
287311
name: awesome-lint
288312
runs-on: ubuntu-latest
@@ -291,6 +315,7 @@ jobs:
291315
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
292316
with:
293317
fetch-depth: 1
318+
persist-credentials: false
294319

295320
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
296321
with:
@@ -308,12 +333,13 @@ jobs:
308333
ref: ${{ github.event.pull_request.base.sha }}
309334
path: .trusted-base
310335
fetch-depth: 1
336+
persist-credentials: false
311337

312338
- name: Run trusted awesome-list checks
313339
if: github.event_name == 'pull_request'
314340
run: |
315341
node .trusted-base/scripts/check-awesome-list.mjs --root "$GITHUB_WORKSPACE"
316-
(cd .trusted-base && pnpm dlx awesome-lint "$GITHUB_WORKSPACE/README.md")
342+
(cd .trusted-base && pnpm dlx awesome-lint@2.3.0 "$GITHUB_WORKSPACE/README.md")
317343
318344
- name: Install dependencies
319345
if: github.event_name != 'pull_request'

package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"type": "module",
55
"scripts": {
66
"// note": "echo \"Note: upstream awesome-lint needs network.\"",
7-
"check:awesome-list:upstream": "pnpm dlx awesome-lint",
7+
"check:awesome-list:upstream": "pnpm dlx awesome-lint@2.3.0",
88
"test": "node --test scripts/*.test.mjs",
99
"check:awesome-list": "node scripts/check-awesome-list.mjs",
1010
"check:repo-hygiene": "node scripts/check-repo-hygiene.mjs",
@@ -16,8 +16,5 @@
1616
"links:absolute": "node scripts/convert-readme-links.mjs --to absolute",
1717
"links:relative": "node scripts/convert-readme-links.mjs --to relative",
1818
"cleanup:legacy": "node scripts/cleanup-legacy-artifacts.mjs"
19-
},
20-
"devDependencies": {
21-
"rimraf": "^6.0.1"
2219
}
2320
}

pnpm-lock.yaml

Lines changed: 1 addition & 77 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/cleanup-legacy-artifacts.mjs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#!/usr/bin/env node
22

33
import { existsSync } from "node:fs";
4+
import { rm } from "node:fs/promises";
45
import { isAbsolute, relative, resolve } from "node:path";
56
import { fileURLToPath } from "node:url";
6-
import { rimraf } from "rimraf";
77

88
export const defaultLegacyArtifacts = ["rules-legacy", "rules-new", ".cursorrules"];
99

@@ -20,18 +20,10 @@ export async function cleanupLegacyArtifacts({
2020
}
2121

2222
const removed = existingTargets.map(({ artifact }) => artifact);
23-
const ok = await rimraf(
24-
existingTargets.map(({ resolved }) => resolved),
25-
{
26-
glob: false,
27-
preserveRoot: true,
28-
},
23+
await Promise.all(
24+
existingTargets.map(({ resolved }) => rm(resolved, { recursive: true, force: true })),
2925
);
3026

31-
if (!ok) {
32-
throw new Error(`Unable to remove all legacy artifacts: ${removed.join(", ")}`);
33-
}
34-
3527
return removed;
3628
}
3729

scripts/workflow-security.test.mjs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ const pullRequestTrustJob = jobBlock("pull-request-trust", "readme-hygiene");
99
const readmeHygieneJob = jobBlock("readme-hygiene", "rule-hygiene");
1010
const ruleHygieneJob = jobBlock("rule-hygiene", "issue-template-policy");
1111
const issueTemplatePolicyJob = jobBlock("issue-template-policy", "repo-security");
12-
const repoSecurityJob = jobBlock("repo-security", "awesome-lint");
12+
const repoSecurityJob = jobBlock("repo-security", "test");
13+
const testJob = jobBlock("test", "awesome-lint");
1314
const awesomeLintJob = workflow.slice(workflow.indexOf(" awesome-lint:"));
1415

1516
function jobBlock(jobName, nextJobName) {
@@ -104,6 +105,16 @@ test("workflow has an explicit awesome-lint job for every pull request", () => {
104105
assert.match(workflow, /^ pull_request:\n\s+branches:\s+\[main\]$/m);
105106
});
106107

108+
test("workflow has an explicit test job for pull requests and pushes", () => {
109+
assert.match(testJob, /^ test:\n\s+runs-on:\s+ubuntu-latest$/m);
110+
assert.match(testJob, /if:\s+github\.event_name == 'pull_request' \|\| github\.event_name == 'push'/);
111+
assert.doesNotMatch(testJob, /pull_request_target/);
112+
assert.match(testJob, /persist-credentials:\s+false/);
113+
assert.match(testJob, /corepack prepare pnpm@10\.20\.0 --activate/);
114+
assert.match(testJob, /pnpm install --frozen-lockfile/);
115+
assert.match(testJob, /pnpm test/);
116+
});
117+
107118
test("trusted PR gates do not execute contributor-controlled code", () => {
108119
for (const job of [readmeHygieneJob, ruleHygieneJob, issueTemplatePolicyJob, repoSecurityJob]) {
109120
assert.match(job, /path:\s+pr/);
@@ -119,7 +130,7 @@ test("the old bundled repo-hygiene check is not a required PR concern", () => {
119130

120131
test("pull requests run trusted awesome-list checks", () => {
121132
assert.match(workflow, /node \.trusted-base\/scripts\/check-awesome-list\.mjs --root "\$GITHUB_WORKSPACE"/);
122-
assert.match(workflow, /pnpm dlx awesome-lint "\$GITHUB_WORKSPACE\/README\.md"/);
133+
assert.match(workflow, /pnpm dlx awesome-lint@2\.3\.0 "\$GITHUB_WORKSPACE\/README\.md"/);
123134
});
124135

125136
test("pushes run local awesome-list checks", () => {
@@ -128,6 +139,17 @@ test("pushes run local awesome-list checks", () => {
128139
assert.match(workflow, /pnpm run check:awesome-list:upstream/);
129140
});
130141

142+
test("awesome-lint job uses pinned package code without persistent checkout credentials", () => {
143+
const checkoutSteps = awesomeLintJob.match(/uses:\s+actions\/checkout@[a-f0-9]{40}\s+#\s+v4[\s\S]*?(?=\n\s+- uses:|\n\s+- name:|$)/g) ?? [];
144+
assert.equal(checkoutSteps.length, 2);
145+
146+
for (const step of checkoutSteps) {
147+
assert.match(step, /persist-credentials:\s+false/);
148+
}
149+
150+
assert.match(awesomeLintJob, /pnpm dlx awesome-lint@2\.3\.0 "\$GITHUB_WORKSPACE\/README\.md"/);
151+
});
152+
131153
test("external GitHub Actions are pinned to full commit SHAs", () => {
132154
const usesLines = workflow.match(/^\s*uses:\s+.+$/gm) ?? [];
133155
assert.ok(usesLines.length > 0);

0 commit comments

Comments
 (0)