Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; | |
| 3 | ||
| 4 | import type { CodeAlert, SecretFinding } from "@g1t/contracts"; | |
| 5 | ||
| 6 | import { | |
| 7 | codeFilters, | |
| 8 | codeScanningBranch, | |
| 9 | codeScanningPullBody, | |
| 10 | codeScanningWorkflow, | |
| 11 | countStates, | |
| 12 | keepCode, | |
| 13 | keepSecret, | |
| 14 | legacySecurityTarget, | |
| 15 | secretFilters, | |
| 16 | secretTypes, | |
| 17 | severityCounts, | |
| 18 | total, | |
| 19 | trendMax, | |
| 20 | } from "./security-suite.ts"; | |
| 21 | ||
| 22 | const secret = (over: Partial<SecretFinding> = {}): SecretFinding => ({ | |
| 23 | id: "sec_1", | |
| 24 | repoId: "r", | |
| 25 | kind: "github_token", | |
| 26 | label: "a GitHub token", | |
| 27 | path: "scripts/release.sh", | |
| 28 | line: 12, | |
| 29 | commit: "abcdef1234", | |
| 30 | preview: "ghp_X7…", | |
| 31 | status: "open", | |
| 32 | source: "push", | |
| 33 | foundBy: "ana", | |
| 34 | foundAt: "2026-10-06T09:00:00.000Z", | |
| 35 | decidedBy: null, | |
| 36 | reason: null, | |
| 37 | decidedAt: null, | |
| 38 | state: "open", | |
| 39 | ...over, | |
| 40 | }); | |
| 41 | ||
| 42 | const code = (over: Partial<CodeAlert> = {}): CodeAlert => ({ | |
| 43 | id: "cod_1", | |
| 44 | number: 1, | |
| 45 | repoId: "r", | |
| 46 | tool: "Semgrep OSS", | |
| 47 | category: "Semgrep OSS", | |
| 48 | ruleId: "rule", | |
| 49 | ruleName: null, | |
| 50 | ruleDescription: null, | |
| 51 | help: null, | |
| 52 | helpUri: null, | |
| 53 | tags: [], | |
| 54 | level: "error", | |
| 55 | securitySeverity: null, | |
| 56 | severity: "high", | |
| 57 | message: "m", | |
| 58 | path: "a.js", | |
| 59 | startLine: 1, | |
| 60 | endLine: 1, | |
| 61 | startColumn: null, | |
| 62 | endColumn: null, | |
| 63 | state: "open", | |
| 64 | fingerprint: "f", | |
| 65 | firstCommit: "c", | |
| 66 | lastCommit: "c", | |
| 67 | createdAt: "", | |
| 68 | updatedAt: "", | |
| 69 | fixedAt: null, | |
| 70 | dismissedBy: null, | |
| 71 | dismissedReason: null, | |
| 72 | dismissedComment: null, | |
| 73 | dismissedAt: null, | |
| 74 | issue: null, | |
| 75 | ...over, | |
| 76 | }); | |
| 77 | ||
| 78 | test("secret filters are read from the address and narrow the list", () => { | |
| 79 | const filters = secretFilters(new URLSearchParams("state=open&validity=active&bypassed=true")); | |
| 80 | assert.deepEqual(filters, { state: "open", type: null, validity: "active", bypassed: true }); | |
| 81 | const bypassed = secret({ validity: "active", bypass: { reason: "will_fix_later", comment: null, by: "ana", at: "x", approvedBy: null } }); | |
| 82 | assert.equal(keepSecret(bypassed, filters), true); | |
| 83 | assert.equal(keepSecret(secret({ validity: "active" }), filters), false); | |
| 84 | // Unknown words fall back to the defaults. | |
| 85 | assert.deepEqual(secretFilters(new URLSearchParams("state=everything&validity=maybe")), { state: "open", type: null, validity: null, bypassed: null }); | |
| 86 | // Never asked counts as unknown. | |
| 87 | assert.equal(keepSecret(secret(), { state: "open", type: null, validity: "unknown", bypassed: null }), true); | |
| 88 | }); | |
| 89 | ||
| 90 | test("secret types are listed once each, custom patterns by name", () => { | |
| 91 | const types = secretTypes([secret(), secret({ id: "sec_2" }), secret({ kind: "custom_pattern", patternName: "Acme key", label: "a match for the custom pattern \"Acme key\"" })]); | |
| 92 | assert.deepEqual(types, [["github_token", "GitHub token"], ["custom_pattern", "Custom: Acme key"]].sort((a, b) => a[1].localeCompare(b[1]))); | |
| 93 | }); | |
| 94 | ||
| 95 | test("code filters and counts", () => { | |
| 96 | const filters = codeFilters(new URLSearchParams("severity=high&tool=Semgrep OSS")); | |
| 97 | assert.equal(keepCode(code(), filters), true); | |
| 98 | assert.equal(keepCode(code({ severity: "low" }), filters), false); | |
| 99 | assert.equal(keepCode(code({ state: "fixed" }), filters), false); | |
| 100 | assert.deepEqual(countStates([code(), code({ state: "fixed" }), code({ state: "fixed" })]), { open: 1, dismissed: 0, fixed: 2 }); | |
| 101 | const counts = severityCounts([code(), code({ severity: "critical" }), code({ state: "dismissed" })]); | |
| 102 | assert.deepEqual(counts, { critical: 1, high: 1, medium: 0, low: 0, unknown: 0 }); | |
| 103 | assert.equal(total(counts), 2); | |
| 104 | }); | |
| 105 | ||
| 106 | test("old Security links go to the sections that replaced their tabs", () => { | |
| 107 | const base = "/acme/rocket"; | |
| 108 | assert.equal(legacySecurityTarget(base, new URLSearchParams("tab=secrets&finding=sec_9")), "/acme/rocket/security/secret-scanning/sec_9"); | |
| 109 | assert.equal(legacySecurityTarget(base, new URLSearchParams("finding=vul_3")), "/acme/rocket/security/vulnerabilities?finding=vul_3"); | |
| 110 | assert.equal(legacySecurityTarget(base, new URLSearchParams("tab=dependencies&state=fixed")), "/acme/rocket/security/vulnerabilities?state=fixed"); | |
| 111 | assert.equal(legacySecurityTarget(base, new URLSearchParams("")), null); | |
| 112 | }); | |
| 113 | ||
| 114 | test("the starter workflow scans each language it finds, then uploads SARIF for the right ref", () => { | |
| 115 | const yaml = codeScanningWorkflow("main"); | |
| 116 | assert.match(yaml, /branches: \["main"\]/); | |
| 117 | // A scanner per language, each run only when the repository has it. | |
| 118 | assert.match(yaml, /if: steps\.languages\.outputs\.python == 'true'/); | |
| 119 | assert.match(yaml, /bandit --recursive \. .*\n.*--format sarif --output \/tmp\/sarif\/python\.sarif/); | |
| 120 | assert.match(yaml, /if: steps\.languages\.outputs\.go == 'true'/); | |
| 121 | assert.match(yaml, /-fmt sarif -out "\$out" \.\/\.\.\./); | |
| 122 | assert.match(yaml, /if: steps\.languages\.outputs\.javascript == 'true'/); | |
| 123 | assert.match(yaml, /eslint-plugin-security/); | |
| 124 | assert.match(yaml, /@microsoft\/eslint-formatter-sarif/); | |
| 125 | assert.match(yaml, /if: steps\.languages\.outputs\.rust == 'true'/); | |
| 126 | assert.match(yaml, /cargo clippy --all-targets --message-format=json/); | |
| 127 | assert.match(yaml, /clippy-sarif/); | |
| 128 | assert.ok(!/semgrep/i.test(yaml), "no Semgrep"); | |
| 129 | // Each language's results under their own category. | |
| 130 | for (const category of ["python", "javascript", '"go"', '"rust"']) assert.ok(yaml.includes(category), category); | |
| 131 | assert.match(yaml, /--arg category "\$category"/); | |
| 132 | assert.match(yaml, /refs\/pull\/\$\(jq -r \.number "\$GITHUB_EVENT_PATH"\)\/head/); | |
| 133 | assert.match(yaml, /--rawfile sarif "\$file\.b64"/); | |
| 134 | assert.match(yaml, /\/code-scanning\/sarifs/); | |
| 135 | assert.match(yaml, /\$\{\{ secrets\.G1T_TOKEN \}\}/); | |
| 136 | assert.ok(!yaml.includes("\t"), "YAML takes no tabs"); | |
| 137 | assert.match(codeScanningPullBody("main"), /Code scanning\*\* check/); | |
| 138 | assert.equal(codeScanningBranch([]), "add-code-scanning"); | |
| 139 | assert.equal(codeScanningBranch(["add-code-scanning", "add-code-scanning-2"]), "add-code-scanning-3"); | |
| 140 | }); | |
| 141 | ||
| 142 | test("a trend is scaled to its tallest day", () => { | |
| 143 | assert.equal(trendMax([]), 1); | |
| 144 | assert.equal(trendMax([{ day: "d", secretScanning: 1, codeScanning: 2, vulnerability: 3 }]), 6); | |
| 145 | }); |