mirror of
https://github.com/github/codeql-action.git
synced 2026-10-03 09:14:58 +00:00
Merge branch 'main' into dependabot/npm_and_yarn/npm-minor-10933408d3
This commit is contained in:
@@ -4,7 +4,7 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
|
||||
|
||||
## [UNRELEASED]
|
||||
|
||||
No user facing changes.
|
||||
- _Upcoming breaking change_: Add a deprecation warning for customers using CodeQL version 2.20.6 and earlier. These versions of CodeQL were discontinued on 1 July 2026 alongside GitHub Enterprise Server 3.16, and will be unsupported by the next minor release of the CodeQL Action. [#3956](https://github.com/github/codeql-action/pull/3956)
|
||||
|
||||
## 4.37.0 - 08 Jul 2026
|
||||
|
||||
|
||||
167
lib/entry-points.js
generated
167
lib/entry-points.js
generated
@@ -141462,6 +141462,61 @@ var toolrunner = __toESM(require_toolrunner());
|
||||
var github = __toESM(require_github());
|
||||
var io2 = __toESM(require_io());
|
||||
|
||||
// src/environment.ts
|
||||
function getRequiredEnvVar(env, paramName) {
|
||||
const value = env[paramName];
|
||||
if (value === void 0 || value.length === 0) {
|
||||
throw new Error(`${paramName} environment variable must be set`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function getRequiredEnvParam(paramName) {
|
||||
return getRequiredEnvVar(process.env, paramName);
|
||||
}
|
||||
function getOptionalEnvVarFrom(env, paramName) {
|
||||
const value = env[paramName];
|
||||
if (value?.trim().length === 0) {
|
||||
return void 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function getOptionalEnvVar(paramName) {
|
||||
return getOptionalEnvVarFrom(process.env, paramName);
|
||||
}
|
||||
var ReadOnlyEnv = class {
|
||||
constructor(vars) {
|
||||
this.vars = vars;
|
||||
}
|
||||
vars;
|
||||
/** Tries to get the value for `name` and throws if there isn't one. */
|
||||
getRequired(name) {
|
||||
return getRequiredEnvVar(this.vars, name);
|
||||
}
|
||||
/** Gets the value for `name`, or `undefined` if it isn't set or empty. */
|
||||
getOptional(name) {
|
||||
return getOptionalEnvVarFrom(this.vars, name);
|
||||
}
|
||||
/** Gets the entries of the underlying `ProcessEnv`. */
|
||||
entries() {
|
||||
return Object.entries(this.vars);
|
||||
}
|
||||
};
|
||||
var Env = class extends ReadOnlyEnv {
|
||||
changed = false;
|
||||
/** Sets an environment variable. */
|
||||
set(name, value) {
|
||||
this.vars[name] = value;
|
||||
this.changed = true;
|
||||
}
|
||||
/** Gets a value indicating whether `set` was called at least once. */
|
||||
hasChanged() {
|
||||
return this.changed;
|
||||
}
|
||||
};
|
||||
function getEnv(env = process.env) {
|
||||
return new Env(env);
|
||||
}
|
||||
|
||||
// src/util.ts
|
||||
var fs = __toESM(require("fs"));
|
||||
var fsPromises = __toESM(require("fs/promises"));
|
||||
@@ -144432,7 +144487,7 @@ var semver = __toESM(require_semver2());
|
||||
|
||||
// src/api-compatibility.json
|
||||
var maximumVersion = "3.22";
|
||||
var minimumVersion = "3.16";
|
||||
var minimumVersion = "3.17";
|
||||
|
||||
// src/json/index.ts
|
||||
function parseString(data) {
|
||||
@@ -144775,32 +144830,6 @@ function initializeEnvironment(version) {
|
||||
core2.exportVariable("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true");
|
||||
core2.exportVariable("CODEQL_ACTION_VERSION" /* VERSION */, version);
|
||||
}
|
||||
function getEnv(env = process.env) {
|
||||
return {
|
||||
getRequired: (name) => getRequiredEnvVar(env, name),
|
||||
getOptional: (name) => getOptionalEnvVarFrom(env, name)
|
||||
};
|
||||
}
|
||||
function getRequiredEnvVar(env, paramName) {
|
||||
const value = env[paramName];
|
||||
if (value === void 0 || value.length === 0) {
|
||||
throw new Error(`${paramName} environment variable must be set`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function getRequiredEnvParam(paramName) {
|
||||
return getRequiredEnvVar(process.env, paramName);
|
||||
}
|
||||
function getOptionalEnvVarFrom(env, paramName) {
|
||||
const value = env[paramName];
|
||||
if (value?.trim().length === 0) {
|
||||
return void 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function getOptionalEnvVar(paramName) {
|
||||
return getOptionalEnvVarFrom(process.env, paramName);
|
||||
}
|
||||
var HTTPError = class extends Error {
|
||||
status;
|
||||
constructor(message, status) {
|
||||
@@ -145150,31 +145179,30 @@ var getOptionalInput = function(name) {
|
||||
const value = core3.getInput(name);
|
||||
return value.length > 0 ? value : void 0;
|
||||
};
|
||||
function getTemporaryDirectory() {
|
||||
const value = process.env["CODEQL_ACTION_TEMP"];
|
||||
return value !== void 0 && value !== "" ? value : getRequiredEnvParam("RUNNER_TEMP" /* RUNNER_TEMP */);
|
||||
function getTemporaryDirectory(env = getEnv()) {
|
||||
return env.getOptional("CODEQL_ACTION_TEMP" /* TEMP */) ?? env.getRequired("RUNNER_TEMP" /* RUNNER_TEMP */);
|
||||
}
|
||||
var PR_DIFF_RANGE_JSON_FILENAME = "pr-diff-range.json";
|
||||
function getDiffRangesJsonFilePath() {
|
||||
return path2.join(getTemporaryDirectory(), PR_DIFF_RANGE_JSON_FILENAME);
|
||||
function getDiffRangesJsonFilePath(env = getEnv()) {
|
||||
return path2.join(getTemporaryDirectory(env), PR_DIFF_RANGE_JSON_FILENAME);
|
||||
}
|
||||
function getActionVersion() {
|
||||
return "4.37.1";
|
||||
}
|
||||
function getWorkflowEventName() {
|
||||
return getRequiredEnvParam("GITHUB_EVENT_NAME" /* GITHUB_EVENT_NAME */);
|
||||
function getWorkflowEventName(env = getEnv()) {
|
||||
return env.getRequired("GITHUB_EVENT_NAME" /* GITHUB_EVENT_NAME */);
|
||||
}
|
||||
function isRunningLocalAction() {
|
||||
const relativeScriptPath = getRelativeScriptPath();
|
||||
function isRunningLocalAction(env = getEnv()) {
|
||||
const relativeScriptPath = getRelativeScriptPath(env);
|
||||
return relativeScriptPath.startsWith("..") || path2.isAbsolute(relativeScriptPath);
|
||||
}
|
||||
function getRelativeScriptPath() {
|
||||
const runnerTemp = getRequiredEnvParam("RUNNER_TEMP" /* RUNNER_TEMP */);
|
||||
function getRelativeScriptPath(env) {
|
||||
const runnerTemp = env.getRequired("RUNNER_TEMP" /* RUNNER_TEMP */);
|
||||
const actionsDirectory = path2.join(path2.dirname(runnerTemp), "_actions");
|
||||
return path2.relative(actionsDirectory, __filename);
|
||||
}
|
||||
function getWorkflowEvent() {
|
||||
const eventJsonFile = getRequiredEnvParam("GITHUB_EVENT_PATH" /* GITHUB_EVENT_PATH */);
|
||||
function getWorkflowEvent(env = getEnv()) {
|
||||
const eventJsonFile = env.getRequired("GITHUB_EVENT_PATH" /* GITHUB_EVENT_PATH */);
|
||||
try {
|
||||
return JSON.parse(fs2.readFileSync(eventJsonFile, "utf-8"));
|
||||
} catch (e) {
|
||||
@@ -145230,8 +145258,8 @@ function getUploadValue(input) {
|
||||
return "always";
|
||||
}
|
||||
}
|
||||
function getWorkflowRunID() {
|
||||
const workflowRunIdString = getRequiredEnvParam("GITHUB_RUN_ID" /* GITHUB_RUN_ID */);
|
||||
function getWorkflowRunID(env = getEnv()) {
|
||||
const workflowRunIdString = env.getRequired("GITHUB_RUN_ID" /* GITHUB_RUN_ID */);
|
||||
const workflowRunID = parseInt(workflowRunIdString, 10);
|
||||
if (Number.isNaN(workflowRunID)) {
|
||||
throw new Error(
|
||||
@@ -145245,8 +145273,8 @@ function getWorkflowRunID() {
|
||||
}
|
||||
return workflowRunID;
|
||||
}
|
||||
function getWorkflowRunAttempt() {
|
||||
const workflowRunAttemptString = getRequiredEnvParam(
|
||||
function getWorkflowRunAttempt(env = getEnv()) {
|
||||
const workflowRunAttemptString = env.getRequired(
|
||||
"GITHUB_RUN_ATTEMPT" /* GITHUB_RUN_ATTEMPT */
|
||||
);
|
||||
const workflowRunAttempt = parseInt(workflowRunAttemptString, 10);
|
||||
@@ -145299,14 +145327,14 @@ var getFileType = async (filePath) => {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
function isSelfHostedRunner() {
|
||||
return process.env.RUNNER_ENVIRONMENT === "self-hosted";
|
||||
function isSelfHostedRunner(env = getEnv()) {
|
||||
return env.getOptional("RUNNER_ENVIRONMENT" /* RUNNER_ENVIRONMENT */) === "self-hosted";
|
||||
}
|
||||
function isDynamicWorkflow() {
|
||||
return getWorkflowEventName() === "dynamic";
|
||||
function isDynamicWorkflow(env = getEnv()) {
|
||||
return getWorkflowEventName(env) === "dynamic";
|
||||
}
|
||||
function isDefaultSetup() {
|
||||
return isDynamicWorkflow();
|
||||
function isDefaultSetup(env = getEnv()) {
|
||||
return isDynamicWorkflow(env);
|
||||
}
|
||||
function prettyPrintInvocation(cmd, args) {
|
||||
return [cmd, ...args].map((x) => x.includes(" ") ? `'${x}'` : x).join(" ");
|
||||
@@ -145370,8 +145398,9 @@ async function runTool(cmd, args = [], opts = {}) {
|
||||
return stdout;
|
||||
}
|
||||
var persistedInputsKey = "persisted_inputs";
|
||||
var persistInputs = function() {
|
||||
const inputEnvironmentVariables = Object.entries(process.env).filter(
|
||||
var persistInputs = function(env = getEnv()) {
|
||||
const entries = env.entries();
|
||||
const inputEnvironmentVariables = entries.filter(
|
||||
([name]) => name.startsWith("INPUT_")
|
||||
);
|
||||
core3.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables));
|
||||
@@ -145384,7 +145413,7 @@ var restoreInputs = function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
function getPullRequestBranches() {
|
||||
function getPullRequestBranches(env = getEnv()) {
|
||||
const pullRequest = github.context.payload.pull_request;
|
||||
if (pullRequest) {
|
||||
return {
|
||||
@@ -145395,8 +145424,10 @@ function getPullRequestBranches() {
|
||||
head: pullRequest.head.label
|
||||
};
|
||||
}
|
||||
const codeScanningRef = process.env.CODE_SCANNING_REF;
|
||||
const codeScanningBaseBranch = process.env.CODE_SCANNING_BASE_BRANCH;
|
||||
const codeScanningRef = env.getOptional("CODE_SCANNING_REF" /* CODE_SCANNING_REF */);
|
||||
const codeScanningBaseBranch = env.getOptional(
|
||||
"CODE_SCANNING_BASE_BRANCH" /* CODE_SCANNING_BASE_BRANCH */
|
||||
);
|
||||
if (codeScanningRef && codeScanningBaseBranch) {
|
||||
return {
|
||||
base: codeScanningBaseBranch,
|
||||
@@ -145407,8 +145438,8 @@ function getPullRequestBranches() {
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
function isAnalyzingPullRequest() {
|
||||
return getPullRequestBranches() !== void 0;
|
||||
function isAnalyzingPullRequest(env = getEnv()) {
|
||||
return getPullRequestBranches(env) !== void 0;
|
||||
}
|
||||
var qualityCategoryMapping = {
|
||||
"c#": "csharp",
|
||||
@@ -145420,8 +145451,8 @@ var qualityCategoryMapping = {
|
||||
typescript: "javascript-typescript",
|
||||
kotlin: "java-kotlin"
|
||||
};
|
||||
function fixCodeQualityCategory(logger, category) {
|
||||
if (category !== void 0 && isDefaultSetup() && category.startsWith("/language:")) {
|
||||
function fixCodeQualityCategory(logger, category, env = getEnv()) {
|
||||
if (category !== void 0 && isDefaultSetup(env) && category.startsWith("/language:")) {
|
||||
const language = category.substring("/language:".length);
|
||||
const mappedLanguage = qualityCategoryMapping[language];
|
||||
if (mappedLanguage) {
|
||||
@@ -145605,15 +145636,15 @@ function createApiClientWithDetails(apiDetails, { allowExternal = false } = {})
|
||||
})
|
||||
);
|
||||
}
|
||||
function getApiDetails() {
|
||||
function getApiDetails(env = getEnv()) {
|
||||
return {
|
||||
auth: getRequiredInput("token"),
|
||||
url: getRequiredEnvParam("GITHUB_SERVER_URL" /* GITHUB_SERVER_URL */),
|
||||
apiURL: getRequiredEnvParam("GITHUB_API_URL" /* GITHUB_API_URL */)
|
||||
url: env.getRequired("GITHUB_SERVER_URL" /* GITHUB_SERVER_URL */),
|
||||
apiURL: env.getRequired("GITHUB_API_URL" /* GITHUB_API_URL */)
|
||||
};
|
||||
}
|
||||
function getApiClient() {
|
||||
return createApiClientWithDetails(getApiDetails());
|
||||
function getApiClient(env = getEnv()) {
|
||||
return createApiClientWithDetails(getApiDetails(env));
|
||||
}
|
||||
function getApiClientWithExternalAuth(apiDetails) {
|
||||
return createApiClientWithDetails(apiDetails, { allowExternal: true });
|
||||
@@ -151013,9 +151044,9 @@ async function getCombinedTracerConfig(codeql, config) {
|
||||
// src/codeql.ts
|
||||
var cachedCodeQL = void 0;
|
||||
var CODEQL_MINIMUM_VERSION = "2.19.4";
|
||||
var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4";
|
||||
var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15";
|
||||
var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09";
|
||||
var CODEQL_NEXT_MINIMUM_VERSION = "2.20.7";
|
||||
var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.16";
|
||||
var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-07-01";
|
||||
var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
|
||||
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger, checkVersion) {
|
||||
try {
|
||||
@@ -151648,7 +151679,7 @@ async function setupCppAutobuild(codeql, logger) {
|
||||
logger
|
||||
);
|
||||
if (await features.getValue("cpp_dependency_installation_enabled" /* CppDependencyInstallation */, codeql)) {
|
||||
if (process.env["RUNNER_ENVIRONMENT"] === "self-hosted" && process.env[envVar] !== "true") {
|
||||
if (process.env["RUNNER_ENVIRONMENT" /* RUNNER_ENVIRONMENT */] === "self-hosted" && process.env[envVar] !== "true") {
|
||||
logger.info(
|
||||
`Disabling ${featureName} as we are on a self-hosted runner.${getWorkflowEventName() !== "dynamic" ? ` To override this, set the ${envVar} environment variable to 'true' in your workflow. See ${"https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow" /* DEFINE_ENV_VARIABLES */} for more information.` : ""}`
|
||||
);
|
||||
|
||||
@@ -7,12 +7,13 @@ import * as github from "@actions/github";
|
||||
import * as io from "@actions/io";
|
||||
|
||||
import type { Config } from "./config-utils";
|
||||
import { Env, EnvVar, ActionsEnvVars } from "./environment";
|
||||
import { Logger } from "./logging";
|
||||
import {
|
||||
doesDirectoryExist,
|
||||
getCodeQLDatabasePath,
|
||||
getRequiredEnvParam,
|
||||
ConfigurationError,
|
||||
getEnv,
|
||||
} from "./util";
|
||||
|
||||
/**
|
||||
@@ -21,28 +22,6 @@ import {
|
||||
*/
|
||||
declare const __CODEQL_ACTION_VERSION__: string;
|
||||
|
||||
/**
|
||||
* Enumerates known GitHub Actions environment variables that we expect
|
||||
* to be set in a GitHub Actions environment.
|
||||
*/
|
||||
export enum ActionsEnvVars {
|
||||
GITHUB_ACTION_REPOSITORY = "GITHUB_ACTION_REPOSITORY",
|
||||
GITHUB_API_URL = "GITHUB_API_URL",
|
||||
GITHUB_EVENT_NAME = "GITHUB_EVENT_NAME",
|
||||
GITHUB_EVENT_PATH = "GITHUB_EVENT_PATH",
|
||||
GITHUB_JOB = "GITHUB_JOB",
|
||||
GITHUB_REF = "GITHUB_REF",
|
||||
GITHUB_REPOSITORY = "GITHUB_REPOSITORY",
|
||||
GITHUB_RUN_ATTEMPT = "GITHUB_RUN_ATTEMPT",
|
||||
GITHUB_RUN_ID = "GITHUB_RUN_ID",
|
||||
GITHUB_SERVER_URL = "GITHUB_SERVER_URL",
|
||||
GITHUB_SHA = "GITHUB_SHA",
|
||||
GITHUB_WORKFLOW = "GITHUB_WORKFLOW",
|
||||
RUNNER_NAME = "RUNNER_NAME",
|
||||
RUNNER_OS = "RUNNER_OS",
|
||||
RUNNER_TEMP = "RUNNER_TEMP",
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstracts over GitHub Actions functions so that we do not have to stub
|
||||
* global functions in tests.
|
||||
@@ -83,17 +62,21 @@ export const getOptionalInput = function (name: string): string | undefined {
|
||||
return value.length > 0 ? value : undefined;
|
||||
};
|
||||
|
||||
export function getTemporaryDirectory(): string {
|
||||
const value = process.env["CODEQL_ACTION_TEMP"];
|
||||
return value !== undefined && value !== ""
|
||||
? value
|
||||
: getRequiredEnvParam(ActionsEnvVars.RUNNER_TEMP);
|
||||
/**
|
||||
* Gets the temporary directory used by the CodeQL Action. This will either be the temporary
|
||||
* directory that has been set in `CODEQL_ACTION_TEMP` by e.g. a previous step, or the
|
||||
* value of `RUNNER_TEMP` otherwise.
|
||||
*/
|
||||
export function getTemporaryDirectory(env: Env = getEnv()): string {
|
||||
return (
|
||||
env.getOptional(EnvVar.TEMP) ?? env.getRequired(ActionsEnvVars.RUNNER_TEMP)
|
||||
);
|
||||
}
|
||||
|
||||
const PR_DIFF_RANGE_JSON_FILENAME = "pr-diff-range.json";
|
||||
|
||||
export function getDiffRangesJsonFilePath(): string {
|
||||
return path.join(getTemporaryDirectory(), PR_DIFF_RANGE_JSON_FILENAME);
|
||||
export function getDiffRangesJsonFilePath(env: Env = getEnv()): string {
|
||||
return path.join(getTemporaryDirectory(env), PR_DIFF_RANGE_JSON_FILENAME);
|
||||
}
|
||||
|
||||
export function getActionVersion(): string {
|
||||
@@ -105,16 +88,16 @@ export function getActionVersion(): string {
|
||||
*
|
||||
* This will be "dynamic" for default setup workflow runs.
|
||||
*/
|
||||
export function getWorkflowEventName() {
|
||||
return getRequiredEnvParam(ActionsEnvVars.GITHUB_EVENT_NAME);
|
||||
export function getWorkflowEventName(env: Env = getEnv()) {
|
||||
return env.getRequired(ActionsEnvVars.GITHUB_EVENT_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current workflow is executing a local copy of the Action, e.g. we're running
|
||||
* a workflow on the codeql-action repo itself.
|
||||
*/
|
||||
export function isRunningLocalAction(): boolean {
|
||||
const relativeScriptPath = getRelativeScriptPath();
|
||||
export function isRunningLocalAction(env: Env = getEnv()): boolean {
|
||||
const relativeScriptPath = getRelativeScriptPath(env);
|
||||
return (
|
||||
relativeScriptPath.startsWith("..") || path.isAbsolute(relativeScriptPath)
|
||||
);
|
||||
@@ -125,15 +108,15 @@ export function isRunningLocalAction(): boolean {
|
||||
*
|
||||
* This can be used to get the Action's name or tell if we're running a local Action.
|
||||
*/
|
||||
function getRelativeScriptPath(): string {
|
||||
const runnerTemp = getRequiredEnvParam(ActionsEnvVars.RUNNER_TEMP);
|
||||
function getRelativeScriptPath(env: Env): string {
|
||||
const runnerTemp = env.getRequired(ActionsEnvVars.RUNNER_TEMP);
|
||||
const actionsDirectory = path.join(path.dirname(runnerTemp), "_actions");
|
||||
return path.relative(actionsDirectory, __filename);
|
||||
}
|
||||
|
||||
/** Returns the contents of `GITHUB_EVENT_PATH` as a JSON object. */
|
||||
export function getWorkflowEvent(): any {
|
||||
const eventJsonFile = getRequiredEnvParam(ActionsEnvVars.GITHUB_EVENT_PATH);
|
||||
export function getWorkflowEvent(env: Env = getEnv()): any {
|
||||
const eventJsonFile = env.getRequired(ActionsEnvVars.GITHUB_EVENT_PATH);
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(eventJsonFile, "utf-8"));
|
||||
} catch (e) {
|
||||
@@ -202,8 +185,8 @@ export function getUploadValue(input: string | undefined): UploadKind {
|
||||
/**
|
||||
* Get the workflow run ID.
|
||||
*/
|
||||
export function getWorkflowRunID(): number {
|
||||
const workflowRunIdString = getRequiredEnvParam(ActionsEnvVars.GITHUB_RUN_ID);
|
||||
export function getWorkflowRunID(env: Env = getEnv()): number {
|
||||
const workflowRunIdString = env.getRequired(ActionsEnvVars.GITHUB_RUN_ID);
|
||||
const workflowRunID = parseInt(workflowRunIdString, 10);
|
||||
if (Number.isNaN(workflowRunID)) {
|
||||
throw new Error(
|
||||
@@ -221,8 +204,8 @@ export function getWorkflowRunID(): number {
|
||||
/**
|
||||
* Get the workflow run attempt number.
|
||||
*/
|
||||
export function getWorkflowRunAttempt(): number {
|
||||
const workflowRunAttemptString = getRequiredEnvParam(
|
||||
export function getWorkflowRunAttempt(env: Env = getEnv()): number {
|
||||
const workflowRunAttemptString = env.getRequired(
|
||||
ActionsEnvVars.GITHUB_RUN_ATTEMPT,
|
||||
);
|
||||
const workflowRunAttempt = parseInt(workflowRunAttemptString, 10);
|
||||
@@ -290,18 +273,18 @@ export const getFileType = async (filePath: string): Promise<string> => {
|
||||
}
|
||||
};
|
||||
|
||||
export function isSelfHostedRunner() {
|
||||
return process.env.RUNNER_ENVIRONMENT === "self-hosted";
|
||||
export function isSelfHostedRunner(env: Env = getEnv()) {
|
||||
return env.getOptional(ActionsEnvVars.RUNNER_ENVIRONMENT) === "self-hosted";
|
||||
}
|
||||
|
||||
/** Determines whether the workflow trigger is `dynamic`. */
|
||||
export function isDynamicWorkflow(): boolean {
|
||||
return getWorkflowEventName() === "dynamic";
|
||||
export function isDynamicWorkflow(env: Env = getEnv()): boolean {
|
||||
return getWorkflowEventName(env) === "dynamic";
|
||||
}
|
||||
|
||||
/** Determines whether we are running in default setup. */
|
||||
export function isDefaultSetup(): boolean {
|
||||
return isDynamicWorkflow();
|
||||
export function isDefaultSetup(env: Env = getEnv()): boolean {
|
||||
return isDynamicWorkflow(env);
|
||||
}
|
||||
|
||||
export function prettyPrintInvocation(cmd: string, args: string[]): string {
|
||||
@@ -399,9 +382,10 @@ const persistedInputsKey = "persisted_inputs";
|
||||
* This would be simplified if actions/runner#3514 is addressed.
|
||||
* https://github.com/actions/runner/issues/3514
|
||||
*/
|
||||
export const persistInputs = function () {
|
||||
const inputEnvironmentVariables = Object.entries(process.env).filter(
|
||||
([name]) => name.startsWith("INPUT_"),
|
||||
export const persistInputs = function (env: Env = getEnv()) {
|
||||
const entries = env.entries();
|
||||
const inputEnvironmentVariables = entries.filter(([name]) =>
|
||||
name.startsWith("INPUT_"),
|
||||
);
|
||||
core.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables));
|
||||
};
|
||||
@@ -429,7 +413,9 @@ export interface PullRequestBranches {
|
||||
* @returns the base and head branches of the pull request, or undefined if
|
||||
* we are not analyzing a pull request.
|
||||
*/
|
||||
export function getPullRequestBranches(): PullRequestBranches | undefined {
|
||||
export function getPullRequestBranches(
|
||||
env: Env = getEnv(),
|
||||
): PullRequestBranches | undefined {
|
||||
const pullRequest = github.context.payload.pull_request;
|
||||
if (pullRequest) {
|
||||
return {
|
||||
@@ -443,8 +429,10 @@ export function getPullRequestBranches(): PullRequestBranches | undefined {
|
||||
|
||||
// PR analysis under Default Setup does not have the pull_request context,
|
||||
// but it should set CODE_SCANNING_REF and CODE_SCANNING_BASE_BRANCH.
|
||||
const codeScanningRef = process.env.CODE_SCANNING_REF;
|
||||
const codeScanningBaseBranch = process.env.CODE_SCANNING_BASE_BRANCH;
|
||||
const codeScanningRef = env.getOptional(EnvVar.CODE_SCANNING_REF);
|
||||
const codeScanningBaseBranch = env.getOptional(
|
||||
EnvVar.CODE_SCANNING_BASE_BRANCH,
|
||||
);
|
||||
if (codeScanningRef && codeScanningBaseBranch) {
|
||||
return {
|
||||
base: codeScanningBaseBranch,
|
||||
@@ -459,8 +447,8 @@ export function getPullRequestBranches(): PullRequestBranches | undefined {
|
||||
/**
|
||||
* Returns whether we are analyzing a pull request.
|
||||
*/
|
||||
export function isAnalyzingPullRequest(): boolean {
|
||||
return getPullRequestBranches() !== undefined;
|
||||
export function isAnalyzingPullRequest(env: Env = getEnv()): boolean {
|
||||
return getPullRequestBranches(env) !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -484,13 +472,14 @@ const qualityCategoryMapping: Record<string, string> = {
|
||||
export function fixCodeQualityCategory(
|
||||
logger: Logger,
|
||||
category?: string,
|
||||
env: Env = getEnv(),
|
||||
): string | undefined {
|
||||
// The `category` should always be set by Default Setup. We perform this check
|
||||
// to avoid potential issues if Code Quality supports Advanced Setup in the future
|
||||
// and before this workaround is removed.
|
||||
if (
|
||||
category !== undefined &&
|
||||
isDefaultSetup() &&
|
||||
isDefaultSetup(env) &&
|
||||
category.startsWith("/language:")
|
||||
) {
|
||||
const language = category.substring("/language:".length);
|
||||
|
||||
@@ -6,7 +6,8 @@ import * as sinon from "sinon";
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import * as api from "./api-client";
|
||||
import { DO_NOT_RETRY_STATUSES } from "./api-client";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import { ActionsEnvVars } from "./environment";
|
||||
import { getTestEnv, setupTests } from "./testing-utils";
|
||||
import * as util from "./util";
|
||||
|
||||
setupTests(test);
|
||||
@@ -20,16 +21,13 @@ test.serial("getApiClient", async (t) => {
|
||||
const githubStub: sinon.SinonStub = sinon.stub();
|
||||
pluginStub.returns(githubStub);
|
||||
|
||||
sinon.stub(actionsUtil, "getRequiredInput").withArgs("token").returns("xyz");
|
||||
const requiredEnvParamStub = sinon.stub(util, "getRequiredEnvParam");
|
||||
requiredEnvParamStub
|
||||
.withArgs("GITHUB_SERVER_URL")
|
||||
.returns("http://github.localhost");
|
||||
requiredEnvParamStub
|
||||
.withArgs("GITHUB_API_URL")
|
||||
.returns("http://api.github.localhost");
|
||||
const env = getTestEnv();
|
||||
env.set(ActionsEnvVars.GITHUB_SERVER_URL, "http://github.localhost");
|
||||
env.set(ActionsEnvVars.GITHUB_API_URL, "http://api.github.localhost");
|
||||
|
||||
api.getApiClient();
|
||||
sinon.stub(actionsUtil, "getRequiredInput").withArgs("token").returns("xyz");
|
||||
|
||||
api.getApiClient(env);
|
||||
|
||||
t.assert(
|
||||
githubStub.calledOnceWithExactly({
|
||||
|
||||
@@ -2,12 +2,8 @@ import * as core from "@actions/core";
|
||||
import * as githubUtils from "@actions/github/lib/utils";
|
||||
import * as retry from "@octokit/plugin-retry";
|
||||
|
||||
import {
|
||||
ActionsEnvVars,
|
||||
getActionVersion,
|
||||
getRequiredInput,
|
||||
} from "./actions-util";
|
||||
import { EnvVar } from "./environment";
|
||||
import { getActionVersion, getRequiredInput } from "./actions-util";
|
||||
import { EnvVar, ReadOnlyEnv, ActionsEnvVars, getEnv } from "./environment";
|
||||
import { Logger } from "./logging";
|
||||
import { getRepositoryNwo, RepositoryNwo } from "./repository";
|
||||
import {
|
||||
@@ -71,16 +67,16 @@ function createApiClientWithDetails(
|
||||
);
|
||||
}
|
||||
|
||||
export function getApiDetails(): GitHubApiDetails {
|
||||
export function getApiDetails(env: ReadOnlyEnv = getEnv()): GitHubApiDetails {
|
||||
return {
|
||||
auth: getRequiredInput("token"),
|
||||
url: getRequiredEnvParam(ActionsEnvVars.GITHUB_SERVER_URL),
|
||||
apiURL: getRequiredEnvParam(ActionsEnvVars.GITHUB_API_URL),
|
||||
url: env.getRequired(ActionsEnvVars.GITHUB_SERVER_URL),
|
||||
apiURL: env.getRequired(ActionsEnvVars.GITHUB_API_URL),
|
||||
};
|
||||
}
|
||||
|
||||
export function getApiClient() {
|
||||
return createApiClientWithDetails(getApiDetails());
|
||||
export function getApiClient(env: ReadOnlyEnv = getEnv()) {
|
||||
return createApiClientWithDetails(getApiDetails(env));
|
||||
}
|
||||
|
||||
export function getApiClientWithExternalAuth(
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"maximumVersion": "3.22", "minimumVersion": "3.16"}
|
||||
{"maximumVersion": "3.22", "minimumVersion": "3.17"}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { getGitHubVersion } from "./api-client";
|
||||
import { CodeQL, getCodeQL } from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { DocUrl } from "./doc-url";
|
||||
import { EnvVar } from "./environment";
|
||||
import { ActionsEnvVars, EnvVar } from "./environment";
|
||||
import { Feature, featureConfig, initFeatures } from "./feature-flags";
|
||||
import { BuiltInLanguage, Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
@@ -126,7 +126,7 @@ export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) {
|
||||
if (await features.getValue(Feature.CppDependencyInstallation, codeql)) {
|
||||
// disable autoinstall on self-hosted runners unless explicitly requested
|
||||
if (
|
||||
process.env["RUNNER_ENVIRONMENT"] === "self-hosted" &&
|
||||
process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] === "self-hosted" &&
|
||||
process.env[envVar] !== "true"
|
||||
) {
|
||||
logger.info(
|
||||
|
||||
@@ -272,17 +272,17 @@ const CODEQL_MINIMUM_VERSION = "2.19.4";
|
||||
/**
|
||||
* This version will shortly become the oldest version of CodeQL that the Action will run with.
|
||||
*/
|
||||
const CODEQL_NEXT_MINIMUM_VERSION = "2.19.4";
|
||||
const CODEQL_NEXT_MINIMUM_VERSION = "2.20.7";
|
||||
|
||||
/**
|
||||
* This is the version of GHES that was most recently deprecated.
|
||||
*/
|
||||
const GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15";
|
||||
const GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.16";
|
||||
|
||||
/**
|
||||
* This is the deprecation date for the version of GHES that was most recently deprecated.
|
||||
*/
|
||||
const GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09";
|
||||
const GHES_MOST_RECENT_DEPRECATION_DATE = "2026-07-01";
|
||||
|
||||
/** The CLI verbosity level to use for extraction in debug mode. */
|
||||
const EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import test from "ava";
|
||||
import sinon from "sinon";
|
||||
|
||||
import { ActionsEnvVars } from "../actions-util";
|
||||
import { ActionsEnvVars } from "../environment";
|
||||
import * as errors from "../error-messages";
|
||||
import { Feature } from "../feature-flags";
|
||||
import { callee, getTestEnv } from "../testing-utils";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ActionState } from "../action-common";
|
||||
import { ActionsEnvVars } from "../actions-util";
|
||||
import { Env } from "../environment";
|
||||
import { Env, ActionsEnvVars } from "../environment";
|
||||
import * as errorMessages from "../error-messages";
|
||||
import { Feature } from "../feature-flags";
|
||||
import { ConfigurationError, Failure, Result, Success } from "../util";
|
||||
|
||||
@@ -17,6 +17,18 @@ export enum EnvVar {
|
||||
*/
|
||||
CLI_VERBOSITY = "CODEQL_VERBOSITY",
|
||||
|
||||
/**
|
||||
* Set by Default Setup to the base branch of the PR being analysed, if analysing a PR.
|
||||
* This is needed because the `pull_request` context is not available for `dynamic` events.
|
||||
*/
|
||||
CODE_SCANNING_BASE_BRANCH = "CODE_SCANNING_BASE_BRANCH",
|
||||
|
||||
/**
|
||||
* Set by Default Setup to the full ref being analysed, if analysing a PR.
|
||||
* This is needed because the `pull_request` context is not available for `dynamic` events.
|
||||
*/
|
||||
CODE_SCANNING_REF = "CODE_SCANNING_REF",
|
||||
|
||||
/**
|
||||
* `PersistedVersionInfo` for the CodeQL CLI, so later Actions steps can reuse it instead of
|
||||
* invoking `codeql version` again.
|
||||
@@ -83,6 +95,9 @@ export enum EnvVar {
|
||||
/** Whether to suppress the warning if the current CLI will soon be unsupported. */
|
||||
SUPPRESS_DEPRECATED_SOON_WARNING = "CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING",
|
||||
|
||||
/** Used to dictate or persist the temporary directory used by the CodeQL Action. */
|
||||
TEMP = "CODEQL_ACTION_TEMP",
|
||||
|
||||
/** Whether to disable uploading SARIF results or status reports to the GitHub API */
|
||||
TEST_MODE = "CODEQL_ACTION_TEST_MODE",
|
||||
|
||||
@@ -161,10 +176,122 @@ export enum EnvVar {
|
||||
RISK_ASSESSMENT_ID = "CODEQL_ACTION_RISK_ASSESSMENT_ID",
|
||||
}
|
||||
|
||||
/** A wrapper around an environment, to allow abstracting away from `process.env` in tests. */
|
||||
export interface Env {
|
||||
/** Tries to get the value for `name` and throws if there isn't one. */
|
||||
getRequired(name: string): string;
|
||||
/** Gets the value for `name`, or `undefined` if it isn't set or empty. */
|
||||
getOptional(name: string): string | undefined;
|
||||
/**
|
||||
* Enumerates known GitHub Actions environment variables that we expect
|
||||
* to be set in a GitHub Actions environment.
|
||||
*/
|
||||
export enum ActionsEnvVars {
|
||||
GITHUB_ACTION_REPOSITORY = "GITHUB_ACTION_REPOSITORY",
|
||||
GITHUB_API_URL = "GITHUB_API_URL",
|
||||
GITHUB_EVENT_NAME = "GITHUB_EVENT_NAME",
|
||||
GITHUB_EVENT_PATH = "GITHUB_EVENT_PATH",
|
||||
GITHUB_JOB = "GITHUB_JOB",
|
||||
GITHUB_REF = "GITHUB_REF",
|
||||
GITHUB_REPOSITORY = "GITHUB_REPOSITORY",
|
||||
GITHUB_RUN_ATTEMPT = "GITHUB_RUN_ATTEMPT",
|
||||
GITHUB_RUN_ID = "GITHUB_RUN_ID",
|
||||
GITHUB_SERVER_URL = "GITHUB_SERVER_URL",
|
||||
GITHUB_SHA = "GITHUB_SHA",
|
||||
GITHUB_WORKFLOW = "GITHUB_WORKFLOW",
|
||||
RUNNER_ENVIRONMENT = "RUNNER_ENVIRONMENT",
|
||||
RUNNER_NAME = "RUNNER_NAME",
|
||||
RUNNER_OS = "RUNNER_OS",
|
||||
RUNNER_TEMP = "RUNNER_TEMP",
|
||||
}
|
||||
|
||||
/** A type representing all known environment variables. */
|
||||
export type KnownEnvVar = EnvVar | ActionsEnvVars;
|
||||
|
||||
/**
|
||||
* Gets an environment variable, but throws an error if it is not set.
|
||||
*/
|
||||
function getRequiredEnvVar(env: NodeJS.ProcessEnv, paramName: string): string {
|
||||
const value = env[paramName];
|
||||
if (value === undefined || value.length === 0) {
|
||||
throw new Error(`${paramName} environment variable must be set`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an environment parameter, but throw an error if it is not set.
|
||||
*
|
||||
* @deprecated Use `getRequired` of a `ReadOnlyEnv` or `Env` instance instead.
|
||||
*/
|
||||
export function getRequiredEnvParam(paramName: string): string {
|
||||
return getRequiredEnvVar(process.env, paramName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an environment variable, but returns `undefined` if it is not set or empty.
|
||||
*/
|
||||
function getOptionalEnvVarFrom(
|
||||
env: NodeJS.ProcessEnv,
|
||||
paramName: string,
|
||||
): string | undefined {
|
||||
const value = env[paramName];
|
||||
if (value?.trim().length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an environment variable, but return `undefined` if it is not set or empty.
|
||||
*
|
||||
* @deprecated Use `getOptional` of a `ReadOnlyEnv` or `Env` instance instead.
|
||||
*/
|
||||
export function getOptionalEnvVar(paramName: string): string | undefined {
|
||||
return getOptionalEnvVarFrom(process.env, paramName);
|
||||
}
|
||||
|
||||
/**
|
||||
* An abstraction around read-only environment variables, to allow abstracting away from `process.env`
|
||||
* in tests, while clearly signalling in regular code that the consumer of the `ReadOnlyEnv` instance
|
||||
* will only read from it.
|
||||
*/
|
||||
export class ReadOnlyEnv<T extends string | undefined = string | undefined> {
|
||||
constructor(protected readonly vars: Record<string, T>) {}
|
||||
|
||||
/** Tries to get the value for `name` and throws if there isn't one. */
|
||||
public getRequired(name: string): string {
|
||||
return getRequiredEnvVar(this.vars, name);
|
||||
}
|
||||
|
||||
/** Gets the value for `name`, or `undefined` if it isn't set or empty. */
|
||||
public getOptional(name: string): string | undefined {
|
||||
return getOptionalEnvVarFrom(this.vars, name);
|
||||
}
|
||||
|
||||
/** Gets the entries of the underlying `ProcessEnv`. */
|
||||
public entries(): Array<[string, T]> {
|
||||
return Object.entries(this.vars);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper around an environment, to allow abstracting away from `process.env` in tests.
|
||||
* Use `ReadOnlyEnv` instead if you only plan to read from the environment.
|
||||
* This type allows writing to the environment.
|
||||
*/
|
||||
export class Env<
|
||||
T extends string | undefined = string | undefined,
|
||||
> extends ReadOnlyEnv<T> {
|
||||
private changed: boolean = false;
|
||||
|
||||
/** Sets an environment variable. */
|
||||
public set(name: string, value: T): void {
|
||||
this.vars[name] = value;
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
/** Gets a value indicating whether `set` was called at least once. */
|
||||
public hasChanged(): boolean {
|
||||
return this.changed;
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets an `Env` instance for `env`, which is `process.env` by default. */
|
||||
export function getEnv(env: NodeJS.ProcessEnv = process.env): Env {
|
||||
return new Env(env);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { createStubCodeQL } from "./codeql";
|
||||
import { ActionsEnvVars } from "./environment";
|
||||
import { Feature } from "./feature-flags";
|
||||
import {
|
||||
checkPacksForOverlayCompatibility,
|
||||
@@ -84,7 +85,7 @@ for (const { runnerEnv, ErrorConstructor, message } of [
|
||||
`cleanupDatabaseClusterDirectory throws a ${ErrorConstructor.name} when cleanup fails on ${runnerEnv} runner`,
|
||||
async (t) => {
|
||||
await withTmpDir(async (tmpDir: string) => {
|
||||
process.env["RUNNER_ENVIRONMENT"] = runnerEnv;
|
||||
process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnv;
|
||||
|
||||
const dbLocation = path.resolve(tmpDir, "dbs");
|
||||
fs.mkdirSync(dbLocation, { recursive: true });
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import * as api from "./api-client";
|
||||
import { EnvVar } from "./environment";
|
||||
import { Feature } from "./feature-flags";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { getCacheRestoreKeyPrefix } from "./overlay/caching";
|
||||
@@ -637,8 +638,8 @@ test.serial(
|
||||
async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
process.env["CODE_SCANNING_REF"] = "refs/heads/feature-branch";
|
||||
process.env["CODE_SCANNING_BASE_BRANCH"] = "main";
|
||||
process.env[EnvVar.CODE_SCANNING_REF] = "refs/heads/feature-branch";
|
||||
process.env[EnvVar.CODE_SCANNING_BASE_BRANCH] = "main";
|
||||
|
||||
sinon.stub(api, "getAutomationID").resolves("test/");
|
||||
const listStub = sinon.stub(api, "listActionsCaches").resolves([
|
||||
|
||||
@@ -11,7 +11,7 @@ import nock from "nock";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import { ActionState, StateFeature } from "./action-common";
|
||||
import { ActionsEnv, ActionsEnvVars, getActionVersion } from "./actions-util";
|
||||
import { ActionsEnv, getActionVersion } from "./actions-util";
|
||||
import { AnalysisKind } from "./analyses";
|
||||
import * as apiClient from "./api-client";
|
||||
import { GitHubApiDetails } from "./api-client";
|
||||
@@ -19,7 +19,7 @@ import { CachingKind } from "./caching-utils";
|
||||
import * as codeql from "./codeql";
|
||||
import { Config } from "./config-utils";
|
||||
import * as defaults from "./defaults.json";
|
||||
import { Env } from "./environment";
|
||||
import { Env, ActionsEnvVars } from "./environment";
|
||||
import {
|
||||
CodeQLDefaultVersionInfo,
|
||||
Feature,
|
||||
@@ -331,11 +331,15 @@ export type ActionVarOverrides = Partial<
|
||||
* excluding some that are expected to be set to paths. See `setupActionsVars`.
|
||||
*
|
||||
* @param overrides Overrides for the defaults.
|
||||
* @param env The environment to set the variables for.
|
||||
*/
|
||||
export function setupBaseActionsVars(overrides?: ActionVarOverrides) {
|
||||
export function setupBaseActionsVars(
|
||||
overrides?: ActionVarOverrides,
|
||||
env: Env = getEnv(),
|
||||
) {
|
||||
const vars = { ...DEFAULT_ACTIONS_VARS, ...overrides };
|
||||
for (const [key, value] of Object.entries(vars)) {
|
||||
process.env[key] = value;
|
||||
env.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
55
src/util.ts
55
src/util.ts
@@ -13,11 +13,14 @@ import * as apiCompatibility from "./api-compatibility.json";
|
||||
import type { CodeQL, VersionInfo } from "./codeql";
|
||||
import type { Pack } from "./config/db-config";
|
||||
import type { Config } from "./config-utils";
|
||||
import { Env, EnvVar } from "./environment";
|
||||
import { EnvVar, getRequiredEnvParam } from "./environment";
|
||||
import * as json from "./json";
|
||||
import { Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
|
||||
// Re-export for backwards compatibility to avoid updating a lot of imports elsewhere.
|
||||
export { getRequiredEnvParam, getOptionalEnvVar, getEnv } from "./environment";
|
||||
|
||||
/**
|
||||
* The name of the file containing the base database OIDs, as stored in the
|
||||
* root of the database location.
|
||||
@@ -566,56 +569,6 @@ export function initializeEnvironment(version: string) {
|
||||
core.exportVariable(EnvVar.VERSION, version);
|
||||
}
|
||||
|
||||
/** Gets an `Env` instance for `env`, which is `process.env` by default. */
|
||||
export function getEnv(env: NodeJS.ProcessEnv = process.env): Env {
|
||||
return {
|
||||
getRequired: (name) => getRequiredEnvVar(env, name),
|
||||
getOptional: (name) => getOptionalEnvVarFrom(env, name),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an environment variable, but throws an error if it is not set.
|
||||
*/
|
||||
export function getRequiredEnvVar(
|
||||
env: NodeJS.ProcessEnv,
|
||||
paramName: string,
|
||||
): string {
|
||||
const value = env[paramName];
|
||||
if (value === undefined || value.length === 0) {
|
||||
throw new Error(`${paramName} environment variable must be set`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an environment parameter, but throw an error if it is not set.
|
||||
*/
|
||||
export function getRequiredEnvParam(paramName: string): string {
|
||||
return getRequiredEnvVar(process.env, paramName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an environment variable, but returns `undefined` if it is not set or empty.
|
||||
*/
|
||||
export function getOptionalEnvVarFrom(
|
||||
env: NodeJS.ProcessEnv,
|
||||
paramName: string,
|
||||
): string | undefined {
|
||||
const value = env[paramName];
|
||||
if (value?.trim().length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an environment variable, but return `undefined` if it is not set or empty.
|
||||
*/
|
||||
export function getOptionalEnvVar(paramName: string): string | undefined {
|
||||
return getOptionalEnvVarFrom(process.env, paramName);
|
||||
}
|
||||
|
||||
export class HTTPError extends Error {
|
||||
public status: number;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user