Merge remote-tracking branch 'origin/main' into mbg/start-proxy/deprecate-fallback

This commit is contained in:
Michael B. Gale
2026-10-14 13:56:57 +01:00
17 changed files with 625 additions and 303 deletions

283
lib/entry-points.js generated
View File

@@ -21656,8 +21656,8 @@ var require_core = __commonJS({
exports2.warning = warning14;
exports2.notice = notice;
exports2.info = info8;
exports2.startGroup = startGroup4;
exports2.endGroup = endGroup4;
exports2.startGroup = startGroup3;
exports2.endGroup = endGroup3;
exports2.group = group;
exports2.saveState = saveState3;
exports2.getState = getState3;
@@ -21755,20 +21755,20 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``);
function info8(message) {
process.stdout.write(message + os7.EOL);
}
function startGroup4(name) {
function startGroup3(name) {
(0, command_1.issue)("group", name);
}
function endGroup4() {
function endGroup3() {
(0, command_1.issue)("endgroup");
}
function group(name, fn) {
return __awaiter2(this, void 0, void 0, function* () {
startGroup4(name);
startGroup3(name);
let result;
try {
result = yield fn();
} finally {
endGroup4();
endGroup3();
}
return result;
});
@@ -100013,7 +100013,7 @@ var require_package = __commonJS({
"node_modules/@actions/cache/package.json"(exports2, module2) {
module2.exports = {
name: "@actions/cache",
version: "5.2.0",
version: "5.3.0",
preview: true,
description: "Actions cache lib",
keywords: [
@@ -100050,22 +100050,22 @@ var require_package = __commonJS({
url: "https://github.com/actions/toolkit/issues"
},
dependencies: {
"@actions/core": "^2.0.0",
"@actions/core": "^2.0.3",
"@actions/exec": "^2.0.0",
"@actions/glob": "^0.5.1",
"@protobuf-ts/runtime-rpc": "^2.11.1",
"@actions/http-client": "^3.0.2",
"@actions/io": "^2.0.0",
"@azure/abort-controller": "^1.1.0",
"@azure/core-rest-pipeline": "^1.22.0",
"@azure/storage-blob": "^12.29.1",
"@azure/core-rest-pipeline": "^1.25.0",
"@azure/storage-blob": "^12.34.0",
"@protobuf-ts/runtime-rpc": "^2.11.1",
semver: "^6.3.1"
},
devDependencies: {
"@types/node": "^24.1.0",
"@types/semver": "^6.0.0",
"@protobuf-ts/plugin": "^2.9.4",
typescript: "^5.2.2"
"@protobuf-ts/plugin": "^2.11.1",
"@types/node": "^24.13.6",
"@types/semver": "^6.2.7",
typescript: "^5.9.3"
},
overrides: {
"uri-js": "npm:uri-js-replace@^1.0.1",
@@ -105592,6 +105592,7 @@ var require_tar = __commonJS({
exports2.listTar = listTar;
exports2.extractTar = extractTar3;
exports2.createTar = createTar;
var core29 = __importStar2(require_core());
var exec_1 = require_exec();
var io9 = __importStar2(require_io());
var fs_1 = require("fs");
@@ -105644,7 +105645,7 @@ var require_tar = __commonJS({
args.push("--posix", "-cf", BSD_TAR_ZSTD ? tarFile : cacheFileName.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "--exclude", BSD_TAR_ZSTD ? tarFile : cacheFileName.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "-P", "-C", workingDirectory.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "--files-from", constants_1.ManifestFilename);
break;
case "extract":
args.push("-xf", BSD_TAR_ZSTD ? tarFile : archivePath.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "-P", "-C", workingDirectory.replace(new RegExp(`\\${path30.sep}`, "g"), "/"));
args.push("-xf", BSD_TAR_ZSTD ? tarFile : archivePath.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "-P", "-C", BSD_TAR_ZSTD ? quoteAbsolutePath(workingDirectory) : workingDirectory.replace(new RegExp(`\\${path30.sep}`, "g"), "/"));
break;
case "list":
args.push("-tf", BSD_TAR_ZSTD ? tarFile : archivePath.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "-P");
@@ -105675,16 +105676,19 @@ var require_tar = __commonJS({
} else {
args = [[...tarArgs].join(" "), [...compressionArgs].join(" ")];
}
if (BSD_TAR_ZSTD) {
return args;
}
return [args.join(" ")];
return {
commands: BSD_TAR_ZSTD ? args : [args.join(" ")],
requiresTempDirectory: BSD_TAR_ZSTD && type !== "create"
};
});
}
function getWorkingDirectory() {
var _a6;
return (_a6 = process.env["GITHUB_WORKSPACE"]) !== null && _a6 !== void 0 ? _a6 : process.cwd();
}
function quoteAbsolutePath(filePath) {
return `"${path30.resolve(filePath).replace(new RegExp(`\\${path30.sep}`, "g"), "/")}"`;
}
function getDecompressionProgram(tarPath, compressionMethod, archivePath) {
return __awaiter2(this, void 0, void 0, function* () {
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD && compressionMethod !== constants_1.CompressionMethod.Gzip && IS_WINDOWS;
@@ -105693,17 +105697,13 @@ var require_tar = __commonJS({
return BSD_TAR_ZSTD ? [
"zstd -d --long=30 --force -o",
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path30.sep}`, "g"), "/")
quoteAbsolutePath(archivePath)
] : [
"--use-compress-program",
IS_WINDOWS ? '"zstd -d --long=30"' : "unzstd --long=30"
];
case constants_1.CompressionMethod.ZstdWithoutLong:
return BSD_TAR_ZSTD ? [
"zstd -d --force -o",
constants_1.TarFilename,
archivePath.replace(new RegExp(`\\${path30.sep}`, "g"), "/")
] : ["--use-compress-program", IS_WINDOWS ? '"zstd -d"' : "unzstd"];
return BSD_TAR_ZSTD ? ["zstd -d --force -o", constants_1.TarFilename, quoteAbsolutePath(archivePath)] : ["--use-compress-program", IS_WINDOWS ? '"zstd -d"' : "unzstd"];
default:
return ["-z"];
}
@@ -105748,24 +105748,39 @@ var require_tar = __commonJS({
}
});
}
function execReadCommands(archivePath, compressionMethod, type) {
return __awaiter2(this, void 0, void 0, function* () {
const { commands, requiresTempDirectory } = yield getCommands(compressionMethod, type, archivePath);
const tempDirectory = requiresTempDirectory ? yield utils.createTempDirectory() : void 0;
try {
yield execCommands(commands, tempDirectory);
} finally {
if (tempDirectory) {
try {
yield io9.rmRF(tempDirectory);
} catch (error3) {
core29.debug(`Failed to delete temporary tar directory: ${error3}`);
}
}
}
});
}
function listTar(archivePath, compressionMethod) {
return __awaiter2(this, void 0, void 0, function* () {
const commands = yield getCommands(compressionMethod, "list", archivePath);
yield execCommands(commands);
yield execReadCommands(archivePath, compressionMethod, "list");
});
}
function extractTar3(archivePath, compressionMethod) {
return __awaiter2(this, void 0, void 0, function* () {
const workingDirectory = getWorkingDirectory();
yield io9.mkdirP(workingDirectory);
const commands = yield getCommands(compressionMethod, "extract", archivePath);
yield execCommands(commands);
yield execReadCommands(archivePath, compressionMethod, "extract");
});
}
function createTar(archiveFolder, sourceDirectories, compressionMethod) {
return __awaiter2(this, void 0, void 0, function* () {
(0, fs_1.writeFileSync)(path30.join(archiveFolder, constants_1.ManifestFilename), sourceDirectories.join("\n"));
const commands = yield getCommands(compressionMethod, "create");
const { commands } = yield getCommands(compressionMethod, "create");
yield execCommands(commands, archiveFolder);
});
}
@@ -107346,6 +107361,12 @@ var require_follow_redirects = __commonJS({
RedirectableRequest.prototype._sanitizeOptions = function(options) {
if (!options.headers) {
options.headers = {};
} else if (Array.isArray(options.headers)) {
var headerList = options.headers;
options.headers = {};
for (var i = 0; i < headerList.length; i += 2) {
options.headers[headerList[i]] = headerList[i + 1];
}
}
if (!isArray2(options.sensitiveHeaders)) {
options.sensitiveHeaders = [];
@@ -107620,7 +107641,7 @@ var require_follow_redirects = __commonJS({
return URL2 && value instanceof URL2;
}
function escapeRegex(regex) {
return regex.replace(/[\]\\/()*+?.$]/g, "\\$&");
return regex.replace(/[[\]\\/()*+?.^$|]/g, "\\$&");
}
module2.exports = wrap({ http, https: https3 });
module2.exports.wrap = wrap;
@@ -145651,22 +145672,22 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``);
process.stdout.write(message + os7.EOL);
}
exports2.info = info8;
function startGroup4(name) {
function startGroup3(name) {
(0, command_1.issue)("group", name);
}
exports2.startGroup = startGroup4;
function endGroup4() {
exports2.startGroup = startGroup3;
function endGroup3() {
(0, command_1.issue)("endgroup");
}
exports2.endGroup = endGroup4;
exports2.endGroup = endGroup3;
function group(name, fn) {
return __awaiter2(this, void 0, void 0, function* () {
startGroup4(name);
startGroup3(name);
let result;
try {
result = yield fn();
} finally {
endGroup4();
endGroup3();
}
return result;
});
@@ -166063,6 +166084,11 @@ var toolrunner = __toESM(require_toolrunner());
var github = __toESM(require_github());
var io2 = __toESM(require_io());
// src/config/action-config.ts
function hasConfigKey(config, key) {
return config[key] !== void 0;
}
// src/environment.ts
var core = __toESM(require_core());
function getRequiredEnvVar(env, paramName) {
@@ -168107,7 +168133,7 @@ function readBlockScalar(state, parentIndent, props) {
state.position = linePosition + column;
throwError(state, "tab characters must not be used in indentation");
}
if (column < maxLeadingIndent) {
if (column >= parentIndent && column < maxLeadingIndent) {
state.position = linePosition + column;
throwError(state, "bad indentation of a mapping entry");
}
@@ -168317,13 +168343,16 @@ function readBlockMapping(state, nodeIndent, flowIndent, props) {
ch = state.input.charCodeAt(++state.position);
if (!isWsOrEolOrEnd(ch)) throwError(state, "a whitespace character is expected after the key-value separator within a block mapping");
if (!mappingOpened) {
restoreState(state, beforeKey);
addMappingEvent(state, beforeKey.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, COLLECTION_STYLE.BLOCK);
state.events.splice(beforeKey.eventsLength, 0, {
type: EVENT_ID.MAPPING,
start: beforeKey.position,
anchorStart: props.anchorStart,
anchorEnd: props.anchorEnd,
tagStart: props.tagStart,
tagEnd: props.tagEnd,
style: COLLECTION_STYLE.BLOCK
});
mappingOpened = true;
parseNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true);
ch = state.input.charCodeAt(state.position);
while (isWhiteSpace(ch)) ch = state.input.charCodeAt(++state.position);
state.position++;
}
detected = true;
atExplicitKey = false;
@@ -170172,27 +170201,33 @@ function getWorkflowEvent(env = getEnv()) {
);
}
}
async function printDebugLogs(config) {
async function printDebugLogs(logger2, config) {
if (!hasConfigKey(config, "languages") || !hasConfigKey(config, "dbLocation")) {
logger2.debug(
`Not printing debug logs, because the configuration does not include the 'languages' or 'dbLocation' fields.`
);
return;
}
for (const language of config.languages) {
const databaseDirectory = getCodeQLDatabasePath(config, language);
const logsDirectory = path2.join(databaseDirectory, "log");
if (!doesDirectoryExist(logsDirectory)) {
core4.info(`Directory ${logsDirectory} does not exist.`);
logger2.info(`Directory ${logsDirectory} does not exist.`);
continue;
}
const walkLogFiles = (dir) => {
const entries = fs2.readdirSync(dir, { withFileTypes: true });
if (entries.length === 0) {
core4.info(`No debug logs found at directory ${logsDirectory}.`);
logger2.info(`No debug logs found at directory ${logsDirectory}.`);
}
for (const entry of entries) {
if (entry.isFile()) {
const absolutePath = path2.resolve(dir, entry.name);
core4.startGroup(
logger2.startGroup(
`CodeQL Debug Logs - ${language} - ${entry.name} from file at path ${absolutePath}`
);
process.stdout.write(fs2.readFileSync(absolutePath));
core4.endGroup();
logger2.info(fs2.readFileSync(absolutePath, "utf-8"));
logger2.endGroup();
} else if (entry.isDirectory()) {
walkLogFiles(path2.resolve(dir, entry.name));
}
@@ -171381,9 +171416,14 @@ function getAddressString(address) {
}
// src/status-report.ts
var ACTION_DISPLAY_NAMES = {
["finish" /* Analyze */]: "analyze",
["init-post" /* InitPost */]: "init post"
};
function getDisplayActionName(actionName) {
if (actionName === "finish" /* Analyze */) {
return "analyze";
const displayName = ACTION_DISPLAY_NAMES[actionName];
if (displayName !== void 0) {
return displayName;
}
return actionName;
}
@@ -175033,20 +175073,47 @@ function getLocalConfig(logger2, configFile, validateConfig) {
function getPathToParsedConfigFile(tempDir) {
return path11.join(tempDir, "config");
}
async function saveConfig(config, logger2) {
function getPathToFailedConfigFile(tempDir) {
return path11.join(tempDir, "failed-config");
}
function saveConfigFile(logger2, configFilePath, config) {
const configString = JSON.stringify(config);
const configFile = getPathToParsedConfigFile(config.tempDir);
fs10.mkdirSync(path11.dirname(configFile), { recursive: true });
fs10.writeFileSync(configFile, configString, "utf8");
fs10.mkdirSync(path11.dirname(configFilePath), { recursive: true });
fs10.writeFileSync(configFilePath, configString, "utf8");
logger2.debug("Saved config:");
logger2.debug(configString);
}
async function getConfig(tempDir, logger2) {
const configFile = getPathToParsedConfigFile(tempDir);
if (!fs10.existsSync(configFile)) {
async function saveConfig(config, logger2) {
const configFile = getPathToParsedConfigFile(config.tempDir);
saveConfigFile(logger2, configFile, config);
}
function saveAbortedInitConfig(action, config) {
if (action.name !== "init" /* Init */) {
throw new Error(
`Internal error: 'saveAbortedInitConfig' should only be called by '${"init" /* Init */}', but was called by '${action.name}'.`
);
}
const failedConfig = {
version: config.version,
tempDir: config.tempDir,
codeQLCmd: config.codeQLCmd,
debugMode: config.debugMode,
gitHubVersion: config.gitHubVersion,
languages: config.languages,
analysisKinds: config.analysisKinds
};
action.logger.debug(`Saving config for failed init step.`);
saveConfigFile(
action.logger,
getPathToFailedConfigFile(config.tempDir),
failedConfig
);
}
function readConfigFile(logger2, configFilePath) {
if (!fs10.existsSync(configFilePath)) {
return void 0;
}
const configString = fs10.readFileSync(configFile, "utf8");
const configString = fs10.readFileSync(configFilePath, "utf8");
logger2.debug("Loaded config:");
logger2.debug(configString);
const config = JSON.parse(configString);
@@ -175067,6 +175134,18 @@ async function getConfig(tempDir, logger2) {
}
return config;
}
async function getConfig(tempDir, logger2) {
const configFile = getPathToParsedConfigFile(tempDir);
return readConfigFile(logger2, configFile);
}
function getAbortedInitConfig(action, tempDir) {
if (action.name !== "init-post" /* InitPost */) {
throw new Error(
`Internal error: 'getAbortedInitConfig' should only be called by '${"init-post" /* InitPost */}', but was called by '${action.name}'.`
);
}
return readConfigFile(action.logger, getPathToFailedConfigFile(tempDir));
}
async function generateRegistries(registriesInput, tempDir, logger2) {
const registries = parseRegistries(registriesInput);
let registriesAuthTokens;
@@ -186494,6 +186573,15 @@ async function run3(actionState) {
}
await checkInstallPython311(config.languages, codeql);
} catch (unwrappedError) {
if (config !== void 0) {
try {
saveAbortedInitConfig(actionState, config);
} catch (configSaveError) {
logger2.warning(
`Unable to save configuration for '${"init-post" /* InitPost */}' step: ${getErrorMessage(configSaveError)}`
);
}
}
const error3 = wrapError(unwrappedError);
core19.setFailed(error3.message);
const statusReportBase = await createStatusReportBase(
@@ -186922,14 +187010,14 @@ async function uploadFailureInfo(uploadAllAvailableDebugArtifacts, printDebugLog
);
}
}
if (config.debugMode) {
if (config.debugMode && hasConfigKey(config, "dbLocation")) {
logger2.info(
"Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts..."
);
await uploadAllAvailableDebugArtifacts(codeql, config, logger2);
await printDebugLogs2(config);
await printDebugLogs2(logger2, config);
}
if (isSelfHostedRunner()) {
if (isSelfHostedRunner() && config.dbLocation) {
try {
fs30.rmSync(config.dbLocation, {
recursive: true,
@@ -186944,6 +187032,10 @@ async function uploadFailureInfo(uploadAllAvailableDebugArtifacts, printDebugLog
`Failed to clean up database cluster directory ${config.dbLocation}. Details: ${e}`
);
}
} else if (config.dbLocation === void 0) {
logger2.debug(
"Skipping cleanup of database cluster directory since the configuration does not include a database path."
);
} else {
logger2.debug(
"Skipping cleanup of database cluster directory since we are running on a GitHub-hosted runner which will be automatically cleaned up."
@@ -186967,6 +187059,11 @@ function isConclusiveJobStatus(jobStatus) {
async function recordOverlayStatus(codeql, config, features, jobStatus, env, logger2) {
if (config.overlayDatabaseMode !== "overlay-base" /* OverlayBase */ || env.getOptional("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */) === "true" || !await features.getValue("overlay_analysis_status_save" /* OverlayAnalysisStatusSave */)) {
return;
} else if (config.languages === void 0) {
logger2.debug(
"Not recording overlay status, because the configuration contains no 'languages'."
);
return;
}
if (!isConclusiveJobStatus(jobStatus) && !didCodeQlReportError(env)) {
logger2.info(
@@ -187069,15 +187166,19 @@ async function removeUploadedSarif(uploadFailedSarifResult, logger2) {
}
// src/init-action-post.ts
async function run4(startedAt) {
const logger2 = getActionsLogger();
async function run4(action) {
const logger2 = action.logger;
let config;
let uploadFailedSarifResult;
let dependencyCachingUsage;
try {
const jobStatus2 = getOptionalInput("job-status");
restoreInputs(logger2);
config = await getConfig(getTemporaryDirectory(), logger2);
const tmpDir = getTemporaryDirectory();
config = await getConfig(tmpDir, logger2);
if (config === void 0) {
config = getAbortedInitConfig(action, tmpDir);
}
const gitHubVersion = config?.gitHubVersion ?? await getGitHubVersion();
checkGitHubVersionInRange(gitHubVersion, logger2);
const repositoryNwo = getRepositoryNwo();
@@ -187101,10 +187202,10 @@ async function run4(startedAt) {
repositoryNwo,
features,
jobStatus2,
getEnv(),
action.env,
logger2
);
if (await isAnalyzingDefaultBranch() && config.dependencyCachingEnabled !== "none" /* None */) {
if (await isAnalyzingDefaultBranch() && hasConfigKey(config, "dependencyCachingEnabled") && config.dependencyCachingEnabled !== "none" /* None */) {
dependencyCachingUsage = await getDependencyCacheUsage(logger2);
}
}
@@ -187112,9 +187213,9 @@ async function run4(startedAt) {
const error3 = wrapApiConfigurationError(wrapError(unwrappedError));
core20.setFailed(error3.message);
const statusReportBase2 = await createStatusReportBase(
"init-post" /* InitPost */,
action.name,
getActionsStatus(error3),
startedAt,
action.startedAt,
config,
await checkDiskUsage(logger2),
logger2,
@@ -187126,12 +187227,12 @@ async function run4(startedAt) {
}
return;
}
const jobStatus = getFinalJobStatus(config);
const jobStatus = getFinalJobStatus(action, config);
logger2.info(`CodeQL job status was ${getJobStatusDisplayName(jobStatus)}.`);
const statusReportBase = await createStatusReportBase(
"init-post" /* InitPost */,
action.name,
"success",
startedAt,
action.startedAt,
config,
await checkDiskUsage(logger2),
logger2
@@ -187148,25 +187249,25 @@ async function run4(startedAt) {
logger2.info("Status report sent for init-post step.");
}
}
function getFinalJobStatus(config) {
const existingJobStatus = getJobStatusFromEnvironment();
function getFinalJobStatus(action, config) {
const existingJobStatus = getJobStatusFromEnvironment(action.env);
if (existingJobStatus !== void 0) {
return existingJobStatus;
}
let jobStatus;
if (process.env["CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */] === "true") {
exportEnvVar("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */);
if (action.env.getOptional("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */) === "true") {
action.env.export("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */);
jobStatus = "JOB_STATUS_SUCCESS" /* SuccessStatus */;
} else if (config !== void 0) {
jobStatus = "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */;
} else {
jobStatus = "JOB_STATUS_UNKNOWN" /* UnknownStatus */;
}
exportEnvVar("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus);
action.env.export("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus);
return jobStatus;
}
function getJobStatusFromEnvironment() {
const jobStatusFromEnvironment = process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */];
function getJobStatusFromEnvironment(env) {
const jobStatusFromEnvironment = env.getOptional("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */);
if (jobStatusFromEnvironment !== void 0) {
if (Object.values(JobStatus).includes(jobStatusFromEnvironment)) {
return jobStatusFromEnvironment;
@@ -187175,20 +187276,12 @@ function getJobStatusFromEnvironment() {
}
return void 0;
}
var initPost = {
name: "init-post" /* InitPost */,
run: run4
};
async function runWrapper5() {
const startedAt = /* @__PURE__ */ new Date();
const logger2 = getActionsLogger();
try {
await run4(startedAt);
} catch (error3) {
core20.setFailed(`init post action failed: ${wrapError(error3).message}`);
await sendUnhandledErrorStatusReport(
"init-post" /* InitPost */,
startedAt,
error3,
logger2
);
}
return await runInActions(initPost);
}
// src/resolve-environment-action.ts
@@ -188562,7 +188655,7 @@ tmp/lib/tmp.js:
*)
js-yaml/dist/js-yaml.mjs:
(*! js-yaml 5.4.2 https://github.com/nodeca/js-yaml @license MIT *)
(*! js-yaml 5.4.3 https://github.com/nodeca/js-yaml @license MIT *)
long/index.js:
(**

205
package-lock.json generated
View File

@@ -14,7 +14,7 @@
"dependencies": {
"@actions/artifact": "^5.0.3",
"@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2",
"@actions/cache": "^5.2.0",
"@actions/cache": "^5.3.0",
"@actions/core": "^2.0.3",
"@actions/exec": "^2.0.0",
"@actions/github": "^8.0.1",
@@ -23,14 +23,14 @@
"@actions/io": "^2.0.0",
"@actions/tool-cache": "^3.0.1",
"@octokit/core": "^7.0.8",
"@octokit/plugin-paginate-rest": "^15.0.0",
"@octokit/plugin-paginate-rest": "^16.0.0",
"@octokit/plugin-rest-endpoint-methods": "^18.0.0",
"@octokit/plugin-retry": "^8.1.1",
"archiver": "^8.0.0",
"follow-redirects": "^1.16.0",
"follow-redirects": "^1.16.1",
"get-folder-size": "^5.0.0",
"https-proxy-agent": "^7.0.6",
"js-yaml": "^5.4.2",
"js-yaml": "^5.4.3",
"jsonschema": "1.5.0",
"long": "^5.3.2",
"node-forge": "^1.4.0",
@@ -57,14 +57,14 @@
"eslint-import-resolver-typescript": "^4.4.5",
"eslint-plugin-github": "^6.1.2",
"eslint-plugin-import-x": "^4.17.1",
"eslint-plugin-jsdoc": "^65.0.1",
"eslint-plugin-jsdoc": "^65.2.0",
"eslint-plugin-no-async-foreach": "^0.1.1",
"glob": "^13.0.6",
"globals": "^17.12.0",
"globals": "^17.13.0",
"nock": "^14.0.17",
"sinon": "^22.1.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.70.1"
"typescript-eslint": "^8.71.1"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -458,19 +458,19 @@
}
},
"node_modules/@actions/cache": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.2.0.tgz",
"integrity": "sha512-1R1Oc8cuDNCygsIP7gLiKLGCymOw/k5FkGQkXZFcLz6/RWyMImkfP0dZX6kjA9SRAmANcKNocI2XrsIaZ1it8w==",
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.3.0.tgz",
"integrity": "sha512-VqJBlQFt1lpp7op7o/Z0syWywX9cN8TxjFCPjHyGHmXCiczU5NII5ZdEpGpTelUnOGFG2bO7viUx9q3q7WR/Gg==",
"license": "MIT",
"dependencies": {
"@actions/core": "^2.0.0",
"@actions/core": "^2.0.3",
"@actions/exec": "^2.0.0",
"@actions/glob": "^0.5.1",
"@actions/http-client": "^3.0.2",
"@actions/io": "^2.0.0",
"@azure/abort-controller": "^1.1.0",
"@azure/core-rest-pipeline": "^1.22.0",
"@azure/storage-blob": "^12.29.1",
"@azure/core-rest-pipeline": "^1.25.0",
"@azure/storage-blob": "^12.34.0",
"@protobuf-ts/runtime-rpc": "^2.11.1",
"semver": "^6.3.1"
}
@@ -2204,12 +2204,12 @@
"license": "MIT"
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-15.0.0.tgz",
"integrity": "sha512-lw9A9YL5s4VPj+VEx8uMxaxQm2YTgrPDkrLEuZuu18R8TK3oPcXF4K6t52nx6xn1RcogZC9i188sAr/4XYJaQQ==",
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-16.0.0.tgz",
"integrity": "sha512-7RtUeGZypAK4EA4LrjTCnsLALNOoUcYh5vOnCNXpdIQVTQCPh4OFu7324iPqAls3KGgVnZktKUnNKZCOKyHrlA==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^17.0.0"
"@octokit/types": "^18.0.0"
},
"engines": {
"node": ">= 20"
@@ -2218,21 +2218,6 @@
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
"version": "28.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-28.0.0.tgz",
"integrity": "sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==",
"license": "MIT"
},
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-17.0.0.tgz",
"integrity": "sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^28.0.0"
}
},
"node_modules/@octokit/plugin-request-log": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
@@ -2717,17 +2702,17 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.70.1.tgz",
"integrity": "sha512-nDNrUQ/4ruSNYbu749TRY7cfrzPtoLHEXSNBI8aaNY32LlZCajixqRf3FqcKC4p5Cam4VOHYx/t+i5+nKXvrqA==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.71.1.tgz",
"integrity": "sha512-nNlBf6HuotqMgZvSkWD5hNdemiBIxQ2NmrlgfcUIeZRs+BbakjscCQRq/Hb74EFVnFiSWWdL12JruqwBy3ERDw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.70.1",
"@typescript-eslint/type-utils": "8.70.1",
"@typescript-eslint/utils": "8.70.1",
"@typescript-eslint/visitor-keys": "8.70.1",
"@typescript-eslint/scope-manager": "8.71.1",
"@typescript-eslint/type-utils": "8.71.1",
"@typescript-eslint/utils": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1",
"ignore": "^7.0.5",
"natural-compare": "^1.4.0",
"ts-api-utils": "^2.5.0"
@@ -2740,7 +2725,7 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.70.1",
"@typescript-eslint/parser": "^8.71.1",
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.1.0"
}
@@ -2756,16 +2741,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.70.1.tgz",
"integrity": "sha512-nO974WLllwhSFWQXnMLj6nDGa8f0khKEz1JzpPJ1u7Vm/4X1X6ZHajpoknU4bb41vJyMB0HHVyS2GqdhWfIXZw==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.71.1.tgz",
"integrity": "sha512-oM/5sAqz/l1v/zYK1qTOPrn2+JIrBGC1V6uNYucRO5gh6eT9vWJ/RhPbGE59byvZEUQ4VP6XkLBaS5Jti5jpvw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.70.1",
"@typescript-eslint/types": "8.70.1",
"@typescript-eslint/typescript-estree": "8.70.1",
"@typescript-eslint/visitor-keys": "8.70.1",
"@typescript-eslint/scope-manager": "8.71.1",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1",
"debug": "^4.4.3"
},
"engines": {
@@ -2799,14 +2784,14 @@
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.70.1.tgz",
"integrity": "sha512-62xOgboPfwc3/IgPSX/W6oQR3ZbF04194FPGUGH8HL8iLFHbt/456/8Ph1wLNUgVF+s94FlHoipBsz+v7+LMnA==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.71.1.tgz",
"integrity": "sha512-Oijc9RUsohHjncg6iGi7gCtjnEjYt9FWv9u6ygK8uKcHK5eLjLAkqERQ9BaytbpceOFdk6kifPCS/zAZE+A99g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.70.1",
"@typescript-eslint/types": "^8.70.1",
"@typescript-eslint/tsconfig-utils": "^8.71.1",
"@typescript-eslint/types": "^8.71.1",
"debug": "^4.4.3"
},
"engines": {
@@ -2839,14 +2824,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.70.1.tgz",
"integrity": "sha512-Pa0EeSeAusQc1WbjQMac+YfenewYTBu0KjgYvkUKwhXaHUKbFog23Dm/rp0DX/6tyYOQ3Xl1a+3EcFNZynGHCw==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.71.1.tgz",
"integrity": "sha512-1YUDZXdTnXLlob03SFHBipdyMBsDVm7zoSz0ytTJ39dk5J1TgsTK03VlR/dLXG/RLLUrPcYbD4rp23BmHxHP0w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.70.1",
"@typescript-eslint/visitor-keys": "8.70.1"
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2857,9 +2842,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.1.tgz",
"integrity": "sha512-jumze1fPI+sDOaM2TWGQdn39PDxTr7TZGeuyLkAbNyx2vtMT3uRnVKChN0hfht5V2TugphJzF6bYXvBcE09qqg==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.71.1.tgz",
"integrity": "sha512-oTvkml5SxXhgg+WWKhod5qWQICDXtOB+/Hi9VdPKFAANJ2b7YOgMffgvzXuqog7R6A/JtrzRf128dsxummyWhg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2874,15 +2859,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.70.1.tgz",
"integrity": "sha512-7zKTnyvaVWqzLZHPFQtX1hVHqgkMC+WebPWakNCSyrQVbIP1AM0L0TlBZtACldIRb6PptI8Odk+jyZ5kP3B1VA==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.71.1.tgz",
"integrity": "sha512-kH3t3jZCYv2PZSBEWPKTariLrCaoF1CLoPitYFBJOhAGEwWnSRAtGEifrfrpBa4K9JlwWNZotgA5w3/wLSk/FQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.70.1",
"@typescript-eslint/typescript-estree": "8.70.1",
"@typescript-eslint/utils": "8.70.1",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1",
"@typescript-eslint/utils": "8.71.1",
"debug": "^4.4.3",
"ts-api-utils": "^2.5.0"
},
@@ -2917,9 +2902,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.70.1.tgz",
"integrity": "sha512-Dm1ypdhhrGCTyyehxElhgJ6kgk8MVCv5qXdoOVqPr1uqk42jX8KjrZqhROvdShczA8qrDoYiOWn1ykWlx2k81Q==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.71.1.tgz",
"integrity": "sha512-ybYnPTUwg3VQQOFEiBPLs8Jxl1ry2vXdn1kVKguomBbvxpetdu3MKTNDqFNUrlG8ylP9MpZosmXMFYlGQHk1oQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2931,16 +2916,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.70.1.tgz",
"integrity": "sha512-TU8PwyGN0PQJUcE96mw8eCQ44SmxGdQlJmlWakHaHQ15eIuuvye5yNtmh/i6oS88jzXVQB71xdNkbkB/fMwL0g==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.71.1.tgz",
"integrity": "sha512-pSKSEK1JJpHs6KiKVtABCE4iJK5d7FLFzDXQNBQ2oRY7LEd3UwOt3TZemTgu9syTIf56dJWlTn/pdmrO9oKUXQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.70.1",
"@typescript-eslint/tsconfig-utils": "8.70.1",
"@typescript-eslint/types": "8.70.1",
"@typescript-eslint/visitor-keys": "8.70.1",
"@typescript-eslint/project-service": "8.71.1",
"@typescript-eslint/tsconfig-utils": "8.71.1",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
@@ -3016,16 +3001,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.70.1.tgz",
"integrity": "sha512-Esgul8MsnKnRLdYU2Eb2cRV9bS5HJYtKj1ByJnOzzG2M58DGdSUQ1jUuILxipqcpB2h9WLrbD5GijIWUjX/Tqw==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.71.1.tgz",
"integrity": "sha512-CBjT6gfAz3DW2j9Q4moFnqt208Aq+506sVGXfpRcyAeqn0EpayL0mjdWoCO2t3RC7GewNrFxdeehuEaPg6DMzQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.70.1",
"@typescript-eslint/types": "8.70.1",
"@typescript-eslint/typescript-estree": "8.70.1"
"@typescript-eslint/scope-manager": "8.71.1",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3040,13 +3025,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.70.1.tgz",
"integrity": "sha512-Vwj9lUIW5Xq3wQ9w6gv3R86g1hMK8f2zNOdGTAgeXUMMXFK78G9ruCjjqutHMNJc0+CH7LYRnHeUB9IT8wFmcw==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.71.1.tgz",
"integrity": "sha512-0GxiUGqMU0qXJt58cBsiG3DP8lUmBaFo2vChtUX+CT7PnR3v/VGLLrzVP4K9r1lNiZXjHYefMBbPunplr09v6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.70.1",
"@typescript-eslint/types": "8.71.1",
"eslint-visitor-keys": "^5.0.0"
},
"engines": {
@@ -5380,9 +5365,9 @@
}
},
"node_modules/eslint-plugin-jsdoc": {
"version": "65.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-65.0.1.tgz",
"integrity": "sha512-7IvB+ZS71WCw5tGKh6f6D5k55qtXKdrGTnIpQTBKWdpyZ5IfhGHfh0i6ArWlCJ4JEtz22YRk5Bqu1MvbOlpMKQ==",
"version": "65.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-65.2.0.tgz",
"integrity": "sha512-IMZaNwdDa5otUQYGWN1pzywZLsGKswitvFFNhcO8IOsBfaWpWIDXYuZh2sYhe9MNyKN9hz0YryOFaKdpbTP5Bw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -6007,9 +5992,9 @@
"license": "ISC"
},
"node_modules/follow-redirects": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
"integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.1.tgz",
"integrity": "sha512-FNvFGzoMLWmE6Yj9spb/zjd7yiNCHiAW9/Tg9CXrQ8wuu32HtlJOwWO11OJafl5FfY3DxTdQ0vj42zU1kvv5jg==",
"funding": [
{
"type": "individual",
@@ -6293,9 +6278,9 @@
}
},
"node_modules/globals": {
"version": "17.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-17.12.0.tgz",
"integrity": "sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==",
"version": "17.13.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-17.13.0.tgz",
"integrity": "sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7136,9 +7121,9 @@
}
},
"node_modules/js-yaml": {
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.2.tgz",
"integrity": "sha512-m+aqu+LwO1O6sIopafj8HUVl5aawITwZQe/yHpMCKjaWBaA/d07B/QdMb3529REftiU+RMMHL3Vlsw3hON7vWg==",
"version": "5.4.3",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.3.tgz",
"integrity": "sha512-yzzNtgczwgoVHNigCyKTXcQJU4Y8t/ikU4UxXW0BvrLfHTGWZhsNcOT2s/a7vn81/4KqVnNmHjaUEPlvWnNwVw==",
"funding": [
{
"type": "github",
@@ -7494,9 +7479,9 @@
}
},
"node_modules/mdast-util-from-markdown": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz",
"integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.1.0.tgz",
"integrity": "sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
@@ -9996,16 +9981,16 @@
}
},
"node_modules/typescript-eslint": {
"version": "8.70.1",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.70.1.tgz",
"integrity": "sha512-AcWG7KDjZ2THNXsgwttMaGmzVi0VFRlFYfqFHYQRbDpF3owuYbuiL8c7UUrd2k8s3PoSfIQrWfrGXfcElrWLYA==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.71.1.tgz",
"integrity": "sha512-oiNVPC3/NbV1FpaHU07l8O6ynqG9v4PAiW2WvTrAmZdR0f2HI/gE668ElMLCK7Xbsu5k2fK5C4fXNiq05j7/nQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.70.1",
"@typescript-eslint/parser": "8.70.1",
"@typescript-eslint/typescript-estree": "8.70.1",
"@typescript-eslint/utils": "8.70.1"
"@typescript-eslint/eslint-plugin": "8.71.1",
"@typescript-eslint/parser": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1",
"@typescript-eslint/utils": "8.71.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -10500,10 +10485,10 @@
"@actions/core": "^2.0.3",
"@actions/github": "^8.0.1",
"@octokit/core": "^7.0.8",
"@octokit/plugin-paginate-rest": ">=15.0.0",
"@octokit/plugin-paginate-rest": ">=16.0.0",
"@octokit/plugin-rest-endpoint-methods": "^18.0.0",
"lite-matter": "^0.1.2",
"mdast-util-from-markdown": "^2.0.3",
"mdast-util-from-markdown": "^2.1.0",
"semver": "^7.8.5",
"yaml": "^2.9.1"
},

View File

@@ -22,7 +22,7 @@
"dependencies": {
"@actions/artifact": "^5.0.3",
"@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2",
"@actions/cache": "^5.2.0",
"@actions/cache": "^5.3.0",
"@actions/core": "^2.0.3",
"@actions/exec": "^2.0.0",
"@actions/github": "^8.0.1",
@@ -31,14 +31,14 @@
"@actions/io": "^2.0.0",
"@actions/tool-cache": "^3.0.1",
"@octokit/core": "^7.0.8",
"@octokit/plugin-paginate-rest": "^15.0.0",
"@octokit/plugin-paginate-rest": "^16.0.0",
"@octokit/plugin-rest-endpoint-methods": "^18.0.0",
"@octokit/plugin-retry": "^8.1.1",
"archiver": "^8.0.0",
"follow-redirects": "^1.16.0",
"follow-redirects": "^1.16.1",
"get-folder-size": "^5.0.0",
"https-proxy-agent": "^7.0.6",
"js-yaml": "^5.4.2",
"js-yaml": "^5.4.3",
"jsonschema": "1.5.0",
"long": "^5.3.2",
"node-forge": "^1.4.0",
@@ -65,14 +65,14 @@
"eslint-import-resolver-typescript": "^4.4.5",
"eslint-plugin-github": "^6.1.2",
"eslint-plugin-import-x": "^4.17.1",
"eslint-plugin-jsdoc": "^65.0.1",
"eslint-plugin-jsdoc": "^65.2.0",
"eslint-plugin-no-async-foreach": "^0.1.1",
"glob": "^13.0.6",
"globals": "^17.12.0",
"globals": "^17.13.0",
"nock": "^14.0.17",
"sinon": "^22.1.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.70.1"
"typescript-eslint": "^8.71.1"
},
"overrides": {
"@actions/tool-cache": {

View File

@@ -6,10 +6,10 @@
"@actions/core": "^2.0.3",
"@actions/github": "^8.0.1",
"@octokit/core": "^7.0.8",
"@octokit/plugin-paginate-rest": ">=15.0.0",
"@octokit/plugin-paginate-rest": ">=16.0.0",
"@octokit/plugin-rest-endpoint-methods": "^18.0.0",
"lite-matter": "^0.1.2",
"mdast-util-from-markdown": "^2.0.3",
"mdast-util-from-markdown": "^2.1.0",
"semver": "^7.8.5",
"yaml": "^2.9.1"
},

View File

@@ -19,6 +19,24 @@ import { getErrorMessage } from "./util";
setupTests(test);
for (const [key, displayName] of Object.entries(
statusReport.ACTION_DISPLAY_NAMES,
)) {
test(`getDisplayActionName - '${displayName}' instead of '${key}'`, (t) => {
t.is(statusReport.getDisplayActionName(key as ActionName), displayName);
});
}
test("getDisplayActionName - returns action name", (t) => {
for (const actionName of Object.values(ActionName)) {
if (statusReport.ACTION_DISPLAY_NAMES[actionName]) {
continue;
}
t.is(statusReport.getDisplayActionName(actionName), actionName);
}
});
interface RunInActionsTestOpts {
runFn?: () => Promise<any>;
expectedErrorMessage?: string;

View File

@@ -7,12 +7,13 @@ import {
isAnalyzingPullRequest,
isDefaultSetup,
isDynamicWorkflow,
printDebugLogs,
} from "./actions-util";
import { computeAutomationID } from "./api-client";
import { EnvVar } from "./environment";
import { getRunnerLogger } from "./logging";
import { setupTests } from "./testing-utils";
import { initializeEnvironment } from "./util";
import { RecordingLogger, setupTests } from "./testing-utils";
import { initializeEnvironment, withTmpDir } from "./util";
setupTests(test);
@@ -100,6 +101,21 @@ test("computeAutomationID()", async (t) => {
);
});
test("printDebugLogs - doesn't throw when config doesn't have needed properties", async (t) => {
const logger = new RecordingLogger();
await t.notThrowsAsync(printDebugLogs(logger, {}));
await t.notThrowsAsync(printDebugLogs(logger, { languages: [] }));
await t.notThrowsAsync(printDebugLogs(logger, { dbLocation: "nowhere" }));
});
test("printDebugLogs - doesn't throw when language db doesn't exist", async (t) =>
withTmpDir(async (tmpDir) => {
const logger = new RecordingLogger();
await t.notThrowsAsync(
printDebugLogs(logger, { dbLocation: tmpDir, languages: ["javascript"] }),
);
}));
test.serial("getPullRequestBranches() with pull request context", (t) => {
withMockedContext(
{

View File

@@ -6,7 +6,7 @@ import * as toolrunner from "@actions/exec/lib/toolrunner";
import * as github from "@actions/github";
import * as io from "@actions/io";
import type { Config } from "./config-utils";
import { hasConfigKey, type Config } from "./config/action-config";
import { Env, EnvVar, ActionsEnvVars, ReadOnlyEnv } from "./environment";
import { Logger } from "./logging";
import {
@@ -131,28 +131,38 @@ export function getWorkflowEvent(env: Env = getEnv()): any {
}
}
export async function printDebugLogs(config: Config) {
export async function printDebugLogs(logger: Logger, config: Partial<Config>) {
if (
!hasConfigKey(config, "languages") ||
!hasConfigKey(config, "dbLocation")
) {
logger.debug(
`Not printing debug logs, because the configuration does not include the 'languages' or 'dbLocation' fields.`,
);
return;
}
for (const language of config.languages) {
const databaseDirectory = getCodeQLDatabasePath(config, language);
const logsDirectory = path.join(databaseDirectory, "log");
if (!doesDirectoryExist(logsDirectory)) {
core.info(`Directory ${logsDirectory} does not exist.`);
logger.info(`Directory ${logsDirectory} does not exist.`);
continue; // Skip this language database.
}
const walkLogFiles = (dir: string) => {
const entries = fs.readdirSync(dir, { withFileTypes: true });
if (entries.length === 0) {
core.info(`No debug logs found at directory ${logsDirectory}.`);
logger.info(`No debug logs found at directory ${logsDirectory}.`);
}
for (const entry of entries) {
if (entry.isFile()) {
const absolutePath = path.resolve(dir, entry.name);
core.startGroup(
logger.startGroup(
`CodeQL Debug Logs - ${language} - ${entry.name} from file at path ${absolutePath}`,
);
process.stdout.write(fs.readFileSync(absolutePath));
core.endGroup();
logger.info(fs.readFileSync(absolutePath, "utf-8"));
logger.endGroup();
} else if (entry.isDirectory()) {
walkLogFiles(path.resolve(dir, entry.name));
}

View File

@@ -9,6 +9,7 @@ import { getTemporaryDirectory } from "./actions-util";
import * as analyses from "./analyses";
import { setupCppAutobuild } from "./autobuild";
import { type CodeQL } from "./codeql";
import type { ActionConfig } from "./config/action-config";
import { defaultSuites } from "./config/db-config";
import * as configUtils from "./config-utils";
import {
@@ -171,7 +172,7 @@ async function shouldExtractLanguage(
}
export function dbIsFinalized(
config: configUtils.Config,
config: ActionConfig<"dbLocation">,
language: Language,
logger: Logger,
) {

View File

@@ -15,6 +15,7 @@ import * as api from "./api-client";
import * as outputCache from "./cli/output-cache";
import type { VersionInfo } from "./cli/types";
import { CliError, wrapCliConfigurationError } from "./cli-errors";
import type { ActionConfig } from "./config/action-config";
import { appendExtraQueryExclusions, type Config } from "./config-utils";
import { DocUrl } from "./doc-url";
import { EnvVar, getEnv, exportEnvVar } from "./environment";
@@ -197,7 +198,7 @@ export interface CodeQL {
diagnosticsExport(
sarifFile: string,
automationDetailsId: string | undefined,
config: Config,
config: ActionConfig<"tempDir">,
): Promise<void>;
/** Get the location of an extractor for the specified language. */
resolveExtractor(language: Language): Promise<string>;
@@ -913,7 +914,7 @@ async function getCodeQLForCmd(
async diagnosticsExport(
sarifFile: string,
automationDetailsId: string | undefined,
config: Config,
config: ActionConfig<"tempDir">,
): Promise<void> {
const args = [
"diagnostics",
@@ -1237,7 +1238,9 @@ export async function getTrapCachingExtractorConfigArgsForLang(
*
* This will not exist if the configuration is being parsed in the Action.
*/
function getGeneratedCodeScanningConfigPath(config: Config): string {
function getGeneratedCodeScanningConfigPath(
config: ActionConfig<"tempDir">,
): string {
return path.resolve(config.tempDir, "user-config.yaml");
}

View File

@@ -21,7 +21,11 @@ import {
import * as api from "./api-client";
import { getCachingKind } from "./caching-utils";
import { type CodeQL } from "./codeql";
import { type Config } from "./config/action-config";
import {
type AbortedInitConfig,
type ActionConfig,
type Config,
} from "./config/action-config";
import {
calculateAugmentation,
ExcludeQueryFilter,
@@ -71,6 +75,7 @@ import {
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import { shouldSkipOverlayAnalysis } from "./overlay/status";
import { RepositoryNwo } from "./repository";
import { ActionName } from "./status-report";
import { ToolsFeature } from "./tools-features";
import { downloadTrapCaches } from "./trap-caching";
import {
@@ -1379,31 +1384,86 @@ export function getPathToParsedConfigFile(tempDir: string): string {
return path.join(tempDir, "config");
}
function getPathToFailedConfigFile(tempDir: string): string {
return path.join(tempDir, "failed-config");
}
/**
* Store the given config to the path returned from getPathToParsedConfigFile.
* Writes {@link config} to {@link configFilePath}.
*
* This function is not intended to be called, other than by
* {@link saveConfig} and {@link saveAbortedInitConfig} below.
*/
export async function saveConfig(config: Config, logger: Logger) {
function saveConfigFile(
logger: Logger,
configFilePath: string,
config: Partial<Config>,
) {
const configString = JSON.stringify(config);
const configFile = getPathToParsedConfigFile(config.tempDir);
fs.mkdirSync(path.dirname(configFile), { recursive: true });
fs.writeFileSync(configFile, configString, "utf8");
fs.mkdirSync(path.dirname(configFilePath), { recursive: true });
fs.writeFileSync(configFilePath, configString, "utf8");
logger.debug("Saved config:");
logger.debug(configString);
}
/**
* Get the config that has been saved to the given temp dir.
* If the config could not be found then returns undefined.
* Store the given config to the path returned from getPathToParsedConfigFile.
*/
export async function getConfig(
tempDir: string,
export async function saveConfig(config: Config, logger: Logger) {
const configFile = getPathToParsedConfigFile(config.tempDir);
saveConfigFile(logger, configFile, config);
}
/**
* Store parts of {@link config} as a failed configuration file.
*
* The file will only contain parts of {@link config} that are relevant to
* the `init-post` step in the workflow.
*/
export function saveAbortedInitConfig(
action: ActionState<["Base", "Logger"]>,
config: Config,
) {
// Should only be called by init.
if (action.name !== ActionName.Init) {
throw new Error(
`Internal error: 'saveAbortedInitConfig' should only be called by '${ActionName.Init}', but was called by '${action.name}'.`,
);
}
// Create a copy of the input `Config` that only contains the keys we want.
const failedConfig: AbortedInitConfig = {
version: config.version,
tempDir: config.tempDir,
codeQLCmd: config.codeQLCmd,
debugMode: config.debugMode,
gitHubVersion: config.gitHubVersion,
languages: config.languages,
analysisKinds: config.analysisKinds,
};
action.logger.debug(`Saving config for failed init step.`);
saveConfigFile(
action.logger,
getPathToFailedConfigFile(config.tempDir),
failedConfig,
);
}
/**
* Attempts to read a {@link Config} from {@link configFilePath}.
*
* This function is not intended to be called, other than by
* {@link getConfig} and {@link getAbortedInitConfig} below.
*/
function readConfigFile(
logger: Logger,
): Promise<Config | undefined> {
const configFile = getPathToParsedConfigFile(tempDir);
if (!fs.existsSync(configFile)) {
configFilePath: string,
): Config | undefined {
if (!fs.existsSync(configFilePath)) {
return undefined;
}
const configString = fs.readFileSync(configFile, "utf8");
const configString = fs.readFileSync(configFilePath, "utf8");
logger.debug("Loaded config:");
logger.debug(configString);
@@ -1428,6 +1488,38 @@ export async function getConfig(
return config as Config;
}
/**
* Get the config that has been saved to the given temp dir.
* If the config could not be found then returns undefined.
*/
export async function getConfig(
tempDir: string,
logger: Logger,
): Promise<Config | undefined> {
const configFile = getPathToParsedConfigFile(tempDir);
return readConfigFile(logger, configFile);
}
/**
* Loads a {@link AbortedInitConfig} from a failed `init` step if it exists.
*
* The result will only contain parts of a {@link Config} that are relevant to
* the `init-post` step in the workflow.
*/
export function getAbortedInitConfig(
action: ActionState<["Base", "Logger"]>,
tempDir: string,
): AbortedInitConfig | undefined {
// Only intended to be called by the `init-post` action.
if (action.name !== ActionName.InitPost) {
throw new Error(
`Internal error: 'getAbortedInitConfig' should only be called by '${ActionName.InitPost}', but was called by '${action.name}'.`,
);
}
return readConfigFile(action.logger, getPathToFailedConfigFile(tempDir));
}
/**
* Generate a `qlconfig.yml` file from the `registries` input.
* This file is used by the CodeQL CLI to list the registries to use for each
@@ -1618,21 +1710,27 @@ export function appendExtraQueryExclusions(
/**
* Returns `true` if Code Scanning analysis is enabled, or `false` if not.
*/
export function isCodeScanningEnabled(config: Config): boolean {
export function isCodeScanningEnabled(
config: ActionConfig<"analysisKinds">,
): boolean {
return config.analysisKinds.includes(AnalysisKind.CodeScanning);
}
/**
* Returns `true` if Code Quality analysis is enabled, or `false` if not.
*/
export function isCodeQualityEnabled(config: Config): boolean {
export function isCodeQualityEnabled(
config: ActionConfig<"analysisKinds">,
): boolean {
return config.analysisKinds.includes(AnalysisKind.CodeQuality);
}
/**
* Returns `true` if Code Scanning Risk Assessment analysis is enabled, or `false` if not.
*/
export function isRiskAssessmentEnabled(config: Config): boolean {
export function isRiskAssessmentEnabled(
config: ActionConfig<"analysisKinds">,
): boolean {
return config.analysisKinds.includes(AnalysisKind.RiskAssessment);
}

View File

@@ -126,3 +126,38 @@ export interface Config {
*/
enableFileCoverageInformation: boolean;
}
/** Properties available in `Config`. */
export type ActionConfigProperties = keyof Config;
/**
* The CodeQL Action configuration state that is persisted
* between steps of the CodeQL Action in a CodeQL workflow.
*
* By default, this is equivalent to `Config`. By explicitly
* providing required property names for `T` this can be restricted
* to requiring only those. For example, in `ActionConfig<"codeQLCmd">`
* all properties except `codeqlCmd` are optional.
*/
export type ActionConfig<
T extends ActionConfigProperties = ActionConfigProperties,
> = Partial<Config> & Pick<Config, T>;
/** Helper function to check whether `config` has `key` to narrow the type of `config`. */
export function hasConfigKey<Key extends ActionConfigProperties>(
config: Partial<Config>,
key: Key,
): config is ActionConfig<Key> {
return config[key] !== undefined;
}
/** A minimal configuration that we can make available even when `init` aborts. */
export type AbortedInitConfig = ActionConfig<
| "version"
| "tempDir"
| "gitHubVersion"
| "debugMode"
| "languages"
| "analysisKinds"
| "codeQLCmd"
>;

View File

@@ -10,7 +10,7 @@ import { getOptionalInput, getTemporaryDirectory } from "./actions-util";
import { dbIsFinalized } from "./analyze";
import { scanArtifactsForTokens } from "./artifact-scanner";
import { type CodeQL } from "./codeql";
import { Config } from "./config-utils";
import type { ActionConfig } from "./config/action-config";
import { EnvVar, exportEnvVar } from "./environment";
import * as json from "./json";
import { Language } from "./languages";
@@ -89,7 +89,7 @@ export async function uploadCombinedSarifArtifacts(
* @return The path to that debug artifact, or undefined if an error occurs.
*/
function tryPrepareSarifDebugArtifact(
config: Config,
config: ActionConfig<"dbLocation">,
language: Language,
logger: Logger,
): string | undefined {
@@ -131,7 +131,7 @@ function tryPrepareSarifDebugArtifact(
*/
async function tryBundleDatabase(
codeql: CodeQL,
config: Config,
config: ActionConfig<"dbLocation">,
language: Language,
logger: Logger,
): Promise<string | undefined> {
@@ -157,6 +157,11 @@ async function tryBundleDatabase(
}
}
/** The minimal configuration needed for `tryUploadAllAvailableDebugArtifacts`. */
export type UploadDebugArtifactsConfig = ActionConfig<
"languages" | "gitHubVersion" | "dbLocation" | "debugArtifactName"
>;
/**
* Attempt to upload all available debug artifacts.
*
@@ -164,7 +169,7 @@ async function tryBundleDatabase(
*/
export async function tryUploadAllAvailableDebugArtifacts(
codeql: CodeQL,
config: Config,
config: UploadDebugArtifactsConfig,
logger: Logger,
) {
const filesToUpload: string[] = [];
@@ -353,7 +358,7 @@ export async function getArtifactUploaderClient(
* all files in the database folder and return the path.
*/
async function createPartialDatabaseBundle(
config: Config,
config: ActionConfig<"dbLocation">,
language: Language,
): Promise<string> {
const databasePath = getCodeQLDatabasePath(config, language);
@@ -394,7 +399,7 @@ async function createPartialDatabaseBundle(
*/
async function createDatabaseBundleCli(
codeql: CodeQL,
config: Config,
config: ActionConfig<"dbLocation">,
language: Language,
): Promise<string> {
const databaseBundlePath = await bundleDb(

View File

@@ -7,6 +7,11 @@ import * as actionsUtil from "./actions-util";
import { CodeScanning, RiskAssessment } from "./analyses";
import { getApiClient, getGitHubVersion } from "./api-client";
import { CodeQL, getCodeQL } from "./codeql";
import {
hasConfigKey,
type AbortedInitConfig,
type ActionConfig,
} from "./config/action-config";
import {
Config,
isCodeScanningEnabled,
@@ -16,6 +21,7 @@ import {
getArtifactSuffix,
getArtifactUploaderClient,
sanitizeArtifactName,
type UploadDebugArtifactsConfig,
} from "./debug-artifacts";
import * as dependencyCaching from "./dependency-caching";
import { EnvVar, ReadOnlyEnv } from "./environment";
@@ -86,6 +92,11 @@ interface FailedSarifInfo {
checkoutPath: string;
}
/** The minimal Action configuration required to prepare and upload a failed SARIF. */
export type FailedSarifConfig = ActionConfig<
"codeQLCmd" | "tempDir" | "analysisKinds" | "languages"
>;
/**
* Tries to prepare a SARIF file that contains information about a failed analysis.
*
@@ -94,7 +105,7 @@ interface FailedSarifInfo {
async function prepareFailedSarif(
logger: Logger,
features: FeatureEnablement,
config: Config,
config: FailedSarifConfig,
): Promise<Result<FailedSarifInfo, UploadFailedSarifResult>> {
if (!config.codeQLCmd) {
return new Failure({
@@ -160,7 +171,7 @@ async function prepareFailedSarif(
async function generateFailedSarif(
logger: Logger,
features: FeatureEnablement,
config: Config,
config: ActionConfig<"codeQLCmd" | "tempDir">,
category: string | undefined,
checkoutPath: string,
sarifFile?: string,
@@ -192,7 +203,7 @@ async function generateFailedSarif(
* category for the workflow.
*/
async function maybeUploadFailedSarif(
config: Config,
config: FailedSarifConfig,
repositoryNwo: RepositoryNwo,
features: FeatureEnablement,
logger: Logger,
@@ -227,7 +238,7 @@ async function maybeUploadFailedSarif(
/** Uploads a failed SARIF file as workflow artifact, if it can be generated. */
async function maybeUploadFailedSarifArtifact(
config: Config,
config: FailedSarifConfig,
features: FeatureEnablement,
logger: Logger,
): Promise<UploadFailedSarifResult> {
@@ -267,7 +278,7 @@ async function maybeUploadFailedSarifArtifact(
* @returns The results of uploading the SARIF file for the failure.
*/
export async function tryUploadSarifIfRunFailed(
config: Config,
config: FailedSarifConfig,
repositoryNwo: RepositoryNwo,
features: FeatureEnablement,
logger: Logger,
@@ -324,12 +335,12 @@ export async function tryUploadSarifIfRunFailed(
export async function uploadFailureInfo(
uploadAllAvailableDebugArtifacts: (
codeql: CodeQL,
config: Config,
config: UploadDebugArtifactsConfig,
logger: Logger,
) => Promise<void>,
printDebugLogs: (config: Config) => Promise<void>,
printDebugLogs: (logger: Logger, config: Partial<Config>) => Promise<void>,
codeql: CodeQL,
config: Config,
config: Config | AbortedInitConfig,
repositoryNwo: RepositoryNwo,
features: FeatureEnablement,
jobStatus: string | undefined,
@@ -376,15 +387,15 @@ export async function uploadFailureInfo(
}
// Upload appropriate Actions artifacts for debugging
if (config.debugMode) {
if (config.debugMode && hasConfigKey(config, "dbLocation")) {
logger.info(
"Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts...",
);
await uploadAllAvailableDebugArtifacts(codeql, config, logger);
await printDebugLogs(config);
await printDebugLogs(logger, config);
}
if (actionsUtil.isSelfHostedRunner()) {
if (actionsUtil.isSelfHostedRunner() && config.dbLocation) {
try {
fs.rmSync(config.dbLocation, {
recursive: true,
@@ -399,6 +410,10 @@ export async function uploadFailureInfo(
`Failed to clean up database cluster directory ${config.dbLocation}. Details: ${e}`,
);
}
} else if (config.dbLocation === undefined) {
logger.debug(
"Skipping cleanup of database cluster directory since the configuration does not include a database path.",
);
} else {
logger.debug(
"Skipping cleanup of database cluster directory since we are running on a GitHub-hosted " +
@@ -447,7 +462,7 @@ function isConclusiveJobStatus(jobStatus: string | undefined): boolean {
*/
async function recordOverlayStatus(
codeql: CodeQL,
config: Config,
config: Partial<Config>,
features: FeatureEnablement,
jobStatus: string | undefined,
env: ReadOnlyEnv,
@@ -459,6 +474,11 @@ async function recordOverlayStatus(
!(await features.getValue(Feature.OverlayAnalysisStatusSave))
) {
return;
} else if (config.languages === undefined) {
logger.debug(
"Not recording overlay status, because the configuration contains no 'languages'.",
);
return;
}
// Only record a failure when the job outcome tells us something about the analysis. A cancelled

View File

@@ -6,6 +6,7 @@
import * as core from "@actions/core";
import { runInActions, type Action, type ActionState } from "./action-common";
import {
restoreInputs,
getOptionalInput,
@@ -15,22 +16,25 @@ import {
import { getGitHubVersion, wrapApiConfigurationError } from "./api-client";
import { CachingKind } from "./caching-utils";
import { getCodeQL } from "./codeql";
import { type Config, getConfig } from "./config-utils";
import {
hasConfigKey,
type AbortedInitConfig,
type Config,
} from "./config/action-config";
import { getAbortedInitConfig, getConfig } from "./config-utils";
import * as debugArtifacts from "./debug-artifacts";
import {
DependencyCachingUsageReport,
getDependencyCacheUsage,
} from "./dependency-caching";
import { EnvVar, getEnv, exportEnvVar } from "./environment";
import { EnvVar, type ReadOnlyEnv } from "./environment";
import { initFeatures } from "./feature-flags";
import * as gitUtils from "./git-utils";
import * as initActionPostHelper from "./init-action-post-helper";
import { getActionsLogger } from "./logging";
import { getRepositoryNwo } from "./repository";
import {
StatusReportBase,
sendStatusReport,
sendUnhandledErrorStatusReport,
createStatusReportBase,
getActionsStatus,
ActionName,
@@ -45,16 +49,17 @@ interface InitPostStatusReport
initActionPostHelper.JobStatusReport,
initActionPostHelper.DependencyCachingUsageReport {}
async function run(startedAt: Date) {
async function run(action: ActionState<["Base", "Logger", "Env"]>) {
// To capture errors appropriately, keep as much code within the try-catch as
// possible, and only use safe functions outside.
const logger = action.logger;
const logger = getActionsLogger();
let config: Config | undefined;
let config: Config | AbortedInitConfig | undefined;
let uploadFailedSarifResult:
| initActionPostHelper.UploadFailedSarifResult
| undefined;
let dependencyCachingUsage: DependencyCachingUsageReport | undefined;
try {
// Read the job status before restoring inputs, since it is provided by the Actions runtime
// environment for this step and would otherwise be overwritten by the value that the `init`
@@ -64,7 +69,15 @@ async function run(startedAt: Date) {
// Restore inputs from `init` Action.
restoreInputs(logger);
config = await getConfig(getTemporaryDirectory(), logger);
const tmpDir = getTemporaryDirectory();
config = await getConfig(tmpDir, logger);
// If we weren't able to read the normal configuration file, the `init` step failed before it could write it.
// Try to load the "failed" configuration file instead which may have been written by the `init` step
// with a minimal configuration for this post-action.
if (config === undefined) {
config = getAbortedInitConfig(action, tmpDir);
}
const gitHubVersion = config?.gitHubVersion ?? (await getGitHubVersion());
checkGitHubVersionInRange(gitHubVersion, logger);
@@ -92,7 +105,7 @@ async function run(startedAt: Date) {
repositoryNwo,
features,
jobStatus,
getEnv(),
action.env,
logger,
);
@@ -102,6 +115,7 @@ async function run(startedAt: Date) {
// and where caching may not be enabled.
if (
(await gitUtils.isAnalyzingDefaultBranch()) &&
hasConfigKey(config, "dependencyCachingEnabled") &&
config.dependencyCachingEnabled !== CachingKind.None
) {
dependencyCachingUsage = await getDependencyCacheUsage(logger);
@@ -112,9 +126,9 @@ async function run(startedAt: Date) {
core.setFailed(error.message);
const statusReportBase = await createStatusReportBase(
ActionName.InitPost,
action.name,
getActionsStatus(error),
startedAt,
action.startedAt,
config,
await checkDiskUsage(logger),
logger,
@@ -126,13 +140,13 @@ async function run(startedAt: Date) {
}
return;
}
const jobStatus = getFinalJobStatus(config);
const jobStatus = getFinalJobStatus(action, config);
logger.info(`CodeQL job status was ${getJobStatusDisplayName(jobStatus)}.`);
const statusReportBase = await createStatusReportBase(
ActionName.InitPost,
action.name,
"success",
startedAt,
action.startedAt,
config,
await checkDiskUsage(logger),
logger,
@@ -157,16 +171,21 @@ async function run(startedAt: Date) {
* Otherwise, we determine the job status based on whether the analyze step
* completed successfully and whether we have a valid CodeQL config.
*/
function getFinalJobStatus(config: Config | undefined): JobStatus {
const existingJobStatus = getJobStatusFromEnvironment();
function getFinalJobStatus(
action: ActionState<["Env"]>,
config: Partial<Config> | undefined,
): JobStatus {
const existingJobStatus = getJobStatusFromEnvironment(action.env);
if (existingJobStatus !== undefined) {
return existingJobStatus;
}
let jobStatus: JobStatus;
if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] === "true") {
exportEnvVar(EnvVar.JOB_STATUS, JobStatus.SuccessStatus);
if (
action.env.getOptional(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY) === "true"
) {
action.env.export(EnvVar.JOB_STATUS, JobStatus.SuccessStatus);
jobStatus = JobStatus.SuccessStatus;
} else if (config !== undefined) {
// - We have computed a CodeQL config
@@ -191,7 +210,7 @@ function getFinalJobStatus(config: Config | undefined): JobStatus {
// This shouldn't be necessary, but in the odd case that we run more than one
// `init` post step, ensure the job status is consistent between them.
exportEnvVar(EnvVar.JOB_STATUS, jobStatus);
action.env.export(EnvVar.JOB_STATUS, jobStatus);
return jobStatus;
}
@@ -200,8 +219,8 @@ function getFinalJobStatus(config: Config | undefined): JobStatus {
*
* If the job status is invalid, return `UnknownStatus`.
*/
function getJobStatusFromEnvironment(): JobStatus | undefined {
const jobStatusFromEnvironment = process.env[EnvVar.JOB_STATUS];
function getJobStatusFromEnvironment(env: ReadOnlyEnv): JobStatus | undefined {
const jobStatusFromEnvironment = env.getOptional(EnvVar.JOB_STATUS);
if (jobStatusFromEnvironment !== undefined) {
// Validate the job status from the environment. If it is invalid, return unknown.
@@ -216,18 +235,11 @@ function getJobStatusFromEnvironment(): JobStatus | undefined {
return undefined;
}
const initPost: Action = {
name: ActionName.InitPost,
run,
};
export async function runWrapper() {
const startedAt = new Date();
const logger = getActionsLogger();
try {
await run(startedAt);
} catch (error) {
core.setFailed(`init post action failed: ${wrapError(error).message}`);
await sendUnhandledErrorStatusReport(
ActionName.InitPost,
startedAt,
error,
logger,
);
}
return await runInActions(initPost);
}

View File

@@ -457,6 +457,18 @@ async function run(
await checkInstallPython311(config.languages, codeql);
} catch (unwrappedError) {
// If we have initialised the Action state, then try to save a subset of it for use by the `init-post` action
// so that it can try to create and upload additional diagnostic information.
if (config !== undefined) {
try {
configUtils.saveAbortedInitConfig(actionState, config);
} catch (configSaveError) {
logger.warning(
`Unable to save configuration for '${ActionName.InitPost}' step: ${getErrorMessage(configSaveError)}`,
);
}
}
const error = wrapError(unwrappedError);
core.setFailed(error.message);
const statusReportBase = await createStatusReportBase(

View File

@@ -61,13 +61,21 @@ export enum ActionName {
UploadSarif = "upload-sarif",
}
/** A partial mapping from `ActionName` to names for actions whose display name is not the `ActionName` value. */
export const ACTION_DISPLAY_NAMES: Partial<Record<ActionName, string>> = {
[ActionName.Analyze]: "analyze",
[ActionName.InitPost]: "init post",
};
/**
* Maps an `ActionName` to its display name. Usually that is the same, except
* for `ActionName.Analyze` where it is `"analyze"` instead of `"finish"`.
* Maps an {@link ActionName} to its display name. Usually that is the same, except
* for actions which have a different display name in {@link ACTION_DISPLAY_NAMES}.
*/
export function getDisplayActionName(actionName: ActionName): string {
if (actionName === ActionName.Analyze) {
return "analyze";
const displayName = ACTION_DISPLAY_NAMES[actionName];
if (displayName !== undefined) {
return displayName;
}
return actionName;
}

View File

@@ -12,6 +12,7 @@ import * as semver from "semver";
import * as apiCompatibility from "./api-compatibility.json";
import type { CodeQL } from "./codeql";
import type { ActionConfig } from "./config/action-config";
import type { Pack } from "./config/db-config";
import type { Config } from "./config-utils";
import {
@@ -450,7 +451,10 @@ export function getThreadsFlag(
/**
* Get the path where the CodeQL database for the given language lives.
*/
export function getCodeQLDatabasePath(config: Config, language: Language) {
export function getCodeQLDatabasePath(
config: ActionConfig<"dbLocation">,
language: Language,
) {
return path.resolve(config.dbLocation, language);
}
@@ -644,7 +648,9 @@ export async function codeQlVersionAtLeast(
return semver.gte((await codeql.getVersion()).version, requiredVersion);
}
export function getBaseDatabaseOidsFilePath(config: Config): string {
export function getBaseDatabaseOidsFilePath(
config: ActionConfig<"dbLocation">,
): string {
return path.join(config.dbLocation, BASE_DATABASE_OIDS_FILE_NAME);
}
@@ -656,7 +662,7 @@ export function getBaseDatabaseOidsFilePath(config: Config): string {
* given `includeDiagnostics` value.
*/
export async function bundleDb(
config: Config,
config: ActionConfig<"dbLocation">,
language: Language,
codeql: CodeQL,
dbName: string,