Move workflow check to a function in init.ts and add tests

This commit is contained in:
Michael B. Gale
2025-10-27 15:57:44 +00:00
parent 127851b399
commit 06fbd897c4
9 changed files with 1847 additions and 1689 deletions

View File

@@ -40,6 +40,7 @@ import { loadPropertiesFromApi } from "./feature-flags/properties";
import {
checkInstallPython311,
checkPacksForOverlayCompatibility,
checkWorkflow,
cleanupDatabaseClusterDirectory,
initCodeQL,
initConfig,
@@ -86,7 +87,6 @@ import {
getErrorMessage,
BuildMode,
} from "./util";
import { validateWorkflow } from "./workflow";
/**
* Sends a status report indicating that the `init` Action is starting.
@@ -288,19 +288,9 @@ async function run() {
toolsSource = initCodeQLResult.toolsSource;
zstdAvailability = initCodeQLResult.zstdAvailability;
// Check the workflow for problems, unless `SKIP_WORKFLOW_VALIDATION` is `true`.
if (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();
}
// 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

View File

@@ -2,23 +2,81 @@ import * as fs from "fs";
import path from "path";
import test, { ExecutionContext } from "ava";
import * as sinon from "sinon";
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({});
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({});
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({});
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("cleanupDatabaseClusterDirectory cleans up where possible", async (t) => {
await withTmpDir(async (tmpDir: string) => {
const dbLocation = path.resolve(tmpDir, "dbs");

View File

@@ -1,6 +1,7 @@
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";
@@ -9,6 +10,7 @@ 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";
@@ -16,6 +18,29 @@ 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`.
if (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,