import { describe, expect, it } from "vitest"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; describe("A03 Software Supply Chain Failures", () => { it("enforces deploy workflow dependency-audit gate for api and web", () => { const repoRoot = resolve(__dirname, "..", ".."); const deployWorkflow = readFileSync( resolve(repoRoot, ".gitea/workflows/deploy.yml"), "utf8" ); expect(deployWorkflow).toContain("name: Supply chain checks (production dependencies)"); expect(deployWorkflow).toContain("cd api"); expect(deployWorkflow).toContain("cd ../web"); const npmCiMatches = deployWorkflow.match(/\bnpm ci\b/g) ?? []; expect(npmCiMatches.length).toBeGreaterThanOrEqual(2); const auditMatches = deployWorkflow.match(/npm audit --omit=dev --audit-level=high/g) ?? []; expect(auditMatches.length).toBeGreaterThanOrEqual(2); }); it("pins checkout action to an explicit version tag", () => { const repoRoot = resolve(__dirname, "..", ".."); const deployWorkflow = readFileSync( resolve(repoRoot, ".gitea/workflows/deploy.yml"), "utf8" ); expect(deployWorkflow).toMatch(/uses:\s*actions\/checkout@v\d+\.\d+\.\d+/); }); });