Substitute matrix variables into category input

This is a common case, so we should handle it.
This commit is contained in:
Henry Mercer 2022-11-22 18:26:14 +00:00
parent e2d523ca5e
commit daf4614f68
6 changed files with 119 additions and 53 deletions

25
lib/workflow.js generated
View file

@ -19,7 +19,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCategoryInput = exports.getAnalyzeSteps = exports.getWorkflowRunID = exports.getWorkflowPath = exports.getWorkflow = exports.formatWorkflowCause = exports.formatWorkflowErrors = exports.validateWorkflow = exports.getWorkflowErrors = exports.WorkflowErrors = exports.patternIsSuperset = void 0;
exports.tryGetCategoryInput = exports.getAnalyzeSteps = exports.getWorkflowRunID = exports.getWorkflowPath = exports.getWorkflow = exports.formatWorkflowCause = exports.formatWorkflowErrors = exports.validateWorkflow = exports.getWorkflowErrors = exports.WorkflowErrors = exports.patternIsSuperset = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const core = __importStar(require("@actions/core"));
@ -254,7 +254,14 @@ function getAnalyzeSteps(job) {
return steps.filter((step) => { var _a; return (_a = step.uses) === null || _a === void 0 ? void 0 : _a.includes("github/codeql-action/analyze"); });
}
exports.getAnalyzeSteps = getAnalyzeSteps;
function getCategoryInput(workflow) {
/**
* Makes a best effort attempt to retrieve the category input for the particular job,
* given a set of matrix variables.
*
* @returns the category input, or undefined if the category input is not defined
* @throws an error if the category input could not be determined
*/
function tryGetCategoryInput(workflow, matrixVars) {
if (!workflow.jobs) {
throw new Error("Could not get category input since workflow.jobs was undefined.");
}
@ -269,10 +276,16 @@ function getCategoryInput(workflow) {
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.");
// Make a basic attempt to substitute matrix variables
// First normalize by removing whitespace
let category = categories[0].replace(/\${{\s+/, "${{").replace(/\s+}}/, "}}");
for (const [key, value] of Object.entries(matrixVars)) {
category = category.replace(`\${{matrix.${key}}}`, value);
}
return categories[0];
if (category.includes("${{")) {
throw new Error("Could not get category input since it contained an unrecognized dynamic value.");
}
return category;
}
exports.getCategoryInput = getCategoryInput;
exports.tryGetCategoryInput = tryGetCategoryInput;
//# sourceMappingURL=workflow.js.map

File diff suppressed because one or more lines are too long

52
lib/workflow.test.js generated
View file

@ -355,8 +355,8 @@ function errorCodes(actual, expected) {
on: ["push"]
`)), []));
});
(0, ava_1.default)("getCategoryInput returns category for simple workflow with category", (t) => {
t.is((0, workflow_1.getCategoryInput)(yaml.load(`
(0, ava_1.default)("tryGetCategoryInput returns category for simple workflow with category", (t) => {
t.is((0, workflow_1.tryGetCategoryInput)(yaml.load(`
jobs:
analysis:
runs-on: ubuntu-latest
@ -366,10 +366,10 @@ function errorCodes(actual, expected) {
- uses: github/codeql-action/analyze@v2
with:
category: some-category
`)), "some-category");
`), {}), "some-category");
});
(0, ava_1.default)("getCategoryInput returns undefined for simple workflow without category", (t) => {
t.is((0, workflow_1.getCategoryInput)(yaml.load(`
(0, ava_1.default)("tryGetCategoryInput returns undefined for simple workflow without category", (t) => {
t.is((0, workflow_1.tryGetCategoryInput)(yaml.load(`
jobs:
analysis:
runs-on: ubuntu-latest
@ -377,30 +377,42 @@ function errorCodes(actual, expected) {
- uses: actions/checkout@v2
- uses: github/codeql-action/init@v2
- uses: github/codeql-action/analyze@v2
`)), undefined);
`), {}), undefined);
});
(0, ava_1.default)("getCategoryInput throws error for workflow with dynamic category", (t) => {
t.throws(() => (0, workflow_1.getCategoryInput)(yaml.load(`
(0, ava_1.default)("tryGetCategoryInput finds category for workflow with language matrix", (t) => {
t.is((0, workflow_1.tryGetCategoryInput)(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 }}"
`), { language: "javascript" }), "/language:javascript");
});
(0, ava_1.default)("tryGetCategoryInput throws error for workflow with dynamic category", (t) => {
t.throws(() => (0, workflow_1.tryGetCategoryInput)(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 }}"
`)), {
message: "Could not get category input since it contained a dynamic value.",
category: "\${{ github.workflow }}"
`), {}), {
message: "Could not get category input since it contained an unrecognized dynamic value.",
});
});
(0, ava_1.default)("getCategoryInput throws error for workflow with multiple categories", (t) => {
t.throws(() => (0, workflow_1.getCategoryInput)(yaml.load(`
(0, ava_1.default)("tryGetCategoryInput throws error for workflow with multiple categories", (t) => {
t.throws(() => (0, workflow_1.tryGetCategoryInput)(yaml.load(`
jobs:
analysis:
runs-on: ubuntu-latest
@ -413,7 +425,7 @@ function errorCodes(actual, expected) {
- uses: github/codeql-action/analyze@v2
with:
category: another-category
`)), {
`), {}), {
message: "Could not get category input since multiple categories were specified by the analysis step.",
});
});

File diff suppressed because one or more lines are too long