Skip to content

Commit 44aeac1

Browse files
authored
Merge branch 'main' into dependabot/github_actions/dot-github/workflows/actions/download-artifact-6
2 parents 9c39f0a + ad8ad98 commit 44aeac1

File tree

6 files changed

+159
-30
lines changed

6 files changed

+159
-30
lines changed

lib/init-action-post.js

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/init-action.js

Lines changed: 21 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/environment.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,10 @@ export enum EnvVar {
137137
* This setting is more specific than `CODEQL_ACTION_TEST_MODE`, which implies this option.
138138
*/
139139
SKIP_SARIF_UPLOAD = "CODEQL_ACTION_SKIP_SARIF_UPLOAD",
140+
141+
/**
142+
* Whether to skip workflow validation. Intended for internal use, where we know that
143+
* the workflow is valid and validation is not necessary.
144+
*/
145+
SKIP_WORKFLOW_VALIDATION = "CODEQL_ACTION_SKIP_WORKFLOW_VALIDATION",
140146
}

src/init-action.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ import {
8686
getErrorMessage,
8787
BuildMode,
8888
} from "./util";
89-
import { validateWorkflow } from "./workflow";
89+
import { checkWorkflow } from "./workflow";
9090

9191
/**
9292
* Sends a status report indicating that the `init` Action is starting.
@@ -288,16 +288,9 @@ async function run() {
288288
toolsSource = initCodeQLResult.toolsSource;
289289
zstdAvailability = initCodeQLResult.zstdAvailability;
290290

291-
core.startGroup("Validating workflow");
292-
const validateWorkflowResult = await validateWorkflow(codeql, logger);
293-
if (validateWorkflowResult === undefined) {
294-
logger.info("Detected no issues with the code scanning workflow.");
295-
} else {
296-
logger.warning(
297-
`Unable to validate code scanning workflow: ${validateWorkflowResult}`,
298-
);
299-
}
300-
core.endGroup();
291+
// Check the workflow for problems. If there are any problems, they are reported
292+
// to the workflow log. No exceptions are thrown.
293+
await checkWorkflow(logger, codeql);
301294

302295
// Set CODEQL_ENABLE_EXPERIMENTAL_FEATURES for Rust if between 2.19.3 (included) and 2.22.1 (excluded)
303296
// We need to set this environment variable before initializing the config, otherwise Rust

src/workflow.test.ts

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@ import test, { ExecutionContext } from "ava";
22
import * as yaml from "js-yaml";
33
import * as sinon from "sinon";
44

5-
import { getCodeQLForTesting } from "./codeql";
6-
import { setupTests } from "./testing-utils";
5+
import * as actionsUtil from "./actions-util";
6+
import { createStubCodeQL, getCodeQLForTesting } from "./codeql";
7+
import { EnvVar } from "./environment";
78
import {
9+
checkExpectedLogMessages,
10+
getRecordingLogger,
11+
LoggedMessage,
12+
setupTests,
13+
} from "./testing-utils";
14+
import {
15+
checkWorkflow,
816
CodedError,
917
formatWorkflowCause,
1018
formatWorkflowErrors,
@@ -13,6 +21,7 @@ import {
1321
Workflow,
1422
WorkflowErrors,
1523
} from "./workflow";
24+
import * as workflow from "./workflow";
1625

1726
function errorCodes(
1827
actual: CodedError[],
@@ -870,3 +879,78 @@ test("getCategoryInputOrThrow throws error for workflow with multiple calls to a
870879
},
871880
);
872881
});
882+
883+
test("checkWorkflow - validates workflow if `SKIP_WORKFLOW_VALIDATION` is not set", async (t) => {
884+
const messages: LoggedMessage[] = [];
885+
const codeql = createStubCodeQL({});
886+
887+
sinon.stub(actionsUtil, "isDynamicWorkflow").returns(false);
888+
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
889+
validateWorkflow.resolves(undefined);
890+
891+
await checkWorkflow(getRecordingLogger(messages), codeql);
892+
893+
t.assert(
894+
validateWorkflow.calledOnce,
895+
"`checkWorkflow` unexpectedly did not call `validateWorkflow`",
896+
);
897+
checkExpectedLogMessages(t, messages, [
898+
"Detected no issues with the code scanning workflow.",
899+
]);
900+
});
901+
902+
test("checkWorkflow - logs problems with workflow validation", async (t) => {
903+
const messages: LoggedMessage[] = [];
904+
const codeql = createStubCodeQL({});
905+
906+
sinon.stub(actionsUtil, "isDynamicWorkflow").returns(false);
907+
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
908+
validateWorkflow.resolves("problem");
909+
910+
await checkWorkflow(getRecordingLogger(messages), codeql);
911+
912+
t.assert(
913+
validateWorkflow.calledOnce,
914+
"`checkWorkflow` unexpectedly did not call `validateWorkflow`",
915+
);
916+
checkExpectedLogMessages(t, messages, [
917+
"Unable to validate code scanning workflow: problem",
918+
]);
919+
});
920+
921+
test("checkWorkflow - skips validation if `SKIP_WORKFLOW_VALIDATION` is `true`", async (t) => {
922+
process.env[EnvVar.SKIP_WORKFLOW_VALIDATION] = "true";
923+
924+
const messages: LoggedMessage[] = [];
925+
const codeql = createStubCodeQL({});
926+
927+
sinon.stub(actionsUtil, "isDynamicWorkflow").returns(false);
928+
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
929+
930+
await checkWorkflow(getRecordingLogger(messages), codeql);
931+
932+
t.assert(
933+
validateWorkflow.notCalled,
934+
"`checkWorkflow` called `validateWorkflow` unexpectedly",
935+
);
936+
t.is(messages.length, 0);
937+
});
938+
939+
test("checkWorkflow - skips validation for `dynamic` workflows", async (t) => {
940+
const messages: LoggedMessage[] = [];
941+
const codeql = createStubCodeQL({});
942+
943+
const isDynamicWorkflow = sinon
944+
.stub(actionsUtil, "isDynamicWorkflow")
945+
.returns(true);
946+
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
947+
948+
await checkWorkflow(getRecordingLogger(messages), codeql);
949+
950+
t.assert(isDynamicWorkflow.calledOnce);
951+
t.assert(
952+
validateWorkflow.notCalled,
953+
"`checkWorkflow` called `validateWorkflow` unexpectedly",
954+
);
955+
t.is(messages.length, 0);
956+
});

src/workflow.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import zlib from "zlib";
55
import * as core from "@actions/core";
66
import * as yaml from "js-yaml";
77

8+
import { isDynamicWorkflow } from "./actions-util";
89
import * as api from "./api-client";
910
import { CodeQL } from "./codeql";
11+
import { EnvVar } from "./environment";
1012
import { Logger } from "./logging";
1113
import {
1214
getRequiredEnvParam,
@@ -216,7 +218,7 @@ function hasWorkflowTrigger(triggerName: string, doc: Workflow): boolean {
216218
return Object.prototype.hasOwnProperty.call(doc.on, triggerName);
217219
}
218220

219-
export async function validateWorkflow(
221+
async function validateWorkflow(
220222
codeql: CodeQL,
221223
logger: Logger,
222224
): Promise<undefined | string> {
@@ -462,3 +464,36 @@ export function getCheckoutPathInputOrThrow(
462464
) || getRequiredEnvParam("GITHUB_WORKSPACE") // if unspecified, checkout_path defaults to ${{ github.workspace }}
463465
);
464466
}
467+
468+
/**
469+
* A wrapper around `validateWorkflow` which reports the outcome.
470+
*
471+
* @param logger The logger to use.
472+
* @param codeql The CodeQL instance.
473+
*/
474+
export async function checkWorkflow(logger: Logger, codeql: CodeQL) {
475+
// Check the workflow for problems, unless `SKIP_WORKFLOW_VALIDATION` is `true`
476+
// or the workflow trigger is `dynamic`.
477+
if (
478+
!isDynamicWorkflow() &&
479+
process.env[EnvVar.SKIP_WORKFLOW_VALIDATION] !== "true"
480+
) {
481+
core.startGroup("Validating workflow");
482+
const validateWorkflowResult = await internal.validateWorkflow(
483+
codeql,
484+
logger,
485+
);
486+
if (validateWorkflowResult === undefined) {
487+
logger.info("Detected no issues with the code scanning workflow.");
488+
} else {
489+
logger.debug(
490+
`Unable to validate code scanning workflow: ${validateWorkflowResult}`,
491+
);
492+
}
493+
core.endGroup();
494+
}
495+
}
496+
497+
export const internal = {
498+
validateWorkflow,
499+
};

0 commit comments

Comments
 (0)