Add function to read the analysis category from a workflow

This commit is contained in:
Henry Mercer 2022-11-22 18:15:28 +00:00
parent 996d04b1e5
commit e2d523ca5e
6 changed files with 227 additions and 3 deletions

View file

@ -6,6 +6,7 @@ import {
CodedError,
formatWorkflowCause,
formatWorkflowErrors,
getCategoryInput,
getWorkflowErrors,
patternIsSuperset,
Workflow,
@ -522,3 +523,93 @@ test("getWorkflowErrors() should not report an error if PRs are totally unconfig
)
);
});
test("getCategoryInput returns category for simple workflow with category", (t) => {
t.is(
getCategoryInput(
yaml.load(`
jobs:
analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: github/codeql-action/init@v2
- uses: github/codeql-action/analyze@v2
with:
category: some-category
`) as Workflow
),
"some-category"
);
});
test("getCategoryInput returns undefined for simple workflow without category", (t) => {
t.is(
getCategoryInput(
yaml.load(`
jobs:
analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: github/codeql-action/init@v2
- uses: github/codeql-action/analyze@v2
`) as Workflow
),
undefined
);
});
test("getCategoryInput throws error for workflow with dynamic category", (t) => {
t.throws(
() =>
getCategoryInput(
yaml.load(`
jobs:
analysis:
runs-on: ubuntu-latest
strategy:
matrix:
language: [javascript, python]
steps:
- uses: actions/checkout@v2
- uses: github/codeql-action/init@v2
with:
language: \${{ matrix.language }}
- uses: github/codeql-action/analyze@v2
with:
category: "/language:\${{ matrix.language }}"
`) as Workflow
),
{
message:
"Could not get category input since it contained a dynamic value.",
}
);
});
test("getCategoryInput throws error for workflow with multiple categories", (t) => {
t.throws(
() =>
getCategoryInput(
yaml.load(`
jobs:
analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: github/codeql-action/init@v2
- uses: github/codeql-action/analyze@v2
with:
category: some-category
- uses: github/codeql-action/analyze@v2
with:
category: another-category
`) as Workflow
),
{
message:
"Could not get category input since multiple categories were specified by the analysis step.",
}
);
});

View file

@ -9,6 +9,8 @@ import { getRequiredEnvParam } from "./util";
interface WorkflowJobStep {
run: any;
uses?: string;
with?: { [key: string]: string };
}
interface WorkflowJob {
@ -290,3 +292,43 @@ export function getWorkflowRunID(): number {
}
return workflowRunID;
}
export function getAnalyzeSteps(job: WorkflowJob): WorkflowJobStep[] {
const steps = job.steps;
if (!Array.isArray(steps)) {
throw new Error(
"Could not get analyze steps since job.steps was not an array."
);
}
return steps.filter((step) =>
step.uses?.includes("github/codeql-action/analyze")
);
}
export function getCategoryInput(workflow: Workflow): string | undefined {
if (!workflow.jobs) {
throw new Error(
"Could not get category input since workflow.jobs was undefined."
);
}
const categories: string[] = Object.values(workflow.jobs)
.map((job) => getAnalyzeSteps(job).map((step) => step.with?.category))
.flat()
.filter((category) => category !== undefined)
.map((category) => category!);
if (categories.length === 0) {
return undefined;
}
if (!categories.every((category) => category === categories[0])) {
throw new Error(
"Could not get category input since multiple categories were specified by the analysis step."
);
}
if (categories[0].includes("${{")) {
throw new Error(
"Could not get category input since it contained a dynamic value."
);
}
return categories[0];
}