Add environment variables to signal feature and version to the CLI
This PR ensures environment variables are set before any invocation of the CLI. Here is a list of vars that are set: https://github.com/github/codeql-coreql-team/issues/1124#issuecomment-852463521 This ensures the CLI knows the features and versions of the containing actions/runner. Additionally: - Fix the user agent so that it more closely aligns with user agent spec - Refactor environment variable initialization so that it all happens in one place and call. - Move Mode, getRequiredEnvParam, setMode, getMode out of actions-util and into util. actions-util is meant for utils only called by the action, not the runner. The `prepareLocalRunEnvironment()` method is most likely deprecated and should be removed. I originally added it because I had a way of working where I would run the action from my local machine to test out changes, but this was always a little flaky. So, I no longer use this way of working. I will probably remove it soon.
This commit is contained in:
parent
539d968ad7
commit
3708898bf2
48 changed files with 387 additions and 250 deletions
|
|
@ -4,6 +4,7 @@ import sinon from "sinon";
|
|||
|
||||
import * as actionsutil from "./actions-util";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import { getMode, initializeEnvironment, Mode } from "./util";
|
||||
|
||||
function errorCodes(
|
||||
actual: actionsutil.CodedError[],
|
||||
|
|
@ -66,7 +67,7 @@ test("getAnalysisKey() when a local run", async (t) => {
|
|||
process.env.CODEQL_ACTION_ANALYSIS_KEY = "";
|
||||
process.env.GITHUB_JOB = "";
|
||||
|
||||
actionsutil.prepareLocalRunEnvironment();
|
||||
initializeEnvironment(Mode.actions, "1.2.3");
|
||||
|
||||
const actualAnalysisKey = await actionsutil.getAnalysisKey();
|
||||
|
||||
|
|
@ -129,7 +130,7 @@ test("prepareEnvironment() when a local run", (t) => {
|
|||
process.env.GITHUB_JOB = "YYY";
|
||||
process.env.CODEQL_ACTION_ANALYSIS_KEY = "TEST";
|
||||
|
||||
actionsutil.prepareLocalRunEnvironment();
|
||||
initializeEnvironment(Mode.actions, "1.2.3");
|
||||
|
||||
// unchanged
|
||||
t.deepEqual(process.env.GITHUB_JOB, "YYY");
|
||||
|
|
@ -137,7 +138,7 @@ test("prepareEnvironment() when a local run", (t) => {
|
|||
|
||||
process.env.CODEQL_LOCAL_RUN = "true";
|
||||
|
||||
actionsutil.prepareLocalRunEnvironment();
|
||||
initializeEnvironment(Mode.actions, "1.2.3");
|
||||
|
||||
// unchanged
|
||||
t.deepEqual(process.env.GITHUB_JOB, "YYY");
|
||||
|
|
@ -145,7 +146,7 @@ test("prepareEnvironment() when a local run", (t) => {
|
|||
|
||||
process.env.CODEQL_ACTION_ANALYSIS_KEY = "";
|
||||
|
||||
actionsutil.prepareLocalRunEnvironment();
|
||||
initializeEnvironment(Mode.actions, "1.2.3");
|
||||
|
||||
// updated
|
||||
t.deepEqual(process.env.GITHUB_JOB, "YYY");
|
||||
|
|
@ -154,11 +155,20 @@ test("prepareEnvironment() when a local run", (t) => {
|
|||
process.env.GITHUB_JOB = "";
|
||||
process.env.CODEQL_ACTION_ANALYSIS_KEY = "";
|
||||
|
||||
actionsutil.prepareLocalRunEnvironment();
|
||||
initializeEnvironment(Mode.actions, "1.2.3");
|
||||
|
||||
// updated
|
||||
t.deepEqual(process.env.GITHUB_JOB, "UNKNOWN-JOB");
|
||||
t.deepEqual(process.env.CODEQL_ACTION_ANALYSIS_KEY, "LOCAL-RUN:UNKNOWN-JOB");
|
||||
|
||||
process.env.GITHUB_JOB = "";
|
||||
process.env.CODEQL_ACTION_ANALYSIS_KEY = "";
|
||||
|
||||
initializeEnvironment(Mode.runner, "1.2.3");
|
||||
|
||||
// unchanged. local runs not allowed for runner
|
||||
t.deepEqual(process.env.GITHUB_JOB, "");
|
||||
t.deepEqual(process.env.CODEQL_ACTION_ANALYSIS_KEY, "");
|
||||
});
|
||||
|
||||
test("getWorkflowErrors() when on is empty", (t) => {
|
||||
|
|
@ -691,10 +701,12 @@ on: ["push"]
|
|||
);
|
||||
});
|
||||
|
||||
test("mode", (t) => {
|
||||
actionsutil.setMode(actionsutil.Mode.actions);
|
||||
t.deepEqual(actionsutil.getMode(), actionsutil.Mode.actions);
|
||||
test("initializeEnvironment", (t) => {
|
||||
initializeEnvironment(Mode.actions, "1.2.3");
|
||||
t.deepEqual(getMode(), Mode.actions);
|
||||
t.deepEqual(process.env.CODEQL_ACTION_VERSION, "1.2.3");
|
||||
|
||||
actionsutil.setMode(actionsutil.Mode.runner);
|
||||
t.deepEqual(actionsutil.getMode(), actionsutil.Mode.runner);
|
||||
initializeEnvironment(Mode.runner, "4.5.6");
|
||||
t.deepEqual(getMode(), Mode.runner);
|
||||
t.deepEqual(process.env.CODEQL_ACTION_VERSION, "4.5.6");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ import * as yaml from "js-yaml";
|
|||
|
||||
import * as api from "./api-client";
|
||||
import * as sharedEnv from "./shared-environment";
|
||||
import { GITHUB_DOTCOM_URL, isLocalRun } from "./util";
|
||||
import { getRequiredEnvParam, GITHUB_DOTCOM_URL, isLocalRun } from "./util";
|
||||
|
||||
export enum Mode {
|
||||
actions = "Action",
|
||||
runner = "Runner",
|
||||
}
|
||||
/**
|
||||
* The utils in this module are meant to be run inside of the action only.
|
||||
* Code paths from the runner should not enter this module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper around core.getInput for inputs that always have a value.
|
||||
|
|
@ -38,25 +38,6 @@ export function getOptionalInput(name: string): string | undefined {
|
|||
return value.length > 0 ? value : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an environment parameter, but throw an error if it is not set.
|
||||
*/
|
||||
export function getRequiredEnvParam(paramName: string): string {
|
||||
const value = process.env[paramName];
|
||||
if (value === undefined || value.length === 0) {
|
||||
throw new Error(`${paramName} environment variable must be set`);
|
||||
}
|
||||
core.debug(`${paramName}=${value}`);
|
||||
return value;
|
||||
}
|
||||
|
||||
export function getTemporaryDirectory(): string {
|
||||
const value = process.env["CODEQL_ACTION_TEMP"];
|
||||
return value !== undefined && value !== ""
|
||||
? value
|
||||
: getRequiredEnvParam("RUNNER_TEMP");
|
||||
}
|
||||
|
||||
export function getToolCacheDirectory(): string {
|
||||
const value = process.env["CODEQL_ACTION_TOOL_CACHE"];
|
||||
return value !== undefined && value !== ""
|
||||
|
|
@ -732,30 +713,3 @@ export function getRelativeScriptPath(): string {
|
|||
const actionsDirectory = path.join(path.dirname(runnerTemp), "_actions");
|
||||
return path.relative(actionsDirectory, __filename);
|
||||
}
|
||||
|
||||
const CODEQL_RUN_MODE_ENV_VAR = "CODEQL_RUN_MODE";
|
||||
|
||||
export function setMode(mode: Mode) {
|
||||
// avoid accessing actions core when in runner mode
|
||||
if (mode === Mode.actions) {
|
||||
core.exportVariable(CODEQL_RUN_MODE_ENV_VAR, mode);
|
||||
} else {
|
||||
process.env[CODEQL_RUN_MODE_ENV_VAR] = mode;
|
||||
}
|
||||
}
|
||||
|
||||
export function getMode(): Mode {
|
||||
// Make sure we fail fast if the env var is missing. This should
|
||||
// only happen if there is a bug in our code and we neglected
|
||||
// to set the mode early in the process.
|
||||
const mode = getRequiredEnvParam(CODEQL_RUN_MODE_ENV_VAR);
|
||||
|
||||
if (mode !== Mode.actions && mode !== Mode.runner) {
|
||||
throw new Error(`Unknown mode: ${mode}.`);
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
export function isActions(): boolean {
|
||||
return getMode() === Mode.actions;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ import { getActionsLogger } from "./logging";
|
|||
import * as upload_lib from "./upload-lib";
|
||||
import * as util from "./util";
|
||||
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
|
||||
interface AnalysisStatusReport
|
||||
extends upload_lib.UploadStatusReport,
|
||||
QueriesStatusReport {}
|
||||
|
|
@ -49,10 +52,9 @@ async function run() {
|
|||
const startedAt = new Date();
|
||||
let stats: AnalysisStatusReport | undefined = undefined;
|
||||
let config: Config | undefined = undefined;
|
||||
actionsUtil.setMode(actionsUtil.Mode.actions);
|
||||
util.initializeEnvironment(util.Mode.actions, pkg.version);
|
||||
|
||||
try {
|
||||
actionsUtil.prepareLocalRunEnvironment();
|
||||
if (
|
||||
!(await actionsUtil.sendStatusReport(
|
||||
await actionsUtil.createStatusReportBase(
|
||||
|
|
@ -65,7 +67,7 @@ async function run() {
|
|||
return;
|
||||
}
|
||||
const logger = getActionsLogger();
|
||||
config = await getConfig(actionsUtil.getTemporaryDirectory(), logger);
|
||||
config = await getConfig(util.getTemporaryDirectory(), logger);
|
||||
if (config === undefined) {
|
||||
throw new Error(
|
||||
"Config file could not be found at expected location. Has the 'init' action been called?"
|
||||
|
|
@ -74,7 +76,7 @@ async function run() {
|
|||
|
||||
const apiDetails = {
|
||||
auth: actionsUtil.getRequiredInput("token"),
|
||||
url: actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
url: util.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
};
|
||||
const outputDir = actionsUtil.getRequiredInput("output");
|
||||
const queriesStats = await runAnalyze(
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import * as githubUtils from "@actions/github/lib/utils";
|
|||
import test, { ExecutionContext } from "ava";
|
||||
import sinon from "sinon";
|
||||
|
||||
import { Mode, setMode } from "./actions-util";
|
||||
import { getApiClient } from "./api-client";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import { Mode, initializeEnvironment } from "./util";
|
||||
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
|
|
@ -15,7 +15,7 @@ let githubStub: sinon.SinonStub;
|
|||
|
||||
test.beforeEach(() => {
|
||||
githubStub = sinon.stub(githubUtils, "GitHub");
|
||||
setMode(Mode.actions);
|
||||
initializeEnvironment(Mode.actions, pkg.version);
|
||||
});
|
||||
|
||||
test("Get the client API", async (t) => {
|
||||
|
|
@ -30,7 +30,7 @@ test("Get the client API", async (t) => {
|
|||
{
|
||||
auth: "token xyz",
|
||||
baseUrl: "http://hucairz/api/v3",
|
||||
userAgent: `CodeQL Action/${pkg.version}`,
|
||||
userAgent: `CodeQL-Action/${pkg.version}`,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
@ -47,7 +47,7 @@ test("Get the client API external", async (t) => {
|
|||
{
|
||||
auth: "token abc",
|
||||
baseUrl: "http://hucairz/api/v3",
|
||||
userAgent: `CodeQL Action/${pkg.version}`,
|
||||
userAgent: `CodeQL-Action/${pkg.version}`,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
@ -63,7 +63,7 @@ test("Get the client API external not present", async (t) => {
|
|||
{
|
||||
auth: "token xyz",
|
||||
baseUrl: "http://hucairz/api/v3",
|
||||
userAgent: `CodeQL Action/${pkg.version}`,
|
||||
userAgent: `CodeQL-Action/${pkg.version}`,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
@ -79,7 +79,7 @@ test("Get the client API with github url", async (t) => {
|
|||
{
|
||||
auth: "token xyz",
|
||||
baseUrl: "https://api.github.com",
|
||||
userAgent: `CodeQL Action/${pkg.version}`,
|
||||
userAgent: `CodeQL-Action/${pkg.version}`,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import * as path from "path";
|
|||
import * as githubUtils from "@actions/github/lib/utils";
|
||||
import consoleLogLevel from "console-log-level";
|
||||
|
||||
import { getMode, getRequiredEnvParam, getRequiredInput } from "./actions-util";
|
||||
import { isLocalRun } from "./util";
|
||||
import { getRequiredInput } from "./actions-util";
|
||||
import { getMode, getRequiredEnvParam, isLocalRun } from "./util";
|
||||
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
|
|
@ -40,7 +40,7 @@ export const getApiClient = function (
|
|||
return new githubUtils.GitHub(
|
||||
githubUtils.getOctokitOptions(auth, {
|
||||
baseUrl: getApiUrl(apiDetails.url),
|
||||
userAgent: `CodeQL ${getMode()}/${pkg.version}`,
|
||||
userAgent: `CodeQL-${getMode()}/${pkg.version}`,
|
||||
log: consoleLogLevel({ level: "debug" }),
|
||||
})
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@ import * as core from "@actions/core";
|
|||
|
||||
import {
|
||||
createStatusReportBase,
|
||||
getTemporaryDirectory,
|
||||
Mode,
|
||||
prepareLocalRunEnvironment,
|
||||
sendStatusReport,
|
||||
setMode,
|
||||
StatusReportBase,
|
||||
} from "./actions-util";
|
||||
import { determineAutobuildLanguage, runAutobuild } from "./autobuild";
|
||||
import * as config_utils from "./config-utils";
|
||||
import { Language } from "./languages";
|
||||
import { getActionsLogger } from "./logging";
|
||||
import { getTemporaryDirectory, initializeEnvironment, Mode } from "./util";
|
||||
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
|
||||
interface AutobuildStatusReport extends StatusReportBase {
|
||||
// Comma-separated set of languages being auto-built
|
||||
|
|
@ -27,7 +27,7 @@ async function sendCompletedStatusReport(
|
|||
failingLanguage?: string,
|
||||
cause?: Error
|
||||
) {
|
||||
setMode(Mode.actions);
|
||||
initializeEnvironment(Mode.actions, pkg.version);
|
||||
|
||||
const status =
|
||||
failingLanguage !== undefined || cause !== undefined
|
||||
|
|
@ -53,7 +53,6 @@ async function run() {
|
|||
const startedAt = new Date();
|
||||
let language: Language | undefined = undefined;
|
||||
try {
|
||||
prepareLocalRunEnvironment();
|
||||
if (
|
||||
!(await sendStatusReport(
|
||||
await createStatusReportBase("autobuild", "starting", startedAt)
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ import * as toolcache from "@actions/tool-cache";
|
|||
import test from "ava";
|
||||
import nock from "nock";
|
||||
|
||||
import { Mode, setMode } from "./actions-util";
|
||||
import * as codeql from "./codeql";
|
||||
import * as defaults from "./defaults.json";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { setupTests, setupActionsVars } from "./testing-utils";
|
||||
import * as util from "./util";
|
||||
import { Mode, initializeEnvironment } from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ const sampleGHAEApiDetails = {
|
|||
};
|
||||
|
||||
test.beforeEach(() => {
|
||||
setMode(Mode.actions);
|
||||
initializeEnvironment(Mode.actions, "1.2.3");
|
||||
});
|
||||
|
||||
test("download codeql bundle cache", async (t) => {
|
||||
|
|
@ -371,14 +371,14 @@ test("getExtraOptions throws for bad content", (t) => {
|
|||
);
|
||||
});
|
||||
|
||||
test.only("getCodeQLActionRepository", (t) => {
|
||||
test("getCodeQLActionRepository", (t) => {
|
||||
const logger = getRunnerLogger(true);
|
||||
|
||||
setMode(Mode.actions);
|
||||
initializeEnvironment(Mode.actions, "1.2.3");
|
||||
const repoActions = codeql.getCodeQLActionRepository(logger);
|
||||
t.deepEqual(repoActions, "github/codeql-action");
|
||||
|
||||
setMode(Mode.runner);
|
||||
initializeEnvironment(Mode.runner, "1.2.3");
|
||||
|
||||
// isRunningLocalAction() === true
|
||||
delete process.env["GITHUB_ACTION_REPOSITORY"];
|
||||
|
|
|
|||
|
|
@ -11,11 +11,7 @@ import { default as queryString } from "query-string";
|
|||
import * as semver from "semver";
|
||||
import { v4 as uuidV4 } from "uuid";
|
||||
|
||||
import {
|
||||
isRunningLocalAction,
|
||||
getRelativeScriptPath,
|
||||
isActions,
|
||||
} from "./actions-util";
|
||||
import { isRunningLocalAction, getRelativeScriptPath } from "./actions-util";
|
||||
import * as api from "./api-client";
|
||||
import * as defaults from "./defaults.json"; // Referenced from codeql-action-sync-tool!
|
||||
import { errorMatchers } from "./error-matcher";
|
||||
|
|
@ -149,7 +145,7 @@ function getCodeQLBundleName(): string {
|
|||
}
|
||||
|
||||
export function getCodeQLActionRepository(logger: Logger): string {
|
||||
if (isActions()) {
|
||||
if (util.isActions()) {
|
||||
return CODEQL_DEFAULT_ACTION_REPOSITORY;
|
||||
} else {
|
||||
return getActionsCodeQLActionRepository(logger);
|
||||
|
|
|
|||
|
|
@ -3,14 +3,9 @@ import * as core from "@actions/core";
|
|||
import {
|
||||
createStatusReportBase,
|
||||
getOptionalInput,
|
||||
getRequiredEnvParam,
|
||||
getRequiredInput,
|
||||
getTemporaryDirectory,
|
||||
getToolCacheDirectory,
|
||||
Mode,
|
||||
prepareLocalRunEnvironment,
|
||||
sendStatusReport,
|
||||
setMode,
|
||||
StatusReportBase,
|
||||
validateWorkflow,
|
||||
} from "./actions-util";
|
||||
|
|
@ -26,7 +21,17 @@ import {
|
|||
import { Language } from "./languages";
|
||||
import { getActionsLogger } from "./logging";
|
||||
import { parseRepositoryNwo } from "./repository";
|
||||
import { checkGitHubVersionInRange, getGitHubVersion } from "./util";
|
||||
import {
|
||||
getRequiredEnvParam,
|
||||
getTemporaryDirectory,
|
||||
initializeEnvironment,
|
||||
Mode,
|
||||
checkGitHubVersionInRange,
|
||||
getGitHubVersion,
|
||||
} from "./util";
|
||||
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
|
||||
interface InitSuccessStatusReport extends StatusReportBase {
|
||||
// Comma-separated list of languages that analysis was run for
|
||||
|
|
@ -103,7 +108,7 @@ async function sendSuccessStatusReport(
|
|||
async function run() {
|
||||
const startedAt = new Date();
|
||||
const logger = getActionsLogger();
|
||||
setMode(Mode.actions);
|
||||
initializeEnvironment(Mode.actions, pkg.version);
|
||||
|
||||
let config: configUtils.Config;
|
||||
let codeql: CodeQL;
|
||||
|
|
@ -119,8 +124,6 @@ async function run() {
|
|||
checkGitHubVersionInRange(gitHubVersion, logger, Mode.actions);
|
||||
|
||||
try {
|
||||
prepareLocalRunEnvironment();
|
||||
|
||||
const workflowErrors = await validateWorkflow();
|
||||
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import * as path from "path";
|
|||
|
||||
import { Command } from "commander";
|
||||
|
||||
import { Mode, setMode } from "./actions-util";
|
||||
import { runAnalyze } from "./analyze";
|
||||
import { determineAutobuildLanguage, runAutobuild } from "./autobuild";
|
||||
import { CodeQL, getCodeQL } from "./codeql";
|
||||
|
|
@ -22,6 +21,8 @@ import {
|
|||
getThreadsFlag,
|
||||
parseGitHubUrl,
|
||||
getGitHubAuth,
|
||||
initializeEnvironment,
|
||||
Mode,
|
||||
} from "./util";
|
||||
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
|
|
@ -29,7 +30,7 @@ const pkg = require("../package.json");
|
|||
|
||||
const program = new Command();
|
||||
program.version(pkg.version).hook("preAction", () => {
|
||||
setMode(Mode.runner);
|
||||
initializeEnvironment(Mode.runner, pkg.version);
|
||||
});
|
||||
|
||||
function getTempDir(userInput: string | undefined): string {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import * as actionsToolcache from "@actions/tool-cache";
|
|||
import * as safeWhich from "@chrisgavin/safe-which";
|
||||
import * as semver from "semver";
|
||||
|
||||
import { isActions } from "./actions-util";
|
||||
import { Logger } from "./logging";
|
||||
import { isActions } from "./util";
|
||||
|
||||
/*
|
||||
* This file acts as an interface to the functionality of the actions toolcache.
|
||||
|
|
|
|||
|
|
@ -3,16 +3,21 @@ import * as path from "path";
|
|||
|
||||
import test from "ava";
|
||||
|
||||
import { Mode, setMode } from "./actions-util";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import * as uploadLib from "./upload-lib";
|
||||
import { GitHubVersion, GitHubVariant, withTmpDir } from "./util";
|
||||
import {
|
||||
initializeEnvironment,
|
||||
Mode,
|
||||
GitHubVersion,
|
||||
GitHubVariant,
|
||||
withTmpDir,
|
||||
} from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
test.beforeEach(() => {
|
||||
setMode(Mode.actions);
|
||||
initializeEnvironment(Mode.actions, "1.2.3");
|
||||
});
|
||||
|
||||
test("validateSarifFileSchema - valid", (t) => {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ async function uploadPayload(
|
|||
|
||||
const client = api.getApiClient(apiDetails);
|
||||
|
||||
const reqURL = actionsUtil.isActions()
|
||||
const reqURL = util.isActions()
|
||||
? "PUT /repos/:owner/:repo/code-scanning/analysis"
|
||||
: "POST /repos/:owner/:repo/code-scanning/sarifs";
|
||||
const response = await client.request(reqURL, {
|
||||
|
|
@ -150,12 +150,12 @@ export async function uploadFromActions(
|
|||
): Promise<UploadStatusReport> {
|
||||
return await uploadFiles(
|
||||
getSarifFilePaths(sarifPath),
|
||||
parseRepositoryNwo(actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY")),
|
||||
parseRepositoryNwo(util.getRequiredEnvParam("GITHUB_REPOSITORY")),
|
||||
await actionsUtil.getCommitOid(),
|
||||
await actionsUtil.getRef(),
|
||||
await actionsUtil.getAnalysisKey(),
|
||||
actionsUtil.getOptionalInput("category"),
|
||||
actionsUtil.getRequiredEnvParam("GITHUB_WORKFLOW"),
|
||||
util.getRequiredEnvParam("GITHUB_WORKFLOW"),
|
||||
actionsUtil.getWorkflowRunID(),
|
||||
actionsUtil.getRequiredInput("checkout_path"),
|
||||
actionsUtil.getRequiredInput("matrix"),
|
||||
|
|
@ -275,7 +275,7 @@ export function buildPayload(
|
|||
toolNames: string[],
|
||||
gitHubVersion: util.GitHubVersion
|
||||
) {
|
||||
if (actionsUtil.isActions()) {
|
||||
if (util.isActions()) {
|
||||
const payloadObj = {
|
||||
commit_oid: commitOid,
|
||||
ref,
|
||||
|
|
@ -339,7 +339,7 @@ async function uploadFiles(
|
|||
logger.startGroup("Uploading results");
|
||||
logger.info(`Processing sarif files: ${JSON.stringify(sarifFiles)}`);
|
||||
|
||||
if (actionsUtil.isActions()) {
|
||||
if (util.isActions()) {
|
||||
// This check only works on actions as env vars don't persist between calls to the runner
|
||||
const sentinelEnvVar = "CODEQL_UPLOAD_SARIF";
|
||||
if (process.env[sentinelEnvVar]) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,15 @@ import * as core from "@actions/core";
|
|||
import * as actionsUtil from "./actions-util";
|
||||
import { getActionsLogger } from "./logging";
|
||||
import * as upload_lib from "./upload-lib";
|
||||
import { getGitHubVersion } from "./util";
|
||||
import {
|
||||
getGitHubVersion,
|
||||
getRequiredEnvParam,
|
||||
initializeEnvironment,
|
||||
Mode,
|
||||
} from "./util";
|
||||
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
|
||||
interface UploadSarifStatusReport
|
||||
extends actionsUtil.StatusReportBase,
|
||||
|
|
@ -26,7 +34,7 @@ async function sendSuccessStatusReport(
|
|||
}
|
||||
|
||||
async function run() {
|
||||
actionsUtil.setMode(actionsUtil.Mode.actions);
|
||||
initializeEnvironment(Mode.actions, pkg.version);
|
||||
const startedAt = new Date();
|
||||
if (
|
||||
!(await actionsUtil.sendStatusReport(
|
||||
|
|
@ -43,7 +51,7 @@ async function run() {
|
|||
try {
|
||||
const apiDetails = {
|
||||
auth: actionsUtil.getRequiredInput("token"),
|
||||
url: actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
url: getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
};
|
||||
|
||||
const gitHubVersion = await getGitHubVersion(apiDetails);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import sinon from "sinon";
|
|||
import * as api from "./api-client";
|
||||
import { getRunnerLogger, Logger } from "./logging";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import { initializeEnvironment, Mode } from "./util";
|
||||
import * as util from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
|
@ -77,6 +78,8 @@ test("getThreadsFlag() throws if the threads input is not an integer", (t) => {
|
|||
});
|
||||
|
||||
test("isLocalRun() runs correctly", (t) => {
|
||||
initializeEnvironment(Mode.actions, "1.2.3");
|
||||
|
||||
process.env.CODEQL_LOCAL_RUN = "";
|
||||
t.assert(!util.isLocalRun());
|
||||
|
||||
|
|
@ -91,6 +94,9 @@ test("isLocalRun() runs correctly", (t) => {
|
|||
|
||||
process.env.CODEQL_LOCAL_RUN = "hucairz";
|
||||
t.assert(util.isLocalRun());
|
||||
|
||||
initializeEnvironment(Mode.runner, "1.2.3");
|
||||
t.assert(!util.isLocalRun());
|
||||
});
|
||||
|
||||
test("getExtraOptionsEnvParam() succeeds on valid JSON with invalid options (for now)", (t) => {
|
||||
|
|
|
|||
97
src/util.ts
97
src/util.ts
|
|
@ -6,7 +6,7 @@ import { Readable } from "stream";
|
|||
import * as core from "@actions/core";
|
||||
import * as semver from "semver";
|
||||
|
||||
import { isActions, Mode } from "./actions-util";
|
||||
import { prepareLocalRunEnvironment } from "./actions-util";
|
||||
import { getApiClient, GitHubApiDetails } from "./api-client";
|
||||
import * as apiCompatibility from "./api-compatibility.json";
|
||||
import { Config } from "./config-utils";
|
||||
|
|
@ -40,7 +40,9 @@ export function isLocalRun(): boolean {
|
|||
return (
|
||||
!!process.env.CODEQL_LOCAL_RUN &&
|
||||
process.env.CODEQL_LOCAL_RUN !== "false" &&
|
||||
process.env.CODEQL_LOCAL_RUN !== "0"
|
||||
process.env.CODEQL_LOCAL_RUN !== "0" &&
|
||||
// local runs only allowed for actions
|
||||
isActions()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -396,3 +398,94 @@ class ExhaustivityCheckingError extends Error {
|
|||
export function assertNever(value: never): never {
|
||||
throw new ExhaustivityCheckingError(value);
|
||||
}
|
||||
|
||||
export enum Mode {
|
||||
actions = "Action",
|
||||
runner = "Runner",
|
||||
}
|
||||
|
||||
/**
|
||||
* Environment variables to be set by codeql-action and used by the
|
||||
* CLI. These environment variables are relevant for both the runner
|
||||
* and the action.
|
||||
*/
|
||||
enum EnvVar {
|
||||
// either 'actions' or 'runner'
|
||||
RUN_MODE = "CODEQL_ACTION_RUN_MODE",
|
||||
|
||||
// semver of this action
|
||||
VERSION = "CODEQL_ACTION_VERSION",
|
||||
|
||||
// if set to a truthy value, then the action might combine SARIF
|
||||
// output from several `interpret-results` runs for the same language
|
||||
FEATURE_SARIF_COMBINE = "CODEQL_ACTION_FEATURE_SARIF_COMBINE",
|
||||
|
||||
// if set to a truthy value, then the action will upload SARIF,
|
||||
// not the CLI
|
||||
FEATURE_WILL_UPLOAD = "CODEQL_ACTION_FEATURE_WILL_UPLOAD",
|
||||
|
||||
// if set to a truthy value, then the action is using its
|
||||
// own deprecated and non-standard way of scanning for multiple
|
||||
// languages
|
||||
FEATURE_MULTI_LANGUAGE = "CODEQL_ACTION_FEATURE_MULTI_LANGUAGE",
|
||||
|
||||
// if set to a truthy value, then the action is using its
|
||||
// own sandwiched workflow mechanism
|
||||
FEATURE_SANDWICH = "CODEQL_ACTION_FEATURE_SANDWICH",
|
||||
}
|
||||
|
||||
export function initializeEnvironment(mode: Mode, version: string) {
|
||||
// avoid accessing actions core when in runner mode
|
||||
if (mode === Mode.actions) {
|
||||
core.exportVariable(EnvVar.RUN_MODE, mode);
|
||||
core.exportVariable(EnvVar.VERSION, version);
|
||||
core.exportVariable(EnvVar.FEATURE_SARIF_COMBINE, "true");
|
||||
core.exportVariable(EnvVar.FEATURE_WILL_UPLOAD, "true");
|
||||
core.exportVariable(EnvVar.FEATURE_MULTI_LANGUAGE, "true");
|
||||
core.exportVariable(EnvVar.FEATURE_SANDWICH, "true");
|
||||
|
||||
prepareLocalRunEnvironment();
|
||||
} else {
|
||||
process.env[EnvVar.RUN_MODE] = mode;
|
||||
process.env[EnvVar.VERSION] = version;
|
||||
process.env[EnvVar.FEATURE_SARIF_COMBINE] = "true";
|
||||
process.env[EnvVar.FEATURE_WILL_UPLOAD] = "true";
|
||||
process.env[EnvVar.FEATURE_MULTI_LANGUAGE] = "true";
|
||||
process.env[EnvVar.FEATURE_SANDWICH] = "true";
|
||||
}
|
||||
}
|
||||
|
||||
export function getMode(): Mode {
|
||||
// Make sure we fail fast if the env var is missing. This should
|
||||
// only happen if there is a bug in our code and we neglected
|
||||
// to set the mode early in the process.
|
||||
const mode = getRequiredEnvParam(EnvVar.RUN_MODE);
|
||||
|
||||
if (mode !== Mode.actions && mode !== Mode.runner) {
|
||||
throw new Error(`Unknown mode: ${mode}.`);
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
export function isActions(): boolean {
|
||||
return getMode() === Mode.actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an environment parameter, but throw an error if it is not set.
|
||||
*/
|
||||
export function getRequiredEnvParam(paramName: string): string {
|
||||
const value = process.env[paramName];
|
||||
if (value === undefined || value.length === 0) {
|
||||
throw new Error(`${paramName} environment variable must be set`);
|
||||
}
|
||||
core.debug(`${paramName}=${value}`);
|
||||
return value;
|
||||
}
|
||||
|
||||
export function getTemporaryDirectory(): string {
|
||||
const value = process.env["CODEQL_ACTION_TEMP"];
|
||||
return value !== undefined && value !== ""
|
||||
? value
|
||||
: getRequiredEnvParam("RUNNER_TEMP");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue