mirror of
https://github.com/github/codeql-action.git
synced 2025-12-06 07:48:17 +08:00
Merge pull request #3240 from github/mbg/allow-skip-workflow-validation
Support skipping workflow validation
This commit is contained in:
12
lib/init-action-post.js
generated
12
lib/init-action-post.js
generated
@@ -19755,22 +19755,22 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``);
|
||||
process.stdout.write(message + os3.EOL);
|
||||
}
|
||||
exports2.info = info5;
|
||||
function startGroup3(name) {
|
||||
function startGroup4(name) {
|
||||
(0, command_1.issue)("group", name);
|
||||
}
|
||||
exports2.startGroup = startGroup3;
|
||||
function endGroup3() {
|
||||
exports2.startGroup = startGroup4;
|
||||
function endGroup4() {
|
||||
(0, command_1.issue)("endgroup");
|
||||
}
|
||||
exports2.endGroup = endGroup3;
|
||||
exports2.endGroup = endGroup4;
|
||||
function group(name, fn) {
|
||||
return __awaiter4(this, void 0, void 0, function* () {
|
||||
startGroup3(name);
|
||||
startGroup4(name);
|
||||
let result;
|
||||
try {
|
||||
result = yield fn();
|
||||
} finally {
|
||||
endGroup3();
|
||||
endGroup4();
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
31
lib/init-action.js
generated
31
lib/init-action.js
generated
@@ -92208,6 +92208,26 @@ async function getWorkflowAbsolutePath(logger) {
|
||||
`Expected to find a code scanning workflow file at ${absolutePath}, but no such file existed. This can happen if the currently running workflow checks out a branch that doesn't contain the corresponding workflow file.`
|
||||
);
|
||||
}
|
||||
async function checkWorkflow(logger, codeql) {
|
||||
if (!isDynamicWorkflow() && process.env["CODEQL_ACTION_SKIP_WORKFLOW_VALIDATION" /* SKIP_WORKFLOW_VALIDATION */] !== "true") {
|
||||
core12.startGroup("Validating workflow");
|
||||
const validateWorkflowResult = await internal.validateWorkflow(
|
||||
codeql,
|
||||
logger
|
||||
);
|
||||
if (validateWorkflowResult === void 0) {
|
||||
logger.info("Detected no issues with the code scanning workflow.");
|
||||
} else {
|
||||
logger.debug(
|
||||
`Unable to validate code scanning workflow: ${validateWorkflowResult}`
|
||||
);
|
||||
}
|
||||
core12.endGroup();
|
||||
}
|
||||
}
|
||||
var internal = {
|
||||
validateWorkflow
|
||||
};
|
||||
|
||||
// src/init-action.ts
|
||||
async function sendStartingStatusReport(startedAt, config, logger) {
|
||||
@@ -92345,16 +92365,7 @@ async function run() {
|
||||
toolsVersion = initCodeQLResult.toolsVersion;
|
||||
toolsSource = initCodeQLResult.toolsSource;
|
||||
zstdAvailability = initCodeQLResult.zstdAvailability;
|
||||
core13.startGroup("Validating workflow");
|
||||
const validateWorkflowResult = await validateWorkflow(codeql, logger);
|
||||
if (validateWorkflowResult === void 0) {
|
||||
logger.info("Detected no issues with the code scanning workflow.");
|
||||
} else {
|
||||
logger.warning(
|
||||
`Unable to validate code scanning workflow: ${validateWorkflowResult}`
|
||||
);
|
||||
}
|
||||
core13.endGroup();
|
||||
await checkWorkflow(logger, codeql);
|
||||
if (
|
||||
// Only enable the experimental features env variable for Rust analysis if the user has explicitly
|
||||
// requested rust - don't enable it via language autodetection.
|
||||
|
||||
@@ -137,4 +137,10 @@ export enum EnvVar {
|
||||
* This setting is more specific than `CODEQL_ACTION_TEST_MODE`, which implies this option.
|
||||
*/
|
||||
SKIP_SARIF_UPLOAD = "CODEQL_ACTION_SKIP_SARIF_UPLOAD",
|
||||
|
||||
/**
|
||||
* Whether to skip workflow validation. Intended for internal use, where we know that
|
||||
* the workflow is valid and validation is not necessary.
|
||||
*/
|
||||
SKIP_WORKFLOW_VALIDATION = "CODEQL_ACTION_SKIP_WORKFLOW_VALIDATION",
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ import {
|
||||
getErrorMessage,
|
||||
BuildMode,
|
||||
} from "./util";
|
||||
import { validateWorkflow } from "./workflow";
|
||||
import { checkWorkflow } from "./workflow";
|
||||
|
||||
/**
|
||||
* Sends a status report indicating that the `init` Action is starting.
|
||||
@@ -288,16 +288,9 @@ async function run() {
|
||||
toolsSource = initCodeQLResult.toolsSource;
|
||||
zstdAvailability = initCodeQLResult.zstdAvailability;
|
||||
|
||||
core.startGroup("Validating workflow");
|
||||
const validateWorkflowResult = await validateWorkflow(codeql, logger);
|
||||
if (validateWorkflowResult === undefined) {
|
||||
logger.info("Detected no issues with the code scanning workflow.");
|
||||
} else {
|
||||
logger.warning(
|
||||
`Unable to validate code scanning workflow: ${validateWorkflowResult}`,
|
||||
);
|
||||
}
|
||||
core.endGroup();
|
||||
// Check the workflow for problems. If there are any problems, they are reported
|
||||
// to the workflow log. No exceptions are thrown.
|
||||
await checkWorkflow(logger, codeql);
|
||||
|
||||
// Set CODEQL_ENABLE_EXPERIMENTAL_FEATURES for Rust if between 2.19.3 (included) and 2.22.1 (excluded)
|
||||
// We need to set this environment variable before initializing the config, otherwise Rust
|
||||
|
||||
@@ -2,9 +2,17 @@ import test, { ExecutionContext } from "ava";
|
||||
import * as yaml from "js-yaml";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import { getCodeQLForTesting } from "./codeql";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { createStubCodeQL, getCodeQLForTesting } from "./codeql";
|
||||
import { EnvVar } from "./environment";
|
||||
import {
|
||||
checkExpectedLogMessages,
|
||||
getRecordingLogger,
|
||||
LoggedMessage,
|
||||
setupTests,
|
||||
} from "./testing-utils";
|
||||
import {
|
||||
checkWorkflow,
|
||||
CodedError,
|
||||
formatWorkflowCause,
|
||||
formatWorkflowErrors,
|
||||
@@ -13,6 +21,7 @@ import {
|
||||
Workflow,
|
||||
WorkflowErrors,
|
||||
} from "./workflow";
|
||||
import * as workflow from "./workflow";
|
||||
|
||||
function errorCodes(
|
||||
actual: CodedError[],
|
||||
@@ -870,3 +879,78 @@ test("getCategoryInputOrThrow throws error for workflow with multiple calls to a
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test("checkWorkflow - validates workflow if `SKIP_WORKFLOW_VALIDATION` is not set", async (t) => {
|
||||
const messages: LoggedMessage[] = [];
|
||||
const codeql = createStubCodeQL({});
|
||||
|
||||
sinon.stub(actionsUtil, "isDynamicWorkflow").returns(false);
|
||||
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
|
||||
validateWorkflow.resolves(undefined);
|
||||
|
||||
await checkWorkflow(getRecordingLogger(messages), codeql);
|
||||
|
||||
t.assert(
|
||||
validateWorkflow.calledOnce,
|
||||
"`checkWorkflow` unexpectedly did not call `validateWorkflow`",
|
||||
);
|
||||
checkExpectedLogMessages(t, messages, [
|
||||
"Detected no issues with the code scanning workflow.",
|
||||
]);
|
||||
});
|
||||
|
||||
test("checkWorkflow - logs problems with workflow validation", async (t) => {
|
||||
const messages: LoggedMessage[] = [];
|
||||
const codeql = createStubCodeQL({});
|
||||
|
||||
sinon.stub(actionsUtil, "isDynamicWorkflow").returns(false);
|
||||
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
|
||||
validateWorkflow.resolves("problem");
|
||||
|
||||
await checkWorkflow(getRecordingLogger(messages), codeql);
|
||||
|
||||
t.assert(
|
||||
validateWorkflow.calledOnce,
|
||||
"`checkWorkflow` unexpectedly did not call `validateWorkflow`",
|
||||
);
|
||||
checkExpectedLogMessages(t, messages, [
|
||||
"Unable to validate code scanning workflow: problem",
|
||||
]);
|
||||
});
|
||||
|
||||
test("checkWorkflow - skips validation if `SKIP_WORKFLOW_VALIDATION` is `true`", async (t) => {
|
||||
process.env[EnvVar.SKIP_WORKFLOW_VALIDATION] = "true";
|
||||
|
||||
const messages: LoggedMessage[] = [];
|
||||
const codeql = createStubCodeQL({});
|
||||
|
||||
sinon.stub(actionsUtil, "isDynamicWorkflow").returns(false);
|
||||
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
|
||||
|
||||
await checkWorkflow(getRecordingLogger(messages), codeql);
|
||||
|
||||
t.assert(
|
||||
validateWorkflow.notCalled,
|
||||
"`checkWorkflow` called `validateWorkflow` unexpectedly",
|
||||
);
|
||||
t.is(messages.length, 0);
|
||||
});
|
||||
|
||||
test("checkWorkflow - skips validation for `dynamic` workflows", async (t) => {
|
||||
const messages: LoggedMessage[] = [];
|
||||
const codeql = createStubCodeQL({});
|
||||
|
||||
const isDynamicWorkflow = sinon
|
||||
.stub(actionsUtil, "isDynamicWorkflow")
|
||||
.returns(true);
|
||||
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
|
||||
|
||||
await checkWorkflow(getRecordingLogger(messages), codeql);
|
||||
|
||||
t.assert(isDynamicWorkflow.calledOnce);
|
||||
t.assert(
|
||||
validateWorkflow.notCalled,
|
||||
"`checkWorkflow` called `validateWorkflow` unexpectedly",
|
||||
);
|
||||
t.is(messages.length, 0);
|
||||
});
|
||||
|
||||
@@ -5,8 +5,10 @@ import zlib from "zlib";
|
||||
import * as core from "@actions/core";
|
||||
import * as yaml from "js-yaml";
|
||||
|
||||
import { isDynamicWorkflow } from "./actions-util";
|
||||
import * as api from "./api-client";
|
||||
import { CodeQL } from "./codeql";
|
||||
import { EnvVar } from "./environment";
|
||||
import { Logger } from "./logging";
|
||||
import {
|
||||
getRequiredEnvParam,
|
||||
@@ -216,7 +218,7 @@ function hasWorkflowTrigger(triggerName: string, doc: Workflow): boolean {
|
||||
return Object.prototype.hasOwnProperty.call(doc.on, triggerName);
|
||||
}
|
||||
|
||||
export async function validateWorkflow(
|
||||
async function validateWorkflow(
|
||||
codeql: CodeQL,
|
||||
logger: Logger,
|
||||
): Promise<undefined | string> {
|
||||
@@ -462,3 +464,36 @@ export function getCheckoutPathInputOrThrow(
|
||||
) || getRequiredEnvParam("GITHUB_WORKSPACE") // if unspecified, checkout_path defaults to ${{ github.workspace }}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper around `validateWorkflow` which reports the outcome.
|
||||
*
|
||||
* @param logger The logger to use.
|
||||
* @param codeql The CodeQL instance.
|
||||
*/
|
||||
export async function checkWorkflow(logger: Logger, codeql: CodeQL) {
|
||||
// Check the workflow for problems, unless `SKIP_WORKFLOW_VALIDATION` is `true`
|
||||
// or the workflow trigger is `dynamic`.
|
||||
if (
|
||||
!isDynamicWorkflow() &&
|
||||
process.env[EnvVar.SKIP_WORKFLOW_VALIDATION] !== "true"
|
||||
) {
|
||||
core.startGroup("Validating workflow");
|
||||
const validateWorkflowResult = await internal.validateWorkflow(
|
||||
codeql,
|
||||
logger,
|
||||
);
|
||||
if (validateWorkflowResult === undefined) {
|
||||
logger.info("Detected no issues with the code scanning workflow.");
|
||||
} else {
|
||||
logger.debug(
|
||||
`Unable to validate code scanning workflow: ${validateWorkflowResult}`,
|
||||
);
|
||||
}
|
||||
core.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
export const internal = {
|
||||
validateWorkflow,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user