mirror of
https://github.com/github/codeql-action.git
synced 2025-12-31 19:50:32 +08:00
Move checkWorkflow to workflow.ts
This commit is contained in:
@@ -40,7 +40,6 @@ import { loadPropertiesFromApi } from "./feature-flags/properties";
|
||||
import {
|
||||
checkInstallPython311,
|
||||
checkPacksForOverlayCompatibility,
|
||||
checkWorkflow,
|
||||
cleanupDatabaseClusterDirectory,
|
||||
initCodeQL,
|
||||
initConfig,
|
||||
@@ -87,6 +86,7 @@ import {
|
||||
getErrorMessage,
|
||||
BuildMode,
|
||||
} from "./util";
|
||||
import { checkWorkflow } from "./workflow";
|
||||
|
||||
/**
|
||||
* Sends a status report indicating that the `init` Action is starting.
|
||||
|
||||
@@ -2,104 +2,23 @@ import * as fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
import test, { ExecutionContext } from "ava";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { createStubCodeQL } from "./codeql";
|
||||
import { EnvVar } from "./environment";
|
||||
import {
|
||||
checkPacksForOverlayCompatibility,
|
||||
checkWorkflow,
|
||||
cleanupDatabaseClusterDirectory,
|
||||
} from "./init";
|
||||
import { KnownLanguage } from "./languages";
|
||||
import {
|
||||
LoggedMessage,
|
||||
checkExpectedLogMessages,
|
||||
createTestConfig,
|
||||
getRecordingLogger,
|
||||
setupTests,
|
||||
} from "./testing-utils";
|
||||
import { ConfigurationError, withTmpDir } from "./util";
|
||||
import * as workflow from "./workflow";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
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, "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, "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, "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, "validateWorkflow");
|
||||
|
||||
await checkWorkflow(getRecordingLogger(messages), codeql);
|
||||
|
||||
t.assert(isDynamicWorkflow.calledOnce);
|
||||
t.assert(
|
||||
validateWorkflow.notCalled,
|
||||
"`checkWorkflow` called `validateWorkflow` unexpectedly",
|
||||
);
|
||||
t.is(messages.length, 0);
|
||||
});
|
||||
|
||||
test("cleanupDatabaseClusterDirectory cleans up where possible", async (t) => {
|
||||
await withTmpDir(async (tmpDir: string) => {
|
||||
const dbLocation = path.resolve(tmpDir, "dbs");
|
||||
|
||||
35
src/init.ts
35
src/init.ts
@@ -1,20 +1,14 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
import * as core from "@actions/core";
|
||||
import * as toolrunner from "@actions/exec/lib/toolrunner";
|
||||
import * as io from "@actions/io";
|
||||
import * as yaml from "js-yaml";
|
||||
|
||||
import {
|
||||
getOptionalInput,
|
||||
isDynamicWorkflow,
|
||||
isSelfHostedRunner,
|
||||
} from "./actions-util";
|
||||
import { getOptionalInput, isSelfHostedRunner } from "./actions-util";
|
||||
import { GitHubApiDetails } from "./api-client";
|
||||
import { CodeQL, setupCodeQL } from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { CodeQLDefaultVersionInfo, FeatureEnablement } from "./feature-flags";
|
||||
import { KnownLanguage, Language } from "./languages";
|
||||
import { Logger, withGroupAsync } from "./logging";
|
||||
@@ -22,33 +16,6 @@ import { ToolsSource } from "./setup-codeql";
|
||||
import { ZstdAvailability } from "./tar";
|
||||
import { ToolsDownloadStatusReport } from "./tools-download";
|
||||
import * as util from "./util";
|
||||
import { validateWorkflow } from "./workflow";
|
||||
|
||||
/**
|
||||
* 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 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();
|
||||
}
|
||||
}
|
||||
|
||||
export async function initCodeQL(
|
||||
toolsInput: string | undefined,
|
||||
|
||||
@@ -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.warning(
|
||||
`Unable to validate code scanning workflow: ${validateWorkflowResult}`,
|
||||
);
|
||||
}
|
||||
core.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
export const internal = {
|
||||
validateWorkflow,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user