mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-14 02:42:24 +03:00
CodeQL js/incomplete-sanitization (#888): the hand-rolled replace only escaped double quotes, so a backslash in the fixture would have produced a malformed YAML scalar. JSON.stringify covers every escape the double-quoted YAML scalar needs.
146 lines
5.0 KiB
TypeScript
146 lines
5.0 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { readFileSync, readdirSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
import {
|
|
classifyRunsOn,
|
|
findProvenanceOnSelfHosted,
|
|
} from "../../scripts/check/lib/provenanceRunner.mjs";
|
|
|
|
/**
|
|
* v3.8.50, 10th publish attempt, 76 minutes in — after the tag, the GitHub
|
|
* Release and the Docker images were already public:
|
|
*
|
|
* 422 Unprocessable Entity - Error verifying sigstore provenance bundle:
|
|
* Unsupported GitHub Actions runner environment: "self-hosted".
|
|
*
|
|
* `USE_VPS_RUNNER` had routed the publish job to the .113 pool on 2026-08-02;
|
|
* no release happened between 07-30 and 08-28, so nothing surfaced it. The
|
|
* pairing is pure text, so it must fail the workflow lint on the PR that
|
|
* introduces it.
|
|
*/
|
|
const ROOT = join(import.meta.dirname, "../..");
|
|
const WORKFLOWS = join(ROOT, ".github/workflows");
|
|
|
|
// The exact runs-on expression npm-publish.yml used when it broke.
|
|
const VPS_EXPR =
|
|
"${{ (vars.USE_VPS_RUNNER == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)) && fromJSON('[\"self-hosted\",\"omni-release\"]') || 'ubuntu-latest' }}";
|
|
|
|
function workflow(runsOn: string, run: string, extra = ""): string {
|
|
return [
|
|
"name: t",
|
|
"on: push",
|
|
"jobs:",
|
|
" publish:",
|
|
` runs-on: ${runsOn}`,
|
|
extra,
|
|
" steps:",
|
|
" - name: upload",
|
|
` run: ${run}`,
|
|
"",
|
|
].join("\n");
|
|
}
|
|
|
|
test("classifyRunsOn: literal, array, object-with-labels and the fromJSON expression are self-hosted", () => {
|
|
assert.equal(classifyRunsOn("self-hosted"), "self-hosted");
|
|
assert.equal(classifyRunsOn(["self-hosted", "omni-release"]), "self-hosted");
|
|
assert.equal(classifyRunsOn({ group: "Default", labels: ["self-hosted"] }), "self-hosted");
|
|
assert.equal(classifyRunsOn(VPS_EXPR), "self-hosted");
|
|
});
|
|
|
|
test("classifyRunsOn: hosted labels are hosted, opaque expressions are unknown (never guessed)", () => {
|
|
assert.equal(classifyRunsOn("ubuntu-latest"), "hosted");
|
|
assert.equal(classifyRunsOn(["ubuntu-latest"]), "hosted");
|
|
assert.equal(classifyRunsOn("${{ matrix.os }}"), "unknown");
|
|
assert.equal(classifyRunsOn(undefined), "unknown");
|
|
});
|
|
|
|
test("flags --provenance inside a job routed to the self-hosted pool", () => {
|
|
const found = findProvenanceOnSelfHosted(
|
|
workflow(
|
|
JSON.stringify(VPS_EXPR),
|
|
'npm stage publish --provenance --access public --tag "$TAG"'
|
|
),
|
|
"npm-publish.yml"
|
|
);
|
|
assert.deepEqual(found, [{ file: "npm-publish.yml", job: "publish", step: "upload" }]);
|
|
});
|
|
|
|
test("also catches the literal label and the --provenance-file form", () => {
|
|
assert.equal(
|
|
findProvenanceOnSelfHosted(workflow("self-hosted", "npm publish --provenance")).length,
|
|
1
|
|
);
|
|
assert.equal(
|
|
findProvenanceOnSelfHosted(
|
|
workflow("[self-hosted, omni-release]", "npm publish --provenance-file=./p.json")
|
|
).length,
|
|
0,
|
|
"--provenance-file is a different flag (a pre-built bundle) and is not what the registry rejects"
|
|
);
|
|
assert.equal(
|
|
findProvenanceOnSelfHosted(workflow("self-hosted", "npm publish --provenance=true")).length,
|
|
1
|
|
);
|
|
});
|
|
|
|
test("does not flag hosted jobs, unknown runners, or self-hosted jobs without the flag", () => {
|
|
assert.deepEqual(
|
|
findProvenanceOnSelfHosted(workflow("ubuntu-latest", "npm publish --provenance")),
|
|
[]
|
|
);
|
|
assert.deepEqual(
|
|
findProvenanceOnSelfHosted(workflow("${{ matrix.os }}", "npm publish --provenance")),
|
|
[]
|
|
);
|
|
assert.deepEqual(
|
|
findProvenanceOnSelfHosted(workflow("self-hosted", "npm publish --access public")),
|
|
[]
|
|
);
|
|
// The word only in a step NAME or a comment is not a finding.
|
|
assert.deepEqual(
|
|
findProvenanceOnSelfHosted(
|
|
[
|
|
"name: t",
|
|
"on: push",
|
|
"jobs:",
|
|
" j:",
|
|
" runs-on: self-hosted",
|
|
" steps:",
|
|
" - name: provenance note",
|
|
" run: echo hi # --provenance later",
|
|
"",
|
|
].join("\n")
|
|
),
|
|
[],
|
|
"a comment after the command is still part of the run string — accept that the regex is conservative"
|
|
);
|
|
});
|
|
|
|
test("reusable-workflow jobs (uses:) and unparseable YAML are not this rule's findings", () => {
|
|
const reusable = [
|
|
"name: t",
|
|
"on: push",
|
|
"jobs:",
|
|
" j:",
|
|
" uses: ./.github/workflows/x.yml",
|
|
"",
|
|
].join("\n");
|
|
assert.deepEqual(findProvenanceOnSelfHosted(reusable), []);
|
|
assert.deepEqual(findProvenanceOnSelfHosted("jobs: [unclosed"), []);
|
|
});
|
|
|
|
test("regression guard: no workflow in this repo publishes with --provenance from a self-hosted runner", () => {
|
|
const files = readdirSync(WORKFLOWS).filter((f) => /\.ya?ml$/.test(f));
|
|
assert.ok(files.length > 10, "expected the real workflow set");
|
|
const findings = files.flatMap((f) =>
|
|
findProvenanceOnSelfHosted(readFileSync(join(WORKFLOWS, f), "utf8"), f)
|
|
);
|
|
assert.deepEqual(
|
|
findings,
|
|
[],
|
|
`npm rejects provenance from self-hosted runners (422) — move the upload to a github-hosted job: ${JSON.stringify(findings)}`
|
|
);
|
|
});
|