diff --git a/CHANGELOG.md b/CHANGELOG.md index 7463862936..d016b4fedb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th ## [UNRELEASED] -No user facing changes. +- Added an experimental change which, when running a Code Scanning analysis for a PR with [improved incremental analysis](https://github.com/github/roadmap/issues/1158) enabled, prefers CodeQL CLI versions that have a cached overlay-base database for the configured languages. This speeds up analysis for a repository when there is not yet a cached overlay-base database for the latest CLI version. We expect to roll this change out to everyone in May. [#3880](https://github.com/github/codeql-action/pull/3880) ## 4.35.4 - 07 May 2026 diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index 0f1b660594..379439ac9c 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -26352,11 +26352,11 @@ var require_valid = __commonJS({ "node_modules/semver/functions/valid.js"(exports2, module2) { "use strict"; var parse2 = require_parse2(); - var valid3 = (version, options) => { + var valid4 = (version, options) => { const v = parse2(version, options); return v ? v.version : null; }; - module2.exports = valid3; + module2.exports = valid4; } }); @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare2 = require_compare(); - var rcompare = (a, b, loose) => compare2(b, a, loose); - module2.exports = rcompare; + var rcompare3 = (a, b, loose) => compare2(b, a, loose); + module2.exports = rcompare3; } }); @@ -27716,7 +27716,7 @@ var require_semver2 = __commonJS({ var SemVer = require_semver(); var identifiers = require_identifiers(); var parse2 = require_parse2(); - var valid3 = require_valid(); + var valid4 = require_valid(); var clean3 = require_clean(); var inc = require_inc(); var diff = require_diff(); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare2 = require_compare(); - var rcompare = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27754,7 +27754,7 @@ var require_semver2 = __commonJS({ var subset = require_subset(); module2.exports = { parse: parse2, - valid: valid3, + valid: valid4, clean: clean3, inc, diff, @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare2, - rcompare, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -29553,16 +29553,16 @@ var require_attribute = __commonJS({ var result = new ValidatorResult(instance, schema2, options, ctx); var self2 = this; schema2.allOf.forEach(function(v, i) { - var valid3 = self2.validateSchema(instance, v, options, ctx); - if (!valid3.valid) { + var valid4 = self2.validateSchema(instance, v, options, ctx); + if (!valid4.valid) { var id = v.$id || v.id; var msg = id || v.title && JSON.stringify(v.title) || v["$ref"] && "<" + v["$ref"] + ">" || "[subschema " + i + "]"; result.addError({ name: "allOf", - argument: { id: msg, length: valid3.errors.length, valid: valid3 }, - message: "does not match allOf schema " + msg + " with " + valid3.errors.length + " error[s]:" + argument: { id: msg, length: valid4.errors.length, valid: valid4 }, + message: "does not match allOf schema " + msg + " with " + valid4.errors.length + " error[s]:" }); - result.importErrors(valid3); + result.importErrors(valid4); } }); return result; @@ -29851,8 +29851,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMinimum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance > schema2.exclusiveMinimum; - if (!valid3) { + var valid4 = instance > schema2.exclusiveMinimum; + if (!valid4) { result.addError({ name: "exclusiveMinimum", argument: schema2.exclusiveMinimum, @@ -29865,8 +29865,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMaximum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance < schema2.exclusiveMaximum; - if (!valid3) { + var valid4 = instance < schema2.exclusiveMaximum; + if (!valid4) { result.addError({ name: "exclusiveMaximum", argument: schema2.exclusiveMaximum, @@ -32649,8 +32649,8 @@ var require_semver3 = __commonJS({ return null; } } - exports2.valid = valid3; - function valid3(version, options) { + exports2.valid = valid4; + function valid4(version, options) { var v = parse2(version, options); return v ? v.version : null; } @@ -32950,8 +32950,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare; - function rcompare(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare2(b, a, loose); } exports2.sort = sort; @@ -33779,7 +33779,7 @@ var require_cacheUtils = __commonJS({ var crypto2 = __importStar2(require("crypto")); var fs9 = __importStar2(require("fs")); var path9 = __importStar2(require("path")); - var semver9 = __importStar2(require_semver3()); + var semver10 = __importStar2(require_semver3()); var util = __importStar2(require("util")); var constants_1 = require_constants7(); var versionSalt = "1.0"; @@ -33872,7 +33872,7 @@ var require_cacheUtils = __commonJS({ function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver9.clean(versionOutput); + const version = semver10.clean(versionOutput); core15.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; @@ -75278,7 +75278,7 @@ var require_cacheHttpClient = __commonJS({ exports2.getCacheEntry = getCacheEntry; exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; - exports2.saveCache = saveCache4; + exports2.saveCache = saveCache5; var core15 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); @@ -75455,7 +75455,7 @@ Other caches with similar key:`); })); }); } - function saveCache4(cacheId, archivePath, signedUploadURL, options) { + function saveCache5(cacheId, archivePath, signedUploadURL, options) { return __awaiter2(this, void 0, void 0, function* () { const uploadOptions = (0, options_1.getUploadOptions)(options); if (uploadOptions.useAzureSdk) { @@ -80955,8 +80955,8 @@ var require_cache4 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; exports2.isFeatureAvailable = isFeatureAvailable; - exports2.restoreCache = restoreCache4; - exports2.saveCache = saveCache4; + exports2.restoreCache = restoreCache5; + exports2.saveCache = saveCache5; var core15 = __importStar2(require_core()); var path9 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); @@ -81013,7 +81013,7 @@ var require_cache4 = __commonJS({ return !!process.env["ACTIONS_CACHE_URL"]; } } - function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) { + function restoreCache5(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core15.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81157,7 +81157,7 @@ var require_cache4 = __commonJS({ return void 0; }); } - function saveCache4(paths_1, key_1, options_1) { + function saveCache5(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core15.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81394,7 +81394,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var core_1 = require_core(); var os2 = require("os"); var cp = require("child_process"); @@ -81408,7 +81408,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver9.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver10.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -81417,7 +81417,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver9.satisfies(osVersion, item.platform_version); + chk = semver10.satisfies(osVersion, item.platform_version); } } return chk; @@ -81677,7 +81677,7 @@ var require_tool_cache = __commonJS({ var os2 = __importStar2(require("os")); var path9 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var stream = __importStar2(require("stream")); var util = __importStar2(require("util")); var assert_1 = require("assert"); @@ -81950,7 +81950,7 @@ var require_tool_cache = __commonJS({ } function cacheDir(sourceDir, tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch = arch || os2.arch(); core15.debug(`Caching tool ${tool} ${version} ${arch}`); core15.debug(`source dir: ${sourceDir}`); @@ -81968,7 +81968,7 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch = arch || os2.arch(); core15.debug(`Caching tool ${tool} ${version} ${arch}`); core15.debug(`source file: ${sourceFile}`); @@ -81998,7 +81998,7 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver9.clean(versionSpec) || ""; + versionSpec = semver10.clean(versionSpec) || ""; const cachePath = path9.join(_getCacheDirectory(), toolName, versionSpec, arch); core15.debug(`checking cache: ${cachePath}`); if (fs9.existsSync(cachePath) && fs9.existsSync(`${cachePath}.complete`)) { @@ -82078,7 +82078,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path9.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch || ""); + const folderPath = path9.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch || ""); core15.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io6.rmRF(folderPath); @@ -82088,30 +82088,30 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch) { - const folderPath = path9.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch || ""); + const folderPath = path9.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch || ""); const markerPath = `${folderPath}.complete`; fs9.writeFileSync(markerPath, ""); core15.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver9.clean(versionSpec) || ""; + const c = semver10.clean(versionSpec) || ""; core15.debug(`isExplicit: ${c}`); - const valid3 = semver9.valid(c) != null; - core15.debug(`explicit? ${valid3}`); - return valid3; + const valid4 = semver10.valid(c) != null; + core15.debug(`explicit? ${valid4}`); + return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; core15.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver9.gt(a, b)) { + if (semver10.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver9.satisfies(potential, versionSpec); + const satisfied = semver10.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -89825,7 +89825,7 @@ var require_stream_writable = __commonJS({ pna.nextTick(cb, er); } function validChunk(stream, state, chunk, cb) { - var valid3 = true; + var valid4 = true; var er = false; if (chunk === null) { er = new TypeError("May not write null values to stream"); @@ -89835,9 +89835,9 @@ var require_stream_writable = __commonJS({ if (er) { stream.emit("error", er); pna.nextTick(cb, er); - valid3 = false; + valid4 = false; } - return valid3; + return valid4; } Writable.prototype.write = function(chunk, encoding, cb) { var state = this._writableState; @@ -127883,6 +127883,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -128044,20 +128054,26 @@ function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { // src/setup-codeql.ts var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); + +// src/overlay/caching.ts +var actionsCache3 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; // src/tar.ts var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); // src/tools-download.ts var core10 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; // src/tracer-config.ts @@ -128654,7 +128670,7 @@ var core12 = __toESM(require_core()); // src/dependency-caching.ts var import_path = require("path"); -var actionsCache3 = __toESM(require_cache4()); +var actionsCache4 = __toESM(require_cache4()); var glob = __toESM(require_glob()); function getJavaTempDependencyDir() { return (0, import_path.join)(getTemporaryDirectory(), "codeql_java", "repository"); diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 7b3ec243cb..446472b87c 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare3 = require_compare(); - var rcompare2 = (a, b, loose) => compare3(b, a, loose); - module2.exports = rcompare2; + var rcompare3 = (a, b, loose) => compare3(b, a, loose); + module2.exports = rcompare3; } }); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare3 = require_compare(); - var rcompare2 = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare3, - rcompare: rcompare2, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -32950,8 +32950,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare2; - function rcompare2(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare3(b, a, loose); } exports2.sort = sort; @@ -88952,6 +88952,32 @@ var persistInputs = function() { ); core4.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables)); }; +function getPullRequestBranches() { + const pullRequest = github.context.payload.pull_request; + if (pullRequest) { + return { + base: pullRequest.base.ref, + // We use the head label instead of the head ref here, because the head + // ref lacks owner information and by itself does not uniquely identify + // the head branch (which may be in a forked repository). + head: pullRequest.head.label + }; + } + const codeScanningRef = process.env.CODE_SCANNING_REF; + const codeScanningBaseBranch = process.env.CODE_SCANNING_BASE_BRANCH; + if (codeScanningRef && codeScanningBaseBranch) { + return { + base: codeScanningBaseBranch, + // PR analysis under Default Setup analyzes the PR head commit instead of + // the merge commit, so we can use the provided ref directly. + head: codeScanningRef + }; + } + return void 0; +} +function isAnalyzingPullRequest() { + return getPullRequestBranches() !== void 0; +} var qualityCategoryMapping = { "c#": "csharp", cpp: "c-cpp", @@ -89048,7 +89074,7 @@ var SarifScanOrder = [ ]; // src/analyze.ts -var fs13 = __toESM(require("fs")); +var fs14 = __toESM(require("fs")); var path12 = __toESM(require("path")); var import_perf_hooks2 = require("perf_hooks"); var io5 = __toESM(require_io()); @@ -89332,7 +89358,7 @@ function wrapApiConfigurationError(e) { } // src/codeql.ts -var fs12 = __toESM(require("fs")); +var fs13 = __toESM(require("fs")); var path11 = __toESM(require("path")); var core11 = __toESM(require_core()); var toolrunner3 = __toESM(require_toolrunner()); @@ -89729,6 +89755,16 @@ function writeDiagnostic(config, language, diagnostic) { logger.debug(JSON.stringify(diagnostic)); } } +function makeTelemetryDiagnostic(id, name, attributes) { + return makeDiagnostic(id, name, { + attributes, + visibility: { + cliSummaryTable: false, + statusPage: false, + telemetry: true + } + }); +} // src/diff-informed-analysis-utils.ts var fs6 = __toESM(require("fs")); @@ -90086,6 +90122,10 @@ function isSupportedToolsFeature(versionInfo, feature) { var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_"; var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled"; var CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0"; +var LINKED_CODEQL_VERSION = { + cliVersion, + tagName: bundleVersion +}; var featureConfig = { ["allow_toolcache_input" /* AllowToolcacheInput */]: { defaultValue: false, @@ -90240,6 +90280,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -90300,10 +90350,9 @@ var OfflineFeatures = class { this.logger = logger; } logger; - async getDefaultCliVersion(_variant) { + async getEnabledDefaultCliVersions(_variant) { return { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; } /** @@ -90408,11 +90457,11 @@ var Features = class extends OfflineFeatures { logger ); } - async getDefaultCliVersion(variant) { + async getEnabledDefaultCliVersions(variant) { if (supportsFeatureFlags(variant)) { - return await this.gitHubFeatureFlags.getDefaultCliVersionFromFlags(); + return await this.gitHubFeatureFlags.getEnabledDefaultCliVersionsFromFlags(); } - return super.getDefaultCliVersion(variant); + return super.getEnabledDefaultCliVersions(variant); } /** * @@ -90471,34 +90520,36 @@ var GitHubFeatureFlags = class { } return version; } - async getDefaultCliVersionFromFlags() { + /** + * Returns CLI versions enabled by `default_codeql_version_*_enabled` feature + * flags, sorted from highest to lowest. Falls back to the version pinned in + * `defaults.json` if no such flags are enabled. + */ + async getEnabledDefaultCliVersionsFromFlags() { const response = await this.getAllFeatures(); - const enabledFeatureFlagCliVersions = Object.entries(response).map( + const sortedCliVersions = Object.entries(response).map( ([f, isEnabled]) => isEnabled ? this.getCliVersionFromFeatureFlag(f) : void 0 - ).filter((f) => f !== void 0); - if (enabledFeatureFlagCliVersions.length === 0) { + ).filter((f) => f !== void 0).sort(semver5.rcompare); + if (sortedCliVersions.length === 0) { this.logger.warning( `Feature flags do not specify a default CLI version. Falling back to the CLI version shipped with the Action. This is ${cliVersion}.` ); const result = { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; if (this.hasAccessedRemoteFeatureFlags) { result.toolsFeatureFlagsValid = false; } return result; } - const maxCliVersion = enabledFeatureFlagCliVersions.reduce( - (maxVersion, currentVersion) => currentVersion > maxVersion ? currentVersion : maxVersion, - enabledFeatureFlagCliVersions[0] - ); this.logger.debug( - `Derived default CLI version of ${maxCliVersion} from feature flags.` + `Derived default CLI version of ${sortedCliVersions[0]} from feature flags.` ); return { - cliVersion: maxCliVersion, - tagName: `codeql-bundle-v${maxCliVersion}`, + enabledVersions: sortedCliVersions.map((cliVersion2) => ({ + cliVersion: cliVersion2, + tagName: `codeql-bundle-v${cliVersion2}` + })), toolsFeatureFlagsValid: true }; } @@ -90673,6 +90724,17 @@ var builtin_default = { // src/languages/index.ts var builtInLanguageSet = new Set(builtin_default.languages); +function isBuiltInLanguage(language) { + return builtInLanguageSet.has(language); +} +function parseBuiltInLanguage(language) { + language = language.trim().toLowerCase(); + language = builtin_default.aliases[language] ?? language; + if (isBuiltInLanguage(language)) { + return language; + } + return void 0; +} // src/overlay/status.ts var actionsCache = __toESM(require_cache4()); @@ -90885,11 +90947,11 @@ function getPrimaryAnalysisConfig(config) { } // src/setup-codeql.ts -var fs10 = __toESM(require("fs")); +var fs11 = __toESM(require("fs")); var path9 = __toESM(require("path")); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); // node_modules/uuid/dist-node/stringify.js var byteToHex = []; @@ -90935,14 +90997,204 @@ function _v4(options, buf, offset) { } var v4_default = v4; +// src/overlay/caching.ts +var fs8 = __toESM(require("fs")); +var actionsCache3 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; +var CACHE_VERSION2 = 1; +var CACHE_PREFIX = "codeql-overlay-base-database"; +var MAX_CACHE_OPERATION_MS2 = 6e5; +async function checkOverlayBaseDatabase(codeql, config, logger, warningPrefix) { + const baseDatabaseOidsFilePath = getBaseDatabaseOidsFilePath(config); + if (!fs8.existsSync(baseDatabaseOidsFilePath)) { + logger.warning( + `${warningPrefix}: ${baseDatabaseOidsFilePath} does not exist` + ); + return false; + } + for (const language of config.languages) { + const dbPath = getCodeQLDatabasePath(config, language); + try { + const resolveDatabaseOutput = await codeql.resolveDatabase(dbPath); + if (resolveDatabaseOutput === void 0 || !("overlayBaseSpecifier" in resolveDatabaseOutput)) { + logger.info(`${warningPrefix}: no overlayBaseSpecifier defined`); + return false; + } else { + logger.debug( + `Overlay base specifier for ${language} overlay-base database found: ${resolveDatabaseOutput.overlayBaseSpecifier}` + ); + } + } catch (e) { + logger.warning(`${warningPrefix}: failed to resolve database: ${e}`); + return false; + } + } + return true; +} +async function cleanupAndUploadOverlayBaseDatabaseToCache(codeql, config, logger) { + const overlayDatabaseMode = config.overlayDatabaseMode; + if (overlayDatabaseMode !== "overlay-base" /* OverlayBase */) { + logger.debug( + `Overlay database mode is ${overlayDatabaseMode}. Skip uploading overlay-base database to cache.` + ); + return false; + } + if (!config.useOverlayDatabaseCaching) { + logger.debug( + "Overlay database caching is disabled. Skip uploading overlay-base database to cache." + ); + return false; + } + if (isInTestMode()) { + logger.debug( + "In test mode. Skip uploading overlay-base database to cache." + ); + return false; + } + const databaseIsValid = await checkOverlayBaseDatabase( + codeql, + config, + logger, + "Abort uploading overlay-base database to cache" + ); + if (!databaseIsValid) { + return false; + } + await withGroupAsync("Cleaning up databases", async () => { + await codeql.databaseCleanupCluster(config, "overlay" /* Overlay */); + }); + const dbLocation = config.dbLocation; + const databaseSizeBytes = await tryGetFolderBytes(dbLocation, logger); + if (databaseSizeBytes === void 0) { + logger.warning( + "Failed to determine database size. Skip uploading overlay-base database to cache." + ); + return false; + } + if (databaseSizeBytes > OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES) { + const databaseSizeMB = Math.round(databaseSizeBytes / 1e6); + logger.warning( + `Database size (${databaseSizeMB} MB) exceeds maximum upload size (${OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB} MB). Skip uploading overlay-base database to cache.` + ); + return false; + } + const codeQlVersion = (await codeql.getVersion()).version; + const checkoutPath = getRequiredInput("checkout_path"); + const cacheSaveKey = await getCacheSaveKey( + config, + codeQlVersion, + checkoutPath, + logger + ); + logger.info( + `Uploading overlay-base database to Actions cache with key ${cacheSaveKey}` + ); + try { + const cacheId = await waitForResultWithTimeLimit( + MAX_CACHE_OPERATION_MS2, + actionsCache3.saveCache([dbLocation], cacheSaveKey), + () => { + } + ); + if (cacheId === void 0) { + logger.warning("Timed out while uploading overlay-base database"); + return false; + } + } catch (error3) { + logger.warning( + `Failed to upload overlay-base database to cache: ${error3 instanceof Error ? error3.message : String(error3)}` + ); + return false; + } + logger.info(`Successfully uploaded overlay-base database from ${dbLocation}`); + return true; +} +async function getCacheSaveKey(config, codeQlVersion, checkoutPath, logger) { + let runId = 1; + let attemptId = 1; + try { + runId = getWorkflowRunID(); + attemptId = getWorkflowRunAttempt(); + } catch (e) { + logger.warning( + `Failed to get workflow run ID or attempt ID. Reason: ${getErrorMessage(e)}` + ); + } + const sha = await getCommitOid(checkoutPath); + const restoreKeyPrefix = await getCacheRestoreKeyPrefix( + config, + codeQlVersion + ); + return `${restoreKeyPrefix}${sha}-${runId}-${attemptId}`; +} +async function getCacheRestoreKeyPrefix(config, codeQlVersion) { + return `${await getCacheKeyPrefixBase(config.languages)}${codeQlVersion}-`; +} +async function getCacheKeyPrefixBase(parsedLanguages) { + const languagesComponent = [...parsedLanguages].sort().join("_"); + const cacheKeyComponents = { + automationID: await getAutomationID() + // Add more components here as needed in the future + }; + const componentsHash = createCacheKeyHash(cacheKeyComponents); + return `${CACHE_PREFIX}-${CACHE_VERSION2}-${componentsHash}-${languagesComponent}-`; +} +async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger) { + const languages = rawLanguages.map(parseBuiltInLanguage); + if (languages.includes(void 0)) { + logger.warning( + "One or more provided languages are not recognized as built-in languages. Skipping searching for overlay-base databases in cache." + ); + return void 0; + } + const dedupedLanguages = [ + ...new Set(languages.filter((l) => l !== void 0)) + ]; + const cacheKeyPrefix = await getCacheKeyPrefixBase(dedupedLanguages); + logger.debug( + `Searching for overlay-base databases in Actions cache with prefix ${cacheKeyPrefix}` + ); + const caches = await listActionsCaches(cacheKeyPrefix); + if (caches.length === 0) { + logger.info("No overlay-base databases found in Actions cache."); + return []; + } + logger.info( + `Found ${caches.length} overlay-base ${caches.length === 1 ? "database" : "databases"} in the Actions cache.` + ); + const versionRegex = /^([\d.]+)-/; + const versionSet = /* @__PURE__ */ new Set(); + for (const cache of caches) { + if (!cache.key) continue; + const suffix = cache.key.substring(cacheKeyPrefix.length); + const match = suffix.match(versionRegex); + if (match && semver6.valid(match[1])) { + versionSet.add(match[1]); + } + } + if (versionSet.size === 0) { + logger.info( + "Could not parse any CodeQL versions from overlay-base database cache keys." + ); + return []; + } + const versions = [...versionSet].sort(semver6.rcompare); + logger.info( + `Found overlay databases for the following CodeQL versions in the Actions cache: ${versions.join(", ")}` + ); + return versions; +} + // src/tar.ts var import_child_process = require("child_process"); -var fs8 = __toESM(require("fs")); +var fs9 = __toESM(require("fs")); var stream = __toESM(require("stream")); var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); var MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3"; var MIN_REQUIRED_GNU_TAR_VERSION = "1.31"; async function getTarVersion() { @@ -90984,9 +91236,9 @@ async function isZstdAvailable(logger) { case "gnu": return { available: foundZstdBinary && // GNU tar only uses major and minor version numbers - semver6.gte( - semver6.coerce(version), - semver6.coerce(MIN_REQUIRED_GNU_TAR_VERSION) + semver7.gte( + semver7.coerce(version), + semver7.coerce(MIN_REQUIRED_GNU_TAR_VERSION) ), foundZstdBinary, version: tarVersion @@ -90995,7 +91247,7 @@ async function isZstdAvailable(logger) { return { available: foundZstdBinary && // Do a loose comparison since these version numbers don't contain // a patch version number. - semver6.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), + semver7.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), foundZstdBinary, version: tarVersion }; @@ -91010,7 +91262,7 @@ async function isZstdAvailable(logger) { } } async function extract(tarPath, dest, compressionMethod, tarVersion, logger) { - fs8.mkdirSync(dest, { recursive: true }); + fs9.mkdirSync(dest, { recursive: true }); switch (compressionMethod) { case "gzip": return await toolcache.extractTar(tarPath, dest); @@ -91094,7 +91346,7 @@ function inferCompressionMethod(tarPath) { } // src/tools-download.ts -var fs9 = __toESM(require("fs")); +var fs10 = __toESM(require("fs")); var os2 = __toESM(require("os")); var path8 = __toESM(require("path")); var import_perf_hooks = require("perf_hooks"); @@ -91102,7 +91354,7 @@ var core10 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; var TOOLCACHE_TOOL_NAME = "CodeQL"; function makeDownloadFirstToolsDownloadDurations(downloadDurationMs, extractionDurationMs) { @@ -91201,7 +91453,7 @@ async function downloadAndExtract(codeqlURL, compressionMethod, dest, authorizat }; } async function downloadAndExtractZstdWithStreaming(codeqlURL, dest, authorization, headers, tarVersion, logger) { - fs9.mkdirSync(dest, { recursive: true }); + fs10.mkdirSync(dest, { recursive: true }); const agent = new import_http_client.HttpClient().getAgent(codeqlURL); headers = Object.assign( { "User-Agent": "CodeQL Action" }, @@ -91232,13 +91484,13 @@ function getToolcacheDirectory(version) { return path8.join( getRequiredEnvParam("RUNNER_TOOL_CACHE"), TOOLCACHE_TOOL_NAME, - semver7.clean(version) || version, + semver8.clean(version) || version, os2.arch() || "" ); } function writeToolcacheMarkerFile(extractedPath, logger) { const markerFilePath = `${extractedPath}.complete`; - fs9.writeFileSync(markerFilePath, ""); + fs10.writeFileSync(markerFilePath, ""); logger.info(`Created toolcache marker file ${markerFilePath}`); } function sanitizeUrlForStatusReport(url2) { @@ -91357,13 +91609,13 @@ function tryGetTagNameFromUrl(url2, logger) { return match[1]; } function convertToSemVer(version, logger) { - if (!semver8.valid(version)) { + if (!semver9.valid(version)) { logger.debug( `Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.` ); version = `0.0.0-${version}`; } - const s = semver8.clean(version); + const s = semver9.clean(version); if (!s) { throw new Error(`Bundle version ${version} is not in SemVer format.`); } @@ -91373,7 +91625,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { const candidates = toolcache3.findAllVersions("CodeQL").filter(isGoodVersion).map((version) => ({ folder: toolcache3.find("CodeQL", version), version - })).filter(({ folder }) => fs10.existsSync(path9.join(folder, "pinned-version"))); + })).filter(({ folder }) => fs11.existsSync(path9.join(folder, "pinned-version"))); if (candidates.length === 1) { const candidate = candidates[0]; logger.debug( @@ -91395,7 +91647,84 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getEnabledVersionsWithOverlayBaseDatabases(defaultCliVersion, rawLanguages, features, logger) { + if (rawLanguages === void 0 || rawLanguages.length === 0) { + return []; + } + const isEnabled = await features.getValue( + "overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */ + ); + const isDryRun = !isEnabled && await features.getValue("overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */); + if (!isEnabled && !isDryRun) { + return []; + } + let cachedVersions; + try { + cachedVersions = await getCodeQlVersionsForOverlayBaseDatabases( + rawLanguages, + logger + ); + } catch (e) { + logger.warning( + `Could not list overlay-base databases in the Actions cache while choosing a default CodeQL CLI version, falling back to the highest enabled version. Details: ${getErrorMessage(e)}` + ); + return []; + } + if (cachedVersions === void 0 || cachedVersions.length === 0) { + return []; + } + const cachedVersionsSet = new Set(cachedVersions); + const overlayVersions = defaultCliVersion.enabledVersions.filter( + (v) => cachedVersionsSet.has(v.cliVersion) + ); + if (overlayVersions.length === 0) { + return []; + } + const isCachedVersionDifferent = overlayVersions[0].cliVersion !== defaultCliVersion.enabledVersions[0].cliVersion; + if (isCachedVersionDifferent) { + addNoLanguageDiagnostic( + void 0, + makeTelemetryDiagnostic( + "codeql-action/overlay-aware-default-codeql-version", + "Overlay-aware default CodeQL version selection", + { + cachedVersions, + enabledVersions: defaultCliVersion.enabledVersions.map( + (v) => v.cliVersion + ), + isDryRun, + overlayAwareVersion: overlayVersions[0].cliVersion + } + ) + ); + } + if (isDryRun) { + logger.debug( + `Overlay-aware default CodeQL version selection is running in dry-run mode. Would have used version ${overlayVersions[0].cliVersion}.` + ); + return []; + } + return overlayVersions; +} +async function resolveDefaultCliVersion(defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { + if (!useOverlayAwareDefaultCliVersion || !isAnalyzingPullRequest()) { + return defaultCliVersion.enabledVersions[0]; + } + const overlayVersions = await getEnabledVersionsWithOverlayBaseDatabases( + defaultCliVersion, + rawLanguages, + features, + logger + ); + if (overlayVersions.length > 0) { + logger.info( + `Using CodeQL version ${overlayVersions[0].cliVersion} since this is the highest enabled version that has a cached overlay-base database.` + ); + return overlayVersions[0]; + } + return defaultCliVersion.enabledVersions[0]; +} +async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -91489,21 +91818,35 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } } - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } } else if (toolsInput !== void 0) { tagName = tryGetTagNameFromUrl(toolsInput, logger); url2 = toolsInput; if (tagName) { const bundleVersion3 = tryGetBundleVersionFromTagName(tagName, logger); - if (bundleVersion3 && semver8.valid(bundleVersion3)) { + if (bundleVersion3 && semver9.valid(bundleVersion3)) { cliVersion2 = convertToSemVer(bundleVersion3, logger); } } } else { - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } const bundleVersion2 = tagName && tryGetBundleVersionFromTagName(tagName, logger); const humanReadableVersion = cliVersion2 ?? (bundleVersion2 && convertToSemVer(bundleVersion2, logger)) ?? tagName ?? url2 ?? "unknown"; @@ -91700,7 +92043,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -91710,6 +92053,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau const source = await getCodeQLSource( toolsInput, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, apiDetails, variant, zstdAvailability.available, @@ -91768,7 +92113,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau async function useZstdBundle(cliVersion2, tarSupportsZstd) { return ( // In testing, gzip performs better than zstd on Windows. - process.platform !== "win32" && tarSupportsZstd && semver8.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) + process.platform !== "win32" && tarSupportsZstd && semver9.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) ); } function getTempExtractionDir(tempDir) { @@ -91800,7 +92145,7 @@ async function getNightlyToolsUrl(logger) { } } function getLatestToolcacheVersion(logger) { - const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver8.compare(b, a)); + const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver9.compare(b, a)); logger.debug( `Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify( allVersions @@ -91820,7 +92165,7 @@ function isReservedToolsValue(tools) { } // src/tracer-config.ts -var fs11 = __toESM(require("fs")); +var fs12 = __toESM(require("fs")); var path10 = __toESM(require("path")); async function shouldEnableIndirectTracing(codeql, config) { if (config.buildMode === "none" /* None */) { @@ -91840,14 +92185,14 @@ async function endTracingForCluster(codeql, config, logger) { config.dbLocation, "temp/tracingEnvironment/end-tracing.json" ); - if (!fs11.existsSync(envVariablesFile)) { + if (!fs12.existsSync(envVariablesFile)) { throw new Error( `Environment file for ending tracing not found: ${envVariablesFile}` ); } try { const endTracingEnvVariables = JSON.parse( - fs11.readFileSync(envVariablesFile, "utf8") + fs12.readFileSync(envVariablesFile, "utf8") ); for (const [key, value] of Object.entries(endTracingEnvVariables)) { if (value !== null) { @@ -91870,7 +92215,7 @@ 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 EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -91884,6 +92229,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger ); @@ -91959,7 +92306,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { "tools", "tracing-config.lua" ); - return fs12.existsSync(tracingConfigPath); + return fs13.existsSync(tracingConfigPath); }, async isScannedLanguage(language) { return !await this.isTracedLanguage(language); @@ -92435,7 +92782,7 @@ async function writeCodeScanningConfigFile(config, logger) { logger.startGroup("Augmented user configuration file contents"); logger.info(dump(augmentedConfig)); logger.endGroup(); - fs12.writeFileSync(codeScanningConfigFile, dump(augmentedConfig)); + fs13.writeFileSync(codeScanningConfigFile, dump(augmentedConfig)); return codeScanningConfigFile; } var TRAP_CACHE_SIZE_MB = 1024; @@ -92527,7 +92874,7 @@ async function runAutobuild(config, language, logger) { // src/dependency-caching.ts var os3 = __toESM(require("os")); var import_path2 = require("path"); -var actionsCache3 = __toESM(require_cache4()); +var actionsCache4 = __toESM(require_cache4()); var glob = __toESM(require_glob()); var CODEQL_DEPENDENCY_CACHE_PREFIX = "codeql-dependencies"; var CODEQL_DEPENDENCY_CACHE_VERSION = 1; @@ -92665,7 +93012,7 @@ async function uploadDependencyCaches(codeql, features, config, logger) { ); try { const start = performance.now(); - await actionsCache3.saveCache( + await actionsCache4.saveCache( await cacheConfig.getDependencyPaths(codeql, features), key ); @@ -92677,7 +93024,7 @@ async function uploadDependencyCaches(codeql, features, config, logger) { upload_duration_ms }); } catch (error3) { - if (error3 instanceof actionsCache3.ReserveCacheError) { + if (error3 instanceof actionsCache4.ReserveCacheError) { logger.info( `Not uploading cache for ${language}, because ${key} is already in use.` ); @@ -92785,7 +93132,7 @@ function dbIsFinalized(config, language, logger) { const dbPath = getCodeQLDatabasePath(config, language); try { const dbInfo = load( - fs13.readFileSync(path12.resolve(dbPath, "codeql-database.yml"), "utf8") + fs14.readFileSync(path12.resolve(dbPath, "codeql-database.yml"), "utf8") ); return !("inProgress" in dbInfo); } catch { @@ -92870,8 +93217,8 @@ function writeDiffRangeDataExtensionPack(logger, ranges, checkoutPath) { ranges = [{ path: "", startLine: 0, endLine: 0 }]; } const diffRangeDir = path12.join(getTemporaryDirectory(), "pr-diff-range"); - fs13.mkdirSync(diffRangeDir, { recursive: true }); - fs13.writeFileSync( + fs14.mkdirSync(diffRangeDir, { recursive: true }); + fs14.writeFileSync( path12.join(diffRangeDir, "qlpack.yml"), ` name: codeql-action/pr-diff-range @@ -92888,7 +93235,7 @@ dataExtensions: checkoutPath ); const extensionFilePath = path12.join(diffRangeDir, "pr-diff-range.yml"); - fs13.writeFileSync(extensionFilePath, extensionContents); + fs14.writeFileSync(extensionFilePath, extensionContents); logger.debug( `Wrote pr-diff-range extension pack to ${extensionFilePath}: ${extensionContents}` @@ -93040,7 +93387,7 @@ async function runQueries(sarifFolder, memoryFlag, threadsFlag, diffRangePackDir } function getPerQueryAlertCounts(sarifPath) { const sarifObject = JSON.parse( - fs13.readFileSync(sarifPath, "utf8") + fs14.readFileSync(sarifPath, "utf8") ); const perQueryAlertCounts = {}; for (const sarifRun of sarifObject.runs) { @@ -93058,13 +93405,13 @@ async function runQueries(sarifFolder, memoryFlag, threadsFlag, diffRangePackDir } async function runFinalize(features, outputDir, threadsFlag, memoryFlag, codeql, config, logger) { try { - await fs13.promises.rm(outputDir, { force: true, recursive: true }); + await fs14.promises.rm(outputDir, { force: true, recursive: true }); } catch (error3) { if (error3?.code !== "ENOENT") { throw error3; } } - await fs13.promises.mkdir(outputDir, { recursive: true }); + await fs14.promises.mkdir(outputDir, { recursive: true }); const timings = await finalizeDatabaseCreation( codeql, features, @@ -93108,7 +93455,7 @@ async function warnIfGoInstalledAfterInit(config, logger) { } // src/database-upload.ts -var fs14 = __toESM(require("fs")); +var fs15 = __toESM(require("fs")); async function cleanupAndUploadDatabases(repositoryNwo, codeql, config, apiDetails, features, logger) { if (getRequiredInput("upload-database") !== "true") { logger.debug("Database upload disabled in workflow. Skipping upload."); @@ -93144,7 +93491,7 @@ async function cleanupAndUploadDatabases(repositoryNwo, codeql, config, apiDetai const bundledDb = await bundleDb(config, language, codeql, language, { includeDiagnostics: false }); - bundledDbSize = fs14.statSync(bundledDb).size; + bundledDbSize = fs15.statSync(bundledDb).size; const commitOid = await getCommitOid( getRequiredInput("checkout_path") ); @@ -93207,7 +93554,7 @@ async function uploadBundledDatabase(repositoryNwo, language, commitOid, bundled if (uploadsBaseUrl.endsWith("/")) { uploadsBaseUrl = uploadsBaseUrl.slice(0, -1); } - const bundledDbReadStream = fs14.createReadStream(bundledDb); + const bundledDbReadStream = fs15.createReadStream(bundledDb); try { const startTime = performance.now(); await client.request( @@ -93237,151 +93584,6 @@ async function uploadBundledDatabase(repositoryNwo, language, commitOid, bundled } } -// src/overlay/caching.ts -var fs15 = __toESM(require("fs")); -var actionsCache4 = __toESM(require_cache4()); -var semver9 = __toESM(require_semver2()); -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; -var CACHE_VERSION2 = 1; -var CACHE_PREFIX = "codeql-overlay-base-database"; -var MAX_CACHE_OPERATION_MS2 = 6e5; -async function checkOverlayBaseDatabase(codeql, config, logger, warningPrefix) { - const baseDatabaseOidsFilePath = getBaseDatabaseOidsFilePath(config); - if (!fs15.existsSync(baseDatabaseOidsFilePath)) { - logger.warning( - `${warningPrefix}: ${baseDatabaseOidsFilePath} does not exist` - ); - return false; - } - for (const language of config.languages) { - const dbPath = getCodeQLDatabasePath(config, language); - try { - const resolveDatabaseOutput = await codeql.resolveDatabase(dbPath); - if (resolveDatabaseOutput === void 0 || !("overlayBaseSpecifier" in resolveDatabaseOutput)) { - logger.info(`${warningPrefix}: no overlayBaseSpecifier defined`); - return false; - } else { - logger.debug( - `Overlay base specifier for ${language} overlay-base database found: ${resolveDatabaseOutput.overlayBaseSpecifier}` - ); - } - } catch (e) { - logger.warning(`${warningPrefix}: failed to resolve database: ${e}`); - return false; - } - } - return true; -} -async function cleanupAndUploadOverlayBaseDatabaseToCache(codeql, config, logger) { - const overlayDatabaseMode = config.overlayDatabaseMode; - if (overlayDatabaseMode !== "overlay-base" /* OverlayBase */) { - logger.debug( - `Overlay database mode is ${overlayDatabaseMode}. Skip uploading overlay-base database to cache.` - ); - return false; - } - if (!config.useOverlayDatabaseCaching) { - logger.debug( - "Overlay database caching is disabled. Skip uploading overlay-base database to cache." - ); - return false; - } - if (isInTestMode()) { - logger.debug( - "In test mode. Skip uploading overlay-base database to cache." - ); - return false; - } - const databaseIsValid = await checkOverlayBaseDatabase( - codeql, - config, - logger, - "Abort uploading overlay-base database to cache" - ); - if (!databaseIsValid) { - return false; - } - await withGroupAsync("Cleaning up databases", async () => { - await codeql.databaseCleanupCluster(config, "overlay" /* Overlay */); - }); - const dbLocation = config.dbLocation; - const databaseSizeBytes = await tryGetFolderBytes(dbLocation, logger); - if (databaseSizeBytes === void 0) { - logger.warning( - "Failed to determine database size. Skip uploading overlay-base database to cache." - ); - return false; - } - if (databaseSizeBytes > OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES) { - const databaseSizeMB = Math.round(databaseSizeBytes / 1e6); - logger.warning( - `Database size (${databaseSizeMB} MB) exceeds maximum upload size (${OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB} MB). Skip uploading overlay-base database to cache.` - ); - return false; - } - const codeQlVersion = (await codeql.getVersion()).version; - const checkoutPath = getRequiredInput("checkout_path"); - const cacheSaveKey = await getCacheSaveKey( - config, - codeQlVersion, - checkoutPath, - logger - ); - logger.info( - `Uploading overlay-base database to Actions cache with key ${cacheSaveKey}` - ); - try { - const cacheId = await waitForResultWithTimeLimit( - MAX_CACHE_OPERATION_MS2, - actionsCache4.saveCache([dbLocation], cacheSaveKey), - () => { - } - ); - if (cacheId === void 0) { - logger.warning("Timed out while uploading overlay-base database"); - return false; - } - } catch (error3) { - logger.warning( - `Failed to upload overlay-base database to cache: ${error3 instanceof Error ? error3.message : String(error3)}` - ); - return false; - } - logger.info(`Successfully uploaded overlay-base database from ${dbLocation}`); - return true; -} -async function getCacheSaveKey(config, codeQlVersion, checkoutPath, logger) { - let runId = 1; - let attemptId = 1; - try { - runId = getWorkflowRunID(); - attemptId = getWorkflowRunAttempt(); - } catch (e) { - logger.warning( - `Failed to get workflow run ID or attempt ID. Reason: ${getErrorMessage(e)}` - ); - } - const sha = await getCommitOid(checkoutPath); - const restoreKeyPrefix = await getCacheRestoreKeyPrefix( - config, - codeQlVersion - ); - return `${restoreKeyPrefix}${sha}-${runId}-${attemptId}`; -} -async function getCacheRestoreKeyPrefix(config, codeQlVersion) { - return `${await getCacheKeyPrefixBase(config.languages)}${codeQlVersion}-`; -} -async function getCacheKeyPrefixBase(parsedLanguages) { - const languagesComponent = [...parsedLanguages].sort().join("_"); - const cacheKeyComponents = { - automationID: await getAutomationID() - // Add more components here as needed in the future - }; - const componentsHash = createCacheKeyHash(cacheKeyComponents); - return `${CACHE_PREFIX}-${CACHE_VERSION2}-${componentsHash}-${languagesComponent}-`; -} - // src/status-report.ts var os4 = __toESM(require("os")); var core13 = __toESM(require_core()); @@ -94724,7 +94926,7 @@ var core14 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io6 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -94738,6 +94940,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger, true @@ -94886,9 +95090,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo url: getRequiredEnvParam("GITHUB_SERVER_URL"), apiURL: getRequiredEnvParam("GITHUB_API_URL") }; - const codeQLDefaultVersionInfo = await features.getDefaultCliVersion( - gitHubVersion.type - ); + const codeQLDefaultVersionInfo = await features.getEnabledDefaultCliVersions(gitHubVersion.type); const initCodeQLResult = await initCodeQL( void 0, // There is no tools input on the upload action @@ -94896,6 +95098,10 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo tempDir, gitHubVersion.type, codeQLDefaultVersionInfo, + void 0, + // rawLanguages: upload-lib does not run analysis + false, + // useOverlayAwareDefaultCliVersion: upload-lib does not run analysis features, logger ); diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index be61bdeabf..e03e79d14e 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -26352,11 +26352,11 @@ var require_valid = __commonJS({ "node_modules/semver/functions/valid.js"(exports2, module2) { "use strict"; var parse2 = require_parse2(); - var valid3 = (version, options) => { + var valid4 = (version, options) => { const v = parse2(version, options); return v ? v.version : null; }; - module2.exports = valid3; + module2.exports = valid4; } }); @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare2 = require_compare(); - var rcompare = (a, b, loose) => compare2(b, a, loose); - module2.exports = rcompare; + var rcompare3 = (a, b, loose) => compare2(b, a, loose); + module2.exports = rcompare3; } }); @@ -27716,7 +27716,7 @@ var require_semver2 = __commonJS({ var SemVer = require_semver(); var identifiers = require_identifiers(); var parse2 = require_parse2(); - var valid3 = require_valid(); + var valid4 = require_valid(); var clean3 = require_clean(); var inc = require_inc(); var diff = require_diff(); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare2 = require_compare(); - var rcompare = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27754,7 +27754,7 @@ var require_semver2 = __commonJS({ var subset = require_subset(); module2.exports = { parse: parse2, - valid: valid3, + valid: valid4, clean: clean3, inc, diff, @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare2, - rcompare, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -29553,16 +29553,16 @@ var require_attribute = __commonJS({ var result = new ValidatorResult(instance, schema2, options, ctx); var self2 = this; schema2.allOf.forEach(function(v, i) { - var valid3 = self2.validateSchema(instance, v, options, ctx); - if (!valid3.valid) { + var valid4 = self2.validateSchema(instance, v, options, ctx); + if (!valid4.valid) { var id = v.$id || v.id; var msg = id || v.title && JSON.stringify(v.title) || v["$ref"] && "<" + v["$ref"] + ">" || "[subschema " + i + "]"; result.addError({ name: "allOf", - argument: { id: msg, length: valid3.errors.length, valid: valid3 }, - message: "does not match allOf schema " + msg + " with " + valid3.errors.length + " error[s]:" + argument: { id: msg, length: valid4.errors.length, valid: valid4 }, + message: "does not match allOf schema " + msg + " with " + valid4.errors.length + " error[s]:" }); - result.importErrors(valid3); + result.importErrors(valid4); } }); return result; @@ -29851,8 +29851,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMinimum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance > schema2.exclusiveMinimum; - if (!valid3) { + var valid4 = instance > schema2.exclusiveMinimum; + if (!valid4) { result.addError({ name: "exclusiveMinimum", argument: schema2.exclusiveMinimum, @@ -29865,8 +29865,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMaximum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance < schema2.exclusiveMaximum; - if (!valid3) { + var valid4 = instance < schema2.exclusiveMaximum; + if (!valid4) { result.addError({ name: "exclusiveMaximum", argument: schema2.exclusiveMaximum, @@ -32649,8 +32649,8 @@ var require_semver3 = __commonJS({ return null; } } - exports2.valid = valid3; - function valid3(version, options) { + exports2.valid = valid4; + function valid4(version, options) { var v = parse2(version, options); return v ? v.version : null; } @@ -32950,8 +32950,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare; - function rcompare(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare2(b, a, loose); } exports2.sort = sort; @@ -33779,7 +33779,7 @@ var require_cacheUtils = __commonJS({ var crypto2 = __importStar2(require("crypto")); var fs8 = __importStar2(require("fs")); var path9 = __importStar2(require("path")); - var semver9 = __importStar2(require_semver3()); + var semver10 = __importStar2(require_semver3()); var util = __importStar2(require("util")); var constants_1 = require_constants7(); var versionSalt = "1.0"; @@ -33872,7 +33872,7 @@ var require_cacheUtils = __commonJS({ function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver9.clean(versionOutput); + const version = semver10.clean(versionOutput); core15.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; @@ -75278,7 +75278,7 @@ var require_cacheHttpClient = __commonJS({ exports2.getCacheEntry = getCacheEntry; exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; - exports2.saveCache = saveCache3; + exports2.saveCache = saveCache4; var core15 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); @@ -75455,7 +75455,7 @@ Other caches with similar key:`); })); }); } - function saveCache3(cacheId, archivePath, signedUploadURL, options) { + function saveCache4(cacheId, archivePath, signedUploadURL, options) { return __awaiter2(this, void 0, void 0, function* () { const uploadOptions = (0, options_1.getUploadOptions)(options); if (uploadOptions.useAzureSdk) { @@ -80955,8 +80955,8 @@ var require_cache4 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; exports2.isFeatureAvailable = isFeatureAvailable; - exports2.restoreCache = restoreCache3; - exports2.saveCache = saveCache3; + exports2.restoreCache = restoreCache4; + exports2.saveCache = saveCache4; var core15 = __importStar2(require_core()); var path9 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); @@ -81013,7 +81013,7 @@ var require_cache4 = __commonJS({ return !!process.env["ACTIONS_CACHE_URL"]; } } - function restoreCache3(paths_1, primaryKey_1, restoreKeys_1, options_1) { + function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core15.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81157,7 +81157,7 @@ var require_cache4 = __commonJS({ return void 0; }); } - function saveCache3(paths_1, key_1, options_1) { + function saveCache4(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core15.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81394,7 +81394,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var core_1 = require_core(); var os2 = require("os"); var cp = require("child_process"); @@ -81408,7 +81408,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver9.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver10.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -81417,7 +81417,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver9.satisfies(osVersion, item.platform_version); + chk = semver10.satisfies(osVersion, item.platform_version); } } return chk; @@ -81677,7 +81677,7 @@ var require_tool_cache = __commonJS({ var os2 = __importStar2(require("os")); var path9 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var stream = __importStar2(require("stream")); var util = __importStar2(require("util")); var assert_1 = require("assert"); @@ -81950,7 +81950,7 @@ var require_tool_cache = __commonJS({ } function cacheDir(sourceDir, tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch = arch || os2.arch(); core15.debug(`Caching tool ${tool} ${version} ${arch}`); core15.debug(`source dir: ${sourceDir}`); @@ -81968,7 +81968,7 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch = arch || os2.arch(); core15.debug(`Caching tool ${tool} ${version} ${arch}`); core15.debug(`source file: ${sourceFile}`); @@ -81998,7 +81998,7 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver9.clean(versionSpec) || ""; + versionSpec = semver10.clean(versionSpec) || ""; const cachePath = path9.join(_getCacheDirectory(), toolName, versionSpec, arch); core15.debug(`checking cache: ${cachePath}`); if (fs8.existsSync(cachePath) && fs8.existsSync(`${cachePath}.complete`)) { @@ -82078,7 +82078,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path9.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch || ""); + const folderPath = path9.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch || ""); core15.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io5.rmRF(folderPath); @@ -82088,30 +82088,30 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch) { - const folderPath = path9.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch || ""); + const folderPath = path9.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch || ""); const markerPath = `${folderPath}.complete`; fs8.writeFileSync(markerPath, ""); core15.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver9.clean(versionSpec) || ""; + const c = semver10.clean(versionSpec) || ""; core15.debug(`isExplicit: ${c}`); - const valid3 = semver9.valid(c) != null; - core15.debug(`explicit? ${valid3}`); - return valid3; + const valid4 = semver10.valid(c) != null; + core15.debug(`explicit? ${valid4}`); + return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; core15.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver9.gt(a, b)) { + if (semver10.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver9.satisfies(potential, versionSpec); + const satisfied = semver10.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -86538,6 +86538,10 @@ function isSupportedToolsFeature(versionInfo, feature) { // src/feature-flags.ts var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_"; var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled"; +var LINKED_CODEQL_VERSION = { + cliVersion, + tagName: bundleVersion +}; var featureConfig = { ["allow_toolcache_input" /* AllowToolcacheInput */]: { defaultValue: false, @@ -86692,6 +86696,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -86752,10 +86766,9 @@ var OfflineFeatures = class { this.logger = logger; } logger; - async getDefaultCliVersion(_variant) { + async getEnabledDefaultCliVersions(_variant) { return { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; } /** @@ -86860,11 +86873,11 @@ var Features = class extends OfflineFeatures { logger ); } - async getDefaultCliVersion(variant) { + async getEnabledDefaultCliVersions(variant) { if (supportsFeatureFlags(variant)) { - return await this.gitHubFeatureFlags.getDefaultCliVersionFromFlags(); + return await this.gitHubFeatureFlags.getEnabledDefaultCliVersionsFromFlags(); } - return super.getDefaultCliVersion(variant); + return super.getEnabledDefaultCliVersions(variant); } /** * @@ -86923,34 +86936,36 @@ var GitHubFeatureFlags = class { } return version; } - async getDefaultCliVersionFromFlags() { + /** + * Returns CLI versions enabled by `default_codeql_version_*_enabled` feature + * flags, sorted from highest to lowest. Falls back to the version pinned in + * `defaults.json` if no such flags are enabled. + */ + async getEnabledDefaultCliVersionsFromFlags() { const response = await this.getAllFeatures(); - const enabledFeatureFlagCliVersions = Object.entries(response).map( + const sortedCliVersions = Object.entries(response).map( ([f, isEnabled]) => isEnabled ? this.getCliVersionFromFeatureFlag(f) : void 0 - ).filter((f) => f !== void 0); - if (enabledFeatureFlagCliVersions.length === 0) { + ).filter((f) => f !== void 0).sort(semver5.rcompare); + if (sortedCliVersions.length === 0) { this.logger.warning( `Feature flags do not specify a default CLI version. Falling back to the CLI version shipped with the Action. This is ${cliVersion}.` ); const result = { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; if (this.hasAccessedRemoteFeatureFlags) { result.toolsFeatureFlagsValid = false; } return result; } - const maxCliVersion = enabledFeatureFlagCliVersions.reduce( - (maxVersion, currentVersion) => currentVersion > maxVersion ? currentVersion : maxVersion, - enabledFeatureFlagCliVersions[0] - ); this.logger.debug( - `Derived default CLI version of ${maxCliVersion} from feature flags.` + `Derived default CLI version of ${sortedCliVersions[0]} from feature flags.` ); return { - cliVersion: maxCliVersion, - tagName: `codeql-bundle-v${maxCliVersion}`, + enabledVersions: sortedCliVersions.map((cliVersion2) => ({ + cliVersion: cliVersion2, + tagName: `codeql-bundle-v${cliVersion2}` + })), toolsFeatureFlagsValid: true }; } @@ -87180,20 +87195,26 @@ function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { // src/setup-codeql.ts var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); + +// src/overlay/caching.ts +var actionsCache3 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; // src/tar.ts var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); // src/tools-download.ts var core10 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; // src/tracer-config.ts diff --git a/lib/init-action-post.js b/lib/init-action-post.js index b972b1ece8..8e12e0ec6e 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -203,7 +203,7 @@ var require_file_command = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.issueFileCommand = issueFileCommand; exports2.prepareKeyValueMessage = prepareKeyValueMessage; - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs21 = __importStar2(require("fs")); var os4 = __importStar2(require("os")); var utils_1 = require_utils(); @@ -220,7 +220,7 @@ var require_file_command = __commonJS({ }); } function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${crypto2.randomUUID()}`; + const delimiter = `ghadelimiter_${crypto3.randomUUID()}`; const convertedValue = (0, utils_1.toCommandValue)(value); if (key.includes(delimiter)) { throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); @@ -4287,11 +4287,11 @@ var require_util2 = __commonJS({ var { isUint8Array } = require("node:util/types"); var { webidl } = require_webidl(); var supportedHashes = []; - var crypto2; + var crypto3; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); const possibleRelevantHashes = ["sha256", "sha384", "sha512"]; - supportedHashes = crypto2.getHashes().filter((hash2) => possibleRelevantHashes.includes(hash2)); + supportedHashes = crypto3.getHashes().filter((hash2) => possibleRelevantHashes.includes(hash2)); } catch { } function responseURL(response) { @@ -4564,7 +4564,7 @@ var require_util2 = __commonJS({ } } function bytesMatch(bytes, metadataList) { - if (crypto2 === void 0) { + if (crypto3 === void 0) { return true; } const parsedMetadata = parseMetadata(metadataList); @@ -4579,7 +4579,7 @@ var require_util2 = __commonJS({ for (const item of metadata) { const algorithm = item.algo; const expectedValue = item.hash; - let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64"); + let actualValue = crypto3.createHash(algorithm).update(bytes).digest("base64"); if (actualValue[actualValue.length - 1] === "=") { if (actualValue[actualValue.length - 2] === "=") { actualValue = actualValue.slice(0, -2); @@ -5643,8 +5643,8 @@ var require_body = __commonJS({ var { multipartFormDataParser } = require_formdata_parser(); var random; try { - const crypto2 = require("node:crypto"); - random = (max) => crypto2.randomInt(0, max); + const crypto3 = require("node:crypto"); + random = (max) => crypto3.randomInt(0, max); } catch { random = (max) => Math.floor(Math.random(max)); } @@ -17052,13 +17052,13 @@ var require_frame = __commonJS({ "use strict"; var { maxUnsigned16Bit } = require_constants5(); var BUFFER_SIZE = 16386; - var crypto2; + var crypto3; var buffer = null; var bufIdx = BUFFER_SIZE; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); } catch { - crypto2 = { + crypto3 = { // not full compatibility, but minimum. randomFillSync: function randomFillSync(buffer2, _offset, _size) { for (let i = 0; i < buffer2.length; ++i) { @@ -17071,7 +17071,7 @@ var require_frame = __commonJS({ function generateMask() { if (bufIdx === BUFFER_SIZE) { bufIdx = 0; - crypto2.randomFillSync(buffer ??= Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE); + crypto3.randomFillSync(buffer ??= Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE); } return [buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++]]; } @@ -17143,9 +17143,9 @@ var require_connection = __commonJS({ var { Headers, getHeadersList } = require_headers(); var { getDecodeSplit } = require_util2(); var { WebsocketFrameSend } = require_frame(); - var crypto2; + var crypto3; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); } catch { } function establishWebSocketConnection(url2, protocols, client, ws, onEstablish, options) { @@ -17165,7 +17165,7 @@ var require_connection = __commonJS({ const headersList = getHeadersList(new Headers(options.headers)); request2.headersList = headersList; } - const keyValue = crypto2.randomBytes(16).toString("base64"); + const keyValue = crypto3.randomBytes(16).toString("base64"); request2.headersList.append("sec-websocket-key", keyValue); request2.headersList.append("sec-websocket-version", "13"); for (const protocol of protocols) { @@ -17195,7 +17195,7 @@ var require_connection = __commonJS({ return; } const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); - const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64"); + const digest = crypto3.createHash("sha1").update(keyValue + uid).digest("base64"); if (secWSAccept !== digest) { failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header."); return; @@ -26352,11 +26352,11 @@ var require_valid = __commonJS({ "node_modules/semver/functions/valid.js"(exports2, module2) { "use strict"; var parse2 = require_parse2(); - var valid3 = (version, options) => { + var valid4 = (version, options) => { const v = parse2(version, options); return v ? v.version : null; }; - module2.exports = valid3; + module2.exports = valid4; } }); @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare3 = require_compare(); - var rcompare = (a, b, loose) => compare3(b, a, loose); - module2.exports = rcompare; + var rcompare3 = (a, b, loose) => compare3(b, a, loose); + module2.exports = rcompare3; } }); @@ -27716,7 +27716,7 @@ var require_semver2 = __commonJS({ var SemVer = require_semver(); var identifiers = require_identifiers(); var parse2 = require_parse2(); - var valid3 = require_valid(); + var valid4 = require_valid(); var clean3 = require_clean(); var inc = require_inc(); var diff = require_diff(); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare3 = require_compare(); - var rcompare = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27754,7 +27754,7 @@ var require_semver2 = __commonJS({ var subset = require_subset(); module2.exports = { parse: parse2, - valid: valid3, + valid: valid4, clean: clean3, inc, diff, @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare3, - rcompare, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -29553,16 +29553,16 @@ var require_attribute = __commonJS({ var result = new ValidatorResult(instance, schema2, options, ctx); var self2 = this; schema2.allOf.forEach(function(v, i) { - var valid3 = self2.validateSchema(instance, v, options, ctx); - if (!valid3.valid) { + var valid4 = self2.validateSchema(instance, v, options, ctx); + if (!valid4.valid) { var id = v.$id || v.id; var msg = id || v.title && JSON.stringify(v.title) || v["$ref"] && "<" + v["$ref"] + ">" || "[subschema " + i + "]"; result.addError({ name: "allOf", - argument: { id: msg, length: valid3.errors.length, valid: valid3 }, - message: "does not match allOf schema " + msg + " with " + valid3.errors.length + " error[s]:" + argument: { id: msg, length: valid4.errors.length, valid: valid4 }, + message: "does not match allOf schema " + msg + " with " + valid4.errors.length + " error[s]:" }); - result.importErrors(valid3); + result.importErrors(valid4); } }); return result; @@ -29851,8 +29851,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMinimum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance > schema2.exclusiveMinimum; - if (!valid3) { + var valid4 = instance > schema2.exclusiveMinimum; + if (!valid4) { result.addError({ name: "exclusiveMinimum", argument: schema2.exclusiveMinimum, @@ -29865,8 +29865,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMaximum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance < schema2.exclusiveMaximum; - if (!valid3) { + var valid4 = instance < schema2.exclusiveMaximum; + if (!valid4) { result.addError({ name: "exclusiveMaximum", argument: schema2.exclusiveMaximum, @@ -32371,7 +32371,7 @@ var require_internal_hash_files = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.hashFiles = hashFiles2; - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var core19 = __importStar2(require_core()); var fs21 = __importStar2(require("fs")); var stream2 = __importStar2(require("stream")); @@ -32384,7 +32384,7 @@ var require_internal_hash_files = __commonJS({ const writeDelegate = verbose ? core19.info : core19.debug; let hasMatch = false; const githubWorkspace = currentWorkspace ? currentWorkspace : (_d = process.env["GITHUB_WORKSPACE"]) !== null && _d !== void 0 ? _d : process.cwd(); - const result = crypto2.createHash("sha256"); + const result = crypto3.createHash("sha256"); let count = 0; try { for (var _e = true, _f = __asyncValues2(globber.globGenerator()), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) { @@ -32400,7 +32400,7 @@ var require_internal_hash_files = __commonJS({ writeDelegate(`Skip directory '${file}'.`); continue; } - const hash2 = crypto2.createHash("sha256"); + const hash2 = crypto3.createHash("sha256"); const pipeline = util.promisify(stream2.pipeline); yield pipeline(fs21.createReadStream(file), hash2); result.write(hash2.digest()); @@ -32649,8 +32649,8 @@ var require_semver3 = __commonJS({ return null; } } - exports2.valid = valid3; - function valid3(version, options) { + exports2.valid = valid4; + function valid4(version, options) { var v = parse2(version, options); return v ? v.version : null; } @@ -32950,8 +32950,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare; - function rcompare(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare3(b, a, loose); } exports2.sort = sort; @@ -33776,10 +33776,10 @@ var require_cacheUtils = __commonJS({ var exec3 = __importStar2(require_exec()); var glob2 = __importStar2(require_glob()); var io7 = __importStar2(require_io()); - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs21 = __importStar2(require("fs")); var path19 = __importStar2(require("path")); - var semver9 = __importStar2(require_semver3()); + var semver10 = __importStar2(require_semver3()); var util = __importStar2(require("util")); var constants_1 = require_constants7(); var versionSalt = "1.0"; @@ -33800,7 +33800,7 @@ var require_cacheUtils = __commonJS({ } tempDirectory = path19.join(baseLocation, "actions", "temp"); } - const dest = path19.join(tempDirectory, crypto2.randomUUID()); + const dest = path19.join(tempDirectory, crypto3.randomUUID()); yield io7.mkdirP(dest); return dest; }); @@ -33872,7 +33872,7 @@ var require_cacheUtils = __commonJS({ function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver9.clean(versionOutput); + const version = semver10.clean(versionOutput); core19.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; @@ -33908,7 +33908,7 @@ var require_cacheUtils = __commonJS({ components.push("windows-only"); } components.push(versionSalt); - return crypto2.createHash("sha256").update(components.join("|")).digest("hex"); + return crypto3.createHash("sha256").update(components.join("|")).digest("hex"); } function getRuntimeToken() { const token = process.env["ACTIONS_RUNTIME_TOKEN"]; @@ -75278,7 +75278,7 @@ var require_cacheHttpClient = __commonJS({ exports2.getCacheEntry = getCacheEntry; exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; - exports2.saveCache = saveCache4; + exports2.saveCache = saveCache5; var core19 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); @@ -75455,7 +75455,7 @@ Other caches with similar key:`); })); }); } - function saveCache4(cacheId, archivePath, signedUploadURL, options) { + function saveCache5(cacheId, archivePath, signedUploadURL, options) { return __awaiter2(this, void 0, void 0, function* () { const uploadOptions = (0, options_1.getUploadOptions)(options); if (uploadOptions.useAzureSdk) { @@ -80955,8 +80955,8 @@ var require_cache4 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; exports2.isFeatureAvailable = isFeatureAvailable; - exports2.restoreCache = restoreCache4; - exports2.saveCache = saveCache4; + exports2.restoreCache = restoreCache5; + exports2.saveCache = saveCache5; var core19 = __importStar2(require_core()); var path19 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); @@ -81013,7 +81013,7 @@ var require_cache4 = __commonJS({ return !!process.env["ACTIONS_CACHE_URL"]; } } - function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) { + function restoreCache5(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core19.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81157,7 +81157,7 @@ var require_cache4 = __commonJS({ return void 0; }); } - function saveCache4(paths_1, key_1, options_1) { + function saveCache5(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core19.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81394,7 +81394,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var core_1 = require_core(); var os4 = require("os"); var cp = require("child_process"); @@ -81408,7 +81408,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver9.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver10.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -81417,7 +81417,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver9.satisfies(osVersion, item.platform_version); + chk = semver10.satisfies(osVersion, item.platform_version); } } return chk; @@ -81671,13 +81671,13 @@ var require_tool_cache = __commonJS({ exports2.evaluateVersions = evaluateVersions; var core19 = __importStar2(require_core()); var io7 = __importStar2(require_io()); - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs21 = __importStar2(require("fs")); var mm = __importStar2(require_manifest()); var os4 = __importStar2(require("os")); var path19 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var stream2 = __importStar2(require("stream")); var util = __importStar2(require("util")); var assert_1 = require("assert"); @@ -81696,7 +81696,7 @@ var require_tool_cache = __commonJS({ var userAgent2 = "actions/tool-cache"; function downloadTool2(url2, dest, auth2, headers) { return __awaiter2(this, void 0, void 0, function* () { - dest = dest || path19.join(_getTempDirectory(), crypto2.randomUUID()); + dest = dest || path19.join(_getTempDirectory(), crypto3.randomUUID()); yield io7.mkdirP(path19.dirname(dest)); core19.debug(`Downloading ${url2}`); core19.debug(`Destination ${dest}`); @@ -81950,7 +81950,7 @@ var require_tool_cache = __commonJS({ } function cacheDir(sourceDir, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch2 = arch2 || os4.arch(); core19.debug(`Caching tool ${tool} ${version} ${arch2}`); core19.debug(`source dir: ${sourceDir}`); @@ -81968,7 +81968,7 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch2 = arch2 || os4.arch(); core19.debug(`Caching tool ${tool} ${version} ${arch2}`); core19.debug(`source file: ${sourceFile}`); @@ -81998,7 +81998,7 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver9.clean(versionSpec) || ""; + versionSpec = semver10.clean(versionSpec) || ""; const cachePath = path19.join(_getCacheDirectory(), toolName, versionSpec, arch2); core19.debug(`checking cache: ${cachePath}`); if (fs21.existsSync(cachePath) && fs21.existsSync(`${cachePath}.complete`)) { @@ -82070,7 +82070,7 @@ var require_tool_cache = __commonJS({ function _createExtractFolder(dest) { return __awaiter2(this, void 0, void 0, function* () { if (!dest) { - dest = path19.join(_getTempDirectory(), crypto2.randomUUID()); + dest = path19.join(_getTempDirectory(), crypto3.randomUUID()); } yield io7.mkdirP(dest); return dest; @@ -82078,7 +82078,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path19.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); + const folderPath = path19.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch2 || ""); core19.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io7.rmRF(folderPath); @@ -82088,30 +82088,30 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch2) { - const folderPath = path19.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); + const folderPath = path19.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch2 || ""); const markerPath = `${folderPath}.complete`; fs21.writeFileSync(markerPath, ""); core19.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver9.clean(versionSpec) || ""; + const c = semver10.clean(versionSpec) || ""; core19.debug(`isExplicit: ${c}`); - const valid3 = semver9.valid(c) != null; - core19.debug(`explicit? ${valid3}`); - return valid3; + const valid4 = semver10.valid(c) != null; + core19.debug(`explicit? ${valid4}`); + return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; core19.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver9.gt(a, b)) { + if (semver10.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver9.satisfies(potential, versionSpec); + const satisfied = semver10.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -85551,7 +85551,7 @@ var require_blob_upload = __commonJS({ var storage_blob_1 = require_commonjs15(); var config_1 = require_config2(); var core19 = __importStar2(require_core()); - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var stream2 = __importStar2(require("stream")); var errors_1 = require_errors3(); function uploadZipToBlobStorage(authenticatedUploadURL, zipUploadStream) { @@ -85589,7 +85589,7 @@ var require_blob_upload = __commonJS({ }; let sha256Hash = void 0; const uploadStream = new stream2.PassThrough(); - const hashStream = crypto2.createHash("sha256"); + const hashStream = crypto3.createHash("sha256"); zipUploadStream.pipe(uploadStream); zipUploadStream.pipe(hashStream).setEncoding("hex"); core19.info("Beginning upload of artifact content to blob storage"); @@ -89825,7 +89825,7 @@ var require_stream_writable = __commonJS({ pna.nextTick(cb, er); } function validChunk(stream2, state, chunk, cb) { - var valid3 = true; + var valid4 = true; var er = false; if (chunk === null) { er = new TypeError("May not write null values to stream"); @@ -89835,9 +89835,9 @@ var require_stream_writable = __commonJS({ if (er) { stream2.emit("error", er); pna.nextTick(cb, er); - valid3 = false; + valid4 = false; } - return valid3; + return valid4; } Writable.prototype.write = function(chunk, encoding, cb) { var state = this._writableState; @@ -117858,7 +117858,7 @@ var require_download_artifact = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.downloadArtifactInternal = exports2.downloadArtifactPublic = exports2.streamExtractExternal = void 0; var promises_1 = __importDefault2(require("fs/promises")); - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var stream2 = __importStar2(require("stream")); var github4 = __importStar2(require_github2()); var core19 = __importStar2(require_core()); @@ -117919,7 +117919,7 @@ var require_download_artifact = __commonJS({ reject(timeoutError); }; const timer = setTimeout(timerFn, opts.timeout); - const hashStream = crypto2.createHash("sha256").setEncoding("hex"); + const hashStream = crypto3.createHash("sha256").setEncoding("hex"); const passThrough = new stream2.PassThrough(); response.message.pipe(passThrough); passThrough.pipe(hashStream); @@ -118948,7 +118948,7 @@ var require_file_command2 = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.prepareKeyValueMessage = exports2.issueFileCommand = void 0; - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs21 = __importStar2(require("fs")); var os4 = __importStar2(require("os")); var utils_1 = require_utils10(); @@ -118966,7 +118966,7 @@ var require_file_command2 = __commonJS({ } exports2.issueFileCommand = issueFileCommand; function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${crypto2.randomUUID()}`; + const delimiter = `ghadelimiter_${crypto3.randomUUID()}`; const convertedValue = (0, utils_1.toCommandValue)(value); if (key.includes(delimiter)) { throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); @@ -121723,7 +121723,7 @@ var require_tmp = __commonJS({ var fs21 = require("fs"); var os4 = require("os"); var path19 = require("path"); - var crypto2 = require("crypto"); + var crypto3 = require("crypto"); var _c = { fs: fs21.constants, os: os4.constants }; var RANDOM_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; var TEMPLATE_PATTERN = /XXXXXX/; @@ -121903,9 +121903,9 @@ var require_tmp = __commonJS({ function _randomChars(howMany) { let value = [], rnd = null; try { - rnd = crypto2.randomBytes(howMany); + rnd = crypto3.randomBytes(howMany); } catch (e) { - rnd = crypto2.pseudoRandomBytes(howMany); + rnd = crypto3.pseudoRandomBytes(howMany); } for (let i = 0; i < howMany; i++) { value.push(RANDOM_CHARS[rnd[i] % RANDOM_CHARS.length]); @@ -130167,6 +130167,32 @@ var restoreInputs = function() { } } }; +function getPullRequestBranches() { + const pullRequest = github.context.payload.pull_request; + if (pullRequest) { + return { + base: pullRequest.base.ref, + // We use the head label instead of the head ref here, because the head + // ref lacks owner information and by itself does not uniquely identify + // the head branch (which may be in a forked repository). + head: pullRequest.head.label + }; + } + const codeScanningRef = process.env.CODE_SCANNING_REF; + const codeScanningBaseBranch = process.env.CODE_SCANNING_BASE_BRANCH; + if (codeScanningRef && codeScanningBaseBranch) { + return { + base: codeScanningBaseBranch, + // PR analysis under Default Setup analyzes the PR head commit instead of + // the merge commit, so we can use the provided ref directly. + head: codeScanningRef + }; + } + return void 0; +} +function isAnalyzingPullRequest() { + return getPullRequestBranches() !== void 0; +} var qualityCategoryMapping = { "c#": "csharp", cpp: "c-cpp", @@ -130390,6 +130416,11 @@ async function getAnalysisKey() { core5.exportVariable("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); return analysisKey; } +async function getAutomationID() { + const analysis_key = await getAnalysisKey(); + const environment = getRequiredInput("matrix"); + return computeAutomationID(analysis_key, environment); +} function computeAutomationID(analysis_key, environment) { let automationID = `${analysis_key}/`; const matrix = parseMatrixInput(environment); @@ -130455,7 +130486,13 @@ function wrapApiConfigurationError(e) { } // src/caching-utils.ts +var crypto2 = __toESM(require("crypto")); var core6 = __toESM(require_core()); +var cacheKeyHashLength = 16; +function createCacheKeyHash(components) { + const componentsJson = JSON.stringify(components); + return crypto2.createHash("sha256").update(componentsJson).digest("hex").substring(0, cacheKeyHashLength); +} // src/codeql.ts var fs12 = __toESM(require("fs")); @@ -130891,6 +130928,16 @@ function writeDiagnostic(config, language, diagnostic) { logger.debug(JSON.stringify(diagnostic)); } } +function makeTelemetryDiagnostic(id, name, attributes) { + return makeDiagnostic(id, name, { + attributes, + visibility: { + cliSummaryTable: false, + statusPage: false, + telemetry: true + } + }); +} // src/diff-informed-analysis-utils.ts var fs6 = __toESM(require("fs")); @@ -131252,6 +131299,10 @@ function isSafeArtifactUpload(codeQlVersion) { var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_"; var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled"; var CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0"; +var LINKED_CODEQL_VERSION = { + cliVersion, + tagName: bundleVersion +}; var featureConfig = { ["allow_toolcache_input" /* AllowToolcacheInput */]: { defaultValue: false, @@ -131406,6 +131457,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -131466,10 +131527,9 @@ var OfflineFeatures = class { this.logger = logger; } logger; - async getDefaultCliVersion(_variant) { + async getEnabledDefaultCliVersions(_variant) { return { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; } /** @@ -131574,11 +131634,11 @@ var Features = class extends OfflineFeatures { logger ); } - async getDefaultCliVersion(variant) { + async getEnabledDefaultCliVersions(variant) { if (supportsFeatureFlags(variant)) { - return await this.gitHubFeatureFlags.getDefaultCliVersionFromFlags(); + return await this.gitHubFeatureFlags.getEnabledDefaultCliVersionsFromFlags(); } - return super.getDefaultCliVersion(variant); + return super.getEnabledDefaultCliVersions(variant); } /** * @@ -131637,34 +131697,36 @@ var GitHubFeatureFlags = class { } return version; } - async getDefaultCliVersionFromFlags() { + /** + * Returns CLI versions enabled by `default_codeql_version_*_enabled` feature + * flags, sorted from highest to lowest. Falls back to the version pinned in + * `defaults.json` if no such flags are enabled. + */ + async getEnabledDefaultCliVersionsFromFlags() { const response = await this.getAllFeatures(); - const enabledFeatureFlagCliVersions = Object.entries(response).map( + const sortedCliVersions = Object.entries(response).map( ([f, isEnabled]) => isEnabled ? this.getCliVersionFromFeatureFlag(f) : void 0 - ).filter((f) => f !== void 0); - if (enabledFeatureFlagCliVersions.length === 0) { + ).filter((f) => f !== void 0).sort(semver5.rcompare); + if (sortedCliVersions.length === 0) { this.logger.warning( `Feature flags do not specify a default CLI version. Falling back to the CLI version shipped with the Action. This is ${cliVersion}.` ); const result = { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; if (this.hasAccessedRemoteFeatureFlags) { result.toolsFeatureFlagsValid = false; } return result; } - const maxCliVersion = enabledFeatureFlagCliVersions.reduce( - (maxVersion, currentVersion) => currentVersion > maxVersion ? currentVersion : maxVersion, - enabledFeatureFlagCliVersions[0] - ); this.logger.debug( - `Derived default CLI version of ${maxCliVersion} from feature flags.` + `Derived default CLI version of ${sortedCliVersions[0]} from feature flags.` ); return { - cliVersion: maxCliVersion, - tagName: `codeql-bundle-v${maxCliVersion}`, + enabledVersions: sortedCliVersions.map((cliVersion2) => ({ + cliVersion: cliVersion2, + tagName: `codeql-bundle-v${cliVersion2}` + })), toolsFeatureFlagsValid: true }; } @@ -131839,6 +131901,17 @@ var builtin_default = { // src/languages/index.ts var builtInLanguageSet = new Set(builtin_default.languages); +function isBuiltInLanguage(language) { + return builtInLanguageSet.has(language); +} +function parseBuiltInLanguage(language) { + language = language.trim().toLowerCase(); + language = builtin_default.aliases[language] ?? language; + if (isBuiltInLanguage(language)) { + return language; + } + return void 0; +} // src/overlay/status.ts var fs7 = __toESM(require("fs")); @@ -131977,7 +132050,7 @@ var fs11 = __toESM(require("fs")); var path10 = __toESM(require("path")); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); // node_modules/uuid/dist-node/stringify.js var byteToHex = []; @@ -132023,6 +132096,68 @@ function _v4(options, buf, offset) { } var v4_default = v4; +// src/overlay/caching.ts +var actionsCache3 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; +var CACHE_VERSION = 1; +var CACHE_PREFIX = "codeql-overlay-base-database"; +async function getCacheKeyPrefixBase(parsedLanguages) { + const languagesComponent = [...parsedLanguages].sort().join("_"); + const cacheKeyComponents = { + automationID: await getAutomationID() + // Add more components here as needed in the future + }; + const componentsHash = createCacheKeyHash(cacheKeyComponents); + return `${CACHE_PREFIX}-${CACHE_VERSION}-${componentsHash}-${languagesComponent}-`; +} +async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger) { + const languages = rawLanguages.map(parseBuiltInLanguage); + if (languages.includes(void 0)) { + logger.warning( + "One or more provided languages are not recognized as built-in languages. Skipping searching for overlay-base databases in cache." + ); + return void 0; + } + const dedupedLanguages = [ + ...new Set(languages.filter((l) => l !== void 0)) + ]; + const cacheKeyPrefix = await getCacheKeyPrefixBase(dedupedLanguages); + logger.debug( + `Searching for overlay-base databases in Actions cache with prefix ${cacheKeyPrefix}` + ); + const caches = await listActionsCaches(cacheKeyPrefix); + if (caches.length === 0) { + logger.info("No overlay-base databases found in Actions cache."); + return []; + } + logger.info( + `Found ${caches.length} overlay-base ${caches.length === 1 ? "database" : "databases"} in the Actions cache.` + ); + const versionRegex = /^([\d.]+)-/; + const versionSet = /* @__PURE__ */ new Set(); + for (const cache of caches) { + if (!cache.key) continue; + const suffix = cache.key.substring(cacheKeyPrefix.length); + const match = suffix.match(versionRegex); + if (match && semver6.valid(match[1])) { + versionSet.add(match[1]); + } + } + if (versionSet.size === 0) { + logger.info( + "Could not parse any CodeQL versions from overlay-base database cache keys." + ); + return []; + } + const versions = [...versionSet].sort(semver6.rcompare); + logger.info( + `Found overlay databases for the following CodeQL versions in the Actions cache: ${versions.join(", ")}` + ); + return versions; +} + // src/tar.ts var import_child_process = require("child_process"); var fs9 = __toESM(require("fs")); @@ -132030,7 +132165,7 @@ var stream = __toESM(require("stream")); var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); var MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3"; var MIN_REQUIRED_GNU_TAR_VERSION = "1.31"; async function getTarVersion() { @@ -132072,9 +132207,9 @@ async function isZstdAvailable(logger) { case "gnu": return { available: foundZstdBinary && // GNU tar only uses major and minor version numbers - semver6.gte( - semver6.coerce(version), - semver6.coerce(MIN_REQUIRED_GNU_TAR_VERSION) + semver7.gte( + semver7.coerce(version), + semver7.coerce(MIN_REQUIRED_GNU_TAR_VERSION) ), foundZstdBinary, version: tarVersion @@ -132083,7 +132218,7 @@ async function isZstdAvailable(logger) { return { available: foundZstdBinary && // Do a loose comparison since these version numbers don't contain // a patch version number. - semver6.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), + semver7.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), foundZstdBinary, version: tarVersion }; @@ -132190,7 +132325,7 @@ var core10 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; var TOOLCACHE_TOOL_NAME = "CodeQL"; function makeDownloadFirstToolsDownloadDurations(downloadDurationMs, extractionDurationMs) { @@ -132320,7 +132455,7 @@ function getToolcacheDirectory(version) { return path9.join( getRequiredEnvParam("RUNNER_TOOL_CACHE"), TOOLCACHE_TOOL_NAME, - semver7.clean(version) || version, + semver8.clean(version) || version, os.arch() || "" ); } @@ -132445,13 +132580,13 @@ function tryGetTagNameFromUrl(url2, logger) { return match[1]; } function convertToSemVer(version, logger) { - if (!semver8.valid(version)) { + if (!semver9.valid(version)) { logger.debug( `Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.` ); version = `0.0.0-${version}`; } - const s = semver8.clean(version); + const s = semver9.clean(version); if (!s) { throw new Error(`Bundle version ${version} is not in SemVer format.`); } @@ -132483,7 +132618,84 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getEnabledVersionsWithOverlayBaseDatabases(defaultCliVersion, rawLanguages, features, logger) { + if (rawLanguages === void 0 || rawLanguages.length === 0) { + return []; + } + const isEnabled = await features.getValue( + "overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */ + ); + const isDryRun = !isEnabled && await features.getValue("overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */); + if (!isEnabled && !isDryRun) { + return []; + } + let cachedVersions; + try { + cachedVersions = await getCodeQlVersionsForOverlayBaseDatabases( + rawLanguages, + logger + ); + } catch (e) { + logger.warning( + `Could not list overlay-base databases in the Actions cache while choosing a default CodeQL CLI version, falling back to the highest enabled version. Details: ${getErrorMessage(e)}` + ); + return []; + } + if (cachedVersions === void 0 || cachedVersions.length === 0) { + return []; + } + const cachedVersionsSet = new Set(cachedVersions); + const overlayVersions = defaultCliVersion.enabledVersions.filter( + (v) => cachedVersionsSet.has(v.cliVersion) + ); + if (overlayVersions.length === 0) { + return []; + } + const isCachedVersionDifferent = overlayVersions[0].cliVersion !== defaultCliVersion.enabledVersions[0].cliVersion; + if (isCachedVersionDifferent) { + addNoLanguageDiagnostic( + void 0, + makeTelemetryDiagnostic( + "codeql-action/overlay-aware-default-codeql-version", + "Overlay-aware default CodeQL version selection", + { + cachedVersions, + enabledVersions: defaultCliVersion.enabledVersions.map( + (v) => v.cliVersion + ), + isDryRun, + overlayAwareVersion: overlayVersions[0].cliVersion + } + ) + ); + } + if (isDryRun) { + logger.debug( + `Overlay-aware default CodeQL version selection is running in dry-run mode. Would have used version ${overlayVersions[0].cliVersion}.` + ); + return []; + } + return overlayVersions; +} +async function resolveDefaultCliVersion(defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { + if (!useOverlayAwareDefaultCliVersion || !isAnalyzingPullRequest()) { + return defaultCliVersion.enabledVersions[0]; + } + const overlayVersions = await getEnabledVersionsWithOverlayBaseDatabases( + defaultCliVersion, + rawLanguages, + features, + logger + ); + if (overlayVersions.length > 0) { + logger.info( + `Using CodeQL version ${overlayVersions[0].cliVersion} since this is the highest enabled version that has a cached overlay-base database.` + ); + return overlayVersions[0]; + } + return defaultCliVersion.enabledVersions[0]; +} +async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -132577,21 +132789,35 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } } - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } } else if (toolsInput !== void 0) { tagName = tryGetTagNameFromUrl(toolsInput, logger); url2 = toolsInput; if (tagName) { const bundleVersion3 = tryGetBundleVersionFromTagName(tagName, logger); - if (bundleVersion3 && semver8.valid(bundleVersion3)) { + if (bundleVersion3 && semver9.valid(bundleVersion3)) { cliVersion2 = convertToSemVer(bundleVersion3, logger); } } } else { - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } const bundleVersion2 = tagName && tryGetBundleVersionFromTagName(tagName, logger); const humanReadableVersion = cliVersion2 ?? (bundleVersion2 && convertToSemVer(bundleVersion2, logger)) ?? tagName ?? url2 ?? "unknown"; @@ -132788,7 +133014,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -132798,6 +133024,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau const source = await getCodeQLSource( toolsInput, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, apiDetails, variant, zstdAvailability.available, @@ -132856,7 +133084,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau async function useZstdBundle(cliVersion2, tarSupportsZstd) { return ( // In testing, gzip performs better than zstd on Windows. - process.platform !== "win32" && tarSupportsZstd && semver8.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) + process.platform !== "win32" && tarSupportsZstd && semver9.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) ); } function getTempExtractionDir(tempDir) { @@ -132888,7 +133116,7 @@ async function getNightlyToolsUrl(logger) { } } function getLatestToolcacheVersion(logger) { - const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver8.compare(b, a)); + const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver9.compare(b, a)); logger.debug( `Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify( allVersions @@ -132925,7 +133153,7 @@ 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 EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -132939,6 +133167,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger ); @@ -133550,7 +133780,7 @@ var io5 = __toESM(require_io()); var core12 = __toESM(require_core()); // src/dependency-caching.ts -var actionsCache3 = __toESM(require_cache4()); +var actionsCache4 = __toESM(require_cache4()); var glob = __toESM(require_glob()); var CODEQL_DEPENDENCY_CACHE_PREFIX = "codeql-dependencies"; async function getDependencyCacheUsage(logger) { @@ -135198,7 +135428,7 @@ var core14 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io6 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -135212,6 +135442,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger, true @@ -135360,9 +135592,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo url: getRequiredEnvParam("GITHUB_SERVER_URL"), apiURL: getRequiredEnvParam("GITHUB_API_URL") }; - const codeQLDefaultVersionInfo = await features.getDefaultCliVersion( - gitHubVersion.type - ); + const codeQLDefaultVersionInfo = await features.getEnabledDefaultCliVersions(gitHubVersion.type); const initCodeQLResult = await initCodeQL( void 0, // There is no tools input on the upload action @@ -135370,6 +135600,10 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo tempDir, gitHubVersion.type, codeQLDefaultVersionInfo, + void 0, + // rawLanguages: upload-lib does not run analysis + false, + // useOverlayAwareDefaultCliVersion: upload-lib does not run analysis features, logger ); @@ -135385,7 +135619,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo return readSarifFile(outputFile); } function populateRunAutomationDetails(sarifFile, category, analysis_key, environment) { - const automationID = getAutomationID(category, analysis_key, environment); + const automationID = getAutomationID2(category, analysis_key, environment); if (automationID !== void 0) { for (const run2 of sarifFile.runs || []) { if (run2.automationDetails === void 0) { @@ -135398,7 +135632,7 @@ function populateRunAutomationDetails(sarifFile, category, analysis_key, environ } return sarifFile; } -function getAutomationID(category, analysis_key, environment) { +function getAutomationID2(category, analysis_key, environment) { if (category !== void 0) { let automationID = category; if (!automationID.endsWith("/")) { diff --git a/lib/init-action.js b/lib/init-action.js index b7cdc23b79..1ed7e54900 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare2 = require_compare(); - var rcompare2 = (a, b, loose) => compare2(b, a, loose); - module2.exports = rcompare2; + var rcompare3 = (a, b, loose) => compare2(b, a, loose); + module2.exports = rcompare3; } }); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare2 = require_compare(); - var rcompare2 = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare2, - rcompare: rcompare2, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -33101,8 +33101,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare2; - function rcompare2(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare2(b, a, loose); } exports2.sort = sort; @@ -86358,11 +86358,11 @@ function isAnalyzingPullRequest() { } // src/analyses.ts -var AnalysisKind = /* @__PURE__ */ ((AnalysisKind3) => { - AnalysisKind3["CodeScanning"] = "code-scanning"; - AnalysisKind3["CodeQuality"] = "code-quality"; - AnalysisKind3["RiskAssessment"] = "risk-assessment"; - return AnalysisKind3; +var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { + AnalysisKind2["CodeScanning"] = "code-scanning"; + AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["RiskAssessment"] = "risk-assessment"; + return AnalysisKind2; })(AnalysisKind || {}); var compatibilityMatrix = { ["code-scanning" /* CodeScanning */]: /* @__PURE__ */ new Set(["code-quality" /* CodeQuality */]), @@ -86638,6 +86638,18 @@ function computeAutomationID(analysis_key, environment) { } return automationID; } +async function listActionsCaches(keyPrefix, ref) { + const repositoryNwo = getRepositoryNwo(); + return await getApiClient().paginate( + "GET /repos/{owner}/{repo}/actions/caches", + { + owner: repositoryNwo.owner, + repo: repositoryNwo.repo, + key: keyPrefix, + ref + } + ); +} async function getRepositoryProperties(repositoryNwo) { return getApiClient().request("GET /repos/:owner/:repo/properties/values", { owner: repositoryNwo.owner, @@ -87643,6 +87655,10 @@ function isSupportedToolsFeature(versionInfo, feature) { var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_"; var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled"; var CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0"; +var LINKED_CODEQL_VERSION = { + cliVersion, + tagName: bundleVersion +}; var featureConfig = { ["allow_toolcache_input" /* AllowToolcacheInput */]: { defaultValue: false, @@ -87797,6 +87813,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -87857,10 +87883,9 @@ var OfflineFeatures = class { this.logger = logger; } logger; - async getDefaultCliVersion(_variant) { + async getEnabledDefaultCliVersions(_variant) { return { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; } /** @@ -87965,11 +87990,11 @@ var Features = class extends OfflineFeatures { logger ); } - async getDefaultCliVersion(variant) { + async getEnabledDefaultCliVersions(variant) { if (supportsFeatureFlags(variant)) { - return await this.gitHubFeatureFlags.getDefaultCliVersionFromFlags(); + return await this.gitHubFeatureFlags.getEnabledDefaultCliVersionsFromFlags(); } - return super.getDefaultCliVersion(variant); + return super.getEnabledDefaultCliVersions(variant); } /** * @@ -88028,34 +88053,36 @@ var GitHubFeatureFlags = class { } return version; } - async getDefaultCliVersionFromFlags() { + /** + * Returns CLI versions enabled by `default_codeql_version_*_enabled` feature + * flags, sorted from highest to lowest. Falls back to the version pinned in + * `defaults.json` if no such flags are enabled. + */ + async getEnabledDefaultCliVersionsFromFlags() { const response = await this.getAllFeatures(); - const enabledFeatureFlagCliVersions = Object.entries(response).map( + const sortedCliVersions = Object.entries(response).map( ([f, isEnabled]) => isEnabled ? this.getCliVersionFromFeatureFlag(f) : void 0 - ).filter((f) => f !== void 0); - if (enabledFeatureFlagCliVersions.length === 0) { + ).filter((f) => f !== void 0).sort(semver5.rcompare); + if (sortedCliVersions.length === 0) { this.logger.warning( `Feature flags do not specify a default CLI version. Falling back to the CLI version shipped with the Action. This is ${cliVersion}.` ); const result = { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; if (this.hasAccessedRemoteFeatureFlags) { result.toolsFeatureFlagsValid = false; } return result; } - const maxCliVersion = enabledFeatureFlagCliVersions.reduce( - (maxVersion, currentVersion) => currentVersion > maxVersion ? currentVersion : maxVersion, - enabledFeatureFlagCliVersions[0] - ); this.logger.debug( - `Derived default CLI version of ${maxCliVersion} from feature flags.` + `Derived default CLI version of ${sortedCliVersions[0]} from feature flags.` ); return { - cliVersion: maxCliVersion, - tagName: `codeql-bundle-v${maxCliVersion}`, + enabledVersions: sortedCliVersions.map((cliVersion2) => ({ + cliVersion: cliVersion2, + tagName: `codeql-bundle-v${cliVersion2}` + })), toolsFeatureFlagsValid: true }; } @@ -88361,6 +88388,17 @@ var BuiltInLanguage = /* @__PURE__ */ ((BuiltInLanguage2) => { return BuiltInLanguage2; })(BuiltInLanguage || {}); var builtInLanguageSet = new Set(builtin_default.languages); +function isBuiltInLanguage(language) { + return builtInLanguageSet.has(language); +} +function parseBuiltInLanguage(language) { + language = language.trim().toLowerCase(); + language = builtin_default.aliases[language] ?? language; + if (isBuiltInLanguage(language)) { + return language; + } + return void 0; +} // src/overlay/diagnostics.ts async function addOverlayDisablementDiagnostics(config, codeql, overlayDisabledReason) { @@ -89608,7 +89646,7 @@ var internal = { }; // src/init.ts -var fs15 = __toESM(require("fs")); +var fs16 = __toESM(require("fs")); var path15 = __toESM(require("path")); var core12 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); @@ -89616,7 +89654,7 @@ var github2 = __toESM(require_github()); var io5 = __toESM(require_io()); // src/codeql.ts -var fs14 = __toESM(require("fs")); +var fs15 = __toESM(require("fs")); var path14 = __toESM(require("path")); var core11 = __toESM(require_core()); var toolrunner3 = __toESM(require_toolrunner()); @@ -89870,20 +89908,222 @@ function wrapCliConfigurationError(cliError) { } // src/setup-codeql.ts -var fs12 = __toESM(require("fs")); +var fs13 = __toESM(require("fs")); var path12 = __toESM(require("path")); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); + +// src/overlay/caching.ts +var fs10 = __toESM(require("fs")); +var actionsCache4 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; +var CACHE_VERSION2 = 1; +var CACHE_PREFIX = "codeql-overlay-base-database"; +var MAX_CACHE_OPERATION_MS3 = 6e5; +async function checkOverlayBaseDatabase(codeql, config, logger, warningPrefix) { + const baseDatabaseOidsFilePath = getBaseDatabaseOidsFilePath(config); + if (!fs10.existsSync(baseDatabaseOidsFilePath)) { + logger.warning( + `${warningPrefix}: ${baseDatabaseOidsFilePath} does not exist` + ); + return false; + } + for (const language of config.languages) { + const dbPath = getCodeQLDatabasePath(config, language); + try { + const resolveDatabaseOutput = await codeql.resolveDatabase(dbPath); + if (resolveDatabaseOutput === void 0 || !("overlayBaseSpecifier" in resolveDatabaseOutput)) { + logger.info(`${warningPrefix}: no overlayBaseSpecifier defined`); + return false; + } else { + logger.debug( + `Overlay base specifier for ${language} overlay-base database found: ${resolveDatabaseOutput.overlayBaseSpecifier}` + ); + } + } catch (e) { + logger.warning(`${warningPrefix}: failed to resolve database: ${e}`); + return false; + } + } + return true; +} +async function downloadOverlayBaseDatabaseFromCache(codeql, config, logger) { + const overlayDatabaseMode = config.overlayDatabaseMode; + if (overlayDatabaseMode !== "overlay" /* Overlay */) { + logger.debug( + `Overlay database mode is ${overlayDatabaseMode}. Skip downloading overlay-base database from cache.` + ); + return void 0; + } + if (!config.useOverlayDatabaseCaching) { + logger.debug( + "Overlay database caching is disabled. Skip downloading overlay-base database from cache." + ); + return void 0; + } + if (isInTestMode()) { + logger.debug( + "In test mode. Skip downloading overlay-base database from cache." + ); + return void 0; + } + const dbLocation = config.dbLocation; + const codeQlVersion = (await codeql.getVersion()).version; + const cacheRestoreKeyPrefix = await getCacheRestoreKeyPrefix( + config, + codeQlVersion + ); + logger.info( + `Looking in Actions cache for overlay-base database with restore key ${cacheRestoreKeyPrefix}` + ); + let databaseDownloadDurationMs = 0; + try { + const databaseDownloadStart = performance.now(); + const foundKey = await waitForResultWithTimeLimit( + // This ten-minute limit for the cache restore operation is mainly to + // guard against the possibility that the cache service is unresponsive + // and hangs outside the data download. + // + // Data download (which is normally the most time-consuming part of the + // restore operation) should not run long enough to hit this limit. Even + // for an extremely large 10GB database, at a download speed of 40MB/s + // (see below), the download should complete within five minutes. If we + // do hit this limit, there are likely more serious problems other than + // mere slow download speed. + // + // This is important because we don't want any ongoing file operations + // on the database directory when we do hit this limit. Hitting this + // time limit takes us to a fallback path where we re-initialize the + // database from scratch at dbLocation, and having the cache restore + // operation continue to write into dbLocation in the background would + // really mess things up. We want to hit this limit only in the case + // of a hung cache service, not just slow download speed. + MAX_CACHE_OPERATION_MS3, + actionsCache4.restoreCache( + [dbLocation], + cacheRestoreKeyPrefix, + void 0, + { + // Azure SDK download (which is the default) uses 128MB segments; see + // https://github.com/actions/toolkit/blob/main/packages/cache/README.md. + // Setting segmentTimeoutInMs to 3000 translates to segment download + // speed of about 40 MB/s, which should be achievable unless the + // download is unreliable (in which case we do want to abort). + segmentTimeoutInMs: 3e3 + } + ), + () => { + logger.info("Timed out downloading overlay-base database from cache"); + } + ); + databaseDownloadDurationMs = Math.round( + performance.now() - databaseDownloadStart + ); + if (foundKey === void 0) { + logger.info("No overlay-base database found in Actions cache"); + return void 0; + } + logger.info( + `Downloaded overlay-base database in cache with key ${foundKey}` + ); + } catch (error3) { + logger.warning( + `Failed to download overlay-base database from cache: ${error3 instanceof Error ? error3.message : String(error3)}` + ); + return void 0; + } + const databaseIsValid = await checkOverlayBaseDatabase( + codeql, + config, + logger, + "Downloaded overlay-base database is invalid" + ); + if (!databaseIsValid) { + logger.warning("Downloaded overlay-base database failed validation"); + return void 0; + } + const databaseSizeBytes = await tryGetFolderBytes(dbLocation, logger); + if (databaseSizeBytes === void 0) { + logger.info( + "Filesystem error while accessing downloaded overlay-base database" + ); + return void 0; + } + logger.info(`Successfully downloaded overlay-base database to ${dbLocation}`); + return { + databaseSizeBytes: Math.round(databaseSizeBytes), + databaseDownloadDurationMs + }; +} +async function getCacheRestoreKeyPrefix(config, codeQlVersion) { + return `${await getCacheKeyPrefixBase(config.languages)}${codeQlVersion}-`; +} +async function getCacheKeyPrefixBase(parsedLanguages) { + const languagesComponent = [...parsedLanguages].sort().join("_"); + const cacheKeyComponents = { + automationID: await getAutomationID() + // Add more components here as needed in the future + }; + const componentsHash = createCacheKeyHash(cacheKeyComponents); + return `${CACHE_PREFIX}-${CACHE_VERSION2}-${componentsHash}-${languagesComponent}-`; +} +async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger) { + const languages = rawLanguages.map(parseBuiltInLanguage); + if (languages.includes(void 0)) { + logger.warning( + "One or more provided languages are not recognized as built-in languages. Skipping searching for overlay-base databases in cache." + ); + return void 0; + } + const dedupedLanguages = [ + ...new Set(languages.filter((l) => l !== void 0)) + ]; + const cacheKeyPrefix = await getCacheKeyPrefixBase(dedupedLanguages); + logger.debug( + `Searching for overlay-base databases in Actions cache with prefix ${cacheKeyPrefix}` + ); + const caches = await listActionsCaches(cacheKeyPrefix); + if (caches.length === 0) { + logger.info("No overlay-base databases found in Actions cache."); + return []; + } + logger.info( + `Found ${caches.length} overlay-base ${caches.length === 1 ? "database" : "databases"} in the Actions cache.` + ); + const versionRegex = /^([\d.]+)-/; + const versionSet = /* @__PURE__ */ new Set(); + for (const cache of caches) { + if (!cache.key) continue; + const suffix = cache.key.substring(cacheKeyPrefix.length); + const match = suffix.match(versionRegex); + if (match && semver6.valid(match[1])) { + versionSet.add(match[1]); + } + } + if (versionSet.size === 0) { + logger.info( + "Could not parse any CodeQL versions from overlay-base database cache keys." + ); + return []; + } + const versions = [...versionSet].sort(semver6.rcompare); + logger.info( + `Found overlay databases for the following CodeQL versions in the Actions cache: ${versions.join(", ")}` + ); + return versions; +} // src/tar.ts var import_child_process = require("child_process"); -var fs10 = __toESM(require("fs")); +var fs11 = __toESM(require("fs")); var stream = __toESM(require("stream")); var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); var MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3"; var MIN_REQUIRED_GNU_TAR_VERSION = "1.31"; async function getTarVersion() { @@ -89925,9 +90165,9 @@ async function isZstdAvailable(logger) { case "gnu": return { available: foundZstdBinary && // GNU tar only uses major and minor version numbers - semver6.gte( - semver6.coerce(version), - semver6.coerce(MIN_REQUIRED_GNU_TAR_VERSION) + semver7.gte( + semver7.coerce(version), + semver7.coerce(MIN_REQUIRED_GNU_TAR_VERSION) ), foundZstdBinary, version: tarVersion @@ -89936,7 +90176,7 @@ async function isZstdAvailable(logger) { return { available: foundZstdBinary && // Do a loose comparison since these version numbers don't contain // a patch version number. - semver6.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), + semver7.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), foundZstdBinary, version: tarVersion }; @@ -89951,7 +90191,7 @@ async function isZstdAvailable(logger) { } } async function extract(tarPath, dest, compressionMethod, tarVersion, logger) { - fs10.mkdirSync(dest, { recursive: true }); + fs11.mkdirSync(dest, { recursive: true }); switch (compressionMethod) { case "gzip": return await toolcache.extractTar(tarPath, dest); @@ -90035,7 +90275,7 @@ function inferCompressionMethod(tarPath) { } // src/tools-download.ts -var fs11 = __toESM(require("fs")); +var fs12 = __toESM(require("fs")); var os4 = __toESM(require("os")); var path11 = __toESM(require("path")); var import_perf_hooks2 = require("perf_hooks"); @@ -90043,7 +90283,7 @@ var core10 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; var TOOLCACHE_TOOL_NAME = "CodeQL"; function makeDownloadFirstToolsDownloadDurations(downloadDurationMs, extractionDurationMs) { @@ -90142,7 +90382,7 @@ async function downloadAndExtract(codeqlURL, compressionMethod, dest, authorizat }; } async function downloadAndExtractZstdWithStreaming(codeqlURL, dest, authorization, headers, tarVersion, logger) { - fs11.mkdirSync(dest, { recursive: true }); + fs12.mkdirSync(dest, { recursive: true }); const agent = new import_http_client.HttpClient().getAgent(codeqlURL); headers = Object.assign( { "User-Agent": "CodeQL Action" }, @@ -90173,13 +90413,13 @@ function getToolcacheDirectory(version) { return path11.join( getRequiredEnvParam("RUNNER_TOOL_CACHE"), TOOLCACHE_TOOL_NAME, - semver7.clean(version) || version, + semver8.clean(version) || version, os4.arch() || "" ); } function writeToolcacheMarkerFile(extractedPath, logger) { const markerFilePath = `${extractedPath}.complete`; - fs11.writeFileSync(markerFilePath, ""); + fs12.writeFileSync(markerFilePath, ""); logger.info(`Created toolcache marker file ${markerFilePath}`); } function sanitizeUrlForStatusReport(url) { @@ -90298,13 +90538,13 @@ function tryGetTagNameFromUrl(url, logger) { return match[1]; } function convertToSemVer(version, logger) { - if (!semver8.valid(version)) { + if (!semver9.valid(version)) { logger.debug( `Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.` ); version = `0.0.0-${version}`; } - const s = semver8.clean(version); + const s = semver9.clean(version); if (!s) { throw new Error(`Bundle version ${version} is not in SemVer format.`); } @@ -90314,7 +90554,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { const candidates = toolcache3.findAllVersions("CodeQL").filter(isGoodVersion).map((version) => ({ folder: toolcache3.find("CodeQL", version), version - })).filter(({ folder }) => fs12.existsSync(path12.join(folder, "pinned-version"))); + })).filter(({ folder }) => fs13.existsSync(path12.join(folder, "pinned-version"))); if (candidates.length === 1) { const candidate = candidates[0]; logger.debug( @@ -90336,7 +90576,84 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getEnabledVersionsWithOverlayBaseDatabases(defaultCliVersion, rawLanguages, features, logger) { + if (rawLanguages === void 0 || rawLanguages.length === 0) { + return []; + } + const isEnabled = await features.getValue( + "overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */ + ); + const isDryRun = !isEnabled && await features.getValue("overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */); + if (!isEnabled && !isDryRun) { + return []; + } + let cachedVersions; + try { + cachedVersions = await getCodeQlVersionsForOverlayBaseDatabases( + rawLanguages, + logger + ); + } catch (e) { + logger.warning( + `Could not list overlay-base databases in the Actions cache while choosing a default CodeQL CLI version, falling back to the highest enabled version. Details: ${getErrorMessage(e)}` + ); + return []; + } + if (cachedVersions === void 0 || cachedVersions.length === 0) { + return []; + } + const cachedVersionsSet = new Set(cachedVersions); + const overlayVersions = defaultCliVersion.enabledVersions.filter( + (v) => cachedVersionsSet.has(v.cliVersion) + ); + if (overlayVersions.length === 0) { + return []; + } + const isCachedVersionDifferent = overlayVersions[0].cliVersion !== defaultCliVersion.enabledVersions[0].cliVersion; + if (isCachedVersionDifferent) { + addNoLanguageDiagnostic( + void 0, + makeTelemetryDiagnostic( + "codeql-action/overlay-aware-default-codeql-version", + "Overlay-aware default CodeQL version selection", + { + cachedVersions, + enabledVersions: defaultCliVersion.enabledVersions.map( + (v) => v.cliVersion + ), + isDryRun, + overlayAwareVersion: overlayVersions[0].cliVersion + } + ) + ); + } + if (isDryRun) { + logger.debug( + `Overlay-aware default CodeQL version selection is running in dry-run mode. Would have used version ${overlayVersions[0].cliVersion}.` + ); + return []; + } + return overlayVersions; +} +async function resolveDefaultCliVersion(defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { + if (!useOverlayAwareDefaultCliVersion || !isAnalyzingPullRequest()) { + return defaultCliVersion.enabledVersions[0]; + } + const overlayVersions = await getEnabledVersionsWithOverlayBaseDatabases( + defaultCliVersion, + rawLanguages, + features, + logger + ); + if (overlayVersions.length > 0) { + logger.info( + `Using CodeQL version ${overlayVersions[0].cliVersion} since this is the highest enabled version that has a cached overlay-base database.` + ); + return overlayVersions[0]; + } + return defaultCliVersion.enabledVersions[0]; +} +async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -90430,21 +90747,35 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } } - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } } else if (toolsInput !== void 0) { tagName = tryGetTagNameFromUrl(toolsInput, logger); url = toolsInput; if (tagName) { const bundleVersion3 = tryGetBundleVersionFromTagName(tagName, logger); - if (bundleVersion3 && semver8.valid(bundleVersion3)) { + if (bundleVersion3 && semver9.valid(bundleVersion3)) { cliVersion2 = convertToSemVer(bundleVersion3, logger); } } } else { - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } const bundleVersion2 = tagName && tryGetBundleVersionFromTagName(tagName, logger); const humanReadableVersion = cliVersion2 ?? (bundleVersion2 && convertToSemVer(bundleVersion2, logger)) ?? tagName ?? url ?? "unknown"; @@ -90641,7 +90972,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -90651,6 +90982,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau const source = await getCodeQLSource( toolsInput, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, apiDetails, variant, zstdAvailability.available, @@ -90709,7 +91042,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau async function useZstdBundle(cliVersion2, tarSupportsZstd) { return ( // In testing, gzip performs better than zstd on Windows. - process.platform !== "win32" && tarSupportsZstd && semver8.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) + process.platform !== "win32" && tarSupportsZstd && semver9.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) ); } function getTempExtractionDir(tempDir) { @@ -90741,7 +91074,7 @@ async function getNightlyToolsUrl(logger) { } } function getLatestToolcacheVersion(logger) { - const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver8.compare(b, a)); + const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver9.compare(b, a)); logger.debug( `Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify( allVersions @@ -90761,7 +91094,7 @@ function isReservedToolsValue(tools) { } // src/tracer-config.ts -var fs13 = __toESM(require("fs")); +var fs14 = __toESM(require("fs")); var path13 = __toESM(require("path")); async function shouldEnableIndirectTracing(codeql, config) { if (config.buildMode === "none" /* None */) { @@ -90774,7 +91107,7 @@ async function shouldEnableIndirectTracing(codeql, config) { } async function getTracerConfigForCluster(config) { const tracingEnvVariables = JSON.parse( - fs13.readFileSync( + fs14.readFileSync( path13.resolve( config.dbLocation, "temp/tracingEnvironment/start-tracing.json" @@ -90800,7 +91133,7 @@ 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 EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -90814,6 +91147,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger ); @@ -90883,7 +91218,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { "tools", "tracing-config.lua" ); - return fs14.existsSync(tracingConfigPath); + return fs15.existsSync(tracingConfigPath); }, async isScannedLanguage(language) { return !await this.isTracedLanguage(language); @@ -91359,7 +91694,7 @@ async function writeCodeScanningConfigFile(config, logger) { logger.startGroup("Augmented user configuration file contents"); logger.info(dump(augmentedConfig)); logger.endGroup(); - fs14.writeFileSync(codeScanningConfigFile, dump(augmentedConfig)); + fs15.writeFileSync(codeScanningConfigFile, dump(augmentedConfig)); return codeScanningConfigFile; } var TRAP_CACHE_SIZE_MB = 1024; @@ -91403,7 +91738,7 @@ async function getJobRunUuidSarifOptions(codeql) { } // src/init.ts -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -91417,6 +91752,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger, true @@ -91437,7 +91774,7 @@ async function initConfig2(features, inputs) { }); } async function runDatabaseInitCluster(databaseInitEnvironment, codeql, config, sourceRoot, processName, qlconfigFile, logger) { - fs15.mkdirSync(config.dbLocation, { recursive: true }); + fs16.mkdirSync(config.dbLocation, { recursive: true }); await wrapEnvironment( databaseInitEnvironment, async () => await codeql.databaseInitCluster( @@ -91473,24 +91810,24 @@ async function checkPacksForOverlayCompatibility(codeql, config, logger) { function checkPackForOverlayCompatibility(packDir, codeQlOverlayVersion, logger) { try { let qlpackPath = path15.join(packDir, "qlpack.yml"); - if (!fs15.existsSync(qlpackPath)) { + if (!fs16.existsSync(qlpackPath)) { qlpackPath = path15.join(packDir, "codeql-pack.yml"); } const qlpackContents = load( - fs15.readFileSync(qlpackPath, "utf8") + fs16.readFileSync(qlpackPath, "utf8") ); if (!qlpackContents.buildMetadata) { return true; } const packInfoPath = path15.join(packDir, ".packinfo"); - if (!fs15.existsSync(packInfoPath)) { + if (!fs16.existsSync(packInfoPath)) { logger.warning( `The query pack at ${packDir} does not have a .packinfo file, so it cannot support overlay analysis. Recompiling the query pack with the latest CodeQL CLI should solve this problem.` ); return false; } const packInfoFileContents = JSON.parse( - fs15.readFileSync(packInfoPath, "utf8") + fs16.readFileSync(packInfoPath, "utf8") ); const packOverlayVersion = packInfoFileContents.overlayVersion; if (typeof packOverlayVersion !== "number") { @@ -91525,8 +91862,8 @@ async function checkInstallPython311(languages, codeql) { ]).exec(); } } -function cleanupDatabaseClusterDirectory(config, logger, options = {}, rmSync2 = fs15.rmSync) { - if (fs15.existsSync(config.dbLocation) && (fs15.statSync(config.dbLocation).isFile() || fs15.readdirSync(config.dbLocation).length > 0)) { +function cleanupDatabaseClusterDirectory(config, logger, options = {}, rmSync2 = fs16.rmSync) { + if (fs16.existsSync(config.dbLocation) && (fs16.statSync(config.dbLocation).isFile() || fs16.readdirSync(config.dbLocation).length > 0)) { if (!options.disableExistingDirectoryWarning) { logger.warning( `The database cluster directory ${config.dbLocation} must be empty. Attempting to clean it up.` @@ -91630,163 +91967,6 @@ To opt out of this change, ${envVarOptOut}`; core12.exportVariable("CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION" /* DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION */, "true"); } -// src/overlay/caching.ts -var fs16 = __toESM(require("fs")); -var actionsCache4 = __toESM(require_cache4()); -var semver9 = __toESM(require_semver2()); -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; -var CACHE_VERSION2 = 1; -var CACHE_PREFIX = "codeql-overlay-base-database"; -var MAX_CACHE_OPERATION_MS3 = 6e5; -async function checkOverlayBaseDatabase(codeql, config, logger, warningPrefix) { - const baseDatabaseOidsFilePath = getBaseDatabaseOidsFilePath(config); - if (!fs16.existsSync(baseDatabaseOidsFilePath)) { - logger.warning( - `${warningPrefix}: ${baseDatabaseOidsFilePath} does not exist` - ); - return false; - } - for (const language of config.languages) { - const dbPath = getCodeQLDatabasePath(config, language); - try { - const resolveDatabaseOutput = await codeql.resolveDatabase(dbPath); - if (resolveDatabaseOutput === void 0 || !("overlayBaseSpecifier" in resolveDatabaseOutput)) { - logger.info(`${warningPrefix}: no overlayBaseSpecifier defined`); - return false; - } else { - logger.debug( - `Overlay base specifier for ${language} overlay-base database found: ${resolveDatabaseOutput.overlayBaseSpecifier}` - ); - } - } catch (e) { - logger.warning(`${warningPrefix}: failed to resolve database: ${e}`); - return false; - } - } - return true; -} -async function downloadOverlayBaseDatabaseFromCache(codeql, config, logger) { - const overlayDatabaseMode = config.overlayDatabaseMode; - if (overlayDatabaseMode !== "overlay" /* Overlay */) { - logger.debug( - `Overlay database mode is ${overlayDatabaseMode}. Skip downloading overlay-base database from cache.` - ); - return void 0; - } - if (!config.useOverlayDatabaseCaching) { - logger.debug( - "Overlay database caching is disabled. Skip downloading overlay-base database from cache." - ); - return void 0; - } - if (isInTestMode()) { - logger.debug( - "In test mode. Skip downloading overlay-base database from cache." - ); - return void 0; - } - const dbLocation = config.dbLocation; - const codeQlVersion = (await codeql.getVersion()).version; - const cacheRestoreKeyPrefix = await getCacheRestoreKeyPrefix( - config, - codeQlVersion - ); - logger.info( - `Looking in Actions cache for overlay-base database with restore key ${cacheRestoreKeyPrefix}` - ); - let databaseDownloadDurationMs = 0; - try { - const databaseDownloadStart = performance.now(); - const foundKey = await waitForResultWithTimeLimit( - // This ten-minute limit for the cache restore operation is mainly to - // guard against the possibility that the cache service is unresponsive - // and hangs outside the data download. - // - // Data download (which is normally the most time-consuming part of the - // restore operation) should not run long enough to hit this limit. Even - // for an extremely large 10GB database, at a download speed of 40MB/s - // (see below), the download should complete within five minutes. If we - // do hit this limit, there are likely more serious problems other than - // mere slow download speed. - // - // This is important because we don't want any ongoing file operations - // on the database directory when we do hit this limit. Hitting this - // time limit takes us to a fallback path where we re-initialize the - // database from scratch at dbLocation, and having the cache restore - // operation continue to write into dbLocation in the background would - // really mess things up. We want to hit this limit only in the case - // of a hung cache service, not just slow download speed. - MAX_CACHE_OPERATION_MS3, - actionsCache4.restoreCache( - [dbLocation], - cacheRestoreKeyPrefix, - void 0, - { - // Azure SDK download (which is the default) uses 128MB segments; see - // https://github.com/actions/toolkit/blob/main/packages/cache/README.md. - // Setting segmentTimeoutInMs to 3000 translates to segment download - // speed of about 40 MB/s, which should be achievable unless the - // download is unreliable (in which case we do want to abort). - segmentTimeoutInMs: 3e3 - } - ), - () => { - logger.info("Timed out downloading overlay-base database from cache"); - } - ); - databaseDownloadDurationMs = Math.round( - performance.now() - databaseDownloadStart - ); - if (foundKey === void 0) { - logger.info("No overlay-base database found in Actions cache"); - return void 0; - } - logger.info( - `Downloaded overlay-base database in cache with key ${foundKey}` - ); - } catch (error3) { - logger.warning( - `Failed to download overlay-base database from cache: ${error3 instanceof Error ? error3.message : String(error3)}` - ); - return void 0; - } - const databaseIsValid = await checkOverlayBaseDatabase( - codeql, - config, - logger, - "Downloaded overlay-base database is invalid" - ); - if (!databaseIsValid) { - logger.warning("Downloaded overlay-base database failed validation"); - return void 0; - } - const databaseSizeBytes = await tryGetFolderBytes(dbLocation, logger); - if (databaseSizeBytes === void 0) { - logger.info( - "Filesystem error while accessing downloaded overlay-base database" - ); - return void 0; - } - logger.info(`Successfully downloaded overlay-base database to ${dbLocation}`); - return { - databaseSizeBytes: Math.round(databaseSizeBytes), - databaseDownloadDurationMs - }; -} -async function getCacheRestoreKeyPrefix(config, codeQlVersion) { - return `${await getCacheKeyPrefixBase(config.languages)}${codeQlVersion}-`; -} -async function getCacheKeyPrefixBase(parsedLanguages) { - const languagesComponent = [...parsedLanguages].sort().join("_"); - const cacheKeyComponents = { - automationID: await getAutomationID() - // Add more components here as needed in the future - }; - const componentsHash = createCacheKeyHash(cacheKeyComponents); - return `${CACHE_PREFIX}-${CACHE_VERSION2}-${componentsHash}-${languagesComponent}-`; -} - // src/status-report.ts var os5 = __toESM(require("os")); var core13 = __toESM(require_core()); @@ -92354,16 +92534,22 @@ async function run(startedAt) { `The 'init' action should not be run in the same workflow as 'setup-codeql'.` ); } - const codeQLDefaultVersionInfo = await features.getDefaultCliVersion( - gitHubVersion.type - ); + const codeQLDefaultVersionInfo = await features.getEnabledDefaultCliVersions(gitHubVersion.type); toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid; + const rawLanguages = getRawLanguagesNoAutodetect( + getOptionalInput("languages") + ); + const useOverlayAwareDefaultCliVersion = !!analysisKinds?.includes( + "code-scanning" /* CodeScanning */ + ); const initCodeQLResult = await initCodeQL( getOptionalInput("tools"), apiDetails, getTemporaryDirectory(), gitHubVersion.type, codeQLDefaultVersionInfo, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger ); diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index e1fa46a537..5e318a9d89 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -26352,11 +26352,11 @@ var require_valid = __commonJS({ "node_modules/semver/functions/valid.js"(exports2, module2) { "use strict"; var parse2 = require_parse2(); - var valid3 = (version, options) => { + var valid4 = (version, options) => { const v = parse2(version, options); return v ? v.version : null; }; - module2.exports = valid3; + module2.exports = valid4; } }); @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare2 = require_compare(); - var rcompare = (a, b, loose) => compare2(b, a, loose); - module2.exports = rcompare; + var rcompare3 = (a, b, loose) => compare2(b, a, loose); + module2.exports = rcompare3; } }); @@ -27716,7 +27716,7 @@ var require_semver2 = __commonJS({ var SemVer = require_semver(); var identifiers = require_identifiers(); var parse2 = require_parse2(); - var valid3 = require_valid(); + var valid4 = require_valid(); var clean3 = require_clean(); var inc = require_inc(); var diff = require_diff(); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare2 = require_compare(); - var rcompare = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27754,7 +27754,7 @@ var require_semver2 = __commonJS({ var subset = require_subset(); module2.exports = { parse: parse2, - valid: valid3, + valid: valid4, clean: clean3, inc, diff, @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare2, - rcompare, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -29553,16 +29553,16 @@ var require_attribute = __commonJS({ var result = new ValidatorResult(instance, schema2, options, ctx); var self2 = this; schema2.allOf.forEach(function(v, i) { - var valid3 = self2.validateSchema(instance, v, options, ctx); - if (!valid3.valid) { + var valid4 = self2.validateSchema(instance, v, options, ctx); + if (!valid4.valid) { var id = v.$id || v.id; var msg = id || v.title && JSON.stringify(v.title) || v["$ref"] && "<" + v["$ref"] + ">" || "[subschema " + i + "]"; result.addError({ name: "allOf", - argument: { id: msg, length: valid3.errors.length, valid: valid3 }, - message: "does not match allOf schema " + msg + " with " + valid3.errors.length + " error[s]:" + argument: { id: msg, length: valid4.errors.length, valid: valid4 }, + message: "does not match allOf schema " + msg + " with " + valid4.errors.length + " error[s]:" }); - result.importErrors(valid3); + result.importErrors(valid4); } }); return result; @@ -29851,8 +29851,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMinimum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance > schema2.exclusiveMinimum; - if (!valid3) { + var valid4 = instance > schema2.exclusiveMinimum; + if (!valid4) { result.addError({ name: "exclusiveMinimum", argument: schema2.exclusiveMinimum, @@ -29865,8 +29865,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMaximum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance < schema2.exclusiveMaximum; - if (!valid3) { + var valid4 = instance < schema2.exclusiveMaximum; + if (!valid4) { result.addError({ name: "exclusiveMaximum", argument: schema2.exclusiveMaximum, @@ -32649,8 +32649,8 @@ var require_semver3 = __commonJS({ return null; } } - exports2.valid = valid3; - function valid3(version, options) { + exports2.valid = valid4; + function valid4(version, options) { var v = parse2(version, options); return v ? v.version : null; } @@ -32950,8 +32950,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare; - function rcompare(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare2(b, a, loose); } exports2.sort = sort; @@ -33779,7 +33779,7 @@ var require_cacheUtils = __commonJS({ var crypto2 = __importStar2(require("crypto")); var fs6 = __importStar2(require("fs")); var path7 = __importStar2(require("path")); - var semver9 = __importStar2(require_semver3()); + var semver10 = __importStar2(require_semver3()); var util = __importStar2(require("util")); var constants_1 = require_constants7(); var versionSalt = "1.0"; @@ -33872,7 +33872,7 @@ var require_cacheUtils = __commonJS({ function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver9.clean(versionOutput); + const version = semver10.clean(versionOutput); core14.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; @@ -75278,7 +75278,7 @@ var require_cacheHttpClient = __commonJS({ exports2.getCacheEntry = getCacheEntry; exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; - exports2.saveCache = saveCache3; + exports2.saveCache = saveCache4; var core14 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); @@ -75455,7 +75455,7 @@ Other caches with similar key:`); })); }); } - function saveCache3(cacheId, archivePath, signedUploadURL, options) { + function saveCache4(cacheId, archivePath, signedUploadURL, options) { return __awaiter2(this, void 0, void 0, function* () { const uploadOptions = (0, options_1.getUploadOptions)(options); if (uploadOptions.useAzureSdk) { @@ -80955,8 +80955,8 @@ var require_cache4 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; exports2.isFeatureAvailable = isFeatureAvailable; - exports2.restoreCache = restoreCache3; - exports2.saveCache = saveCache3; + exports2.restoreCache = restoreCache4; + exports2.saveCache = saveCache4; var core14 = __importStar2(require_core()); var path7 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); @@ -81013,7 +81013,7 @@ var require_cache4 = __commonJS({ return !!process.env["ACTIONS_CACHE_URL"]; } } - function restoreCache3(paths_1, primaryKey_1, restoreKeys_1, options_1) { + function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core14.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81157,7 +81157,7 @@ var require_cache4 = __commonJS({ return void 0; }); } - function saveCache3(paths_1, key_1, options_1) { + function saveCache4(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core14.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81394,7 +81394,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var core_1 = require_core(); var os2 = require("os"); var cp = require("child_process"); @@ -81408,7 +81408,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver9.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver10.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -81417,7 +81417,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver9.satisfies(osVersion, item.platform_version); + chk = semver10.satisfies(osVersion, item.platform_version); } } return chk; @@ -81677,7 +81677,7 @@ var require_tool_cache = __commonJS({ var os2 = __importStar2(require("os")); var path7 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var stream = __importStar2(require("stream")); var util = __importStar2(require("util")); var assert_1 = require("assert"); @@ -81950,7 +81950,7 @@ var require_tool_cache = __commonJS({ } function cacheDir(sourceDir, tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch = arch || os2.arch(); core14.debug(`Caching tool ${tool} ${version} ${arch}`); core14.debug(`source dir: ${sourceDir}`); @@ -81968,7 +81968,7 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch = arch || os2.arch(); core14.debug(`Caching tool ${tool} ${version} ${arch}`); core14.debug(`source file: ${sourceFile}`); @@ -81998,7 +81998,7 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver9.clean(versionSpec) || ""; + versionSpec = semver10.clean(versionSpec) || ""; const cachePath = path7.join(_getCacheDirectory(), toolName, versionSpec, arch); core14.debug(`checking cache: ${cachePath}`); if (fs6.existsSync(cachePath) && fs6.existsSync(`${cachePath}.complete`)) { @@ -82078,7 +82078,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path7.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch || ""); + const folderPath = path7.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch || ""); core14.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io5.rmRF(folderPath); @@ -82088,30 +82088,30 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch) { - const folderPath = path7.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch || ""); + const folderPath = path7.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch || ""); const markerPath = `${folderPath}.complete`; fs6.writeFileSync(markerPath, ""); core14.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver9.clean(versionSpec) || ""; + const c = semver10.clean(versionSpec) || ""; core14.debug(`isExplicit: ${c}`); - const valid3 = semver9.valid(c) != null; - core14.debug(`explicit? ${valid3}`); - return valid3; + const valid4 = semver10.valid(c) != null; + core14.debug(`explicit? ${valid4}`); + return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; core14.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver9.gt(a, b)) { + if (semver10.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver9.satisfies(potential, versionSpec); + const satisfied = semver10.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -86683,6 +86683,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -86850,20 +86860,26 @@ var toolrunner3 = __toESM(require_toolrunner()); // src/setup-codeql.ts var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); + +// src/overlay/caching.ts +var actionsCache3 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; // src/tar.ts var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); // src/tools-download.ts var core10 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; // src/tracer-config.ts diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index e86bbb192a..243a749cb2 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -203,7 +203,7 @@ var require_file_command = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.issueFileCommand = issueFileCommand; exports2.prepareKeyValueMessage = prepareKeyValueMessage; - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs10 = __importStar2(require("fs")); var os3 = __importStar2(require("os")); var utils_1 = require_utils(); @@ -220,7 +220,7 @@ var require_file_command = __commonJS({ }); } function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${crypto2.randomUUID()}`; + const delimiter = `ghadelimiter_${crypto3.randomUUID()}`; const convertedValue = (0, utils_1.toCommandValue)(value); if (key.includes(delimiter)) { throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); @@ -4287,11 +4287,11 @@ var require_util2 = __commonJS({ var { isUint8Array } = require("node:util/types"); var { webidl } = require_webidl(); var supportedHashes = []; - var crypto2; + var crypto3; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); const possibleRelevantHashes = ["sha256", "sha384", "sha512"]; - supportedHashes = crypto2.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)); + supportedHashes = crypto3.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)); } catch { } function responseURL(response) { @@ -4564,7 +4564,7 @@ var require_util2 = __commonJS({ } } function bytesMatch(bytes, metadataList) { - if (crypto2 === void 0) { + if (crypto3 === void 0) { return true; } const parsedMetadata = parseMetadata(metadataList); @@ -4579,7 +4579,7 @@ var require_util2 = __commonJS({ for (const item of metadata) { const algorithm = item.algo; const expectedValue = item.hash; - let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64"); + let actualValue = crypto3.createHash(algorithm).update(bytes).digest("base64"); if (actualValue[actualValue.length - 1] === "=") { if (actualValue[actualValue.length - 2] === "=") { actualValue = actualValue.slice(0, -2); @@ -5643,8 +5643,8 @@ var require_body = __commonJS({ var { multipartFormDataParser } = require_formdata_parser(); var random; try { - const crypto2 = require("node:crypto"); - random = (max) => crypto2.randomInt(0, max); + const crypto3 = require("node:crypto"); + random = (max) => crypto3.randomInt(0, max); } catch { random = (max) => Math.floor(Math.random(max)); } @@ -17052,13 +17052,13 @@ var require_frame = __commonJS({ "use strict"; var { maxUnsigned16Bit } = require_constants5(); var BUFFER_SIZE = 16386; - var crypto2; + var crypto3; var buffer = null; var bufIdx = BUFFER_SIZE; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); } catch { - crypto2 = { + crypto3 = { // not full compatibility, but minimum. randomFillSync: function randomFillSync(buffer2, _offset, _size) { for (let i = 0; i < buffer2.length; ++i) { @@ -17071,7 +17071,7 @@ var require_frame = __commonJS({ function generateMask() { if (bufIdx === BUFFER_SIZE) { bufIdx = 0; - crypto2.randomFillSync(buffer ??= Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE); + crypto3.randomFillSync(buffer ??= Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE); } return [buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++]]; } @@ -17143,9 +17143,9 @@ var require_connection = __commonJS({ var { Headers, getHeadersList } = require_headers(); var { getDecodeSplit } = require_util2(); var { WebsocketFrameSend } = require_frame(); - var crypto2; + var crypto3; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); } catch { } function establishWebSocketConnection(url, protocols, client, ws, onEstablish, options) { @@ -17165,7 +17165,7 @@ var require_connection = __commonJS({ const headersList = getHeadersList(new Headers(options.headers)); request2.headersList = headersList; } - const keyValue = crypto2.randomBytes(16).toString("base64"); + const keyValue = crypto3.randomBytes(16).toString("base64"); request2.headersList.append("sec-websocket-key", keyValue); request2.headersList.append("sec-websocket-version", "13"); for (const protocol of protocols) { @@ -17195,7 +17195,7 @@ var require_connection = __commonJS({ return; } const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); - const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64"); + const digest = crypto3.createHash("sha1").update(keyValue + uid).digest("base64"); if (secWSAccept !== digest) { failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header."); return; @@ -26352,11 +26352,11 @@ var require_valid = __commonJS({ "node_modules/semver/functions/valid.js"(exports2, module2) { "use strict"; var parse2 = require_parse2(); - var valid3 = (version, options) => { + var valid4 = (version, options) => { const v = parse2(version, options); return v ? v.version : null; }; - module2.exports = valid3; + module2.exports = valid4; } }); @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare2 = require_compare(); - var rcompare = (a, b, loose) => compare2(b, a, loose); - module2.exports = rcompare; + var rcompare3 = (a, b, loose) => compare2(b, a, loose); + module2.exports = rcompare3; } }); @@ -27716,7 +27716,7 @@ var require_semver2 = __commonJS({ var SemVer = require_semver(); var identifiers = require_identifiers(); var parse2 = require_parse2(); - var valid3 = require_valid(); + var valid4 = require_valid(); var clean3 = require_clean(); var inc = require_inc(); var diff = require_diff(); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare2 = require_compare(); - var rcompare = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27754,7 +27754,7 @@ var require_semver2 = __commonJS({ var subset = require_subset(); module2.exports = { parse: parse2, - valid: valid3, + valid: valid4, clean: clean3, inc, diff, @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare2, - rcompare, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -29553,16 +29553,16 @@ var require_attribute = __commonJS({ var result = new ValidatorResult(instance, schema2, options, ctx); var self2 = this; schema2.allOf.forEach(function(v, i) { - var valid3 = self2.validateSchema(instance, v, options, ctx); - if (!valid3.valid) { + var valid4 = self2.validateSchema(instance, v, options, ctx); + if (!valid4.valid) { var id = v.$id || v.id; var msg = id || v.title && JSON.stringify(v.title) || v["$ref"] && "<" + v["$ref"] + ">" || "[subschema " + i + "]"; result.addError({ name: "allOf", - argument: { id: msg, length: valid3.errors.length, valid: valid3 }, - message: "does not match allOf schema " + msg + " with " + valid3.errors.length + " error[s]:" + argument: { id: msg, length: valid4.errors.length, valid: valid4 }, + message: "does not match allOf schema " + msg + " with " + valid4.errors.length + " error[s]:" }); - result.importErrors(valid3); + result.importErrors(valid4); } }); return result; @@ -29851,8 +29851,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMinimum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance > schema2.exclusiveMinimum; - if (!valid3) { + var valid4 = instance > schema2.exclusiveMinimum; + if (!valid4) { result.addError({ name: "exclusiveMinimum", argument: schema2.exclusiveMinimum, @@ -29865,8 +29865,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMaximum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance < schema2.exclusiveMaximum; - if (!valid3) { + var valid4 = instance < schema2.exclusiveMaximum; + if (!valid4) { result.addError({ name: "exclusiveMaximum", argument: schema2.exclusiveMaximum, @@ -32371,7 +32371,7 @@ var require_internal_hash_files = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.hashFiles = hashFiles; - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var core15 = __importStar2(require_core()); var fs10 = __importStar2(require("fs")); var stream2 = __importStar2(require("stream")); @@ -32384,7 +32384,7 @@ var require_internal_hash_files = __commonJS({ const writeDelegate = verbose ? core15.info : core15.debug; let hasMatch = false; const githubWorkspace = currentWorkspace ? currentWorkspace : (_d = process.env["GITHUB_WORKSPACE"]) !== null && _d !== void 0 ? _d : process.cwd(); - const result = crypto2.createHash("sha256"); + const result = crypto3.createHash("sha256"); let count = 0; try { for (var _e = true, _f = __asyncValues2(globber.globGenerator()), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) { @@ -32400,7 +32400,7 @@ var require_internal_hash_files = __commonJS({ writeDelegate(`Skip directory '${file}'.`); continue; } - const hash = crypto2.createHash("sha256"); + const hash = crypto3.createHash("sha256"); const pipeline = util.promisify(stream2.pipeline); yield pipeline(fs10.createReadStream(file), hash); result.write(hash.digest()); @@ -32649,8 +32649,8 @@ var require_semver3 = __commonJS({ return null; } } - exports2.valid = valid3; - function valid3(version, options) { + exports2.valid = valid4; + function valid4(version, options) { var v = parse2(version, options); return v ? v.version : null; } @@ -32950,8 +32950,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare; - function rcompare(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare2(b, a, loose); } exports2.sort = sort; @@ -33776,10 +33776,10 @@ var require_cacheUtils = __commonJS({ var exec = __importStar2(require_exec()); var glob = __importStar2(require_glob()); var io6 = __importStar2(require_io()); - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs10 = __importStar2(require("fs")); var path10 = __importStar2(require("path")); - var semver9 = __importStar2(require_semver3()); + var semver10 = __importStar2(require_semver3()); var util = __importStar2(require("util")); var constants_1 = require_constants7(); var versionSalt = "1.0"; @@ -33800,7 +33800,7 @@ var require_cacheUtils = __commonJS({ } tempDirectory = path10.join(baseLocation, "actions", "temp"); } - const dest = path10.join(tempDirectory, crypto2.randomUUID()); + const dest = path10.join(tempDirectory, crypto3.randomUUID()); yield io6.mkdirP(dest); return dest; }); @@ -33872,7 +33872,7 @@ var require_cacheUtils = __commonJS({ function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver9.clean(versionOutput); + const version = semver10.clean(versionOutput); core15.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; @@ -33908,7 +33908,7 @@ var require_cacheUtils = __commonJS({ components.push("windows-only"); } components.push(versionSalt); - return crypto2.createHash("sha256").update(components.join("|")).digest("hex"); + return crypto3.createHash("sha256").update(components.join("|")).digest("hex"); } function getRuntimeToken() { const token = process.env["ACTIONS_RUNTIME_TOKEN"]; @@ -75278,7 +75278,7 @@ var require_cacheHttpClient = __commonJS({ exports2.getCacheEntry = getCacheEntry; exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; - exports2.saveCache = saveCache3; + exports2.saveCache = saveCache4; var core15 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); @@ -75455,7 +75455,7 @@ Other caches with similar key:`); })); }); } - function saveCache3(cacheId, archivePath, signedUploadURL, options) { + function saveCache4(cacheId, archivePath, signedUploadURL, options) { return __awaiter2(this, void 0, void 0, function* () { const uploadOptions = (0, options_1.getUploadOptions)(options); if (uploadOptions.useAzureSdk) { @@ -80955,8 +80955,8 @@ var require_cache4 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; exports2.isFeatureAvailable = isFeatureAvailable; - exports2.restoreCache = restoreCache3; - exports2.saveCache = saveCache3; + exports2.restoreCache = restoreCache4; + exports2.saveCache = saveCache4; var core15 = __importStar2(require_core()); var path10 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); @@ -81013,7 +81013,7 @@ var require_cache4 = __commonJS({ return !!process.env["ACTIONS_CACHE_URL"]; } } - function restoreCache3(paths_1, primaryKey_1, restoreKeys_1, options_1) { + function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core15.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81157,7 +81157,7 @@ var require_cache4 = __commonJS({ return void 0; }); } - function saveCache3(paths_1, key_1, options_1) { + function saveCache4(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core15.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81394,7 +81394,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var core_1 = require_core(); var os3 = require("os"); var cp = require("child_process"); @@ -81408,7 +81408,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver9.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver10.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -81417,7 +81417,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver9.satisfies(osVersion, item.platform_version); + chk = semver10.satisfies(osVersion, item.platform_version); } } return chk; @@ -81671,13 +81671,13 @@ var require_tool_cache = __commonJS({ exports2.evaluateVersions = evaluateVersions; var core15 = __importStar2(require_core()); var io6 = __importStar2(require_io()); - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs10 = __importStar2(require("fs")); var mm = __importStar2(require_manifest()); var os3 = __importStar2(require("os")); var path10 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var stream2 = __importStar2(require("stream")); var util = __importStar2(require("util")); var assert_1 = require("assert"); @@ -81696,7 +81696,7 @@ var require_tool_cache = __commonJS({ var userAgent2 = "actions/tool-cache"; function downloadTool2(url, dest, auth2, headers) { return __awaiter2(this, void 0, void 0, function* () { - dest = dest || path10.join(_getTempDirectory(), crypto2.randomUUID()); + dest = dest || path10.join(_getTempDirectory(), crypto3.randomUUID()); yield io6.mkdirP(path10.dirname(dest)); core15.debug(`Downloading ${url}`); core15.debug(`Destination ${dest}`); @@ -81950,7 +81950,7 @@ var require_tool_cache = __commonJS({ } function cacheDir(sourceDir, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch2 = arch2 || os3.arch(); core15.debug(`Caching tool ${tool} ${version} ${arch2}`); core15.debug(`source dir: ${sourceDir}`); @@ -81968,7 +81968,7 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch2 = arch2 || os3.arch(); core15.debug(`Caching tool ${tool} ${version} ${arch2}`); core15.debug(`source file: ${sourceFile}`); @@ -81998,7 +81998,7 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver9.clean(versionSpec) || ""; + versionSpec = semver10.clean(versionSpec) || ""; const cachePath = path10.join(_getCacheDirectory(), toolName, versionSpec, arch2); core15.debug(`checking cache: ${cachePath}`); if (fs10.existsSync(cachePath) && fs10.existsSync(`${cachePath}.complete`)) { @@ -82070,7 +82070,7 @@ var require_tool_cache = __commonJS({ function _createExtractFolder(dest) { return __awaiter2(this, void 0, void 0, function* () { if (!dest) { - dest = path10.join(_getTempDirectory(), crypto2.randomUUID()); + dest = path10.join(_getTempDirectory(), crypto3.randomUUID()); } yield io6.mkdirP(dest); return dest; @@ -82078,7 +82078,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path10.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); + const folderPath = path10.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch2 || ""); core15.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io6.rmRF(folderPath); @@ -82088,30 +82088,30 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch2) { - const folderPath = path10.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); + const folderPath = path10.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch2 || ""); const markerPath = `${folderPath}.complete`; fs10.writeFileSync(markerPath, ""); core15.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver9.clean(versionSpec) || ""; + const c = semver10.clean(versionSpec) || ""; core15.debug(`isExplicit: ${c}`); - const valid3 = semver9.valid(c) != null; - core15.debug(`explicit? ${valid3}`); - return valid3; + const valid4 = semver10.valid(c) != null; + core15.debug(`explicit? ${valid4}`); + return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; core15.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver9.gt(a, b)) { + if (semver10.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver9.satisfies(potential, versionSpec); + const satisfied = semver10.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -85605,6 +85605,12 @@ async function checkForTimeout() { process.exit(); } } +function parseMatrixInput(matrixInput) { + if (matrixInput === void 0 || matrixInput === "null") { + return void 0; + } + return JSON.parse(matrixInput); +} function wrapError(error3) { return error3 instanceof Error ? error3 : new Error(String(error3)); } @@ -85824,6 +85830,92 @@ async function runTool(cmd, args = [], opts = {}) { } return stdout; } +function getPullRequestBranches() { + const pullRequest = github.context.payload.pull_request; + if (pullRequest) { + return { + base: pullRequest.base.ref, + // We use the head label instead of the head ref here, because the head + // ref lacks owner information and by itself does not uniquely identify + // the head branch (which may be in a forked repository). + head: pullRequest.head.label + }; + } + const codeScanningRef = process.env.CODE_SCANNING_REF; + const codeScanningBaseBranch = process.env.CODE_SCANNING_BASE_BRANCH; + if (codeScanningRef && codeScanningBaseBranch) { + return { + base: codeScanningBaseBranch, + // PR analysis under Default Setup analyzes the PR head commit instead of + // the merge commit, so we can use the provided ref directly. + head: codeScanningRef + }; + } + return void 0; +} +function isAnalyzingPullRequest() { + return getPullRequestBranches() !== void 0; +} + +// src/analyses.ts +var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { + AnalysisKind2["CodeScanning"] = "code-scanning"; + AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["RiskAssessment"] = "risk-assessment"; + return AnalysisKind2; +})(AnalysisKind || {}); +var compatibilityMatrix = { + ["code-scanning" /* CodeScanning */]: /* @__PURE__ */ new Set(["code-quality" /* CodeQuality */]), + ["code-quality" /* CodeQuality */]: /* @__PURE__ */ new Set(["code-scanning" /* CodeScanning */]), + ["risk-assessment" /* RiskAssessment */]: /* @__PURE__ */ new Set() +}; +var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); +async function parseAnalysisKinds(input) { + const components = input.split(","); + if (components.length < 1) { + throw new ConfigurationError( + "At least one analysis kind must be configured." + ); + } + for (const component of components) { + if (!supportedAnalysisKinds.has(component)) { + throw new ConfigurationError(`Unknown analysis kind: ${component}`); + } + } + return Array.from( + new Set(components.map((component) => component)) + ); +} +var cachedAnalysisKinds; +async function getAnalysisKinds(logger, skipCache = false) { + if (!skipCache && cachedAnalysisKinds !== void 0) { + return cachedAnalysisKinds; + } + const analysisKinds = await parseAnalysisKinds( + getRequiredInput("analysis-kinds") + ); + const qualityQueriesInput = getOptionalInput("quality-queries"); + if (qualityQueriesInput !== void 0) { + logger.warning( + "The `quality-queries` input is deprecated and will be removed in a future version of the CodeQL Action. Use the `analysis-kinds` input to configure different analysis kinds instead." + ); + } + if (!analysisKinds.includes("code-quality" /* CodeQuality */) && qualityQueriesInput !== void 0) { + analysisKinds.push("code-quality" /* CodeQuality */); + } + for (const analysisKind of analysisKinds) { + for (const otherAnalysisKind of analysisKinds) { + if (analysisKind === otherAnalysisKind) continue; + if (!compatibilityMatrix[analysisKind].has(otherAnalysisKind)) { + throw new ConfigurationError( + `${analysisKind} and ${otherAnalysisKind} cannot be enabled at the same time` + ); + } + } + } + cachedAnalysisKinds = analysisKinds; + return cachedAnalysisKinds; +} // src/api-client.ts var core5 = __toESM(require_core()); @@ -86023,6 +86115,37 @@ async function getAnalysisKey() { core5.exportVariable("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); return analysisKey; } +async function getAutomationID() { + const analysis_key = await getAnalysisKey(); + const environment = getRequiredInput("matrix"); + return computeAutomationID(analysis_key, environment); +} +function computeAutomationID(analysis_key, environment) { + let automationID = `${analysis_key}/`; + const matrix = parseMatrixInput(environment); + if (matrix !== void 0) { + for (const entry of Object.entries(matrix).sort()) { + if (typeof entry[1] === "string") { + automationID += `${entry[0]}:${entry[1]}/`; + } else { + automationID += `${entry[0]}:/`; + } + } + } + return automationID; +} +async function listActionsCaches(keyPrefix, ref) { + const repositoryNwo = getRepositoryNwo(); + return await getApiClient().paginate( + "GET /repos/{owner}/{repo}/actions/caches", + { + owner: repositoryNwo.owner, + repo: repositoryNwo.repo, + key: keyPrefix, + ref + } + ); +} function isEnablementError(msg) { return [ /Code Security must be enabled/i, @@ -86061,10 +86184,146 @@ function wrapApiConfigurationError(e) { return e; } +// src/config-utils.ts +var core9 = __toESM(require_core()); + +// src/caching-utils.ts +var crypto2 = __toESM(require("crypto")); +var core6 = __toESM(require_core()); +var cacheKeyHashLength = 16; +function createCacheKeyHash(components) { + const componentsJson = JSON.stringify(components); + return crypto2.createHash("sha256").update(componentsJson).digest("hex").substring(0, cacheKeyHashLength); +} + +// src/config/db-config.ts +var jsonschema = __toESM(require_lib2()); +var semver2 = __toESM(require_semver2()); + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); + +// src/config/db-config.ts +var PACK_IDENTIFIER_PATTERN = (function() { + const alphaNumeric = "[a-z0-9]"; + const alphaNumericDash = "[a-z0-9-]"; + const component = `${alphaNumeric}(${alphaNumericDash}*${alphaNumeric})?`; + return new RegExp(`^${component}/${component}$`); +})(); + +// src/diagnostics.ts +var import_fs = require("fs"); +var import_path = __toESM(require("path")); + +// src/logging.ts +var core7 = __toESM(require_core()); +function getActionsLogger() { + return { + debug: core7.debug, + info: core7.info, + warning: core7.warning, + error: core7.error, + isDebug: core7.isDebug, + startGroup: core7.startGroup, + endGroup: core7.endGroup + }; +} +function formatDuration(durationMs) { + if (durationMs < 1e3) { + return `${durationMs}ms`; + } + if (durationMs < 60 * 1e3) { + return `${(durationMs / 1e3).toFixed(1)}s`; + } + const minutes = Math.floor(durationMs / (60 * 1e3)); + const seconds = Math.floor(durationMs % (60 * 1e3) / 1e3); + return `${minutes}m${seconds}s`; +} + +// src/diagnostics.ts +var unwrittenDiagnostics = []; +var unwrittenDefaultLanguageDiagnostics = []; +var diagnosticCounter = 0; +function makeDiagnostic(id, name, data = void 0) { + return { + ...data, + timestamp: data?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(), + source: { ...data?.source, id, name } + }; +} +function addDiagnostic(config, language, diagnostic) { + const logger = getActionsLogger(); + const databasePath = language ? getCodeQLDatabasePath(config, language) : config.dbLocation; + if ((0, import_fs.existsSync)(databasePath)) { + writeDiagnostic(config, language, diagnostic); + } else { + logger.debug( + `Writing a diagnostic for ${language}, but the database at ${databasePath} does not exist yet.` + ); + unwrittenDiagnostics.push({ diagnostic, language }); + } +} +function addNoLanguageDiagnostic(config, diagnostic) { + if (config !== void 0) { + addDiagnostic( + config, + // Arbitrarily choose the first language. We could also choose all languages, but that + // increases the risk of misinterpreting the data. + config.languages[0], + diagnostic + ); + } else { + unwrittenDefaultLanguageDiagnostics.push(diagnostic); + } +} +function writeDiagnostic(config, language, diagnostic) { + const logger = getActionsLogger(); + const databasePath = language ? getCodeQLDatabasePath(config, language) : config.dbLocation; + const diagnosticsPath = import_path.default.resolve( + databasePath, + "diagnostic", + "codeql-action" + ); + try { + (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); + const uniqueSuffix = (diagnosticCounter++).toString(); + const sanitizedTimestamp = diagnostic.timestamp.replace( + /[^a-zA-Z0-9.-]/g, + "" + ); + const jsonPath = import_path.default.resolve( + diagnosticsPath, + `codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json` + ); + (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); + } catch (err) { + logger.warning(`Unable to write diagnostic message to database: ${err}`); + logger.debug(JSON.stringify(diagnostic)); + } +} +function makeTelemetryDiagnostic(id, name, attributes) { + return makeDiagnostic(id, name, { + attributes, + visibility: { + cliSummaryTable: false, + statusPage: false, + telemetry: true + } + }); +} + // src/feature-flags.ts var fs5 = __toESM(require("fs")); -var path5 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); +var path6 = __toESM(require("path")); +var semver5 = __toESM(require_semver2()); // src/defaults.json var bundleVersion = "codeql-bundle-v2.25.4"; @@ -86072,19 +86331,19 @@ var cliVersion = "2.25.4"; // src/overlay/index.ts var fs4 = __toESM(require("fs")); -var path4 = __toESM(require("path")); +var path5 = __toESM(require("path")); // src/git-utils.ts var fs3 = __toESM(require("fs")); -var path3 = __toESM(require("path")); -var core6 = __toESM(require_core()); +var path4 = __toESM(require("path")); +var core8 = __toESM(require_core()); var toolrunner2 = __toESM(require_toolrunner()); var io3 = __toESM(require_io()); -var semver2 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); var runGitCommand = async function(workingDirectory, args, customErrorMessage, options) { let stdout = ""; let stderr = ""; - core6.debug(`Running git command: git ${args.join(" ")}`); + core8.debug(`Running git command: git ${args.join(" ")}`); try { await new toolrunner2.ToolRunner(await io3.which("git", true), args, { silent: true, @@ -86105,7 +86364,7 @@ var runGitCommand = async function(workingDirectory, args, customErrorMessage, o if (stderr.includes("not a git repository")) { reason = "The checkout path provided to the action does not appear to be a git repository."; } - core6.info(`git call failed. ${customErrorMessage} Error: ${reason}`); + core8.info(`git call failed. ${customErrorMessage} Error: ${reason}`); throw error3; } }; @@ -86167,7 +86426,7 @@ var getGitRoot = async function(sourceRoot) { } }; function hasSubmodules(gitRoot) { - return fs3.existsSync(path3.join(gitRoot, ".gitmodules")); + return fs3.existsSync(path4.join(gitRoot, ".gitmodules")); } var getFileOidsUnderPath = async function(basePath) { const gitRoot = await getGitRoot(basePath); @@ -86234,7 +86493,7 @@ async function getRef() { ) !== head; if (hasChangedRef) { const newRef = ref.replace(pull_ref_regex, "refs/pull/$1/head"); - core6.debug( + core8.debug( `No longer on merge commit, rewriting ref from ${ref} to ${newRef}.` ); return newRef; @@ -86299,7 +86558,7 @@ async function writeOverlayChangesFile(config, sourceRoot, logger) { const diffRangeFiles = await getDiffRangeFilePaths(sourceRoot, logger); const changedFiles = [.../* @__PURE__ */ new Set([...oidChangedFiles, ...diffRangeFiles])]; const changedFilesJson = JSON.stringify({ changes: changedFiles }); - const overlayChangesFile = path4.join( + const overlayChangesFile = path5.join( getTemporaryDirectory(), "overlay-changes.json" ); @@ -86365,13 +86624,13 @@ async function getDiffRangeFilePaths(sourceRoot, logger) { return [...new Set(diffRanges.map((r) => r.path))]; } const relativePaths = diffRanges.map( - (r) => path4.relative(sourceRoot, path4.join(repoRoot, r.path)).replaceAll(path4.sep, "/") + (r) => path5.relative(sourceRoot, path5.join(repoRoot, r.path)).replaceAll(path5.sep, "/") ).filter((rel) => !rel.startsWith("..")); return [...new Set(relativePaths)]; } // src/tools-features.ts -var semver3 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); function isSupportedToolsFeature(versionInfo, feature) { return !!versionInfo.features && versionInfo.features[feature]; } @@ -86380,6 +86639,10 @@ function isSupportedToolsFeature(versionInfo, feature) { var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_"; var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled"; var CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0"; +var LINKED_CODEQL_VERSION = { + cliVersion, + tagName: bundleVersion +}; var featureConfig = { ["allow_toolcache_input" /* AllowToolcacheInput */]: { defaultValue: false, @@ -86534,6 +86797,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -86594,10 +86867,9 @@ var OfflineFeatures = class { this.logger = logger; } logger; - async getDefaultCliVersion(_variant) { + async getEnabledDefaultCliVersions(_variant) { return { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; } /** @@ -86698,15 +86970,15 @@ var Features = class extends OfflineFeatures { super(logger); this.gitHubFeatureFlags = new GitHubFeatureFlags( repositoryNwo, - path5.join(tempDir, FEATURE_FLAGS_FILE_NAME), + path6.join(tempDir, FEATURE_FLAGS_FILE_NAME), logger ); } - async getDefaultCliVersion(variant) { + async getEnabledDefaultCliVersions(variant) { if (supportsFeatureFlags(variant)) { - return await this.gitHubFeatureFlags.getDefaultCliVersionFromFlags(); + return await this.gitHubFeatureFlags.getEnabledDefaultCliVersionsFromFlags(); } - return super.getDefaultCliVersion(variant); + return super.getEnabledDefaultCliVersions(variant); } /** * @@ -86757,7 +87029,7 @@ var GitHubFeatureFlags = class { DEFAULT_VERSION_FEATURE_FLAG_PREFIX.length, f.length - DEFAULT_VERSION_FEATURE_FLAG_SUFFIX.length ).replace(/_/g, "."); - if (!semver4.valid(version)) { + if (!semver5.valid(version)) { this.logger.warning( `Ignoring feature flag ${f} as it does not specify a valid CodeQL version.` ); @@ -86765,34 +87037,36 @@ var GitHubFeatureFlags = class { } return version; } - async getDefaultCliVersionFromFlags() { + /** + * Returns CLI versions enabled by `default_codeql_version_*_enabled` feature + * flags, sorted from highest to lowest. Falls back to the version pinned in + * `defaults.json` if no such flags are enabled. + */ + async getEnabledDefaultCliVersionsFromFlags() { const response = await this.getAllFeatures(); - const enabledFeatureFlagCliVersions = Object.entries(response).map( + const sortedCliVersions = Object.entries(response).map( ([f, isEnabled]) => isEnabled ? this.getCliVersionFromFeatureFlag(f) : void 0 - ).filter((f) => f !== void 0); - if (enabledFeatureFlagCliVersions.length === 0) { + ).filter((f) => f !== void 0).sort(semver5.rcompare); + if (sortedCliVersions.length === 0) { this.logger.warning( `Feature flags do not specify a default CLI version. Falling back to the CLI version shipped with the Action. This is ${cliVersion}.` ); const result = { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; if (this.hasAccessedRemoteFeatureFlags) { result.toolsFeatureFlagsValid = false; } return result; } - const maxCliVersion = enabledFeatureFlagCliVersions.reduce( - (maxVersion, currentVersion) => currentVersion > maxVersion ? currentVersion : maxVersion, - enabledFeatureFlagCliVersions[0] - ); this.logger.debug( - `Derived default CLI version of ${maxCliVersion} from feature flags.` + `Derived default CLI version of ${sortedCliVersions[0]} from feature flags.` ); return { - cliVersion: maxCliVersion, - tagName: `codeql-bundle-v${maxCliVersion}`, + enabledVersions: sortedCliVersions.map((cliVersion2) => ({ + cliVersion: cliVersion2, + tagName: `codeql-bundle-v${cliVersion2}` + })), toolsFeatureFlagsValid: true }; } @@ -86916,6 +87190,99 @@ function initFeatures(gitHubVersion, repositoryNwo, tempDir, logger) { } } +// src/languages/builtin.json +var builtin_default = { + languages: [ + "actions", + "cpp", + "csharp", + "go", + "java", + "javascript", + "python", + "ruby", + "rust", + "swift" + ], + aliases: { + c: "cpp", + "c-c++": "cpp", + "c-cpp": "cpp", + "c#": "csharp", + "c++": "cpp", + "java-kotlin": "java", + "javascript-typescript": "javascript", + kotlin: "java", + typescript: "javascript" + } +}; + +// src/languages/index.ts +var builtInLanguageSet = new Set(builtin_default.languages); +function isBuiltInLanguage(language) { + return builtInLanguageSet.has(language); +} +function parseBuiltInLanguage(language) { + language = language.trim().toLowerCase(); + language = builtin_default.aliases[language] ?? language; + if (isBuiltInLanguage(language)) { + return language; + } + return void 0; +} + +// src/overlay/status.ts +var actionsCache = __toESM(require_cache4()); + +// src/trap-caching.ts +var actionsCache2 = __toESM(require_cache4()); + +// src/config-utils.ts +var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB = 2e4; +var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES = OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB * 1e6; +var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_MB = 14e3; +var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES = OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_MB * 1e6; +var OVERLAY_MINIMUM_MEMORY_MB = 5 * 1024; +function getRawLanguagesNoAutodetect(languagesInput) { + return (languagesInput || "").split(",").map((x) => x.trim().toLowerCase()).filter((x) => x.length > 0); +} +var OVERLAY_ANALYSIS_FEATURES = { + cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, + csharp: "overlay_analysis_csharp" /* OverlayAnalysisCsharp */, + go: "overlay_analysis_go" /* OverlayAnalysisGo */, + java: "overlay_analysis_java" /* OverlayAnalysisJava */, + javascript: "overlay_analysis_javascript" /* OverlayAnalysisJavascript */, + python: "overlay_analysis_python" /* OverlayAnalysisPython */, + ruby: "overlay_analysis_ruby" /* OverlayAnalysisRuby */ +}; +var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { + cpp: "overlay_analysis_code_scanning_cpp" /* OverlayAnalysisCodeScanningCpp */, + csharp: "overlay_analysis_code_scanning_csharp" /* OverlayAnalysisCodeScanningCsharp */, + go: "overlay_analysis_code_scanning_go" /* OverlayAnalysisCodeScanningGo */, + java: "overlay_analysis_code_scanning_java" /* OverlayAnalysisCodeScanningJava */, + javascript: "overlay_analysis_code_scanning_javascript" /* OverlayAnalysisCodeScanningJavascript */, + python: "overlay_analysis_code_scanning_python" /* OverlayAnalysisCodeScanningPython */, + ruby: "overlay_analysis_code_scanning_ruby" /* OverlayAnalysisCodeScanningRuby */ +}; +function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { + const augmentedConfig = cloneObject(cliConfig); + if (extraQueryExclusions.length === 0) { + return augmentedConfig; + } + augmentedConfig["query-filters"] = [ + // Ordering matters. If the first filter is an inclusion, it implicitly + // excludes all queries that are not included. If it is an exclusion, + // it implicitly includes all queries that are not excluded. So user + // filters (if any) should always be first to preserve intent. + ...augmentedConfig["query-filters"] || [], + ...extraQueryExclusions + ]; + if (augmentedConfig["query-filters"]?.length === 0) { + delete augmentedConfig["query-filters"]; + } + return augmentedConfig; +} + // src/init.ts var core12 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); @@ -87176,221 +87543,75 @@ function wrapCliConfigurationError(cliError) { return new ConfigurationError(errorMessageBuilder); } -// src/config-utils.ts -var core9 = __toESM(require_core()); - -// src/analyses.ts -var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { - AnalysisKind2["CodeScanning"] = "code-scanning"; - AnalysisKind2["CodeQuality"] = "code-quality"; - AnalysisKind2["RiskAssessment"] = "risk-assessment"; - return AnalysisKind2; -})(AnalysisKind || {}); -var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); - -// src/caching-utils.ts -var core7 = __toESM(require_core()); - -// src/config/db-config.ts -var jsonschema = __toESM(require_lib2()); -var semver5 = __toESM(require_semver2()); - -// src/feature-flags/properties.ts -var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { - RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; - RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; - RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; - return RepositoryPropertyName2; -})(RepositoryPropertyName || {}); -var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( - Object.values(RepositoryPropertyName) -); - -// src/config/db-config.ts -var PACK_IDENTIFIER_PATTERN = (function() { - const alphaNumeric = "[a-z0-9]"; - const alphaNumericDash = "[a-z0-9-]"; - const component = `${alphaNumeric}(${alphaNumericDash}*${alphaNumeric})?`; - return new RegExp(`^${component}/${component}$`); -})(); - -// src/diagnostics.ts -var import_fs = require("fs"); -var import_path = __toESM(require("path")); - -// src/logging.ts -var core8 = __toESM(require_core()); -function getActionsLogger() { - return { - debug: core8.debug, - info: core8.info, - warning: core8.warning, - error: core8.error, - isDebug: core8.isDebug, - startGroup: core8.startGroup, - endGroup: core8.endGroup - }; -} -function formatDuration(durationMs) { - if (durationMs < 1e3) { - return `${durationMs}ms`; - } - if (durationMs < 60 * 1e3) { - return `${(durationMs / 1e3).toFixed(1)}s`; - } - const minutes = Math.floor(durationMs / (60 * 1e3)); - const seconds = Math.floor(durationMs % (60 * 1e3) / 1e3); - return `${minutes}m${seconds}s`; -} +// src/setup-codeql.ts +var fs8 = __toESM(require("fs")); +var path8 = __toESM(require("path")); +var toolcache3 = __toESM(require_tool_cache()); +var import_fast_deep_equal = __toESM(require_fast_deep_equal()); +var semver9 = __toESM(require_semver2()); -// src/diagnostics.ts -var unwrittenDiagnostics = []; -var unwrittenDefaultLanguageDiagnostics = []; -var diagnosticCounter = 0; -function makeDiagnostic(id, name, data = void 0) { - return { - ...data, - timestamp: data?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(), - source: { ...data?.source, id, name } +// src/overlay/caching.ts +var actionsCache3 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; +var CACHE_VERSION = 1; +var CACHE_PREFIX = "codeql-overlay-base-database"; +async function getCacheKeyPrefixBase(parsedLanguages) { + const languagesComponent = [...parsedLanguages].sort().join("_"); + const cacheKeyComponents = { + automationID: await getAutomationID() + // Add more components here as needed in the future }; + const componentsHash = createCacheKeyHash(cacheKeyComponents); + return `${CACHE_PREFIX}-${CACHE_VERSION}-${componentsHash}-${languagesComponent}-`; } -function addDiagnostic(config, language, diagnostic) { - const logger = getActionsLogger(); - const databasePath = language ? getCodeQLDatabasePath(config, language) : config.dbLocation; - if ((0, import_fs.existsSync)(databasePath)) { - writeDiagnostic(config, language, diagnostic); - } else { - logger.debug( - `Writing a diagnostic for ${language}, but the database at ${databasePath} does not exist yet.` - ); - unwrittenDiagnostics.push({ diagnostic, language }); - } -} -function addNoLanguageDiagnostic(config, diagnostic) { - if (config !== void 0) { - addDiagnostic( - config, - // Arbitrarily choose the first language. We could also choose all languages, but that - // increases the risk of misinterpreting the data. - config.languages[0], - diagnostic +async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger) { + const languages = rawLanguages.map(parseBuiltInLanguage); + if (languages.includes(void 0)) { + logger.warning( + "One or more provided languages are not recognized as built-in languages. Skipping searching for overlay-base databases in cache." ); - } else { - unwrittenDefaultLanguageDiagnostics.push(diagnostic); + return void 0; } -} -function writeDiagnostic(config, language, diagnostic) { - const logger = getActionsLogger(); - const databasePath = language ? getCodeQLDatabasePath(config, language) : config.dbLocation; - const diagnosticsPath = import_path.default.resolve( - databasePath, - "diagnostic", - "codeql-action" + const dedupedLanguages = [ + ...new Set(languages.filter((l) => l !== void 0)) + ]; + const cacheKeyPrefix = await getCacheKeyPrefixBase(dedupedLanguages); + logger.debug( + `Searching for overlay-base databases in Actions cache with prefix ${cacheKeyPrefix}` ); - try { - (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); - const uniqueSuffix = (diagnosticCounter++).toString(); - const sanitizedTimestamp = diagnostic.timestamp.replace( - /[^a-zA-Z0-9.-]/g, - "" - ); - const jsonPath = import_path.default.resolve( - diagnosticsPath, - `codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json` - ); - (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); - } catch (err) { - logger.warning(`Unable to write diagnostic message to database: ${err}`); - logger.debug(JSON.stringify(diagnostic)); - } -} - -// src/languages/builtin.json -var builtin_default = { - languages: [ - "actions", - "cpp", - "csharp", - "go", - "java", - "javascript", - "python", - "ruby", - "rust", - "swift" - ], - aliases: { - c: "cpp", - "c-c++": "cpp", - "c-cpp": "cpp", - "c#": "csharp", - "c++": "cpp", - "java-kotlin": "java", - "javascript-typescript": "javascript", - kotlin: "java", - typescript: "javascript" + const caches = await listActionsCaches(cacheKeyPrefix); + if (caches.length === 0) { + logger.info("No overlay-base databases found in Actions cache."); + return []; } -}; - -// src/languages/index.ts -var builtInLanguageSet = new Set(builtin_default.languages); - -// src/overlay/status.ts -var actionsCache = __toESM(require_cache4()); - -// src/trap-caching.ts -var actionsCache2 = __toESM(require_cache4()); - -// src/config-utils.ts -var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB = 2e4; -var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES = OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB * 1e6; -var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_MB = 14e3; -var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES = OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_MB * 1e6; -var OVERLAY_MINIMUM_MEMORY_MB = 5 * 1024; -var OVERLAY_ANALYSIS_FEATURES = { - cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, - csharp: "overlay_analysis_csharp" /* OverlayAnalysisCsharp */, - go: "overlay_analysis_go" /* OverlayAnalysisGo */, - java: "overlay_analysis_java" /* OverlayAnalysisJava */, - javascript: "overlay_analysis_javascript" /* OverlayAnalysisJavascript */, - python: "overlay_analysis_python" /* OverlayAnalysisPython */, - ruby: "overlay_analysis_ruby" /* OverlayAnalysisRuby */ -}; -var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { - cpp: "overlay_analysis_code_scanning_cpp" /* OverlayAnalysisCodeScanningCpp */, - csharp: "overlay_analysis_code_scanning_csharp" /* OverlayAnalysisCodeScanningCsharp */, - go: "overlay_analysis_code_scanning_go" /* OverlayAnalysisCodeScanningGo */, - java: "overlay_analysis_code_scanning_java" /* OverlayAnalysisCodeScanningJava */, - javascript: "overlay_analysis_code_scanning_javascript" /* OverlayAnalysisCodeScanningJavascript */, - python: "overlay_analysis_code_scanning_python" /* OverlayAnalysisCodeScanningPython */, - ruby: "overlay_analysis_code_scanning_ruby" /* OverlayAnalysisCodeScanningRuby */ -}; -function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { - const augmentedConfig = cloneObject(cliConfig); - if (extraQueryExclusions.length === 0) { - return augmentedConfig; + logger.info( + `Found ${caches.length} overlay-base ${caches.length === 1 ? "database" : "databases"} in the Actions cache.` + ); + const versionRegex = /^([\d.]+)-/; + const versionSet = /* @__PURE__ */ new Set(); + for (const cache of caches) { + if (!cache.key) continue; + const suffix = cache.key.substring(cacheKeyPrefix.length); + const match = suffix.match(versionRegex); + if (match && semver6.valid(match[1])) { + versionSet.add(match[1]); + } } - augmentedConfig["query-filters"] = [ - // Ordering matters. If the first filter is an inclusion, it implicitly - // excludes all queries that are not included. If it is an exclusion, - // it implicitly includes all queries that are not excluded. So user - // filters (if any) should always be first to preserve intent. - ...augmentedConfig["query-filters"] || [], - ...extraQueryExclusions - ]; - if (augmentedConfig["query-filters"]?.length === 0) { - delete augmentedConfig["query-filters"]; + if (versionSet.size === 0) { + logger.info( + "Could not parse any CodeQL versions from overlay-base database cache keys." + ); + return []; } - return augmentedConfig; + const versions = [...versionSet].sort(semver6.rcompare); + logger.info( + `Found overlay databases for the following CodeQL versions in the Actions cache: ${versions.join(", ")}` + ); + return versions; } -// src/setup-codeql.ts -var fs8 = __toESM(require("fs")); -var path8 = __toESM(require("path")); -var toolcache3 = __toESM(require_tool_cache()); -var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); - // src/tar.ts var import_child_process = require("child_process"); var fs6 = __toESM(require("fs")); @@ -87398,7 +87619,7 @@ var stream = __toESM(require("stream")); var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); var MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3"; var MIN_REQUIRED_GNU_TAR_VERSION = "1.31"; async function getTarVersion() { @@ -87440,9 +87661,9 @@ async function isZstdAvailable(logger) { case "gnu": return { available: foundZstdBinary && // GNU tar only uses major and minor version numbers - semver6.gte( - semver6.coerce(version), - semver6.coerce(MIN_REQUIRED_GNU_TAR_VERSION) + semver7.gte( + semver7.coerce(version), + semver7.coerce(MIN_REQUIRED_GNU_TAR_VERSION) ), foundZstdBinary, version: tarVersion @@ -87451,7 +87672,7 @@ async function isZstdAvailable(logger) { return { available: foundZstdBinary && // Do a loose comparison since these version numbers don't contain // a patch version number. - semver6.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), + semver7.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), foundZstdBinary, version: tarVersion }; @@ -87558,7 +87779,7 @@ var core10 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; var TOOLCACHE_TOOL_NAME = "CodeQL"; function makeDownloadFirstToolsDownloadDurations(downloadDurationMs, extractionDurationMs) { @@ -87688,7 +87909,7 @@ function getToolcacheDirectory(version) { return path7.join( getRequiredEnvParam("RUNNER_TOOL_CACHE"), TOOLCACHE_TOOL_NAME, - semver7.clean(version) || version, + semver8.clean(version) || version, os.arch() || "" ); } @@ -87813,13 +88034,13 @@ function tryGetTagNameFromUrl(url, logger) { return match[1]; } function convertToSemVer(version, logger) { - if (!semver8.valid(version)) { + if (!semver9.valid(version)) { logger.debug( `Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.` ); version = `0.0.0-${version}`; } - const s = semver8.clean(version); + const s = semver9.clean(version); if (!s) { throw new Error(`Bundle version ${version} is not in SemVer format.`); } @@ -87851,7 +88072,84 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getEnabledVersionsWithOverlayBaseDatabases(defaultCliVersion, rawLanguages, features, logger) { + if (rawLanguages === void 0 || rawLanguages.length === 0) { + return []; + } + const isEnabled = await features.getValue( + "overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */ + ); + const isDryRun = !isEnabled && await features.getValue("overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */); + if (!isEnabled && !isDryRun) { + return []; + } + let cachedVersions; + try { + cachedVersions = await getCodeQlVersionsForOverlayBaseDatabases( + rawLanguages, + logger + ); + } catch (e) { + logger.warning( + `Could not list overlay-base databases in the Actions cache while choosing a default CodeQL CLI version, falling back to the highest enabled version. Details: ${getErrorMessage(e)}` + ); + return []; + } + if (cachedVersions === void 0 || cachedVersions.length === 0) { + return []; + } + const cachedVersionsSet = new Set(cachedVersions); + const overlayVersions = defaultCliVersion.enabledVersions.filter( + (v) => cachedVersionsSet.has(v.cliVersion) + ); + if (overlayVersions.length === 0) { + return []; + } + const isCachedVersionDifferent = overlayVersions[0].cliVersion !== defaultCliVersion.enabledVersions[0].cliVersion; + if (isCachedVersionDifferent) { + addNoLanguageDiagnostic( + void 0, + makeTelemetryDiagnostic( + "codeql-action/overlay-aware-default-codeql-version", + "Overlay-aware default CodeQL version selection", + { + cachedVersions, + enabledVersions: defaultCliVersion.enabledVersions.map( + (v) => v.cliVersion + ), + isDryRun, + overlayAwareVersion: overlayVersions[0].cliVersion + } + ) + ); + } + if (isDryRun) { + logger.debug( + `Overlay-aware default CodeQL version selection is running in dry-run mode. Would have used version ${overlayVersions[0].cliVersion}.` + ); + return []; + } + return overlayVersions; +} +async function resolveDefaultCliVersion(defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { + if (!useOverlayAwareDefaultCliVersion || !isAnalyzingPullRequest()) { + return defaultCliVersion.enabledVersions[0]; + } + const overlayVersions = await getEnabledVersionsWithOverlayBaseDatabases( + defaultCliVersion, + rawLanguages, + features, + logger + ); + if (overlayVersions.length > 0) { + logger.info( + `Using CodeQL version ${overlayVersions[0].cliVersion} since this is the highest enabled version that has a cached overlay-base database.` + ); + return overlayVersions[0]; + } + return defaultCliVersion.enabledVersions[0]; +} +async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -87945,21 +88243,35 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } } - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } } else if (toolsInput !== void 0) { tagName = tryGetTagNameFromUrl(toolsInput, logger); url = toolsInput; if (tagName) { const bundleVersion3 = tryGetBundleVersionFromTagName(tagName, logger); - if (bundleVersion3 && semver8.valid(bundleVersion3)) { + if (bundleVersion3 && semver9.valid(bundleVersion3)) { cliVersion2 = convertToSemVer(bundleVersion3, logger); } } } else { - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } const bundleVersion2 = tagName && tryGetBundleVersionFromTagName(tagName, logger); const humanReadableVersion = cliVersion2 ?? (bundleVersion2 && convertToSemVer(bundleVersion2, logger)) ?? tagName ?? url ?? "unknown"; @@ -88156,7 +88468,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -88166,6 +88478,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau const source = await getCodeQLSource( toolsInput, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, apiDetails, variant, zstdAvailability.available, @@ -88224,7 +88538,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau async function useZstdBundle(cliVersion2, tarSupportsZstd) { return ( // In testing, gzip performs better than zstd on Windows. - process.platform !== "win32" && tarSupportsZstd && semver8.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) + process.platform !== "win32" && tarSupportsZstd && semver9.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) ); } function getTempExtractionDir(tempDir) { @@ -88256,7 +88570,7 @@ async function getNightlyToolsUrl(logger) { } } function getLatestToolcacheVersion(logger) { - const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver8.compare(b, a)); + const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver9.compare(b, a)); logger.debug( `Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify( allVersions @@ -88293,7 +88607,7 @@ 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 EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -88307,6 +88621,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger ); @@ -88896,7 +89212,7 @@ async function getJobRunUuidSarifOptions(codeql) { } // src/init.ts -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -88910,6 +89226,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger, true @@ -89202,16 +89520,20 @@ async function run(startedAt) { if (statusReportBase !== void 0) { await sendStatusReport(statusReportBase); } - const codeQLDefaultVersionInfo = await features.getDefaultCliVersion( - gitHubVersion.type - ); + const codeQLDefaultVersionInfo = await features.getEnabledDefaultCliVersions(gitHubVersion.type); toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid; + const rawLanguages = getRawLanguagesNoAutodetect( + getOptionalInput("languages") + ); + const analysisKinds = await getAnalysisKinds(logger); const initCodeQLResult = await initCodeQL( getOptionalInput("tools"), apiDetails, getTemporaryDirectory(), gitHubVersion.type, codeQLDefaultVersionInfo, + rawLanguages, + analysisKinds.includes("code-scanning" /* CodeScanning */), features, logger ); diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index 6f70d70937..5e67aaa280 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -26352,11 +26352,11 @@ var require_valid = __commonJS({ "node_modules/semver/functions/valid.js"(exports2, module2) { "use strict"; var parse2 = require_parse2(); - var valid3 = (version, options) => { + var valid4 = (version, options) => { const v = parse2(version, options); return v ? v.version : null; }; - module2.exports = valid3; + module2.exports = valid4; } }); @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare2 = require_compare(); - var rcompare = (a, b, loose) => compare2(b, a, loose); - module2.exports = rcompare; + var rcompare3 = (a, b, loose) => compare2(b, a, loose); + module2.exports = rcompare3; } }); @@ -27716,7 +27716,7 @@ var require_semver2 = __commonJS({ var SemVer = require_semver(); var identifiers = require_identifiers(); var parse2 = require_parse2(); - var valid3 = require_valid(); + var valid4 = require_valid(); var clean3 = require_clean(); var inc = require_inc(); var diff = require_diff(); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare2 = require_compare(); - var rcompare = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27754,7 +27754,7 @@ var require_semver2 = __commonJS({ var subset = require_subset(); module2.exports = { parse: parse2, - valid: valid3, + valid: valid4, clean: clean3, inc, diff, @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare2, - rcompare, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -29553,16 +29553,16 @@ var require_attribute = __commonJS({ var result = new ValidatorResult(instance, schema2, options, ctx); var self2 = this; schema2.allOf.forEach(function(v, i) { - var valid3 = self2.validateSchema(instance, v, options, ctx); - if (!valid3.valid) { + var valid4 = self2.validateSchema(instance, v, options, ctx); + if (!valid4.valid) { var id = v.$id || v.id; var msg = id || v.title && JSON.stringify(v.title) || v["$ref"] && "<" + v["$ref"] + ">" || "[subschema " + i + "]"; result.addError({ name: "allOf", - argument: { id: msg, length: valid3.errors.length, valid: valid3 }, - message: "does not match allOf schema " + msg + " with " + valid3.errors.length + " error[s]:" + argument: { id: msg, length: valid4.errors.length, valid: valid4 }, + message: "does not match allOf schema " + msg + " with " + valid4.errors.length + " error[s]:" }); - result.importErrors(valid3); + result.importErrors(valid4); } }); return result; @@ -29851,8 +29851,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMinimum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance > schema2.exclusiveMinimum; - if (!valid3) { + var valid4 = instance > schema2.exclusiveMinimum; + if (!valid4) { result.addError({ name: "exclusiveMinimum", argument: schema2.exclusiveMinimum, @@ -29865,8 +29865,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMaximum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance < schema2.exclusiveMaximum; - if (!valid3) { + var valid4 = instance < schema2.exclusiveMaximum; + if (!valid4) { result.addError({ name: "exclusiveMaximum", argument: schema2.exclusiveMaximum, @@ -32649,8 +32649,8 @@ var require_semver3 = __commonJS({ return null; } } - exports2.valid = valid3; - function valid3(version, options) { + exports2.valid = valid4; + function valid4(version, options) { var v = parse2(version, options); return v ? v.version : null; } @@ -32950,8 +32950,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare; - function rcompare(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare2(b, a, loose); } exports2.sort = sort; @@ -33779,7 +33779,7 @@ var require_cacheUtils = __commonJS({ var crypto2 = __importStar2(require("crypto")); var fs3 = __importStar2(require("fs")); var path4 = __importStar2(require("path")); - var semver9 = __importStar2(require_semver3()); + var semver10 = __importStar2(require_semver3()); var util = __importStar2(require("util")); var constants_1 = require_constants7(); var versionSalt = "1.0"; @@ -33872,7 +33872,7 @@ var require_cacheUtils = __commonJS({ function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver9.clean(versionOutput); + const version = semver10.clean(versionOutput); core15.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; @@ -75278,7 +75278,7 @@ var require_cacheHttpClient = __commonJS({ exports2.getCacheEntry = getCacheEntry; exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; - exports2.saveCache = saveCache4; + exports2.saveCache = saveCache5; var core15 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); @@ -75455,7 +75455,7 @@ Other caches with similar key:`); })); }); } - function saveCache4(cacheId, archivePath, signedUploadURL, options) { + function saveCache5(cacheId, archivePath, signedUploadURL, options) { return __awaiter2(this, void 0, void 0, function* () { const uploadOptions = (0, options_1.getUploadOptions)(options); if (uploadOptions.useAzureSdk) { @@ -80955,8 +80955,8 @@ var require_cache4 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; exports2.isFeatureAvailable = isFeatureAvailable; - exports2.restoreCache = restoreCache4; - exports2.saveCache = saveCache4; + exports2.restoreCache = restoreCache5; + exports2.saveCache = saveCache5; var core15 = __importStar2(require_core()); var path4 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); @@ -81013,7 +81013,7 @@ var require_cache4 = __commonJS({ return !!process.env["ACTIONS_CACHE_URL"]; } } - function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) { + function restoreCache5(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core15.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81157,7 +81157,7 @@ var require_cache4 = __commonJS({ return void 0; }); } - function saveCache4(paths_1, key_1, options_1) { + function saveCache5(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core15.debug(`Cache service version: ${cacheServiceVersion}`); @@ -88437,7 +88437,7 @@ var require_stream_writable = __commonJS({ pna.nextTick(cb, er); } function validChunk(stream, state, chunk, cb) { - var valid3 = true; + var valid4 = true; var er = false; if (chunk === null) { er = new TypeError("May not write null values to stream"); @@ -88447,9 +88447,9 @@ var require_stream_writable = __commonJS({ if (er) { stream.emit("error", er); pna.nextTick(cb, er); - valid3 = false; + valid4 = false; } - return valid3; + return valid4; } Writable.prototype.write = function(chunk, encoding, cb) { var state = this._writableState; @@ -122745,7 +122745,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var core_1 = require_core(); var os2 = require("os"); var cp = require("child_process"); @@ -122759,7 +122759,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver9.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver10.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -122768,7 +122768,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver9.satisfies(osVersion, item.platform_version); + chk = semver10.satisfies(osVersion, item.platform_version); } } return chk; @@ -123028,7 +123028,7 @@ var require_tool_cache = __commonJS({ var os2 = __importStar2(require("os")); var path4 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var stream = __importStar2(require("stream")); var util = __importStar2(require("util")); var assert_1 = require("assert"); @@ -123301,7 +123301,7 @@ var require_tool_cache = __commonJS({ } function cacheDir(sourceDir, tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch = arch || os2.arch(); core15.debug(`Caching tool ${tool} ${version} ${arch}`); core15.debug(`source dir: ${sourceDir}`); @@ -123319,7 +123319,7 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch = arch || os2.arch(); core15.debug(`Caching tool ${tool} ${version} ${arch}`); core15.debug(`source file: ${sourceFile}`); @@ -123349,7 +123349,7 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver9.clean(versionSpec) || ""; + versionSpec = semver10.clean(versionSpec) || ""; const cachePath = path4.join(_getCacheDirectory(), toolName, versionSpec, arch); core15.debug(`checking cache: ${cachePath}`); if (fs3.existsSync(cachePath) && fs3.existsSync(`${cachePath}.complete`)) { @@ -123429,7 +123429,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path4.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch || ""); + const folderPath = path4.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch || ""); core15.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io6.rmRF(folderPath); @@ -123439,30 +123439,30 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch) { - const folderPath = path4.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch || ""); + const folderPath = path4.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch || ""); const markerPath = `${folderPath}.complete`; fs3.writeFileSync(markerPath, ""); core15.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver9.clean(versionSpec) || ""; + const c = semver10.clean(versionSpec) || ""; core15.debug(`isExplicit: ${c}`); - const valid3 = semver9.valid(c) != null; - core15.debug(`explicit? ${valid3}`); - return valid3; + const valid4 = semver10.valid(c) != null; + core15.debug(`explicit? ${valid4}`); + return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; core15.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver9.gt(a, b)) { + if (semver10.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver9.satisfies(potential, versionSpec); + const satisfied = semver10.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -127203,6 +127203,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -127505,24 +127515,30 @@ var cliErrorsConfig = { // src/setup-codeql.ts var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); + +// src/overlay/caching.ts +var actionsCache3 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; // src/tar.ts var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); // src/tools-download.ts var core10 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; // src/dependency-caching.ts -var actionsCache3 = __toESM(require_cache4()); +var actionsCache4 = __toESM(require_cache4()); var glob = __toESM(require_glob()); // src/artifact-scanner.ts diff --git a/lib/start-proxy-action.js b/lib/start-proxy-action.js index 39fd56a80a..ee67ed723e 100644 --- a/lib/start-proxy-action.js +++ b/lib/start-proxy-action.js @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare = require_compare(); - var rcompare = (a, b, loose) => compare(b, a, loose); - module2.exports = rcompare; + var rcompare2 = (a, b, loose) => compare(b, a, loose); + module2.exports = rcompare2; } }); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare = require_compare(); - var rcompare = require_rcompare(); + var rcompare2 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare, - rcompare, + rcompare: rcompare2, compareLoose, compareBuild, sort, @@ -33772,8 +33772,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare; - function rcompare(a, b, loose) { + exports2.rcompare = rcompare2; + function rcompare2(a, b, loose) { return compare(b, a, loose); } exports2.sort = sort; @@ -103177,6 +103177,10 @@ var semver3 = __toESM(require_semver2()); // src/feature-flags.ts var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_"; var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled"; +var LINKED_CODEQL_VERSION = { + cliVersion, + tagName: bundleVersion +}; var featureConfig = { ["allow_toolcache_input" /* AllowToolcacheInput */]: { defaultValue: false, @@ -103331,6 +103335,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -103391,10 +103405,9 @@ var OfflineFeatures = class { this.logger = logger; } logger; - async getDefaultCliVersion(_variant) { + async getEnabledDefaultCliVersions(_variant) { return { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; } /** @@ -103499,11 +103512,11 @@ var Features = class extends OfflineFeatures { logger ); } - async getDefaultCliVersion(variant) { + async getEnabledDefaultCliVersions(variant) { if (supportsFeatureFlags(variant)) { - return await this.gitHubFeatureFlags.getDefaultCliVersionFromFlags(); + return await this.gitHubFeatureFlags.getEnabledDefaultCliVersionsFromFlags(); } - return super.getDefaultCliVersion(variant); + return super.getEnabledDefaultCliVersions(variant); } /** * @@ -103562,34 +103575,36 @@ var GitHubFeatureFlags = class { } return version; } - async getDefaultCliVersionFromFlags() { + /** + * Returns CLI versions enabled by `default_codeql_version_*_enabled` feature + * flags, sorted from highest to lowest. Falls back to the version pinned in + * `defaults.json` if no such flags are enabled. + */ + async getEnabledDefaultCliVersionsFromFlags() { const response = await this.getAllFeatures(); - const enabledFeatureFlagCliVersions = Object.entries(response).map( + const sortedCliVersions = Object.entries(response).map( ([f, isEnabled]) => isEnabled ? this.getCliVersionFromFeatureFlag(f) : void 0 - ).filter((f) => f !== void 0); - if (enabledFeatureFlagCliVersions.length === 0) { + ).filter((f) => f !== void 0).sort(semver4.rcompare); + if (sortedCliVersions.length === 0) { this.logger.warning( `Feature flags do not specify a default CLI version. Falling back to the CLI version shipped with the Action. This is ${cliVersion}.` ); const result = { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; if (this.hasAccessedRemoteFeatureFlags) { result.toolsFeatureFlagsValid = false; } return result; } - const maxCliVersion = enabledFeatureFlagCliVersions.reduce( - (maxVersion, currentVersion) => currentVersion > maxVersion ? currentVersion : maxVersion, - enabledFeatureFlagCliVersions[0] - ); this.logger.debug( - `Derived default CLI version of ${maxCliVersion} from feature flags.` + `Derived default CLI version of ${sortedCliVersions[0]} from feature flags.` ); return { - cliVersion: maxCliVersion, - tagName: `codeql-bundle-v${maxCliVersion}`, + enabledVersions: sortedCliVersions.map((cliVersion2) => ({ + cliVersion: cliVersion2, + tagName: `codeql-bundle-v${cliVersion2}` + })), toolsFeatureFlagsValid: true }; } @@ -104469,7 +104484,7 @@ async function getReleaseByVersion(version) { } async function getCliVersionFromFeatures(features) { const gitHubVersion = await getGitHubVersion(); - return await features.getDefaultCliVersion(gitHubVersion.type); + return await features.getEnabledDefaultCliVersions(gitHubVersion.type); } async function getDownloadUrl(logger, features) { const proxyPackage = getProxyPackage(); @@ -104477,7 +104492,7 @@ async function getDownloadUrl(logger, features) { const useFeaturesToDetermineCLI = await features.getValue( "start_proxy_use_features_release" /* StartProxyUseFeaturesRelease */ ); - const versionInfo = useFeaturesToDetermineCLI ? await getCliVersionFromFeatures(features) : { + const versionInfo = useFeaturesToDetermineCLI ? (await getCliVersionFromFeatures(features)).enabledVersions[0] : { cliVersion, tagName: bundleVersion }; diff --git a/lib/upload-lib.js b/lib/upload-lib.js index f1f90b4c2a..b649b56721 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -203,7 +203,7 @@ var require_file_command = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.issueFileCommand = issueFileCommand; exports2.prepareKeyValueMessage = prepareKeyValueMessage; - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs14 = __importStar2(require("fs")); var os2 = __importStar2(require("os")); var utils_1 = require_utils(); @@ -220,7 +220,7 @@ var require_file_command = __commonJS({ }); } function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${crypto2.randomUUID()}`; + const delimiter = `ghadelimiter_${crypto3.randomUUID()}`; const convertedValue = (0, utils_1.toCommandValue)(value); if (key.includes(delimiter)) { throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); @@ -4287,11 +4287,11 @@ var require_util2 = __commonJS({ var { isUint8Array } = require("node:util/types"); var { webidl } = require_webidl(); var supportedHashes = []; - var crypto2; + var crypto3; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); const possibleRelevantHashes = ["sha256", "sha384", "sha512"]; - supportedHashes = crypto2.getHashes().filter((hash2) => possibleRelevantHashes.includes(hash2)); + supportedHashes = crypto3.getHashes().filter((hash2) => possibleRelevantHashes.includes(hash2)); } catch { } function responseURL(response) { @@ -4564,7 +4564,7 @@ var require_util2 = __commonJS({ } } function bytesMatch(bytes, metadataList) { - if (crypto2 === void 0) { + if (crypto3 === void 0) { return true; } const parsedMetadata = parseMetadata(metadataList); @@ -4579,7 +4579,7 @@ var require_util2 = __commonJS({ for (const item of metadata) { const algorithm = item.algo; const expectedValue = item.hash; - let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64"); + let actualValue = crypto3.createHash(algorithm).update(bytes).digest("base64"); if (actualValue[actualValue.length - 1] === "=") { if (actualValue[actualValue.length - 2] === "=") { actualValue = actualValue.slice(0, -2); @@ -5643,8 +5643,8 @@ var require_body = __commonJS({ var { multipartFormDataParser } = require_formdata_parser(); var random; try { - const crypto2 = require("node:crypto"); - random = (max) => crypto2.randomInt(0, max); + const crypto3 = require("node:crypto"); + random = (max) => crypto3.randomInt(0, max); } catch { random = (max) => Math.floor(Math.random(max)); } @@ -17052,13 +17052,13 @@ var require_frame = __commonJS({ "use strict"; var { maxUnsigned16Bit } = require_constants5(); var BUFFER_SIZE = 16386; - var crypto2; + var crypto3; var buffer = null; var bufIdx = BUFFER_SIZE; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); } catch { - crypto2 = { + crypto3 = { // not full compatibility, but minimum. randomFillSync: function randomFillSync(buffer2, _offset, _size) { for (let i = 0; i < buffer2.length; ++i) { @@ -17071,7 +17071,7 @@ var require_frame = __commonJS({ function generateMask() { if (bufIdx === BUFFER_SIZE) { bufIdx = 0; - crypto2.randomFillSync(buffer ??= Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE); + crypto3.randomFillSync(buffer ??= Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE); } return [buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++]]; } @@ -17143,9 +17143,9 @@ var require_connection = __commonJS({ var { Headers, getHeadersList } = require_headers(); var { getDecodeSplit } = require_util2(); var { WebsocketFrameSend } = require_frame(); - var crypto2; + var crypto3; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); } catch { } function establishWebSocketConnection(url2, protocols, client, ws, onEstablish, options) { @@ -17165,7 +17165,7 @@ var require_connection = __commonJS({ const headersList = getHeadersList(new Headers(options.headers)); request2.headersList = headersList; } - const keyValue = crypto2.randomBytes(16).toString("base64"); + const keyValue = crypto3.randomBytes(16).toString("base64"); request2.headersList.append("sec-websocket-key", keyValue); request2.headersList.append("sec-websocket-version", "13"); for (const protocol of protocols) { @@ -17195,7 +17195,7 @@ var require_connection = __commonJS({ return; } const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); - const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64"); + const digest = crypto3.createHash("sha1").update(keyValue + uid).digest("base64"); if (secWSAccept !== digest) { failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header."); return; @@ -21993,16 +21993,16 @@ var require_attribute = __commonJS({ var result = new ValidatorResult(instance, schema2, options, ctx); var self2 = this; schema2.allOf.forEach(function(v, i) { - var valid3 = self2.validateSchema(instance, v, options, ctx); - if (!valid3.valid) { + var valid4 = self2.validateSchema(instance, v, options, ctx); + if (!valid4.valid) { var id = v.$id || v.id; var msg = id || v.title && JSON.stringify(v.title) || v["$ref"] && "<" + v["$ref"] + ">" || "[subschema " + i + "]"; result.addError({ name: "allOf", - argument: { id: msg, length: valid3.errors.length, valid: valid3 }, - message: "does not match allOf schema " + msg + " with " + valid3.errors.length + " error[s]:" + argument: { id: msg, length: valid4.errors.length, valid: valid4 }, + message: "does not match allOf schema " + msg + " with " + valid4.errors.length + " error[s]:" }); - result.importErrors(valid3); + result.importErrors(valid4); } }); return result; @@ -22291,8 +22291,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMinimum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance > schema2.exclusiveMinimum; - if (!valid3) { + var valid4 = instance > schema2.exclusiveMinimum; + if (!valid4) { result.addError({ name: "exclusiveMinimum", argument: schema2.exclusiveMinimum, @@ -22305,8 +22305,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMaximum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance < schema2.exclusiveMaximum; - if (!valid3) { + var valid4 = instance < schema2.exclusiveMaximum; + if (!valid4) { result.addError({ name: "exclusiveMaximum", argument: schema2.exclusiveMaximum, @@ -27657,11 +27657,11 @@ var require_valid = __commonJS({ "node_modules/semver/functions/valid.js"(exports2, module2) { "use strict"; var parse2 = require_parse2(); - var valid3 = (version, options) => { + var valid4 = (version, options) => { const v = parse2(version, options); return v ? v.version : null; }; - module2.exports = valid3; + module2.exports = valid4; } }); @@ -27804,8 +27804,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare3 = require_compare(); - var rcompare = (a, b, loose) => compare3(b, a, loose); - module2.exports = rcompare; + var rcompare3 = (a, b, loose) => compare3(b, a, loose); + module2.exports = rcompare3; } }); @@ -29021,7 +29021,7 @@ var require_semver2 = __commonJS({ var SemVer = require_semver(); var identifiers = require_identifiers(); var parse2 = require_parse2(); - var valid3 = require_valid(); + var valid4 = require_valid(); var clean3 = require_clean(); var inc = require_inc(); var diff = require_diff(); @@ -29030,7 +29030,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare3 = require_compare(); - var rcompare = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -29059,7 +29059,7 @@ var require_semver2 = __commonJS({ var subset = require_subset(); module2.exports = { parse: parse2, - valid: valid3, + valid: valid4, clean: clean3, inc, diff, @@ -29068,7 +29068,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare3, - rcompare, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -32371,7 +32371,7 @@ var require_internal_hash_files = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.hashFiles = hashFiles; - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var core14 = __importStar2(require_core()); var fs14 = __importStar2(require("fs")); var stream2 = __importStar2(require("stream")); @@ -32384,7 +32384,7 @@ var require_internal_hash_files = __commonJS({ const writeDelegate = verbose ? core14.info : core14.debug; let hasMatch = false; const githubWorkspace = currentWorkspace ? currentWorkspace : (_d = process.env["GITHUB_WORKSPACE"]) !== null && _d !== void 0 ? _d : process.cwd(); - const result = crypto2.createHash("sha256"); + const result = crypto3.createHash("sha256"); let count = 0; try { for (var _e = true, _f = __asyncValues2(globber.globGenerator()), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) { @@ -32400,7 +32400,7 @@ var require_internal_hash_files = __commonJS({ writeDelegate(`Skip directory '${file}'.`); continue; } - const hash2 = crypto2.createHash("sha256"); + const hash2 = crypto3.createHash("sha256"); const pipeline = util.promisify(stream2.pipeline); yield pipeline(fs14.createReadStream(file), hash2); result.write(hash2.digest()); @@ -32649,8 +32649,8 @@ var require_semver3 = __commonJS({ return null; } } - exports2.valid = valid3; - function valid3(version, options) { + exports2.valid = valid4; + function valid4(version, options) { var v = parse2(version, options); return v ? v.version : null; } @@ -32950,8 +32950,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare; - function rcompare(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare3(b, a, loose); } exports2.sort = sort; @@ -33776,10 +33776,10 @@ var require_cacheUtils = __commonJS({ var exec = __importStar2(require_exec()); var glob = __importStar2(require_glob()); var io6 = __importStar2(require_io()); - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs14 = __importStar2(require("fs")); var path12 = __importStar2(require("path")); - var semver9 = __importStar2(require_semver3()); + var semver10 = __importStar2(require_semver3()); var util = __importStar2(require("util")); var constants_1 = require_constants7(); var versionSalt = "1.0"; @@ -33800,7 +33800,7 @@ var require_cacheUtils = __commonJS({ } tempDirectory = path12.join(baseLocation, "actions", "temp"); } - const dest = path12.join(tempDirectory, crypto2.randomUUID()); + const dest = path12.join(tempDirectory, crypto3.randomUUID()); yield io6.mkdirP(dest); return dest; }); @@ -33872,7 +33872,7 @@ var require_cacheUtils = __commonJS({ function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver9.clean(versionOutput); + const version = semver10.clean(versionOutput); core14.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; @@ -33908,7 +33908,7 @@ var require_cacheUtils = __commonJS({ components.push("windows-only"); } components.push(versionSalt); - return crypto2.createHash("sha256").update(components.join("|")).digest("hex"); + return crypto3.createHash("sha256").update(components.join("|")).digest("hex"); } function getRuntimeToken() { const token = process.env["ACTIONS_RUNTIME_TOKEN"]; @@ -75278,7 +75278,7 @@ var require_cacheHttpClient = __commonJS({ exports2.getCacheEntry = getCacheEntry; exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; - exports2.saveCache = saveCache3; + exports2.saveCache = saveCache4; var core14 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); @@ -75455,7 +75455,7 @@ Other caches with similar key:`); })); }); } - function saveCache3(cacheId, archivePath, signedUploadURL, options) { + function saveCache4(cacheId, archivePath, signedUploadURL, options) { return __awaiter2(this, void 0, void 0, function* () { const uploadOptions = (0, options_1.getUploadOptions)(options); if (uploadOptions.useAzureSdk) { @@ -80955,8 +80955,8 @@ var require_cache4 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; exports2.isFeatureAvailable = isFeatureAvailable; - exports2.restoreCache = restoreCache3; - exports2.saveCache = saveCache3; + exports2.restoreCache = restoreCache4; + exports2.saveCache = saveCache4; var core14 = __importStar2(require_core()); var path12 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); @@ -81013,7 +81013,7 @@ var require_cache4 = __commonJS({ return !!process.env["ACTIONS_CACHE_URL"]; } } - function restoreCache3(paths_1, primaryKey_1, restoreKeys_1, options_1) { + function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core14.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81157,7 +81157,7 @@ var require_cache4 = __commonJS({ return void 0; }); } - function saveCache3(paths_1, key_1, options_1) { + function saveCache4(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core14.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81394,7 +81394,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var core_1 = require_core(); var os2 = require("os"); var cp = require("child_process"); @@ -81408,7 +81408,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver9.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver10.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -81417,7 +81417,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver9.satisfies(osVersion, item.platform_version); + chk = semver10.satisfies(osVersion, item.platform_version); } } return chk; @@ -81671,13 +81671,13 @@ var require_tool_cache = __commonJS({ exports2.evaluateVersions = evaluateVersions; var core14 = __importStar2(require_core()); var io6 = __importStar2(require_io()); - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs14 = __importStar2(require("fs")); var mm = __importStar2(require_manifest()); var os2 = __importStar2(require("os")); var path12 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var stream2 = __importStar2(require("stream")); var util = __importStar2(require("util")); var assert_1 = require("assert"); @@ -81696,7 +81696,7 @@ var require_tool_cache = __commonJS({ var userAgent2 = "actions/tool-cache"; function downloadTool2(url2, dest, auth2, headers) { return __awaiter2(this, void 0, void 0, function* () { - dest = dest || path12.join(_getTempDirectory(), crypto2.randomUUID()); + dest = dest || path12.join(_getTempDirectory(), crypto3.randomUUID()); yield io6.mkdirP(path12.dirname(dest)); core14.debug(`Downloading ${url2}`); core14.debug(`Destination ${dest}`); @@ -81950,7 +81950,7 @@ var require_tool_cache = __commonJS({ } function cacheDir(sourceDir, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch2 = arch2 || os2.arch(); core14.debug(`Caching tool ${tool} ${version} ${arch2}`); core14.debug(`source dir: ${sourceDir}`); @@ -81968,7 +81968,7 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch2 = arch2 || os2.arch(); core14.debug(`Caching tool ${tool} ${version} ${arch2}`); core14.debug(`source file: ${sourceFile}`); @@ -81998,7 +81998,7 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver9.clean(versionSpec) || ""; + versionSpec = semver10.clean(versionSpec) || ""; const cachePath = path12.join(_getCacheDirectory(), toolName, versionSpec, arch2); core14.debug(`checking cache: ${cachePath}`); if (fs14.existsSync(cachePath) && fs14.existsSync(`${cachePath}.complete`)) { @@ -82070,7 +82070,7 @@ var require_tool_cache = __commonJS({ function _createExtractFolder(dest) { return __awaiter2(this, void 0, void 0, function* () { if (!dest) { - dest = path12.join(_getTempDirectory(), crypto2.randomUUID()); + dest = path12.join(_getTempDirectory(), crypto3.randomUUID()); } yield io6.mkdirP(dest); return dest; @@ -82078,7 +82078,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path12.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); + const folderPath = path12.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch2 || ""); core14.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io6.rmRF(folderPath); @@ -82088,30 +82088,30 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch2) { - const folderPath = path12.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); + const folderPath = path12.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch2 || ""); const markerPath = `${folderPath}.complete`; fs14.writeFileSync(markerPath, ""); core14.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver9.clean(versionSpec) || ""; + const c = semver10.clean(versionSpec) || ""; core14.debug(`isExplicit: ${c}`); - const valid3 = semver9.valid(c) != null; - core14.debug(`explicit? ${valid3}`); - return valid3; + const valid4 = semver10.valid(c) != null; + core14.debug(`explicit? ${valid4}`); + return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; core14.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver9.gt(a, b)) { + if (semver10.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver9.satisfies(potential, versionSpec); + const satisfied = semver10.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -88630,6 +88630,32 @@ async function runTool(cmd, args = [], opts = {}) { } return stdout; } +function getPullRequestBranches() { + const pullRequest = github.context.payload.pull_request; + if (pullRequest) { + return { + base: pullRequest.base.ref, + // We use the head label instead of the head ref here, because the head + // ref lacks owner information and by itself does not uniquely identify + // the head branch (which may be in a forked repository). + head: pullRequest.head.label + }; + } + const codeScanningRef = process.env.CODE_SCANNING_REF; + const codeScanningBaseBranch = process.env.CODE_SCANNING_BASE_BRANCH; + if (codeScanningRef && codeScanningBaseBranch) { + return { + base: codeScanningBaseBranch, + // PR analysis under Default Setup analyzes the PR head commit instead of + // the merge commit, so we can use the provided ref directly. + head: codeScanningRef + }; + } + return void 0; +} +function isAnalyzingPullRequest() { + return getPullRequestBranches() !== void 0; +} var qualityCategoryMapping = { "c#": "csharp", cpp: "c-cpp", @@ -88912,6 +88938,11 @@ async function getAnalysisKey() { core5.exportVariable("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); return analysisKey; } +async function getAutomationID() { + const analysis_key = await getAnalysisKey(); + const environment = getRequiredInput("matrix"); + return computeAutomationID(analysis_key, environment); +} function computeAutomationID(analysis_key, environment) { let automationID = `${analysis_key}/`; const matrix = parseMatrixInput(environment); @@ -88926,6 +88957,18 @@ function computeAutomationID(analysis_key, environment) { } return automationID; } +async function listActionsCaches(keyPrefix, ref) { + const repositoryNwo = getRepositoryNwo(); + return await getApiClient().paginate( + "GET /repos/{owner}/{repo}/actions/caches", + { + owner: repositoryNwo.owner, + repo: repositoryNwo.repo, + key: keyPrefix, + ref + } + ); +} function isEnablementError(msg) { return [ /Code Security must be enabled/i, @@ -89224,7 +89267,13 @@ var path6 = __toESM(require("path")); var core9 = __toESM(require_core()); // src/caching-utils.ts +var crypto2 = __toESM(require("crypto")); var core6 = __toESM(require_core()); +var cacheKeyHashLength = 16; +function createCacheKeyHash(components) { + const componentsJson = JSON.stringify(components); + return crypto2.createHash("sha256").update(componentsJson).digest("hex").substring(0, cacheKeyHashLength); +} // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); @@ -89339,6 +89388,16 @@ function writeDiagnostic(config, language, diagnostic) { logger.debug(JSON.stringify(diagnostic)); } } +function makeTelemetryDiagnostic(id, name, attributes) { + return makeDiagnostic(id, name, { + attributes, + visibility: { + cliSummaryTable: false, + statusPage: false, + telemetry: true + } + }); +} // src/diff-informed-analysis-utils.ts var fs5 = __toESM(require("fs")); @@ -89846,6 +89905,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -89952,6 +90021,17 @@ var builtin_default = { // src/languages/index.ts var builtInLanguageSet = new Set(builtin_default.languages); +function isBuiltInLanguage(language) { + return builtInLanguageSet.has(language); +} +function parseBuiltInLanguage(language) { + language = language.trim().toLowerCase(); + language = builtin_default.aliases[language] ?? language; + if (isBuiltInLanguage(language)) { + return language; + } + return void 0; +} // src/overlay/status.ts var actionsCache = __toESM(require_cache4()); @@ -90031,7 +90111,7 @@ var fs9 = __toESM(require("fs")); var path8 = __toESM(require("path")); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); // node_modules/uuid/dist-node/stringify.js var byteToHex = []; @@ -90077,6 +90157,68 @@ function _v4(options, buf, offset) { } var v4_default = v4; +// src/overlay/caching.ts +var actionsCache3 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; +var CACHE_VERSION = 1; +var CACHE_PREFIX = "codeql-overlay-base-database"; +async function getCacheKeyPrefixBase(parsedLanguages) { + const languagesComponent = [...parsedLanguages].sort().join("_"); + const cacheKeyComponents = { + automationID: await getAutomationID() + // Add more components here as needed in the future + }; + const componentsHash = createCacheKeyHash(cacheKeyComponents); + return `${CACHE_PREFIX}-${CACHE_VERSION}-${componentsHash}-${languagesComponent}-`; +} +async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger) { + const languages = rawLanguages.map(parseBuiltInLanguage); + if (languages.includes(void 0)) { + logger.warning( + "One or more provided languages are not recognized as built-in languages. Skipping searching for overlay-base databases in cache." + ); + return void 0; + } + const dedupedLanguages = [ + ...new Set(languages.filter((l) => l !== void 0)) + ]; + const cacheKeyPrefix = await getCacheKeyPrefixBase(dedupedLanguages); + logger.debug( + `Searching for overlay-base databases in Actions cache with prefix ${cacheKeyPrefix}` + ); + const caches = await listActionsCaches(cacheKeyPrefix); + if (caches.length === 0) { + logger.info("No overlay-base databases found in Actions cache."); + return []; + } + logger.info( + `Found ${caches.length} overlay-base ${caches.length === 1 ? "database" : "databases"} in the Actions cache.` + ); + const versionRegex = /^([\d.]+)-/; + const versionSet = /* @__PURE__ */ new Set(); + for (const cache of caches) { + if (!cache.key) continue; + const suffix = cache.key.substring(cacheKeyPrefix.length); + const match = suffix.match(versionRegex); + if (match && semver6.valid(match[1])) { + versionSet.add(match[1]); + } + } + if (versionSet.size === 0) { + logger.info( + "Could not parse any CodeQL versions from overlay-base database cache keys." + ); + return []; + } + const versions = [...versionSet].sort(semver6.rcompare); + logger.info( + `Found overlay databases for the following CodeQL versions in the Actions cache: ${versions.join(", ")}` + ); + return versions; +} + // src/tar.ts var import_child_process = require("child_process"); var fs7 = __toESM(require("fs")); @@ -90084,7 +90226,7 @@ var stream = __toESM(require("stream")); var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); var MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3"; var MIN_REQUIRED_GNU_TAR_VERSION = "1.31"; async function getTarVersion() { @@ -90126,9 +90268,9 @@ async function isZstdAvailable(logger) { case "gnu": return { available: foundZstdBinary && // GNU tar only uses major and minor version numbers - semver6.gte( - semver6.coerce(version), - semver6.coerce(MIN_REQUIRED_GNU_TAR_VERSION) + semver7.gte( + semver7.coerce(version), + semver7.coerce(MIN_REQUIRED_GNU_TAR_VERSION) ), foundZstdBinary, version: tarVersion @@ -90137,7 +90279,7 @@ async function isZstdAvailable(logger) { return { available: foundZstdBinary && // Do a loose comparison since these version numbers don't contain // a patch version number. - semver6.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), + semver7.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), foundZstdBinary, version: tarVersion }; @@ -90244,7 +90386,7 @@ var core10 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; var TOOLCACHE_TOOL_NAME = "CodeQL"; function makeDownloadFirstToolsDownloadDurations(downloadDurationMs, extractionDurationMs) { @@ -90374,7 +90516,7 @@ function getToolcacheDirectory(version) { return path7.join( getRequiredEnvParam("RUNNER_TOOL_CACHE"), TOOLCACHE_TOOL_NAME, - semver7.clean(version) || version, + semver8.clean(version) || version, os.arch() || "" ); } @@ -90499,13 +90641,13 @@ function tryGetTagNameFromUrl(url2, logger) { return match[1]; } function convertToSemVer(version, logger) { - if (!semver8.valid(version)) { + if (!semver9.valid(version)) { logger.debug( `Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.` ); version = `0.0.0-${version}`; } - const s = semver8.clean(version); + const s = semver9.clean(version); if (!s) { throw new Error(`Bundle version ${version} is not in SemVer format.`); } @@ -90537,7 +90679,84 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getEnabledVersionsWithOverlayBaseDatabases(defaultCliVersion, rawLanguages, features, logger) { + if (rawLanguages === void 0 || rawLanguages.length === 0) { + return []; + } + const isEnabled = await features.getValue( + "overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */ + ); + const isDryRun = !isEnabled && await features.getValue("overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */); + if (!isEnabled && !isDryRun) { + return []; + } + let cachedVersions; + try { + cachedVersions = await getCodeQlVersionsForOverlayBaseDatabases( + rawLanguages, + logger + ); + } catch (e) { + logger.warning( + `Could not list overlay-base databases in the Actions cache while choosing a default CodeQL CLI version, falling back to the highest enabled version. Details: ${getErrorMessage(e)}` + ); + return []; + } + if (cachedVersions === void 0 || cachedVersions.length === 0) { + return []; + } + const cachedVersionsSet = new Set(cachedVersions); + const overlayVersions = defaultCliVersion.enabledVersions.filter( + (v) => cachedVersionsSet.has(v.cliVersion) + ); + if (overlayVersions.length === 0) { + return []; + } + const isCachedVersionDifferent = overlayVersions[0].cliVersion !== defaultCliVersion.enabledVersions[0].cliVersion; + if (isCachedVersionDifferent) { + addNoLanguageDiagnostic( + void 0, + makeTelemetryDiagnostic( + "codeql-action/overlay-aware-default-codeql-version", + "Overlay-aware default CodeQL version selection", + { + cachedVersions, + enabledVersions: defaultCliVersion.enabledVersions.map( + (v) => v.cliVersion + ), + isDryRun, + overlayAwareVersion: overlayVersions[0].cliVersion + } + ) + ); + } + if (isDryRun) { + logger.debug( + `Overlay-aware default CodeQL version selection is running in dry-run mode. Would have used version ${overlayVersions[0].cliVersion}.` + ); + return []; + } + return overlayVersions; +} +async function resolveDefaultCliVersion(defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { + if (!useOverlayAwareDefaultCliVersion || !isAnalyzingPullRequest()) { + return defaultCliVersion.enabledVersions[0]; + } + const overlayVersions = await getEnabledVersionsWithOverlayBaseDatabases( + defaultCliVersion, + rawLanguages, + features, + logger + ); + if (overlayVersions.length > 0) { + logger.info( + `Using CodeQL version ${overlayVersions[0].cliVersion} since this is the highest enabled version that has a cached overlay-base database.` + ); + return overlayVersions[0]; + } + return defaultCliVersion.enabledVersions[0]; +} +async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -90631,21 +90850,35 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } } - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } } else if (toolsInput !== void 0) { tagName = tryGetTagNameFromUrl(toolsInput, logger); url2 = toolsInput; if (tagName) { const bundleVersion3 = tryGetBundleVersionFromTagName(tagName, logger); - if (bundleVersion3 && semver8.valid(bundleVersion3)) { + if (bundleVersion3 && semver9.valid(bundleVersion3)) { cliVersion2 = convertToSemVer(bundleVersion3, logger); } } } else { - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } const bundleVersion2 = tagName && tryGetBundleVersionFromTagName(tagName, logger); const humanReadableVersion = cliVersion2 ?? (bundleVersion2 && convertToSemVer(bundleVersion2, logger)) ?? tagName ?? url2 ?? "unknown"; @@ -90842,7 +91075,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -90852,6 +91085,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau const source = await getCodeQLSource( toolsInput, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, apiDetails, variant, zstdAvailability.available, @@ -90910,7 +91145,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau async function useZstdBundle(cliVersion2, tarSupportsZstd) { return ( // In testing, gzip performs better than zstd on Windows. - process.platform !== "win32" && tarSupportsZstd && semver8.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) + process.platform !== "win32" && tarSupportsZstd && semver9.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) ); } function getTempExtractionDir(tempDir) { @@ -90942,7 +91177,7 @@ async function getNightlyToolsUrl(logger) { } } function getLatestToolcacheVersion(logger) { - const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver8.compare(b, a)); + const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver9.compare(b, a)); logger.debug( `Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify( allVersions @@ -90979,7 +91214,7 @@ 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 EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -90993,6 +91228,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger ); @@ -92714,7 +92951,7 @@ var core12 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io5 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -92728,6 +92965,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger, true @@ -92876,9 +93115,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo url: getRequiredEnvParam("GITHUB_SERVER_URL"), apiURL: getRequiredEnvParam("GITHUB_API_URL") }; - const codeQLDefaultVersionInfo = await features.getDefaultCliVersion( - gitHubVersion.type - ); + const codeQLDefaultVersionInfo = await features.getEnabledDefaultCliVersions(gitHubVersion.type); const initCodeQLResult = await initCodeQL( void 0, // There is no tools input on the upload action @@ -92886,6 +93123,10 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo tempDir, gitHubVersion.type, codeQLDefaultVersionInfo, + void 0, + // rawLanguages: upload-lib does not run analysis + false, + // useOverlayAwareDefaultCliVersion: upload-lib does not run analysis features, logger ); @@ -92901,7 +93142,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo return readSarifFile(outputFile); } function populateRunAutomationDetails(sarifFile, category, analysis_key, environment) { - const automationID = getAutomationID(category, analysis_key, environment); + const automationID = getAutomationID2(category, analysis_key, environment); if (automationID !== void 0) { for (const run of sarifFile.runs || []) { if (run.automationDetails === void 0) { @@ -92914,7 +93155,7 @@ function populateRunAutomationDetails(sarifFile, category, analysis_key, environ } return sarifFile; } -function getAutomationID(category, analysis_key, environment) { +function getAutomationID2(category, analysis_key, environment) { if (category !== void 0) { let automationID = category; if (!automationID.endsWith("/")) { diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index 11873a244c..dfafe65015 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -26352,11 +26352,11 @@ var require_valid = __commonJS({ "node_modules/semver/functions/valid.js"(exports2, module2) { "use strict"; var parse2 = require_parse2(); - var valid3 = (version, options) => { + var valid4 = (version, options) => { const v = parse2(version, options); return v ? v.version : null; }; - module2.exports = valid3; + module2.exports = valid4; } }); @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare2 = require_compare(); - var rcompare = (a, b, loose) => compare2(b, a, loose); - module2.exports = rcompare; + var rcompare3 = (a, b, loose) => compare2(b, a, loose); + module2.exports = rcompare3; } }); @@ -27716,7 +27716,7 @@ var require_semver2 = __commonJS({ var SemVer = require_semver(); var identifiers = require_identifiers(); var parse2 = require_parse2(); - var valid3 = require_valid(); + var valid4 = require_valid(); var clean3 = require_clean(); var inc = require_inc(); var diff = require_diff(); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare2 = require_compare(); - var rcompare = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27754,7 +27754,7 @@ var require_semver2 = __commonJS({ var subset = require_subset(); module2.exports = { parse: parse2, - valid: valid3, + valid: valid4, clean: clean3, inc, diff, @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare2, - rcompare, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -80613,7 +80613,7 @@ var require_stream_writable = __commonJS({ pna.nextTick(cb, er); } function validChunk(stream, state, chunk, cb) { - var valid3 = true; + var valid4 = true; var er = false; if (chunk === null) { er = new TypeError("May not write null values to stream"); @@ -80623,9 +80623,9 @@ var require_stream_writable = __commonJS({ if (er) { stream.emit("error", er); pna.nextTick(cb, er); - valid3 = false; + valid4 = false; } - return valid3; + return valid4; } Writable.prototype.write = function(chunk, encoding, cb) { var state = this._writableState; @@ -115281,16 +115281,16 @@ var require_attribute = __commonJS({ var result = new ValidatorResult(instance, schema2, options, ctx); var self2 = this; schema2.allOf.forEach(function(v, i) { - var valid3 = self2.validateSchema(instance, v, options, ctx); - if (!valid3.valid) { + var valid4 = self2.validateSchema(instance, v, options, ctx); + if (!valid4.valid) { var id = v.$id || v.id; var msg = id || v.title && JSON.stringify(v.title) || v["$ref"] && "<" + v["$ref"] + ">" || "[subschema " + i + "]"; result.addError({ name: "allOf", - argument: { id: msg, length: valid3.errors.length, valid: valid3 }, - message: "does not match allOf schema " + msg + " with " + valid3.errors.length + " error[s]:" + argument: { id: msg, length: valid4.errors.length, valid: valid4 }, + message: "does not match allOf schema " + msg + " with " + valid4.errors.length + " error[s]:" }); - result.importErrors(valid3); + result.importErrors(valid4); } }); return result; @@ -115579,8 +115579,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMinimum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance > schema2.exclusiveMinimum; - if (!valid3) { + var valid4 = instance > schema2.exclusiveMinimum; + if (!valid4) { result.addError({ name: "exclusiveMinimum", argument: schema2.exclusiveMinimum, @@ -115593,8 +115593,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMaximum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance < schema2.exclusiveMaximum; - if (!valid3) { + var valid4 = instance < schema2.exclusiveMaximum; + if (!valid4) { result.addError({ name: "exclusiveMaximum", argument: schema2.exclusiveMaximum, @@ -118322,8 +118322,8 @@ var require_semver3 = __commonJS({ return null; } } - exports2.valid = valid3; - function valid3(version, options) { + exports2.valid = valid4; + function valid4(version, options) { var v = parse2(version, options); return v ? v.version : null; } @@ -118623,8 +118623,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare; - function rcompare(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare2(b, a, loose); } exports2.sort = sort; @@ -119452,7 +119452,7 @@ var require_cacheUtils = __commonJS({ var crypto2 = __importStar2(require("crypto")); var fs3 = __importStar2(require("fs")); var path3 = __importStar2(require("path")); - var semver9 = __importStar2(require_semver3()); + var semver10 = __importStar2(require_semver3()); var util = __importStar2(require("util")); var constants_1 = require_constants14(); var versionSalt = "1.0"; @@ -119545,7 +119545,7 @@ var require_cacheUtils = __commonJS({ function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver9.clean(versionOutput); + const version = semver10.clean(versionOutput); core15.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; @@ -120855,7 +120855,7 @@ var require_cacheHttpClient = __commonJS({ exports2.getCacheEntry = getCacheEntry; exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; - exports2.saveCache = saveCache4; + exports2.saveCache = saveCache5; var core15 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); @@ -121032,7 +121032,7 @@ Other caches with similar key:`); })); }); } - function saveCache4(cacheId, archivePath, signedUploadURL, options) { + function saveCache5(cacheId, archivePath, signedUploadURL, options) { return __awaiter2(this, void 0, void 0, function* () { const uploadOptions = (0, options_1.getUploadOptions)(options); if (uploadOptions.useAzureSdk) { @@ -122306,8 +122306,8 @@ var require_cache4 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; exports2.isFeatureAvailable = isFeatureAvailable; - exports2.restoreCache = restoreCache4; - exports2.saveCache = saveCache4; + exports2.restoreCache = restoreCache5; + exports2.saveCache = saveCache5; var core15 = __importStar2(require_core()); var path3 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); @@ -122364,7 +122364,7 @@ var require_cache4 = __commonJS({ return !!process.env["ACTIONS_CACHE_URL"]; } } - function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) { + function restoreCache5(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core15.debug(`Cache service version: ${cacheServiceVersion}`); @@ -122508,7 +122508,7 @@ var require_cache4 = __commonJS({ return void 0; }); } - function saveCache4(paths_1, key_1, options_1) { + function saveCache5(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core15.debug(`Cache service version: ${cacheServiceVersion}`); @@ -122745,7 +122745,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var core_1 = require_core(); var os2 = require("os"); var cp = require("child_process"); @@ -122759,7 +122759,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver9.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver10.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -122768,7 +122768,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver9.satisfies(osVersion, item.platform_version); + chk = semver10.satisfies(osVersion, item.platform_version); } } return chk; @@ -123028,7 +123028,7 @@ var require_tool_cache = __commonJS({ var os2 = __importStar2(require("os")); var path3 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var stream = __importStar2(require("stream")); var util = __importStar2(require("util")); var assert_1 = require("assert"); @@ -123301,7 +123301,7 @@ var require_tool_cache = __commonJS({ } function cacheDir(sourceDir, tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch = arch || os2.arch(); core15.debug(`Caching tool ${tool} ${version} ${arch}`); core15.debug(`source dir: ${sourceDir}`); @@ -123319,7 +123319,7 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch = arch || os2.arch(); core15.debug(`Caching tool ${tool} ${version} ${arch}`); core15.debug(`source file: ${sourceFile}`); @@ -123349,7 +123349,7 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver9.clean(versionSpec) || ""; + versionSpec = semver10.clean(versionSpec) || ""; const cachePath = path3.join(_getCacheDirectory(), toolName, versionSpec, arch); core15.debug(`checking cache: ${cachePath}`); if (fs3.existsSync(cachePath) && fs3.existsSync(`${cachePath}.complete`)) { @@ -123429,7 +123429,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path3.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch || ""); + const folderPath = path3.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch || ""); core15.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io6.rmRF(folderPath); @@ -123439,30 +123439,30 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch) { - const folderPath = path3.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch || ""); + const folderPath = path3.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch || ""); const markerPath = `${folderPath}.complete`; fs3.writeFileSync(markerPath, ""); core15.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver9.clean(versionSpec) || ""; + const c = semver10.clean(versionSpec) || ""; core15.debug(`isExplicit: ${c}`); - const valid3 = semver9.valid(c) != null; - core15.debug(`explicit? ${valid3}`); - return valid3; + const valid4 = semver10.valid(c) != null; + core15.debug(`explicit? ${valid4}`); + return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; core15.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver9.gt(a, b)) { + if (semver10.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver9.satisfies(potential, versionSpec); + const satisfied = semver10.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -127373,6 +127373,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -127492,24 +127502,30 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { // src/setup-codeql.ts var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); + +// src/overlay/caching.ts +var actionsCache3 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; // src/tar.ts var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); // src/tools-download.ts var core10 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; // src/dependency-caching.ts -var actionsCache3 = __toESM(require_cache4()); +var actionsCache4 = __toESM(require_cache4()); var glob = __toESM(require_glob2()); // src/artifact-scanner.ts diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 75e8744beb..522ab1abad 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -203,7 +203,7 @@ var require_file_command = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.issueFileCommand = issueFileCommand; exports2.prepareKeyValueMessage = prepareKeyValueMessage; - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs15 = __importStar2(require("fs")); var os3 = __importStar2(require("os")); var utils_1 = require_utils(); @@ -220,7 +220,7 @@ var require_file_command = __commonJS({ }); } function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${crypto2.randomUUID()}`; + const delimiter = `ghadelimiter_${crypto3.randomUUID()}`; const convertedValue = (0, utils_1.toCommandValue)(value); if (key.includes(delimiter)) { throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); @@ -4287,11 +4287,11 @@ var require_util2 = __commonJS({ var { isUint8Array } = require("node:util/types"); var { webidl } = require_webidl(); var supportedHashes = []; - var crypto2; + var crypto3; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); const possibleRelevantHashes = ["sha256", "sha384", "sha512"]; - supportedHashes = crypto2.getHashes().filter((hash2) => possibleRelevantHashes.includes(hash2)); + supportedHashes = crypto3.getHashes().filter((hash2) => possibleRelevantHashes.includes(hash2)); } catch { } function responseURL(response) { @@ -4564,7 +4564,7 @@ var require_util2 = __commonJS({ } } function bytesMatch(bytes, metadataList) { - if (crypto2 === void 0) { + if (crypto3 === void 0) { return true; } const parsedMetadata = parseMetadata(metadataList); @@ -4579,7 +4579,7 @@ var require_util2 = __commonJS({ for (const item of metadata) { const algorithm = item.algo; const expectedValue = item.hash; - let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64"); + let actualValue = crypto3.createHash(algorithm).update(bytes).digest("base64"); if (actualValue[actualValue.length - 1] === "=") { if (actualValue[actualValue.length - 2] === "=") { actualValue = actualValue.slice(0, -2); @@ -5643,8 +5643,8 @@ var require_body = __commonJS({ var { multipartFormDataParser } = require_formdata_parser(); var random; try { - const crypto2 = require("node:crypto"); - random = (max) => crypto2.randomInt(0, max); + const crypto3 = require("node:crypto"); + random = (max) => crypto3.randomInt(0, max); } catch { random = (max) => Math.floor(Math.random(max)); } @@ -17052,13 +17052,13 @@ var require_frame = __commonJS({ "use strict"; var { maxUnsigned16Bit } = require_constants5(); var BUFFER_SIZE = 16386; - var crypto2; + var crypto3; var buffer = null; var bufIdx = BUFFER_SIZE; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); } catch { - crypto2 = { + crypto3 = { // not full compatibility, but minimum. randomFillSync: function randomFillSync(buffer2, _offset, _size) { for (let i = 0; i < buffer2.length; ++i) { @@ -17071,7 +17071,7 @@ var require_frame = __commonJS({ function generateMask() { if (bufIdx === BUFFER_SIZE) { bufIdx = 0; - crypto2.randomFillSync(buffer ??= Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE); + crypto3.randomFillSync(buffer ??= Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE); } return [buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++]]; } @@ -17143,9 +17143,9 @@ var require_connection = __commonJS({ var { Headers, getHeadersList } = require_headers(); var { getDecodeSplit } = require_util2(); var { WebsocketFrameSend } = require_frame(); - var crypto2; + var crypto3; try { - crypto2 = require("node:crypto"); + crypto3 = require("node:crypto"); } catch { } function establishWebSocketConnection(url2, protocols, client, ws, onEstablish, options) { @@ -17165,7 +17165,7 @@ var require_connection = __commonJS({ const headersList = getHeadersList(new Headers(options.headers)); request2.headersList = headersList; } - const keyValue = crypto2.randomBytes(16).toString("base64"); + const keyValue = crypto3.randomBytes(16).toString("base64"); request2.headersList.append("sec-websocket-key", keyValue); request2.headersList.append("sec-websocket-version", "13"); for (const protocol of protocols) { @@ -17195,7 +17195,7 @@ var require_connection = __commonJS({ return; } const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); - const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64"); + const digest = crypto3.createHash("sha1").update(keyValue + uid).digest("base64"); if (secWSAccept !== digest) { failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header."); return; @@ -26352,11 +26352,11 @@ var require_valid = __commonJS({ "node_modules/semver/functions/valid.js"(exports2, module2) { "use strict"; var parse2 = require_parse2(); - var valid3 = (version, options) => { + var valid4 = (version, options) => { const v = parse2(version, options); return v ? v.version : null; }; - module2.exports = valid3; + module2.exports = valid4; } }); @@ -26499,8 +26499,8 @@ var require_rcompare = __commonJS({ "node_modules/semver/functions/rcompare.js"(exports2, module2) { "use strict"; var compare3 = require_compare(); - var rcompare = (a, b, loose) => compare3(b, a, loose); - module2.exports = rcompare; + var rcompare3 = (a, b, loose) => compare3(b, a, loose); + module2.exports = rcompare3; } }); @@ -27716,7 +27716,7 @@ var require_semver2 = __commonJS({ var SemVer = require_semver(); var identifiers = require_identifiers(); var parse2 = require_parse2(); - var valid3 = require_valid(); + var valid4 = require_valid(); var clean3 = require_clean(); var inc = require_inc(); var diff = require_diff(); @@ -27725,7 +27725,7 @@ var require_semver2 = __commonJS({ var patch = require_patch(); var prerelease = require_prerelease(); var compare3 = require_compare(); - var rcompare = require_rcompare(); + var rcompare3 = require_rcompare(); var compareLoose = require_compare_loose(); var compareBuild = require_compare_build(); var sort = require_sort(); @@ -27754,7 +27754,7 @@ var require_semver2 = __commonJS({ var subset = require_subset(); module2.exports = { parse: parse2, - valid: valid3, + valid: valid4, clean: clean3, inc, diff, @@ -27763,7 +27763,7 @@ var require_semver2 = __commonJS({ patch, prerelease, compare: compare3, - rcompare, + rcompare: rcompare3, compareLoose, compareBuild, sort, @@ -29553,16 +29553,16 @@ var require_attribute = __commonJS({ var result = new ValidatorResult(instance, schema2, options, ctx); var self2 = this; schema2.allOf.forEach(function(v, i) { - var valid3 = self2.validateSchema(instance, v, options, ctx); - if (!valid3.valid) { + var valid4 = self2.validateSchema(instance, v, options, ctx); + if (!valid4.valid) { var id = v.$id || v.id; var msg = id || v.title && JSON.stringify(v.title) || v["$ref"] && "<" + v["$ref"] + ">" || "[subschema " + i + "]"; result.addError({ name: "allOf", - argument: { id: msg, length: valid3.errors.length, valid: valid3 }, - message: "does not match allOf schema " + msg + " with " + valid3.errors.length + " error[s]:" + argument: { id: msg, length: valid4.errors.length, valid: valid4 }, + message: "does not match allOf schema " + msg + " with " + valid4.errors.length + " error[s]:" }); - result.importErrors(valid3); + result.importErrors(valid4); } }); return result; @@ -29851,8 +29851,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMinimum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance > schema2.exclusiveMinimum; - if (!valid3) { + var valid4 = instance > schema2.exclusiveMinimum; + if (!valid4) { result.addError({ name: "exclusiveMinimum", argument: schema2.exclusiveMinimum, @@ -29865,8 +29865,8 @@ var require_attribute = __commonJS({ if (typeof schema2.exclusiveMaximum === "boolean") return; if (!this.types.number(instance)) return; var result = new ValidatorResult(instance, schema2, options, ctx); - var valid3 = instance < schema2.exclusiveMaximum; - if (!valid3) { + var valid4 = instance < schema2.exclusiveMaximum; + if (!valid4) { result.addError({ name: "exclusiveMaximum", argument: schema2.exclusiveMaximum, @@ -32371,7 +32371,7 @@ var require_internal_hash_files = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.hashFiles = hashFiles; - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var core16 = __importStar2(require_core()); var fs15 = __importStar2(require("fs")); var stream2 = __importStar2(require("stream")); @@ -32384,7 +32384,7 @@ var require_internal_hash_files = __commonJS({ const writeDelegate = verbose ? core16.info : core16.debug; let hasMatch = false; const githubWorkspace = currentWorkspace ? currentWorkspace : (_d = process.env["GITHUB_WORKSPACE"]) !== null && _d !== void 0 ? _d : process.cwd(); - const result = crypto2.createHash("sha256"); + const result = crypto3.createHash("sha256"); let count = 0; try { for (var _e = true, _f = __asyncValues2(globber.globGenerator()), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) { @@ -32400,7 +32400,7 @@ var require_internal_hash_files = __commonJS({ writeDelegate(`Skip directory '${file}'.`); continue; } - const hash2 = crypto2.createHash("sha256"); + const hash2 = crypto3.createHash("sha256"); const pipeline = util.promisify(stream2.pipeline); yield pipeline(fs15.createReadStream(file), hash2); result.write(hash2.digest()); @@ -32649,8 +32649,8 @@ var require_semver3 = __commonJS({ return null; } } - exports2.valid = valid3; - function valid3(version, options) { + exports2.valid = valid4; + function valid4(version, options) { var v = parse2(version, options); return v ? v.version : null; } @@ -32950,8 +32950,8 @@ var require_semver3 = __commonJS({ var versionB = new SemVer(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB); } - exports2.rcompare = rcompare; - function rcompare(a, b, loose) { + exports2.rcompare = rcompare3; + function rcompare3(a, b, loose) { return compare3(b, a, loose); } exports2.sort = sort; @@ -33776,10 +33776,10 @@ var require_cacheUtils = __commonJS({ var exec = __importStar2(require_exec()); var glob = __importStar2(require_glob()); var io6 = __importStar2(require_io()); - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs15 = __importStar2(require("fs")); var path13 = __importStar2(require("path")); - var semver9 = __importStar2(require_semver3()); + var semver10 = __importStar2(require_semver3()); var util = __importStar2(require("util")); var constants_1 = require_constants7(); var versionSalt = "1.0"; @@ -33800,7 +33800,7 @@ var require_cacheUtils = __commonJS({ } tempDirectory = path13.join(baseLocation, "actions", "temp"); } - const dest = path13.join(tempDirectory, crypto2.randomUUID()); + const dest = path13.join(tempDirectory, crypto3.randomUUID()); yield io6.mkdirP(dest); return dest; }); @@ -33872,7 +33872,7 @@ var require_cacheUtils = __commonJS({ function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver9.clean(versionOutput); + const version = semver10.clean(versionOutput); core16.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; @@ -33908,7 +33908,7 @@ var require_cacheUtils = __commonJS({ components.push("windows-only"); } components.push(versionSalt); - return crypto2.createHash("sha256").update(components.join("|")).digest("hex"); + return crypto3.createHash("sha256").update(components.join("|")).digest("hex"); } function getRuntimeToken() { const token = process.env["ACTIONS_RUNTIME_TOKEN"]; @@ -75278,7 +75278,7 @@ var require_cacheHttpClient = __commonJS({ exports2.getCacheEntry = getCacheEntry; exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; - exports2.saveCache = saveCache3; + exports2.saveCache = saveCache4; var core16 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); @@ -75455,7 +75455,7 @@ Other caches with similar key:`); })); }); } - function saveCache3(cacheId, archivePath, signedUploadURL, options) { + function saveCache4(cacheId, archivePath, signedUploadURL, options) { return __awaiter2(this, void 0, void 0, function* () { const uploadOptions = (0, options_1.getUploadOptions)(options); if (uploadOptions.useAzureSdk) { @@ -80955,8 +80955,8 @@ var require_cache4 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; exports2.isFeatureAvailable = isFeatureAvailable; - exports2.restoreCache = restoreCache3; - exports2.saveCache = saveCache3; + exports2.restoreCache = restoreCache4; + exports2.saveCache = saveCache4; var core16 = __importStar2(require_core()); var path13 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); @@ -81013,7 +81013,7 @@ var require_cache4 = __commonJS({ return !!process.env["ACTIONS_CACHE_URL"]; } } - function restoreCache3(paths_1, primaryKey_1, restoreKeys_1, options_1) { + function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core16.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81157,7 +81157,7 @@ var require_cache4 = __commonJS({ return void 0; }); } - function saveCache3(paths_1, key_1, options_1) { + function saveCache4(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); core16.debug(`Cache service version: ${cacheServiceVersion}`); @@ -81394,7 +81394,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var core_1 = require_core(); var os3 = require("os"); var cp = require("child_process"); @@ -81408,7 +81408,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver9.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver10.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -81417,7 +81417,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver9.satisfies(osVersion, item.platform_version); + chk = semver10.satisfies(osVersion, item.platform_version); } } return chk; @@ -81671,13 +81671,13 @@ var require_tool_cache = __commonJS({ exports2.evaluateVersions = evaluateVersions; var core16 = __importStar2(require_core()); var io6 = __importStar2(require_io()); - var crypto2 = __importStar2(require("crypto")); + var crypto3 = __importStar2(require("crypto")); var fs15 = __importStar2(require("fs")); var mm = __importStar2(require_manifest()); var os3 = __importStar2(require("os")); var path13 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver9 = __importStar2(require_semver2()); + var semver10 = __importStar2(require_semver2()); var stream2 = __importStar2(require("stream")); var util = __importStar2(require("util")); var assert_1 = require("assert"); @@ -81696,7 +81696,7 @@ var require_tool_cache = __commonJS({ var userAgent2 = "actions/tool-cache"; function downloadTool2(url2, dest, auth2, headers) { return __awaiter2(this, void 0, void 0, function* () { - dest = dest || path13.join(_getTempDirectory(), crypto2.randomUUID()); + dest = dest || path13.join(_getTempDirectory(), crypto3.randomUUID()); yield io6.mkdirP(path13.dirname(dest)); core16.debug(`Downloading ${url2}`); core16.debug(`Destination ${dest}`); @@ -81950,7 +81950,7 @@ var require_tool_cache = __commonJS({ } function cacheDir(sourceDir, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch2 = arch2 || os3.arch(); core16.debug(`Caching tool ${tool} ${version} ${arch2}`); core16.debug(`source dir: ${sourceDir}`); @@ -81968,7 +81968,7 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver9.clean(version) || version; + version = semver10.clean(version) || version; arch2 = arch2 || os3.arch(); core16.debug(`Caching tool ${tool} ${version} ${arch2}`); core16.debug(`source file: ${sourceFile}`); @@ -81998,7 +81998,7 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver9.clean(versionSpec) || ""; + versionSpec = semver10.clean(versionSpec) || ""; const cachePath = path13.join(_getCacheDirectory(), toolName, versionSpec, arch2); core16.debug(`checking cache: ${cachePath}`); if (fs15.existsSync(cachePath) && fs15.existsSync(`${cachePath}.complete`)) { @@ -82070,7 +82070,7 @@ var require_tool_cache = __commonJS({ function _createExtractFolder(dest) { return __awaiter2(this, void 0, void 0, function* () { if (!dest) { - dest = path13.join(_getTempDirectory(), crypto2.randomUUID()); + dest = path13.join(_getTempDirectory(), crypto3.randomUUID()); } yield io6.mkdirP(dest); return dest; @@ -82078,7 +82078,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path13.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); + const folderPath = path13.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch2 || ""); core16.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io6.rmRF(folderPath); @@ -82088,30 +82088,30 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch2) { - const folderPath = path13.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); + const folderPath = path13.join(_getCacheDirectory(), tool, semver10.clean(version) || version, arch2 || ""); const markerPath = `${folderPath}.complete`; fs15.writeFileSync(markerPath, ""); core16.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver9.clean(versionSpec) || ""; + const c = semver10.clean(versionSpec) || ""; core16.debug(`isExplicit: ${c}`); - const valid3 = semver9.valid(c) != null; - core16.debug(`explicit? ${valid3}`); - return valid3; + const valid4 = semver10.valid(c) != null; + core16.debug(`explicit? ${valid4}`); + return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; core16.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver9.gt(a, b)) { + if (semver10.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver9.satisfies(potential, versionSpec); + const satisfied = semver10.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -88668,6 +88668,32 @@ var persistInputs = function() { ); core4.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables)); }; +function getPullRequestBranches() { + const pullRequest = github.context.payload.pull_request; + if (pullRequest) { + return { + base: pullRequest.base.ref, + // We use the head label instead of the head ref here, because the head + // ref lacks owner information and by itself does not uniquely identify + // the head branch (which may be in a forked repository). + head: pullRequest.head.label + }; + } + const codeScanningRef = process.env.CODE_SCANNING_REF; + const codeScanningBaseBranch = process.env.CODE_SCANNING_BASE_BRANCH; + if (codeScanningRef && codeScanningBaseBranch) { + return { + base: codeScanningBaseBranch, + // PR analysis under Default Setup analyzes the PR head commit instead of + // the merge commit, so we can use the provided ref directly. + head: codeScanningRef + }; + } + return void 0; +} +function isAnalyzingPullRequest() { + return getPullRequestBranches() !== void 0; +} var qualityCategoryMapping = { "c#": "csharp", cpp: "c-cpp", @@ -88960,6 +88986,11 @@ async function getAnalysisKey() { core5.exportVariable("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); return analysisKey; } +async function getAutomationID() { + const analysis_key = await getAnalysisKey(); + const environment = getRequiredInput("matrix"); + return computeAutomationID(analysis_key, environment); +} function computeAutomationID(analysis_key, environment) { let automationID = `${analysis_key}/`; const matrix = parseMatrixInput(environment); @@ -88974,6 +89005,18 @@ function computeAutomationID(analysis_key, environment) { } return automationID; } +async function listActionsCaches(keyPrefix, ref) { + const repositoryNwo = getRepositoryNwo(); + return await getApiClient().paginate( + "GET /repos/{owner}/{repo}/actions/caches", + { + owner: repositoryNwo.owner, + repo: repositoryNwo.repo, + key: keyPrefix, + ref + } + ); +} function isEnablementError(msg) { return [ /Code Security must be enabled/i, @@ -89365,6 +89408,10 @@ function isSupportedToolsFeature(versionInfo, feature) { var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_"; var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled"; var CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0"; +var LINKED_CODEQL_VERSION = { + cliVersion, + tagName: bundleVersion +}; var featureConfig = { ["allow_toolcache_input" /* AllowToolcacheInput */]: { defaultValue: false, @@ -89519,6 +89566,16 @@ var featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: void 0 }, + ["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: void 0 + }, + ["overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: void 0 + }, ["overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -89579,10 +89636,9 @@ var OfflineFeatures = class { this.logger = logger; } logger; - async getDefaultCliVersion(_variant) { + async getEnabledDefaultCliVersions(_variant) { return { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; } /** @@ -89687,11 +89743,11 @@ var Features = class extends OfflineFeatures { logger ); } - async getDefaultCliVersion(variant) { + async getEnabledDefaultCliVersions(variant) { if (supportsFeatureFlags(variant)) { - return await this.gitHubFeatureFlags.getDefaultCliVersionFromFlags(); + return await this.gitHubFeatureFlags.getEnabledDefaultCliVersionsFromFlags(); } - return super.getDefaultCliVersion(variant); + return super.getEnabledDefaultCliVersions(variant); } /** * @@ -89750,34 +89806,36 @@ var GitHubFeatureFlags = class { } return version; } - async getDefaultCliVersionFromFlags() { + /** + * Returns CLI versions enabled by `default_codeql_version_*_enabled` feature + * flags, sorted from highest to lowest. Falls back to the version pinned in + * `defaults.json` if no such flags are enabled. + */ + async getEnabledDefaultCliVersionsFromFlags() { const response = await this.getAllFeatures(); - const enabledFeatureFlagCliVersions = Object.entries(response).map( + const sortedCliVersions = Object.entries(response).map( ([f, isEnabled]) => isEnabled ? this.getCliVersionFromFeatureFlag(f) : void 0 - ).filter((f) => f !== void 0); - if (enabledFeatureFlagCliVersions.length === 0) { + ).filter((f) => f !== void 0).sort(semver4.rcompare); + if (sortedCliVersions.length === 0) { this.logger.warning( `Feature flags do not specify a default CLI version. Falling back to the CLI version shipped with the Action. This is ${cliVersion}.` ); const result = { - cliVersion, - tagName: bundleVersion + enabledVersions: [LINKED_CODEQL_VERSION] }; if (this.hasAccessedRemoteFeatureFlags) { result.toolsFeatureFlagsValid = false; } return result; } - const maxCliVersion = enabledFeatureFlagCliVersions.reduce( - (maxVersion, currentVersion) => currentVersion > maxVersion ? currentVersion : maxVersion, - enabledFeatureFlagCliVersions[0] - ); this.logger.debug( - `Derived default CLI version of ${maxCliVersion} from feature flags.` + `Derived default CLI version of ${sortedCliVersions[0]} from feature flags.` ); return { - cliVersion: maxCliVersion, - tagName: `codeql-bundle-v${maxCliVersion}`, + enabledVersions: sortedCliVersions.map((cliVersion2) => ({ + cliVersion: cliVersion2, + tagName: `codeql-bundle-v${cliVersion2}` + })), toolsFeatureFlagsValid: true }; } @@ -90007,7 +90065,13 @@ var path7 = __toESM(require("path")); var core9 = __toESM(require_core()); // src/caching-utils.ts +var crypto2 = __toESM(require("crypto")); var core8 = __toESM(require_core()); +var cacheKeyHashLength = 16; +function createCacheKeyHash(components) { + const componentsJson = JSON.stringify(components); + return crypto2.createHash("sha256").update(componentsJson).digest("hex").substring(0, cacheKeyHashLength); +} // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); @@ -90095,6 +90159,16 @@ function writeDiagnostic(config, language, diagnostic) { logger.debug(JSON.stringify(diagnostic)); } } +function makeTelemetryDiagnostic(id, name, attributes) { + return makeDiagnostic(id, name, { + attributes, + visibility: { + cliSummaryTable: false, + statusPage: false, + telemetry: true + } + }); +} // src/diff-informed-analysis-utils.ts var fs7 = __toESM(require("fs")); @@ -90148,6 +90222,17 @@ var builtin_default = { // src/languages/index.ts var builtInLanguageSet = new Set(builtin_default.languages); +function isBuiltInLanguage(language) { + return builtInLanguageSet.has(language); +} +function parseBuiltInLanguage(language) { + language = language.trim().toLowerCase(); + language = builtin_default.aliases[language] ?? language; + if (isBuiltInLanguage(language)) { + return language; + } + return void 0; +} // src/overlay/status.ts var actionsCache = __toESM(require_cache4()); @@ -90697,7 +90782,7 @@ var fs11 = __toESM(require("fs")); var path9 = __toESM(require("path")); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver8 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); // node_modules/uuid/dist-node/stringify.js var byteToHex = []; @@ -90743,6 +90828,68 @@ function _v4(options, buf, offset) { } var v4_default = v4; +// src/overlay/caching.ts +var actionsCache3 = __toESM(require_cache4()); +var semver6 = __toESM(require_semver2()); +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; +var CACHE_VERSION = 1; +var CACHE_PREFIX = "codeql-overlay-base-database"; +async function getCacheKeyPrefixBase(parsedLanguages) { + const languagesComponent = [...parsedLanguages].sort().join("_"); + const cacheKeyComponents = { + automationID: await getAutomationID() + // Add more components here as needed in the future + }; + const componentsHash = createCacheKeyHash(cacheKeyComponents); + return `${CACHE_PREFIX}-${CACHE_VERSION}-${componentsHash}-${languagesComponent}-`; +} +async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger) { + const languages = rawLanguages.map(parseBuiltInLanguage); + if (languages.includes(void 0)) { + logger.warning( + "One or more provided languages are not recognized as built-in languages. Skipping searching for overlay-base databases in cache." + ); + return void 0; + } + const dedupedLanguages = [ + ...new Set(languages.filter((l) => l !== void 0)) + ]; + const cacheKeyPrefix = await getCacheKeyPrefixBase(dedupedLanguages); + logger.debug( + `Searching for overlay-base databases in Actions cache with prefix ${cacheKeyPrefix}` + ); + const caches = await listActionsCaches(cacheKeyPrefix); + if (caches.length === 0) { + logger.info("No overlay-base databases found in Actions cache."); + return []; + } + logger.info( + `Found ${caches.length} overlay-base ${caches.length === 1 ? "database" : "databases"} in the Actions cache.` + ); + const versionRegex = /^([\d.]+)-/; + const versionSet = /* @__PURE__ */ new Set(); + for (const cache of caches) { + if (!cache.key) continue; + const suffix = cache.key.substring(cacheKeyPrefix.length); + const match = suffix.match(versionRegex); + if (match && semver6.valid(match[1])) { + versionSet.add(match[1]); + } + } + if (versionSet.size === 0) { + logger.info( + "Could not parse any CodeQL versions from overlay-base database cache keys." + ); + return []; + } + const versions = [...versionSet].sort(semver6.rcompare); + logger.info( + `Found overlay databases for the following CodeQL versions in the Actions cache: ${versions.join(", ")}` + ); + return versions; +} + // src/tar.ts var import_child_process = require("child_process"); var fs9 = __toESM(require("fs")); @@ -90750,7 +90897,7 @@ var stream = __toESM(require("stream")); var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver6 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); var MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3"; var MIN_REQUIRED_GNU_TAR_VERSION = "1.31"; async function getTarVersion() { @@ -90792,9 +90939,9 @@ async function isZstdAvailable(logger) { case "gnu": return { available: foundZstdBinary && // GNU tar only uses major and minor version numbers - semver6.gte( - semver6.coerce(version), - semver6.coerce(MIN_REQUIRED_GNU_TAR_VERSION) + semver7.gte( + semver7.coerce(version), + semver7.coerce(MIN_REQUIRED_GNU_TAR_VERSION) ), foundZstdBinary, version: tarVersion @@ -90803,7 +90950,7 @@ async function isZstdAvailable(logger) { return { available: foundZstdBinary && // Do a loose comparison since these version numbers don't contain // a patch version number. - semver6.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), + semver7.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), foundZstdBinary, version: tarVersion }; @@ -90910,7 +91057,7 @@ var core11 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver7 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; var TOOLCACHE_TOOL_NAME = "CodeQL"; function makeDownloadFirstToolsDownloadDurations(downloadDurationMs, extractionDurationMs) { @@ -91040,7 +91187,7 @@ function getToolcacheDirectory(version) { return path8.join( getRequiredEnvParam("RUNNER_TOOL_CACHE"), TOOLCACHE_TOOL_NAME, - semver7.clean(version) || version, + semver8.clean(version) || version, os2.arch() || "" ); } @@ -91165,13 +91312,13 @@ function tryGetTagNameFromUrl(url2, logger) { return match[1]; } function convertToSemVer(version, logger) { - if (!semver8.valid(version)) { + if (!semver9.valid(version)) { logger.debug( `Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.` ); version = `0.0.0-${version}`; } - const s = semver8.clean(version); + const s = semver9.clean(version); if (!s) { throw new Error(`Bundle version ${version} is not in SemVer format.`); } @@ -91203,7 +91350,84 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getEnabledVersionsWithOverlayBaseDatabases(defaultCliVersion, rawLanguages, features, logger) { + if (rawLanguages === void 0 || rawLanguages.length === 0) { + return []; + } + const isEnabled = await features.getValue( + "overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */ + ); + const isDryRun = !isEnabled && await features.getValue("overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */); + if (!isEnabled && !isDryRun) { + return []; + } + let cachedVersions; + try { + cachedVersions = await getCodeQlVersionsForOverlayBaseDatabases( + rawLanguages, + logger + ); + } catch (e) { + logger.warning( + `Could not list overlay-base databases in the Actions cache while choosing a default CodeQL CLI version, falling back to the highest enabled version. Details: ${getErrorMessage(e)}` + ); + return []; + } + if (cachedVersions === void 0 || cachedVersions.length === 0) { + return []; + } + const cachedVersionsSet = new Set(cachedVersions); + const overlayVersions = defaultCliVersion.enabledVersions.filter( + (v) => cachedVersionsSet.has(v.cliVersion) + ); + if (overlayVersions.length === 0) { + return []; + } + const isCachedVersionDifferent = overlayVersions[0].cliVersion !== defaultCliVersion.enabledVersions[0].cliVersion; + if (isCachedVersionDifferent) { + addNoLanguageDiagnostic( + void 0, + makeTelemetryDiagnostic( + "codeql-action/overlay-aware-default-codeql-version", + "Overlay-aware default CodeQL version selection", + { + cachedVersions, + enabledVersions: defaultCliVersion.enabledVersions.map( + (v) => v.cliVersion + ), + isDryRun, + overlayAwareVersion: overlayVersions[0].cliVersion + } + ) + ); + } + if (isDryRun) { + logger.debug( + `Overlay-aware default CodeQL version selection is running in dry-run mode. Would have used version ${overlayVersions[0].cliVersion}.` + ); + return []; + } + return overlayVersions; +} +async function resolveDefaultCliVersion(defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { + if (!useOverlayAwareDefaultCliVersion || !isAnalyzingPullRequest()) { + return defaultCliVersion.enabledVersions[0]; + } + const overlayVersions = await getEnabledVersionsWithOverlayBaseDatabases( + defaultCliVersion, + rawLanguages, + features, + logger + ); + if (overlayVersions.length > 0) { + logger.info( + `Using CodeQL version ${overlayVersions[0].cliVersion} since this is the highest enabled version that has a cached overlay-base database.` + ); + return overlayVersions[0]; + } + return defaultCliVersion.enabledVersions[0]; +} +async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -91297,21 +91521,35 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } } - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } } else if (toolsInput !== void 0) { tagName = tryGetTagNameFromUrl(toolsInput, logger); url2 = toolsInput; if (tagName) { const bundleVersion3 = tryGetBundleVersionFromTagName(tagName, logger); - if (bundleVersion3 && semver8.valid(bundleVersion3)) { + if (bundleVersion3 && semver9.valid(bundleVersion3)) { cliVersion2 = convertToSemVer(bundleVersion3, logger); } } } else { - cliVersion2 = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger + ); + cliVersion2 = version.cliVersion; + tagName = version.tagName; } const bundleVersion2 = tagName && tryGetBundleVersionFromTagName(tagName, logger); const humanReadableVersion = cliVersion2 ?? (bundleVersion2 && convertToSemVer(bundleVersion2, logger)) ?? tagName ?? url2 ?? "unknown"; @@ -91508,7 +91746,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -91518,6 +91756,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau const source = await getCodeQLSource( toolsInput, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, apiDetails, variant, zstdAvailability.available, @@ -91576,7 +91816,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau async function useZstdBundle(cliVersion2, tarSupportsZstd) { return ( // In testing, gzip performs better than zstd on Windows. - process.platform !== "win32" && tarSupportsZstd && semver8.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) + process.platform !== "win32" && tarSupportsZstd && semver9.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) ); } function getTempExtractionDir(tempDir) { @@ -91608,7 +91848,7 @@ async function getNightlyToolsUrl(logger) { } } function getLatestToolcacheVersion(logger) { - const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver8.compare(b, a)); + const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver9.compare(b, a)); logger.debug( `Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify( allVersions @@ -91645,7 +91885,7 @@ 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 EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -91659,6 +91899,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger ); @@ -93380,7 +93622,7 @@ var core13 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io5 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -93394,6 +93636,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger, true @@ -93471,9 +93715,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo url: getRequiredEnvParam("GITHUB_SERVER_URL"), apiURL: getRequiredEnvParam("GITHUB_API_URL") }; - const codeQLDefaultVersionInfo = await features.getDefaultCliVersion( - gitHubVersion.type - ); + const codeQLDefaultVersionInfo = await features.getEnabledDefaultCliVersions(gitHubVersion.type); const initCodeQLResult = await initCodeQL( void 0, // There is no tools input on the upload action @@ -93481,6 +93723,10 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo tempDir, gitHubVersion.type, codeQLDefaultVersionInfo, + void 0, + // rawLanguages: upload-lib does not run analysis + false, + // useOverlayAwareDefaultCliVersion: upload-lib does not run analysis features, logger ); @@ -93496,7 +93742,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo return readSarifFile(outputFile); } function populateRunAutomationDetails(sarifFile, category, analysis_key, environment) { - const automationID = getAutomationID(category, analysis_key, environment); + const automationID = getAutomationID2(category, analysis_key, environment); if (automationID !== void 0) { for (const run2 of sarifFile.runs || []) { if (run2.automationDetails === void 0) { @@ -93509,7 +93755,7 @@ function populateRunAutomationDetails(sarifFile, category, analysis_key, environ } return sarifFile; } -function getAutomationID(category, analysis_key, environment) { +function getAutomationID2(category, analysis_key, environment) { if (category !== void 0) { let automationID = category; if (!automationID.endsWith("/")) { diff --git a/setup-codeql/action.yml b/setup-codeql/action.yml index b7b52b9a30..d9f7ccb40d 100644 --- a/setup-codeql/action.yml +++ b/setup-codeql/action.yml @@ -19,6 +19,25 @@ inputs: If not specified, the Action will check in several places until it finds the CodeQL tools. required: false + languages: + description: >- + A comma-separated list of CodeQL languages that will be analyzed in subsequent + `github/codeql-action/init` and `github/codeql-action/analyze` invocations. If specified, the + Action may use this list to select a CodeQL CLI version that is best suited to analyzing those + languages, for example by preferring a version that has a cached overlay-base database for the + specified languages. This input is not remembered and must also be passed to + `github/codeql-action/init`. + required: false + analysis-kinds: + description: >- + [Internal] A comma-separated list of analysis kinds that subsequent + `github/codeql-action/init` invocations will enable. If specified, the Action may use this + list to select a CodeQL CLI version that is best suited to those analysis kinds. This input is + not remembered and must also be passed to `github/codeql-action/init`. + + Available options are the same as for the `analysis-kinds` input on the `init` Action. + default: 'code-scanning' + required: true token: description: GitHub token to use for authenticating with this instance of GitHub. default: ${{ github.token }} diff --git a/src/codeql.test.ts b/src/codeql.test.ts index 08310df2ad..77fce4d3b7 100644 --- a/src/codeql.test.ts +++ b/src/codeql.test.ts @@ -71,8 +71,10 @@ async function installIntoToolcache({ tmpDir, util.GitHubVariant.GHES, cliVersion !== undefined - ? { cliVersion, tagName } + ? { enabledVersions: [{ cliVersion, tagName }] } : SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion createFeatures([]), getRunnerLogger(true), false, @@ -144,6 +146,8 @@ test.serial( tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, getRunnerLogger(true), false, @@ -176,6 +180,8 @@ test.serial( tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, getRunnerLogger(true), false, @@ -215,6 +221,8 @@ test.serial( tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, getRunnerLogger(true), false, @@ -265,6 +273,8 @@ for (const { tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, getRunnerLogger(true), false, @@ -285,11 +295,11 @@ for (const { for (const toolcacheVersion of [ // Test that we use the tools from the toolcache when `SAMPLE_DEFAULT_CLI_VERSION` is requested // and `SAMPLE_DEFAULT_CLI_VERSION-` is in the toolcache. - SAMPLE_DEFAULT_CLI_VERSION.cliVersion, - `${SAMPLE_DEFAULT_CLI_VERSION.cliVersion}-20230101`, + SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion, + `${SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion}-20230101`, ]) { test.serial( - `uses tools from toolcache when ${SAMPLE_DEFAULT_CLI_VERSION.cliVersion} is requested and ` + + `uses tools from toolcache when ${SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion} is requested and ` + `${toolcacheVersion} is installed`, async (t) => { const features = createFeatures([]); @@ -309,11 +319,16 @@ for (const toolcacheVersion of [ tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, getRunnerLogger(true), false, ); - t.is(result.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion); + t.is( + result.toolsVersion, + SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion, + ); t.is(result.toolsSource, ToolsSource.Toolcache); t.is(result.toolsDownloadStatusReport?.combinedDurationMs, undefined); t.is(result.toolsDownloadStatusReport?.downloadDurationMs, undefined); @@ -343,9 +358,15 @@ test.serial( tmpDir, util.GitHubVariant.GHES, { - cliVersion: defaults.cliVersion, - tagName: defaults.bundleVersion, + enabledVersions: [ + { + cliVersion: defaults.cliVersion, + tagName: defaults.bundleVersion, + }, + ], }, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, getRunnerLogger(true), false, @@ -385,9 +406,15 @@ test.serial( tmpDir, util.GitHubVariant.GHES, { - cliVersion: defaults.cliVersion, - tagName: defaults.bundleVersion, + enabledVersions: [ + { + cliVersion: defaults.cliVersion, + tagName: defaults.bundleVersion, + }, + ], }, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, getRunnerLogger(true), false, @@ -427,6 +454,8 @@ test.serial( tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, getRunnerLogger(true), false, @@ -468,6 +497,8 @@ test.serial( tmpDir, util.GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, getRunnerLogger(true), false, diff --git a/src/codeql.ts b/src/codeql.ts index ecad2ea199..66ed8cebe1 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -305,6 +305,8 @@ const EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; * @param tempDir * @param variant * @param defaultCliVersion + * @param rawLanguages Raw set of languages. + * @param useOverlayAwareDefaultCliVersion Whether to select an overlay-aware default CLI version. * @param features Information about the features that are enabled. * @param logger * @param checkVersion Whether to check that CodeQL CLI meets the minimum @@ -317,6 +319,8 @@ export async function setupCodeQL( tempDir: string, variant: util.GitHubVariant, defaultCliVersion: CodeQLDefaultVersionInfo, + rawLanguages: string[] | undefined, + useOverlayAwareDefaultCliVersion: boolean, features: FeatureEnablement, logger: Logger, checkVersion: boolean, @@ -340,6 +344,8 @@ export async function setupCodeQL( tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger, ); diff --git a/src/config-utils.ts b/src/config-utils.ts index 0b07010070..860f4651f3 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -407,6 +407,7 @@ export async function getLanguages( return languages; } +/** Parses the `languages` input into a list of languages without checking if they are supported by CodeQL. */ export function getRawLanguagesNoAutodetect( languagesInput: string | undefined, ): string[] { diff --git a/src/feature-flags.test.ts b/src/feature-flags.test.ts index 85007df139..d8b5eea04d 100644 --- a/src/feature-flags.test.ts +++ b/src/feature-flags.test.ts @@ -451,12 +451,16 @@ test.serial(`selects CLI from defaults.json on GHES`, async (t) => { await withTmpDir(async (tmpDir) => { const features = setUpFeatureFlagTests(tmpDir); - const defaultCliVersion = await features.getDefaultCliVersion( + const defaultCliVersion = await features.getEnabledDefaultCliVersions( GitHubVariant.GHES, ); t.deepEqual(defaultCliVersion, { - cliVersion: defaults.cliVersion, - tagName: defaults.bundleVersion, + enabledVersions: [ + { + cliVersion: defaults.cliVersion, + tagName: defaults.bundleVersion, + }, + ], }); }); }); @@ -482,10 +486,13 @@ for (const variant of [GitHubVariant.DOTCOM, GitHubVariant.GHEC_DR]) { false; mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement); - const defaultCliVersion = await features.getDefaultCliVersion(variant); + const defaultCliVersion = + await features.getEnabledDefaultCliVersions(variant); t.deepEqual(defaultCliVersion, { - cliVersion: "2.20.1", - tagName: "codeql-bundle-v2.20.1", + enabledVersions: [ + { cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" }, + { cliVersion: "2.20.0", tagName: "codeql-bundle-v2.20.0" }, + ], toolsFeatureFlagsValid: true, }); }); @@ -500,10 +507,15 @@ for (const variant of [GitHubVariant.DOTCOM, GitHubVariant.GHEC_DR]) { const expectedFeatureEnablement = initializeFeatures(true); mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement); - const defaultCliVersion = await features.getDefaultCliVersion(variant); + const defaultCliVersion = + await features.getEnabledDefaultCliVersions(variant); t.deepEqual(defaultCliVersion, { - cliVersion: defaults.cliVersion, - tagName: defaults.bundleVersion, + enabledVersions: [ + { + cliVersion: defaults.cliVersion, + tagName: defaults.bundleVersion, + }, + ], toolsFeatureFlagsValid: false, }); }); @@ -529,10 +541,13 @@ for (const variant of [GitHubVariant.DOTCOM, GitHubVariant.GHEC_DR]) { ] = true; mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement); - const defaultCliVersion = await features.getDefaultCliVersion(variant); + const defaultCliVersion = + await features.getEnabledDefaultCliVersions(variant); t.deepEqual(defaultCliVersion, { - cliVersion: "2.20.1", - tagName: "codeql-bundle-v2.20.1", + enabledVersions: [ + { cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" }, + { cliVersion: "2.20.0", tagName: "codeql-bundle-v2.20.0" }, + ], toolsFeatureFlagsValid: true, }); diff --git a/src/feature-flags.ts b/src/feature-flags.ts index d28800e9b8..e31f8bea7b 100644 --- a/src/feature-flags.ts +++ b/src/feature-flags.ts @@ -29,9 +29,32 @@ const DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled"; */ export const CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0"; -export interface CodeQLDefaultVersionInfo { +const LINKED_CODEQL_VERSION: CodeQLVersionInfo = { + cliVersion: defaults.cliVersion, + tagName: defaults.bundleVersion, +}; + +export interface CodeQLVersionInfo { + /** The version number of the CodeQL CLI, e.g. `2.19.0`. */ cliVersion: string; + /** + * The tag name of the CodeQL Bundle associated with this version, e.g. `codeql-bundle-v2.19.0`. + */ tagName: string; +} + +export interface CodeQLDefaultVersionInfo { + /** + * CodeQL CLI versions that are enabled as defaults, sorted from highest to lowest. + * + * Guaranteed to be non-empty. When feature flags are unavailable, this falls back to a single + * entry containing the version pinned in `defaults.json`. + */ + enabledVersions: CodeQLVersionInfo[]; + /** + * If accessed, whether the tools feature flags are valid, i.e. contain at least one enabled + * version. + */ toolsFeatureFlagsValid?: boolean; } @@ -72,6 +95,19 @@ export enum Feature { OverlayAnalysisGo = "overlay_analysis_go", OverlayAnalysisJava = "overlay_analysis_java", OverlayAnalysisJavascript = "overlay_analysis_javascript", + /** + * When set, chooses the default CodeQL CLI version as the highest version that is both enabled by + * feature flags and present as an overlay-base database in the Actions cache for the configured + * languages. Falls back to the highest feature flagged version if no intersecting overlay-base + * database exists in the cache. + */ + OverlayAnalysisMatchCodeqlVersion = "overlay_analysis_match_codeql_version", + /** + * Like `OverlayAnalysisMatchCodeqlVersion`, but only logs a diagnostic with the version that + * would have been chosen instead of actually changing the default CodeQL CLI version. + * `OverlayAnalysisMatchCodeqlVersion` overrides this flag. + */ + OverlayAnalysisMatchCodeqlVersionDryRun = "overlay_analysis_match_codeql_version_dry_run", OverlayAnalysisPython = "overlay_analysis_python", /** * Controls whether lower disk space requirements are used for overlay hardware checks. @@ -277,6 +313,16 @@ export const featureConfig = { envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING", minimumVersion: undefined, }, + [Feature.OverlayAnalysisMatchCodeqlVersion]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION", + minimumVersion: undefined, + }, + [Feature.OverlayAnalysisMatchCodeqlVersionDryRun]: { + defaultValue: false, + envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", + minimumVersion: undefined, + }, [Feature.OverlayAnalysisResourceChecksV2]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_RESOURCE_CHECKS_V2", @@ -346,8 +392,12 @@ export type FeatureWithoutCLI = { }[keyof typeof featureConfig]; export interface FeatureEnablement { - /** Gets the default version of the CodeQL tools. */ - getDefaultCliVersion( + /** + * Returns the set of default CodeQL CLI versions to consider, sorted from + * highest to lowest. The first entry is the version that the CodeQL Action + * will use by default. The list is always non-empty. + */ + getEnabledDefaultCliVersions( variant: util.GitHubVariant, ): Promise; getValue(feature: FeatureWithoutCLI): Promise; @@ -371,12 +421,11 @@ export const FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json"; class OfflineFeatures implements FeatureEnablement { constructor(protected readonly logger: Logger) {} - async getDefaultCliVersion( + async getEnabledDefaultCliVersions( _variant: util.GitHubVariant, ): Promise { return { - cliVersion: defaults.cliVersion, - tagName: defaults.bundleVersion, + enabledVersions: [LINKED_CODEQL_VERSION], }; } @@ -518,13 +567,13 @@ class Features extends OfflineFeatures { ); } - async getDefaultCliVersion( + async getEnabledDefaultCliVersions( variant: util.GitHubVariant, ): Promise { if (supportsFeatureFlags(variant)) { - return await this.gitHubFeatureFlags.getDefaultCliVersionFromFlags(); + return await this.gitHubFeatureFlags.getEnabledDefaultCliVersionsFromFlags(); } - return super.getDefaultCliVersion(variant); + return super.getEnabledDefaultCliVersions(variant); } /** @@ -600,16 +649,22 @@ class GitHubFeatureFlags { return version; } - async getDefaultCliVersionFromFlags(): Promise { + /** + * Returns CLI versions enabled by `default_codeql_version_*_enabled` feature + * flags, sorted from highest to lowest. Falls back to the version pinned in + * `defaults.json` if no such flags are enabled. + */ + async getEnabledDefaultCliVersionsFromFlags(): Promise { const response = await this.getAllFeatures(); - const enabledFeatureFlagCliVersions = Object.entries(response) + const sortedCliVersions = Object.entries(response) .map(([f, isEnabled]) => isEnabled ? this.getCliVersionFromFeatureFlag(f) : undefined, ) - .filter((f): f is string => f !== undefined); + .filter((f): f is string => f !== undefined) + .sort(semver.rcompare); - if (enabledFeatureFlagCliVersions.length === 0) { + if (sortedCliVersions.length === 0) { // We expect at least one default CLI version to be enabled on Dotcom at any time. However if // the feature flags are misconfigured, rather than crashing, we fall back to the CLI version // shipped with the Action in defaults.json. This has the effect of immediately rolling out @@ -625,8 +680,7 @@ class GitHubFeatureFlags { `shipped with the Action. This is ${defaults.cliVersion}.`, ); const result: CodeQLDefaultVersionInfo = { - cliVersion: defaults.cliVersion, - tagName: defaults.bundleVersion, + enabledVersions: [LINKED_CODEQL_VERSION], }; if (this.hasAccessedRemoteFeatureFlags) { result.toolsFeatureFlagsValid = false; @@ -634,17 +688,14 @@ class GitHubFeatureFlags { return result; } - const maxCliVersion = enabledFeatureFlagCliVersions.reduce( - (maxVersion, currentVersion) => - currentVersion > maxVersion ? currentVersion : maxVersion, - enabledFeatureFlagCliVersions[0], - ); this.logger.debug( - `Derived default CLI version of ${maxCliVersion} from feature flags.`, + `Derived default CLI version of ${sortedCliVersions[0]} from feature flags.`, ); return { - cliVersion: maxCliVersion, - tagName: `codeql-bundle-v${maxCliVersion}`, + enabledVersions: sortedCliVersions.map((cliVersion) => ({ + cliVersion, + tagName: `codeql-bundle-v${cliVersion}`, + })), toolsFeatureFlagsValid: true, }; } diff --git a/src/init-action.ts b/src/init-action.ts index 859dcefa2c..b529b68049 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -298,16 +298,23 @@ async function run(startedAt: Date) { ); } - const codeQLDefaultVersionInfo = await features.getDefaultCliVersion( - gitHubVersion.type, - ); + const codeQLDefaultVersionInfo = + await features.getEnabledDefaultCliVersions(gitHubVersion.type); toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid; + const rawLanguages = configUtils.getRawLanguagesNoAutodetect( + getOptionalInput("languages"), + ); + const useOverlayAwareDefaultCliVersion = !!analysisKinds?.includes( + AnalysisKind.CodeScanning, + ); const initCodeQLResult = await initCodeQL( getOptionalInput("tools"), apiDetails, getTemporaryDirectory(), gitHubVersion.type, codeQLDefaultVersionInfo, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger, ); diff --git a/src/init.ts b/src/init.ts index 8ed6f64005..2533d9a894 100644 --- a/src/init.ts +++ b/src/init.ts @@ -39,6 +39,8 @@ export async function initCodeQL( tempDir: string, variant: util.GitHubVariant, defaultCliVersion: CodeQLDefaultVersionInfo, + rawLanguages: string[] | undefined, + useOverlayAwareDefaultCliVersion: boolean, features: FeatureEnablement, logger: Logger, ): Promise<{ @@ -61,6 +63,8 @@ export async function initCodeQL( tempDir, variant, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, features, logger, true, diff --git a/src/overlay/caching.test.ts b/src/overlay/caching.test.ts index bc7b699016..618a25451d 100644 --- a/src/overlay/caching.test.ts +++ b/src/overlay/caching.test.ts @@ -380,6 +380,32 @@ test.serial( }, ); +test.serial( + "getCodeQlVersionsForOverlayBaseDatabases de-duplicates resolved language aliases", + async (t) => { + const logger = getRunnerLogger(true); + + sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/"); + const listActionsCachesStub = sinon + .stub(apiClient, "listActionsCaches") + .resolves([ + { + key: "codeql-overlay-base-database-1-c5666c509a2d9895-javascript_python-2.25.0-abc123-1-1", + }, + ]); + + const result = await getCodeQlVersionsForOverlayBaseDatabases( + ["javascript", "typescript", "Python", "python"], + logger, + ); + t.deepEqual(result, ["2.25.0"]); + sinon.assert.calledOnceWithExactly( + listActionsCachesStub, + "codeql-overlay-base-database-1-c5666c509a2d9895-javascript_python-", + ); + }, +); + test.serial( "getCodeQlVersionsForOverlayBaseDatabases ignores nightly versions with build metadata", async (t) => { diff --git a/src/overlay/caching.ts b/src/overlay/caching.ts index 268c20c129..c4557cd4ef 100644 --- a/src/overlay/caching.ts +++ b/src/overlay/caching.ts @@ -461,9 +461,10 @@ export async function getCodeQlVersionsForOverlayBaseDatabases( ); return undefined; } - const cacheKeyPrefix = await getCacheKeyPrefixBase( - languages.filter((l) => l !== undefined), - ); + const dedupedLanguages = [ + ...new Set(languages.filter((l) => l !== undefined)), + ]; + const cacheKeyPrefix = await getCacheKeyPrefixBase(dedupedLanguages); logger.debug( `Searching for overlay-base databases in Actions cache with ` + diff --git a/src/setup-codeql-action.ts b/src/setup-codeql-action.ts index bd504f3fd3..c23553c983 100644 --- a/src/setup-codeql-action.ts +++ b/src/setup-codeql-action.ts @@ -7,8 +7,10 @@ import { getRequiredInput, getTemporaryDirectory, } from "./actions-util"; +import { AnalysisKind, getAnalysisKinds } from "./analyses"; import { getGitHubVersion } from "./api-client"; import { CodeQL } from "./codeql"; +import { getRawLanguagesNoAutodetect } from "./config-utils"; import { EnvVar } from "./environment"; import { initFeatures } from "./feature-flags"; import { initCodeQL } from "./init"; @@ -136,16 +138,21 @@ async function run(startedAt: Date): Promise { if (statusReportBase !== undefined) { await sendStatusReport(statusReportBase); } - const codeQLDefaultVersionInfo = await features.getDefaultCliVersion( - gitHubVersion.type, - ); + const codeQLDefaultVersionInfo = + await features.getEnabledDefaultCliVersions(gitHubVersion.type); toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid; + const rawLanguages = getRawLanguagesNoAutodetect( + getOptionalInput("languages"), + ); + const analysisKinds = await getAnalysisKinds(logger); const initCodeQLResult = await initCodeQL( getOptionalInput("tools"), apiDetails, getTemporaryDirectory(), gitHubVersion.type, codeQLDefaultVersionInfo, + rawLanguages, + analysisKinds.includes(AnalysisKind.CodeScanning), features, logger, ); diff --git a/src/setup-codeql.test.ts b/src/setup-codeql.test.ts index fc0ac7b0fb..49d4d66aad 100644 --- a/src/setup-codeql.test.ts +++ b/src/setup-codeql.test.ts @@ -7,8 +7,9 @@ import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; import * as api from "./api-client"; -import { Feature, FeatureEnablement } from "./feature-flags"; +import { Feature } from "./feature-flags"; import { getRunnerLogger } from "./logging"; +import { getCacheRestoreKeyPrefix } from "./overlay/caching"; import * as setupCodeql from "./setup-codeql"; import * as tar from "./tar"; import { @@ -18,8 +19,8 @@ import { SAMPLE_DOTCOM_API_DETAILS, checkExpectedLogMessages, createFeatures, + createTestConfig, getRecordingLogger, - initializeFeatures, makeMacro, mockBundleDownloadApi, setupActionsVars, @@ -34,14 +35,6 @@ import { setupTests(test); -// TODO: Remove when when we no longer need to pass in features (https://github.com/github/codeql-action/issues/2600) -const expectedFeatureEnablement: FeatureEnablement = initializeFeatures( - true, -) as FeatureEnablement; -expectedFeatureEnablement.getValue = function (feature: Feature) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return expectedFeatureEnablement[feature]; -}; test.beforeEach(() => { initializeEnvironment("1.2.3"); }); @@ -108,6 +101,8 @@ test.serial( const source = await setupCodeql.getCodeQLSource( `https://github.com/github/codeql-action/releases/download/${tagName}/codeql-bundle-linux64.tar.gz`, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion SAMPLE_DOTCOM_API_DETAILS, GitHubVariant.DOTCOM, false, @@ -131,6 +126,8 @@ test.serial( const source = await setupCodeql.getCodeQLSource( "linked", SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion SAMPLE_DOTCOM_API_DETAILS, GitHubVariant.DOTCOM, false, @@ -156,6 +153,8 @@ test.serial( const source = await setupCodeql.getCodeQLSource( "latest", SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion SAMPLE_DOTCOM_API_DETAILS, GitHubVariant.DOTCOM, false, @@ -212,6 +211,8 @@ test.serial( "tmp/codeql_action_test/", GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, logger, ); @@ -267,6 +268,8 @@ test.serial( "tmp/codeql_action_test/", GitHubVariant.DOTCOM, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion features, logger, ); @@ -318,6 +321,8 @@ test.serial( const source = await setupCodeql.getCodeQLSource( "nightly", SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion SAMPLE_DOTCOM_API_DETAILS, GitHubVariant.DOTCOM, false, @@ -379,6 +384,8 @@ test.serial( const source = await setupCodeql.getCodeQLSource( undefined, SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion SAMPLE_DOTCOM_API_DETAILS, GitHubVariant.DOTCOM, false, @@ -433,6 +440,8 @@ test.serial( const source = await setupCodeql.getCodeQLSource( "toolcache", SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion SAMPLE_DOTCOM_API_DETAILS, GitHubVariant.DOTCOM, false, @@ -500,6 +509,8 @@ const toolcacheInputFallbackMacro = makeMacro({ const source = await setupCodeql.getCodeQLSource( "toolcache", SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion SAMPLE_DOTCOM_API_DETAILS, GitHubVariant.DOTCOM, false, @@ -515,7 +526,10 @@ const toolcacheInputFallbackMacro = makeMacro({ // Check that `sourceType` and `toolsVersion` match expectations. t.is(source.sourceType, "download"); - t.is(source.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion); + t.is( + source.toolsVersion, + SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion, + ); // Check that key messages we would expect to find in the log are present. for (const expectedMessage of expectedMessages) { @@ -596,3 +610,288 @@ test.serial( t.is(setupCodeql.getLatestToolcacheVersion(getRunnerLogger(true)), "3.2.1"); }, ); + +const overlayMatchEnabledVersions = { + enabledVersions: [ + { cliVersion: "2.20.2", tagName: "codeql-bundle-v2.20.2" }, + { cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" }, + { cliVersion: "2.20.0", tagName: "codeql-bundle-v2.20.0" }, + ], + toolsFeatureFlagsValid: true, +}; + +async function fakeOverlayBaseCacheKey( + language: string, + cliVersion: string, + suffix: string, +): Promise { + const prefix = await getCacheRestoreKeyPrefix( + createTestConfig({ languages: [language] }), + cliVersion, + ); + return `${prefix}${suffix}`; +} + +test.serial( + "getCodeQLSource uses overlay-aware default version when requested for a PR", + 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"; + + sinon.stub(api, "getAutomationID").resolves("test/"); + const listStub = sinon.stub(api, "listActionsCaches").resolves([ + { + key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "abc-1-1"), + }, + ]); + sinon + .stub(toolcache, "find") + .withArgs("CodeQL", "2.20.1") + .returns("/path/to/codeql-2.20.1"); + + const source = await setupCodeql.getCodeQLSource( + undefined, + overlayMatchEnabledVersions, + ["javascript"], + true, + SAMPLE_DOTCOM_API_DETAILS, + GitHubVariant.DOTCOM, + false, + createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]), + getRunnerLogger(true), + ); + + t.assert(listStub.calledOnce); + t.is(source.sourceType, "toolcache"); + t.is(source.toolsVersion, "2.20.1"); + }); + }, +); + +test.serial( + "getCodeQLSource skips overlay-aware default version when not requested", + 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"; + + sinon.stub(api, "getAutomationID").resolves("test/"); + const listStub = sinon.stub(api, "listActionsCaches").resolves([ + { + key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "abc-1-1"), + }, + ]); + sinon + .stub(toolcache, "find") + .withArgs("CodeQL", "2.20.2") + .returns("/path/to/codeql-2.20.2"); + + const source = await setupCodeql.getCodeQLSource( + undefined, + overlayMatchEnabledVersions, + ["javascript"], + false, + SAMPLE_DOTCOM_API_DETAILS, + GitHubVariant.DOTCOM, + false, + createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]), + getRunnerLogger(true), + ); + + t.assert(listStub.notCalled); + t.is(source.sourceType, "toolcache"); + t.is(source.toolsVersion, "2.20.2"); + }); + }, +); + +test.serial( + "getEnabledVersionsWithOverlayBaseDatabases returns flag-enabled versions present in cache, sorted desc", + async (t) => { + sinon.stub(api, "getAutomationID").resolves("test/"); + sinon.stub(api, "listActionsCaches").resolves([ + // Flag-enabled versions present in the cache, listed in non-descending + // order so the test exercises the sort. + { + key: await fakeOverlayBaseCacheKey("javascript", "2.20.0", "ghi-3-1"), + }, + { + key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "def-2-1"), + }, + // Newer than any flag-enabled version: should be filtered out. + { + key: await fakeOverlayBaseCacheKey("javascript", "2.21.0", "abc-1-1"), + }, + ]); + + const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases( + overlayMatchEnabledVersions, + ["javascript"], + createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]), + getRunnerLogger(true), + ); + t.deepEqual(result, [ + { cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" }, + { cliVersion: "2.20.0", tagName: "codeql-bundle-v2.20.0" }, + ]); + }, +); + +test.serial( + "getEnabledVersionsWithOverlayBaseDatabases returns empty when no cached version is flag-enabled", + async (t) => { + sinon.stub(api, "getAutomationID").resolves("test/"); + sinon.stub(api, "listActionsCaches").resolves([ + { + key: await fakeOverlayBaseCacheKey("javascript", "2.19.0", "abc-1-1"), + }, + ]); + + const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases( + overlayMatchEnabledVersions, + ["javascript"], + createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]), + getRunnerLogger(true), + ); + t.deepEqual(result, []); + }, +); + +const noLanguagesMacro = makeMacro({ + exec: async ( + t: ExecutionContext, + rawLanguages: string[] | undefined, + ) => { + const listStub = sinon.stub(api, "listActionsCaches").resolves([]); + + const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases( + overlayMatchEnabledVersions, + rawLanguages, + createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]), + getRunnerLogger(true), + ); + t.deepEqual(result, []); + t.assert( + listStub.notCalled, + "Should not list Actions caches without any rawLanguages.", + ); + }, + title: (providedTitle = "") => + `getEnabledVersionsWithOverlayBaseDatabases does not list caches when rawLanguages is ${providedTitle}`, +}); + +noLanguagesMacro.serial("undefined", undefined); +noLanguagesMacro.serial("an empty array", []); + +test.serial( + "getEnabledVersionsWithOverlayBaseDatabases returns empty when listing caches throws", + async (t) => { + sinon.stub(api, "getAutomationID").resolves("test/"); + sinon.stub(api, "listActionsCaches").rejects(new Error("listing failed")); + + const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases( + overlayMatchEnabledVersions, + ["javascript"], + createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]), + getRunnerLogger(true), + ); + t.deepEqual(result, []); + }, +); + +test.serial( + "getEnabledVersionsWithOverlayBaseDatabases returns versions present in the cache", + async (t) => { + sinon.stub(api, "getAutomationID").resolves("test/"); + sinon.stub(api, "listActionsCaches").resolves([ + { + key: await fakeOverlayBaseCacheKey("javascript", "2.20.2", "abc-1-1"), + }, + ]); + + const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases( + overlayMatchEnabledVersions, + ["javascript"], + createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]), + getRunnerLogger(true), + ); + t.deepEqual(result, [ + { cliVersion: "2.20.2", tagName: "codeql-bundle-v2.20.2" }, + ]); + }, +); + +test.serial( + "getEnabledVersionsWithOverlayBaseDatabases does not list caches when both gates are off", + async (t) => { + const listStub = sinon.stub(api, "listActionsCaches").resolves([]); + + const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases( + overlayMatchEnabledVersions, + ["javascript"], + createFeatures([]), + getRunnerLogger(true), + ); + t.deepEqual(result, []); + t.assert( + listStub.notCalled, + "Should not list Actions caches when both gating feature flags are off.", + ); + }, +); + +test.serial( + "getEnabledVersionsWithOverlayBaseDatabases dry-run returns empty but lists caches", + async (t) => { + sinon.stub(api, "getAutomationID").resolves("test/"); + const listStub = sinon.stub(api, "listActionsCaches").resolves([ + { + key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "abc-1-1"), + }, + ]); + + const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases( + overlayMatchEnabledVersions, + ["javascript"], + createFeatures([Feature.OverlayAnalysisMatchCodeqlVersionDryRun]), + getRunnerLogger(true), + ); + t.deepEqual( + result, + [], + "Dry-run should return an empty list so the caller falls back.", + ); + t.assert( + listStub.calledOnce, + "Dry-run should still list Actions caches to populate the diagnostic.", + ); + }, +); + +test.serial( + "getEnabledVersionsWithOverlayBaseDatabases match flag wins over dry-run", + async (t) => { + sinon.stub(api, "getAutomationID").resolves("test/"); + sinon.stub(api, "listActionsCaches").resolves([ + { + key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "abc-1-1"), + }, + ]); + + const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases( + overlayMatchEnabledVersions, + ["javascript"], + createFeatures([ + Feature.OverlayAnalysisMatchCodeqlVersion, + Feature.OverlayAnalysisMatchCodeqlVersionDryRun, + ]), + getRunnerLogger(true), + ); + t.deepEqual(result, [ + { cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" }, + ]); + }, +); diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 4ca3302f95..3db0b6ca4d 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -7,17 +7,27 @@ import { default as deepEqual } from "fast-deep-equal"; import * as semver from "semver"; import { v4 as uuidV4 } from "uuid"; -import { isDynamicWorkflow, isRunningLocalAction } from "./actions-util"; +import { + isAnalyzingPullRequest, + isDynamicWorkflow, + isRunningLocalAction, +} from "./actions-util"; import * as api from "./api-client"; import * as defaults from "./defaults.json"; -import { addNoLanguageDiagnostic, makeDiagnostic } from "./diagnostics"; +import { + addNoLanguageDiagnostic, + makeDiagnostic, + makeTelemetryDiagnostic, +} from "./diagnostics"; import { CODEQL_VERSION_ZSTD_BUNDLE, CodeQLDefaultVersionInfo, + CodeQLVersionInfo, Feature, FeatureEnablement, } from "./feature-flags"; import { Logger } from "./logging"; +import { getCodeQlVersionsForOverlayBaseDatabases } from "./overlay/caching"; import * as tar from "./tar"; import { downloadAndExtract, @@ -264,12 +274,131 @@ async function findOverridingToolsInCache( return undefined; } +/** + * Returns the sorted set of enabled versions that have cached overlay-base databases for the + * given languages, or an empty list if neither the `OverlayAnalysisMatchCodeqlVersion` nor the + * `OverlayAnalysisMatchCodeqlVersionDryRun` feature flag is enabled. When only the dry-run flag + * is enabled, this performs the lookup and emits a telemetry diagnostic with the version that + * would have been chosen, but still returns an empty list so the caller falls back. + */ +export async function getEnabledVersionsWithOverlayBaseDatabases( + defaultCliVersion: CodeQLDefaultVersionInfo, + rawLanguages: string[] | undefined, + features: FeatureEnablement, + logger: Logger, +): Promise { + if (rawLanguages === undefined || rawLanguages.length === 0) { + return []; + } + const isEnabled = await features.getValue( + Feature.OverlayAnalysisMatchCodeqlVersion, + ); + const isDryRun = + !isEnabled && + (await features.getValue(Feature.OverlayAnalysisMatchCodeqlVersionDryRun)); + if (!isEnabled && !isDryRun) { + return []; + } + + let cachedVersions: string[] | undefined; + try { + cachedVersions = await getCodeQlVersionsForOverlayBaseDatabases( + rawLanguages, + logger, + ); + } catch (e) { + logger.warning( + "Could not list overlay-base databases in the Actions cache while choosing a default " + + `CodeQL CLI version, falling back to the highest enabled version. Details: ${util.getErrorMessage(e)}`, + ); + return []; + } + + if (cachedVersions === undefined || cachedVersions.length === 0) { + return []; + } + + const cachedVersionsSet = new Set(cachedVersions); + const overlayVersions = defaultCliVersion.enabledVersions.filter((v) => + cachedVersionsSet.has(v.cliVersion), + ); + + if (overlayVersions.length === 0) { + return []; + } + + const isCachedVersionDifferent = + overlayVersions[0].cliVersion !== + defaultCliVersion.enabledVersions[0].cliVersion; + + if (isCachedVersionDifferent) { + addNoLanguageDiagnostic( + undefined, + makeTelemetryDiagnostic( + "codeql-action/overlay-aware-default-codeql-version", + "Overlay-aware default CodeQL version selection", + { + cachedVersions, + enabledVersions: defaultCliVersion.enabledVersions.map( + (v) => v.cliVersion, + ), + isDryRun, + overlayAwareVersion: overlayVersions[0].cliVersion, + }, + ), + ); + } + + if (isDryRun) { + logger.debug( + `Overlay-aware default CodeQL version selection is running in dry-run mode. Would have used version ${overlayVersions[0].cliVersion}.`, + ); + return []; + } + + return overlayVersions; +} + +/** + * Resolves the newest enabled default CLI version that has a cached overlay-base database for the + * relevant languages, if running a Code Scanning analysis for a pull request and one exists. + * Otherwise, falls back to the newest enabled default CLI version. + */ +async function resolveDefaultCliVersion( + defaultCliVersion: CodeQLDefaultVersionInfo, + rawLanguages: string[] | undefined, + useOverlayAwareDefaultCliVersion: boolean, + features: FeatureEnablement, + logger: Logger, +): Promise { + if (!useOverlayAwareDefaultCliVersion || !isAnalyzingPullRequest()) { + return defaultCliVersion.enabledVersions[0]; + } + + const overlayVersions = await getEnabledVersionsWithOverlayBaseDatabases( + defaultCliVersion, + rawLanguages, + features, + logger, + ); + if (overlayVersions.length > 0) { + logger.info( + `Using CodeQL version ${overlayVersions[0].cliVersion} since this is the ` + + `highest enabled version that has a cached overlay-base database.`, + ); + return overlayVersions[0]; + } + return defaultCliVersion.enabledVersions[0]; +} + /** * Determines where the CodeQL CLI we want to use comes from. This can be from a local file, * the Actions toolcache, or a download. * * @param toolsInput The argument provided for the `tools` input, if any. * @param defaultCliVersion The default CLI version that's linked to the CodeQL Action. + * @param rawLanguages Raw set of languages. + * @param useOverlayAwareDefaultCliVersion Whether to select an overlay-aware default CLI version. * @param apiDetails Information about the GitHub API. * @param variant The GitHub variant we are running on. * @param tarSupportsZstd Whether zstd is supported by `tar`. @@ -281,6 +410,8 @@ async function findOverridingToolsInCache( export async function getCodeQLSource( toolsInput: string | undefined, defaultCliVersion: CodeQLDefaultVersionInfo, + rawLanguages: string[] | undefined, + useOverlayAwareDefaultCliVersion: boolean, apiDetails: api.GitHubApiDetails, variant: util.GitHubVariant, tarSupportsZstd: boolean, @@ -438,8 +569,15 @@ export async function getCodeQLSource( } } - cliVersion = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger, + ); + cliVersion = version.cliVersion; + tagName = version.tagName; } } else if (toolsInput !== undefined) { // If a tools URL was provided, then use that. @@ -454,9 +592,15 @@ export async function getCodeQLSource( } } } else { - // Otherwise, use the default CLI version passed in. - cliVersion = defaultCliVersion.cliVersion; - tagName = defaultCliVersion.tagName; + const version = await resolveDefaultCliVersion( + defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, + features, + logger, + ); + cliVersion = version.cliVersion; + tagName = version.tagName; } const bundleVersion = @@ -791,6 +935,8 @@ export async function setupCodeQLBundle( tempDir: string, variant: util.GitHubVariant, defaultCliVersion: CodeQLDefaultVersionInfo, + rawLanguages: string[] | undefined, + useOverlayAwareDefaultCliVersion: boolean, features: FeatureEnablement, logger: Logger, ): Promise { @@ -804,6 +950,8 @@ export async function setupCodeQLBundle( const source = await getCodeQLSource( toolsInput, defaultCliVersion, + rawLanguages, + useOverlayAwareDefaultCliVersion, apiDetails, variant, zstdAvailability.available, diff --git a/src/start-proxy.test.ts b/src/start-proxy.test.ts index b2dbc81a40..9f12656f62 100644 --- a/src/start-proxy.test.ts +++ b/src/start-proxy.test.ts @@ -1010,8 +1010,10 @@ test.serial( return true; }); const getDefaultCliVersion = sinon - .stub(features, "getDefaultCliVersion") - .resolves({ cliVersion: "2.20.1", tagName: expectedTag }); + .stub(features, "getEnabledDefaultCliVersions") + .resolves({ + enabledVersions: [{ cliVersion: "2.20.1", tagName: expectedTag }], + }); const path = await startProxyExports.getProxyBinaryPath(logger, features); t.assert(getDefaultCliVersion.calledOnce); diff --git a/src/start-proxy.ts b/src/start-proxy.ts index 1013ae3868..d6111510f6 100644 --- a/src/start-proxy.ts +++ b/src/start-proxy.ts @@ -415,7 +415,7 @@ async function getCliVersionFromFeatures( features: FeatureEnablement, ): Promise { const gitHubVersion = await getGitHubVersion(); - return await features.getDefaultCliVersion(gitHubVersion.type); + return await features.getEnabledDefaultCliVersions(gitHubVersion.type); } /** @@ -440,7 +440,7 @@ export async function getDownloadUrl( // Retrieve information about the CLI version we should use. This will be either the linked // version, or the one enabled by FFs. const versionInfo = useFeaturesToDetermineCLI - ? await getCliVersionFromFeatures(features) + ? (await getCliVersionFromFeatures(features)).enabledVersions[0] : { cliVersion: defaults.cliVersion, tagName: defaults.bundleVersion, diff --git a/src/testing-utils.ts b/src/testing-utils.ts index cdfb37c738..53a1f27e91 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -40,16 +40,20 @@ export const SAMPLE_DOTCOM_API_DETAILS = { apiURL: "https://api.github.com", }; -export const SAMPLE_DEFAULT_CLI_VERSION: CodeQLDefaultVersionInfo = { - cliVersion: "2.20.0", - tagName: "codeql-bundle-v2.20.0", -}; - export const LINKED_CLI_VERSION = { cliVersion: defaults.cliVersion, tagName: defaults.bundleVersion, }; +export const SAMPLE_DEFAULT_CLI_VERSION: CodeQLDefaultVersionInfo = { + enabledVersions: [ + { + cliVersion: "2.20.0", + tagName: "codeql-bundle-v2.20.0", + }, + ], +}; + type TestContext = { stdoutWrite: any; stderrWrite: any; @@ -466,7 +470,7 @@ export function mockCodeQLVersion( */ export function createFeatures(enabledFeatures: Feature[]): FeatureEnablement { return { - getDefaultCliVersion: async () => { + getEnabledDefaultCliVersions: async () => { throw new Error("not implemented"); }, getValue: async (feature) => { diff --git a/src/upload-lib.ts b/src/upload-lib.ts index 2464fe5eaa..83331aeed9 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -156,9 +156,8 @@ async function combineSarifFilesUsingCLI( apiURL: getRequiredEnvParam("GITHUB_API_URL"), }; - const codeQLDefaultVersionInfo = await features.getDefaultCliVersion( - gitHubVersion.type, - ); + const codeQLDefaultVersionInfo = + await features.getEnabledDefaultCliVersions(gitHubVersion.type); const initCodeQLResult = await initCodeQL( undefined, // There is no tools input on the upload action @@ -166,6 +165,8 @@ async function combineSarifFilesUsingCLI( tempDir, gitHubVersion.type, codeQLDefaultVersionInfo, + undefined, // rawLanguages: upload-lib does not run analysis + false, // useOverlayAwareDefaultCliVersion: upload-lib does not run analysis features, logger, );