diff --git a/.github/workflows/__multi-language-autodetect.yml b/.github/workflows/__multi-language-autodetect.yml index 55023cd916..0a0f201ead 100644 --- a/.github/workflows/__multi-language-autodetect.yml +++ b/.github/workflows/__multi-language-autodetect.yml @@ -191,5 +191,6 @@ jobs: exit 1 fi env: + CODEQL_ACTION_CLEANUP_TOOLCACHE_BUNDLES: true CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true CODEQL_ACTION_TEST_MODE: true diff --git a/CHANGELOG.md b/CHANGELOG.md index dc22e818d1..58268df8d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th ## [UNRELEASED] - The CodeQL Action now supports CodeQL releases that are compatible with Linux Arm64 and download the native `linux-arm64` CodeQL bundle when available. [#4072](https://github.com/github/codeql-action/pull/4072) +- On GitHub-hosted runners, the CodeQL Action now deletes unused CodeQL bundles from the toolcache before downloading a different bundle, which frees up disk space for the analysis. We expect to roll this change out to everyone in September. [#4124](https://github.com/github/codeql-action/pull/4124) ## 4.37.9 - 26 Aug 2026 diff --git a/lib/entry-points.js b/lib/entry-points.js index afaa9ba104..249db17bef 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -21641,7 +21641,7 @@ var require_core = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.platform = exports2.toPlatformPath = exports2.toWin32Path = exports2.toPosixPath = exports2.markdownSummary = exports2.summary = exports2.ExitCode = void 0; - exports2.exportVariable = exportVariable16; + exports2.exportVariable = exportVariable17; exports2.setSecret = setSecret2; exports2.addPath = addPath2; exports2.getInput = getInput2; @@ -21673,7 +21673,7 @@ var require_core = __commonJS({ ExitCode2[ExitCode2["Success"] = 0] = "Success"; ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; })(ExitCode || (exports2.ExitCode = ExitCode = {})); - function exportVariable16(name, val) { + function exportVariable17(name, val) { const convertedVal = (0, utils_1.toCommandValue)(val); process.env[name] = convertedVal; const filePath = process.env["GITHUB_ENV"] || ""; @@ -28652,7 +28652,7 @@ var require_light = __commonJS({ } } async trigger(name, ...args) { - var e, promises6; + var e, promises7; try { if (name !== "debug") { this.trigger("debug", `Event triggered: ${name}`, args); @@ -28663,7 +28663,7 @@ var require_light = __commonJS({ this._events[name] = this._events[name].filter(function(listener) { return listener.status !== "none"; }); - promises6 = this._events[name].map(async (listener) => { + promises7 = this._events[name].map(async (listener) => { var e2, returned; if (listener.status === "none") { return; @@ -28686,7 +28686,7 @@ var require_light = __commonJS({ return null; } }); - return (await Promise.all(promises6)).find(function(x) { + return (await Promise.all(promises7)).find(function(x) { return x != null; }); } catch (error3) { @@ -31316,7 +31316,7 @@ var require_internal_glob_options_helper = __commonJS({ })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getOptions = getOptions; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); function getOptions(copy) { const result = { followSymbolicLinks: true, @@ -31328,23 +31328,23 @@ var require_internal_glob_options_helper = __commonJS({ if (copy) { if (typeof copy.followSymbolicLinks === "boolean") { result.followSymbolicLinks = copy.followSymbolicLinks; - core31.debug(`followSymbolicLinks '${result.followSymbolicLinks}'`); + core32.debug(`followSymbolicLinks '${result.followSymbolicLinks}'`); } if (typeof copy.implicitDescendants === "boolean") { result.implicitDescendants = copy.implicitDescendants; - core31.debug(`implicitDescendants '${result.implicitDescendants}'`); + core32.debug(`implicitDescendants '${result.implicitDescendants}'`); } if (typeof copy.matchDirectories === "boolean") { result.matchDirectories = copy.matchDirectories; - core31.debug(`matchDirectories '${result.matchDirectories}'`); + core32.debug(`matchDirectories '${result.matchDirectories}'`); } if (typeof copy.omitBrokenSymbolicLinks === "boolean") { result.omitBrokenSymbolicLinks = copy.omitBrokenSymbolicLinks; - core31.debug(`omitBrokenSymbolicLinks '${result.omitBrokenSymbolicLinks}'`); + core32.debug(`omitBrokenSymbolicLinks '${result.omitBrokenSymbolicLinks}'`); } if (typeof copy.excludeHiddenFiles === "boolean") { result.excludeHiddenFiles = copy.excludeHiddenFiles; - core31.debug(`excludeHiddenFiles '${result.excludeHiddenFiles}'`); + core32.debug(`excludeHiddenFiles '${result.excludeHiddenFiles}'`); } } return result; @@ -33066,7 +33066,7 @@ var require_internal_globber = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DefaultGlobber = void 0; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var fs32 = __importStar2(require("fs")); var globOptionsHelper = __importStar2(require_internal_glob_options_helper()); var path30 = __importStar2(require("path")); @@ -33119,7 +33119,7 @@ var require_internal_globber = __commonJS({ } const stack = []; for (const searchPath of patternHelper.getSearchPaths(patterns)) { - core31.debug(`Search path '${searchPath}'`); + core32.debug(`Search path '${searchPath}'`); try { yield __await2(fs32.promises.lstat(searchPath)); } catch (err) { @@ -33194,7 +33194,7 @@ var require_internal_globber = __commonJS({ } catch (err) { if (err.code === "ENOENT") { if (options.omitBrokenSymbolicLinks) { - core31.debug(`Broken symlink '${item.path}'`); + core32.debug(`Broken symlink '${item.path}'`); return void 0; } throw new Error(`No information found for the path '${item.path}'. This may indicate a broken symbolic link.`); @@ -33210,7 +33210,7 @@ var require_internal_globber = __commonJS({ traversalChain.pop(); } if (traversalChain.some((x) => x === realPath)) { - core31.debug(`Symlink cycle detected for path '${item.path}' and realpath '${realPath}'`); + core32.debug(`Symlink cycle detected for path '${item.path}' and realpath '${realPath}'`); return void 0; } traversalChain.push(realPath); @@ -33313,7 +33313,7 @@ var require_internal_hash_files = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.hashFiles = hashFiles2; var crypto3 = __importStar2(require("crypto")); - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var fs32 = __importStar2(require("fs")); var stream2 = __importStar2(require("stream")); var util3 = __importStar2(require("util")); @@ -33322,7 +33322,7 @@ var require_internal_hash_files = __commonJS({ return __awaiter2(this, arguments, void 0, function* (globber, currentWorkspace, verbose = false) { var _a2, e_1, _b, _c; var _d; - const writeDelegate = verbose ? core31.info : core31.debug; + const writeDelegate = verbose ? core32.info : core32.debug; let hasMatch = false; const githubWorkspace = currentWorkspace ? currentWorkspace : (_d = process.env["GITHUB_WORKSPACE"]) !== null && _d !== void 0 ? _d : process.cwd(); const result = crypto3.createHash("sha256"); @@ -34714,7 +34714,7 @@ var require_cacheUtils = __commonJS({ exports2.assertDefined = assertDefined; exports2.getCacheVersion = getCacheVersion; exports2.getRuntimeToken = getRuntimeToken; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var exec3 = __importStar2(require_exec()); var glob2 = __importStar2(require_glob()); var io9 = __importStar2(require_io()); @@ -34765,7 +34765,7 @@ var require_cacheUtils = __commonJS({ _e = false; const file = _c; const relativeFile = path30.relative(workspace, file).replace(new RegExp(`\\${path30.sep}`, "g"), "/"); - core31.debug(`Matched: ${relativeFile}`); + core32.debug(`Matched: ${relativeFile}`); if (relativeFile === "") { paths.push("."); } else { @@ -34793,7 +34793,7 @@ var require_cacheUtils = __commonJS({ return __awaiter2(this, arguments, void 0, function* (app, additionalArgs = []) { let versionOutput = ""; additionalArgs.push("--version"); - core31.debug(`Checking ${app} ${additionalArgs.join(" ")}`); + core32.debug(`Checking ${app} ${additionalArgs.join(" ")}`); try { yield exec3.exec(`${app}`, additionalArgs, { ignoreReturnCode: true, @@ -34804,10 +34804,10 @@ var require_cacheUtils = __commonJS({ } }); } catch (err) { - core31.debug(err.message); + core32.debug(err.message); } versionOutput = versionOutput.trim(); - core31.debug(versionOutput); + core32.debug(versionOutput); return versionOutput; }); } @@ -34815,7 +34815,7 @@ var require_cacheUtils = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); const version = semver11.clean(versionOutput); - core31.debug(`zstd version: ${version}`); + core32.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; } else { @@ -75113,7 +75113,7 @@ var require_uploadUtils = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.UploadProgress = void 0; exports2.uploadCacheArchiveSDK = uploadCacheArchiveSDK; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var storage_blob_1 = require_commonjs15(); var errors_1 = require_errors2(); var UploadProgress = class { @@ -75155,7 +75155,7 @@ var require_uploadUtils = __commonJS({ const percentage = (100 * (transferredBytes / this.contentLength)).toFixed(1); const elapsedTime = Date.now() - this.startTime; const uploadSpeed = (transferredBytes / (1024 * 1024) / (elapsedTime / 1e3)).toFixed(1); - core31.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`); + core32.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`); if (this.isDone()) { this.displayedComplete = true; } @@ -75212,14 +75212,14 @@ var require_uploadUtils = __commonJS({ }; try { uploadProgress.startDisplayTimer(); - core31.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`); + core32.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`); const response = yield blockBlobClient.uploadFile(archivePath, uploadOptions); if (response._response.status >= 400) { throw new errors_1.InvalidResponseError(`uploadCacheArchiveSDK: upload failed with status code ${response._response.status}`); } return response; } catch (error3) { - core31.warning(`uploadCacheArchiveSDK: internal error uploading cache archive: ${error3.message}`); + core32.warning(`uploadCacheArchiveSDK: internal error uploading cache archive: ${error3.message}`); throw error3; } finally { uploadProgress.stopDisplayTimer(); @@ -75304,7 +75304,7 @@ var require_requestUtils = __commonJS({ exports2.retry = retry2; exports2.retryTypedResponse = retryTypedResponse; exports2.retryHttpClientResponse = retryHttpClientResponse; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var http_client_1 = require_lib(); var constants_1 = require_constants7(); function isSuccessStatusCode(statusCode) { @@ -75362,9 +75362,9 @@ var require_requestUtils = __commonJS({ isRetryable = isRetryableStatusCode(statusCode); errorMessage = `Cache service responded with ${statusCode}`; } - core31.debug(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); + core32.debug(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); if (!isRetryable) { - core31.debug(`${name} - Error is not retryable`); + core32.debug(`${name} - Error is not retryable`); break; } yield sleep(delay2); @@ -75623,7 +75623,7 @@ var require_downloadUtils = __commonJS({ exports2.downloadCacheHttpClient = downloadCacheHttpClient; exports2.downloadCacheHttpClientConcurrent = downloadCacheHttpClientConcurrent; exports2.downloadCacheStorageSDK = downloadCacheStorageSDK; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var http_client_1 = require_lib(); var storage_blob_1 = require_commonjs15(); var buffer = __importStar2(require("buffer")); @@ -75661,7 +75661,7 @@ var require_downloadUtils = __commonJS({ this.segmentIndex = this.segmentIndex + 1; this.segmentSize = segmentSize; this.receivedBytes = 0; - core31.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`); + core32.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`); } /** * Sets the number of bytes received for the current segment. @@ -75695,7 +75695,7 @@ var require_downloadUtils = __commonJS({ const percentage = (100 * (transferredBytes / this.contentLength)).toFixed(1); const elapsedTime = Date.now() - this.startTime; const downloadSpeed = (transferredBytes / (1024 * 1024) / (elapsedTime / 1e3)).toFixed(1); - core31.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`); + core32.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`); if (this.isDone()) { this.displayedComplete = true; } @@ -75745,7 +75745,7 @@ var require_downloadUtils = __commonJS({ })); downloadResponse.message.socket.setTimeout(constants_1.SocketTimeout, () => { downloadResponse.message.destroy(); - core31.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`); + core32.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`); }); yield pipeResponseToStream(downloadResponse, writeStream); const contentLengthHeader = downloadResponse.message.headers["content-length"]; @@ -75756,7 +75756,7 @@ var require_downloadUtils = __commonJS({ throw new Error(`Incomplete download. Expected file size: ${expectedLength}, actual file size: ${actualLength}`); } } else { - core31.debug("Unable to validate download, no Content-Length header"); + core32.debug("Unable to validate download, no Content-Length header"); } }); } @@ -75874,7 +75874,7 @@ var require_downloadUtils = __commonJS({ const properties = yield client.getProperties(); const contentLength = (_a2 = properties.contentLength) !== null && _a2 !== void 0 ? _a2 : -1; if (contentLength < 0) { - core31.debug("Unable to determine content length, downloading file with http-client..."); + core32.debug("Unable to determine content length, downloading file with http-client..."); yield downloadCacheHttpClient(archiveLocation, archivePath); } else { const maxSegmentSize = Math.min(134217728, buffer.constants.MAX_LENGTH); @@ -75964,7 +75964,7 @@ var require_options = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getUploadOptions = getUploadOptions; exports2.getDownloadOptions = getDownloadOptions; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); function getUploadOptions(copy) { const result = { useAzureSdk: false, @@ -75984,9 +75984,9 @@ var require_options = __commonJS({ } result.uploadConcurrency = !isNaN(Number(process.env["CACHE_UPLOAD_CONCURRENCY"])) ? Math.min(32, Number(process.env["CACHE_UPLOAD_CONCURRENCY"])) : result.uploadConcurrency; result.uploadChunkSize = !isNaN(Number(process.env["CACHE_UPLOAD_CHUNK_SIZE"])) ? Math.min(128 * 1024 * 1024, Number(process.env["CACHE_UPLOAD_CHUNK_SIZE"]) * 1024 * 1024) : result.uploadChunkSize; - core31.debug(`Use Azure SDK: ${result.useAzureSdk}`); - core31.debug(`Upload concurrency: ${result.uploadConcurrency}`); - core31.debug(`Upload chunk size: ${result.uploadChunkSize}`); + core32.debug(`Use Azure SDK: ${result.useAzureSdk}`); + core32.debug(`Upload concurrency: ${result.uploadConcurrency}`); + core32.debug(`Upload chunk size: ${result.uploadChunkSize}`); return result; } function getDownloadOptions(copy) { @@ -76022,12 +76022,12 @@ var require_options = __commonJS({ if (segmentDownloadTimeoutMins && !isNaN(Number(segmentDownloadTimeoutMins)) && isFinite(Number(segmentDownloadTimeoutMins))) { result.segmentTimeoutInMs = Number(segmentDownloadTimeoutMins) * 60 * 1e3; } - core31.debug(`Use Azure SDK: ${result.useAzureSdk}`); - core31.debug(`Download concurrency: ${result.downloadConcurrency}`); - core31.debug(`Request timeout (ms): ${result.timeoutInMs}`); - core31.debug(`Cache segment download timeout mins env var: ${process.env["SEGMENT_DOWNLOAD_TIMEOUT_MINS"]}`); - core31.debug(`Segment download timeout (ms): ${result.segmentTimeoutInMs}`); - core31.debug(`Lookup only: ${result.lookupOnly}`); + core32.debug(`Use Azure SDK: ${result.useAzureSdk}`); + core32.debug(`Download concurrency: ${result.downloadConcurrency}`); + core32.debug(`Request timeout (ms): ${result.timeoutInMs}`); + core32.debug(`Cache segment download timeout mins env var: ${process.env["SEGMENT_DOWNLOAD_TIMEOUT_MINS"]}`); + core32.debug(`Segment download timeout (ms): ${result.segmentTimeoutInMs}`); + core32.debug(`Lookup only: ${result.lookupOnly}`); return result; } } @@ -76238,7 +76238,7 @@ var require_cacheHttpClient = __commonJS({ exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; exports2.saveCache = saveCache5; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); var fs32 = __importStar2(require("fs")); @@ -76257,7 +76257,7 @@ var require_cacheHttpClient = __commonJS({ throw new Error("Cache Service Url not found, unable to restore cache."); } const url2 = `${baseUrl}_apis/artifactcache/${resource}`; - core31.debug(`Resource Url: ${url2}`); + core32.debug(`Resource Url: ${url2}`); return url2; } function createAcceptHeader(type, apiVersion) { @@ -76286,7 +76286,7 @@ var require_cacheHttpClient = __commonJS({ return httpClient.getJson(getCacheApiUrl(resource)); })); if (response.statusCode === 204) { - if (core31.isDebug()) { + if (core32.isDebug()) { yield printCachesListForDiagnostics(keys[0], httpClient, version); } return null; @@ -76303,9 +76303,9 @@ var require_cacheHttpClient = __commonJS({ if (!cacheDownloadUrl) { throw new Error("Cache not found."); } - core31.setSecret(cacheDownloadUrl); - core31.debug(`Cache Result:`); - core31.debug(JSON.stringify(cacheResult)); + core32.setSecret(cacheDownloadUrl); + core32.debug(`Cache Result:`); + core32.debug(JSON.stringify(cacheResult)); return cacheResult; }); } @@ -76319,10 +76319,10 @@ var require_cacheHttpClient = __commonJS({ const cacheListResult = response.result; const totalCount = cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.totalCount; if (totalCount && totalCount > 0) { - core31.debug(`No matching cache found for cache key '${key}', version '${version} and scope ${process.env["GITHUB_REF"]}. There exist one or more cache(s) with similar key but they have different version or scope. See more info on cache matching here: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key + core32.debug(`No matching cache found for cache key '${key}', version '${version} and scope ${process.env["GITHUB_REF"]}. There exist one or more cache(s) with similar key but they have different version or scope. See more info on cache matching here: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key Other caches with similar key:`); for (const cacheEntry of (cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.artifactCaches) || []) { - core31.debug(`Cache Key: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheKey}, Cache Version: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheVersion}, Cache Scope: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.scope}, Cache Created: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.creationTime}`); + core32.debug(`Cache Key: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheKey}, Cache Version: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheVersion}, Cache Scope: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.scope}, Cache Created: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.creationTime}`); } } } @@ -76365,7 +76365,7 @@ Other caches with similar key:`); } function uploadChunk(httpClient, resourceUrl, openStream, start, end) { return __awaiter2(this, void 0, void 0, function* () { - core31.debug(`Uploading chunk of size ${end - start + 1} bytes at offset ${start} with content range: ${getContentRange(start, end)}`); + core32.debug(`Uploading chunk of size ${end - start + 1} bytes at offset ${start} with content range: ${getContentRange(start, end)}`); const additionalHeaders = { "Content-Type": "application/octet-stream", "Content-Range": getContentRange(start, end) @@ -76387,7 +76387,7 @@ Other caches with similar key:`); const concurrency = utils.assertDefined("uploadConcurrency", uploadOptions.uploadConcurrency); const maxChunkSize = utils.assertDefined("uploadChunkSize", uploadOptions.uploadChunkSize); const parallelUploads = [...new Array(concurrency).keys()]; - core31.debug("Awaiting all uploads"); + core32.debug("Awaiting all uploads"); let offset = 0; try { yield Promise.all(parallelUploads.map(() => __awaiter2(this, void 0, void 0, function* () { @@ -76430,16 +76430,16 @@ Other caches with similar key:`); yield (0, uploadUtils_1.uploadCacheArchiveSDK)(signedUploadURL, archivePath, options); } else { const httpClient = createHttpClient(); - core31.debug("Upload cache"); + core32.debug("Upload cache"); yield uploadFile(httpClient, cacheId, archivePath, options); - core31.debug("Commiting cache"); + core32.debug("Commiting cache"); const cacheSize = utils.getArchiveFileSizeInBytes(archivePath); - core31.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`); + core32.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`); const commitCacheResponse = yield commitCache(httpClient, cacheId, cacheSize); if (!(0, requestUtils_1.isSuccessStatusCode)(commitCacheResponse.statusCode)) { throw new Error(`Cache service responded with ${commitCacheResponse.statusCode} during commit cache.`); } - core31.info("Cache saved successfully"); + core32.info("Cache saved successfully"); } }); } @@ -81922,7 +81922,7 @@ var require_cache4 = __commonJS({ exports2.isFeatureAvailable = isFeatureAvailable; exports2.restoreCache = restoreCache5; exports2.saveCache = saveCache5; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var path30 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); var cacheHttpClient = __importStar2(require_cacheHttpClient()); @@ -82000,12 +82000,12 @@ var require_cache4 = __commonJS({ 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)(); - core31.debug(`Cache service version: ${cacheServiceVersion}`); + core32.debug(`Cache service version: ${cacheServiceVersion}`); checkPaths(paths); const cacheMode = (0, config_1.getCacheMode)(); if (!(0, config_1.isCacheReadable)(cacheMode)) { - core31.info(`Cache restore skipped: the effective cache-mode '${cacheMode}' does not permit reads.`); - core31.debug(`Skipped restore for paths [${paths.join(", ")}] with primary key '${primaryKey}'.`); + core32.info(`Cache restore skipped: the effective cache-mode '${cacheMode}' does not permit reads.`); + core32.debug(`Skipped restore for paths [${paths.join(", ")}] with primary key '${primaryKey}'.`); return void 0; } switch (cacheServiceVersion) { @@ -82022,8 +82022,8 @@ var require_cache4 = __commonJS({ var _a2; restoreKeys = restoreKeys || []; const keys = [primaryKey, ...restoreKeys]; - core31.debug("Resolved Keys:"); - core31.debug(JSON.stringify(keys)); + core32.debug("Resolved Keys:"); + core32.debug(JSON.stringify(keys)); if (keys.length > 10) { throw new ValidationError(`Key Validation Error: Keys are limited to a maximum of 10.`); } @@ -82050,19 +82050,19 @@ var require_cache4 = __commonJS({ return void 0; } if (options === null || options === void 0 ? void 0 : options.lookupOnly) { - core31.info("Lookup only - skipping download"); + core32.info("Lookup only - skipping download"); return cacheEntry.cacheKey; } archivePath = path30.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); - core31.debug(`Archive Path: ${archivePath}`); + core32.debug(`Archive Path: ${archivePath}`); yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options); - if (core31.isDebug()) { + if (core32.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core31.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); + core32.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); yield (0, tar_1.extractTar)(archivePath, compressionMethod); - core31.info("Cache restored successfully"); + core32.info("Cache restored successfully"); return cacheEntry.cacheKey; } catch (error3) { const typedError = error3; @@ -82070,16 +82070,16 @@ var require_cache4 = __commonJS({ throw error3; } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core31.error(`Failed to restore: ${error3.message}`); + core32.error(`Failed to restore: ${error3.message}`); } else { - core31.warning(`Failed to restore: ${error3.message}`); + core32.warning(`Failed to restore: ${error3.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core31.debug(`Failed to delete archive: ${error3}`); + core32.debug(`Failed to delete archive: ${error3}`); } } return void 0; @@ -82091,8 +82091,8 @@ var require_cache4 = __commonJS({ options = Object.assign(Object.assign({}, options), { useAzureSdk: true }); restoreKeys = restoreKeys || []; const keys = [primaryKey, ...restoreKeys]; - core31.debug("Resolved Keys:"); - core31.debug(JSON.stringify(keys)); + core32.debug("Resolved Keys:"); + core32.debug(JSON.stringify(keys)); if (keys.length > 10) { throw new ValidationError(`Key Validation Error: Keys are limited to a maximum of 10.`); } @@ -82119,30 +82119,30 @@ var require_cache4 = __commonJS({ throw error3; } if (!response.ok) { - core31.debug(`Cache not found for version ${request3.version} of keys: ${keys.join(", ")}`); + core32.debug(`Cache not found for version ${request3.version} of keys: ${keys.join(", ")}`); return void 0; } const isRestoreKeyMatch = request3.key !== response.matchedKey; if (isRestoreKeyMatch) { - core31.info(`Cache hit for restore-key: ${response.matchedKey}`); + core32.info(`Cache hit for restore-key: ${response.matchedKey}`); } else { - core31.info(`Cache hit for: ${response.matchedKey}`); + core32.info(`Cache hit for: ${response.matchedKey}`); } if (options === null || options === void 0 ? void 0 : options.lookupOnly) { - core31.info("Lookup only - skipping download"); + core32.info("Lookup only - skipping download"); return response.matchedKey; } archivePath = path30.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); - core31.debug(`Archive path: ${archivePath}`); - core31.debug(`Starting download of archive to: ${archivePath}`); + core32.debug(`Archive path: ${archivePath}`); + core32.debug(`Starting download of archive to: ${archivePath}`); yield cacheHttpClient.downloadCache(response.signedDownloadUrl, archivePath, options); const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core31.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); - if (core31.isDebug()) { + core32.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); + if (core32.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } yield (0, tar_1.extractTar)(archivePath, compressionMethod); - core31.info("Cache restored successfully"); + core32.info("Cache restored successfully"); return response.matchedKey; } catch (error3) { const typedError = error3; @@ -82150,9 +82150,9 @@ var require_cache4 = __commonJS({ throw error3; } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core31.error(`Failed to restore: ${error3.message}`); + core32.error(`Failed to restore: ${error3.message}`); } else { - core31.warning(`Failed to restore: ${error3.message}`); + core32.warning(`Failed to restore: ${error3.message}`); } } } finally { @@ -82161,7 +82161,7 @@ var require_cache4 = __commonJS({ yield utils.unlinkFile(archivePath); } } catch (error3) { - core31.debug(`Failed to delete archive: ${error3}`); + core32.debug(`Failed to delete archive: ${error3}`); } } return void 0; @@ -82170,13 +82170,13 @@ var require_cache4 = __commonJS({ 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)(); - core31.debug(`Cache service version: ${cacheServiceVersion}`); + core32.debug(`Cache service version: ${cacheServiceVersion}`); checkPaths(paths); checkKey(key); const cacheMode = (0, config_1.getCacheMode)(); if (!(0, config_1.isCacheWritable)(cacheMode)) { - core31.info(`Cache save skipped: the effective cache-mode '${cacheMode}' does not permit writes.`); - core31.debug(`Skipped save for paths [${paths.join(", ")}] with key '${key}'.`); + core32.info(`Cache save skipped: the effective cache-mode '${cacheMode}' does not permit writes.`); + core32.debug(`Skipped save for paths [${paths.join(", ")}] with key '${key}'.`); return -1; } switch (cacheServiceVersion) { @@ -82194,26 +82194,26 @@ var require_cache4 = __commonJS({ const compressionMethod = yield utils.getCompressionMethod(); let cacheId = -1; const cachePaths = yield utils.resolvePaths(paths); - core31.debug("Cache Paths:"); - core31.debug(`${JSON.stringify(cachePaths)}`); + core32.debug("Cache Paths:"); + core32.debug(`${JSON.stringify(cachePaths)}`); if (cachePaths.length === 0) { throw new Error(`Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.`); } const archiveFolder = yield utils.createTempDirectory(); const archivePath = path30.join(archiveFolder, utils.getCacheFileName(compressionMethod)); - core31.debug(`Archive Path: ${archivePath}`); + core32.debug(`Archive Path: ${archivePath}`); try { yield (0, tar_1.createTar)(archiveFolder, cachePaths, compressionMethod); - if (core31.isDebug()) { + if (core32.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const fileSizeLimit = 10 * 1024 * 1024 * 1024; const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core31.debug(`File Size: ${archiveFileSize}`); + core32.debug(`File Size: ${archiveFileSize}`); if (archiveFileSize > fileSizeLimit && !(0, config_1.isGhes)()) { throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); } - core31.debug("Reserving Cache"); + core32.debug("Reserving Cache"); const reserveCacheResponse = yield cacheHttpClient.reserveCache(key, paths, { compressionMethod, enableCrossOsArchive, @@ -82230,28 +82230,28 @@ var require_cache4 = __commonJS({ } throw new ReserveCacheError2(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${detailMessage}`); } - core31.debug(`Saving Cache (ID: ${cacheId})`); + core32.debug(`Saving Cache (ID: ${cacheId})`); yield cacheHttpClient.saveCache(cacheId, archivePath, "", options); } catch (error3) { const typedError = error3; if (typedError.name === ValidationError.name) { throw error3; } else if (typedError.name === CacheWriteDeniedError.name) { - core31.warning(`Failed to save: ${typedError.message}`); + core32.warning(`Failed to save: ${typedError.message}`); } else if (typedError.name === ReserveCacheError2.name) { - core31.info(`Failed to save: ${typedError.message}`); + core32.info(`Failed to save: ${typedError.message}`); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core31.error(`Failed to save: ${typedError.message}`); + core32.error(`Failed to save: ${typedError.message}`); } else { - core31.warning(`Failed to save: ${typedError.message}`); + core32.warning(`Failed to save: ${typedError.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core31.debug(`Failed to delete archive: ${error3}`); + core32.debug(`Failed to delete archive: ${error3}`); } } return cacheId; @@ -82265,23 +82265,23 @@ var require_cache4 = __commonJS({ const twirpClient = cacheTwirpClient.internalCacheTwirpClient(); let cacheId = -1; const cachePaths = yield utils.resolvePaths(paths); - core31.debug("Cache Paths:"); - core31.debug(`${JSON.stringify(cachePaths)}`); + core32.debug("Cache Paths:"); + core32.debug(`${JSON.stringify(cachePaths)}`); if (cachePaths.length === 0) { throw new Error(`Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.`); } const archiveFolder = yield utils.createTempDirectory(); const archivePath = path30.join(archiveFolder, utils.getCacheFileName(compressionMethod)); - core31.debug(`Archive Path: ${archivePath}`); + core32.debug(`Archive Path: ${archivePath}`); try { yield (0, tar_1.createTar)(archiveFolder, cachePaths, compressionMethod); - if (core31.isDebug()) { + if (core32.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core31.debug(`File Size: ${archiveFileSize}`); + core32.debug(`File Size: ${archiveFileSize}`); options.archiveSizeBytes = archiveFileSize; - core31.debug("Reserving Cache"); + core32.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); const request3 = { key, @@ -82292,20 +82292,20 @@ var require_cache4 = __commonJS({ const response = yield twirpClient.CreateCacheEntry(request3); if (!response.ok) { if (response.message && !response.message.startsWith(exports2.CACHE_WRITE_DENIED_PREFIX)) { - core31.warning(`Cache reservation failed: ${response.message}`); + core32.warning(`Cache reservation failed: ${response.message}`); } throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error3) { - core31.debug(`Failed to reserve cache: ${error3}`); + core32.debug(`Failed to reserve cache: ${error3}`); const errorMessage = (_a2 = error3 === null || error3 === void 0 ? void 0 : error3.message) !== null && _a2 !== void 0 ? _a2 : ""; if (errorMessage.startsWith(exports2.CACHE_WRITE_DENIED_PREFIX)) { throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${errorMessage}`); } throw new ReserveCacheError2(`Unable to reserve cache with key ${key}, another job may be creating this cache.`); } - core31.debug(`Attempting to upload cache located at: ${archivePath}`); + core32.debug(`Attempting to upload cache located at: ${archivePath}`); yield cacheHttpClient.saveCache(cacheId, archivePath, signedUploadUrl, options); const finalizeRequest = { key, @@ -82313,7 +82313,7 @@ var require_cache4 = __commonJS({ sizeBytes: `${archiveFileSize}` }; const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); - core31.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); + core32.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { if (finalizeResponse.message) { throw new FinalizeCacheError(finalizeResponse.message); @@ -82326,23 +82326,23 @@ var require_cache4 = __commonJS({ if (typedError.name === ValidationError.name) { throw error3; } else if (typedError.name === CacheWriteDeniedError.name) { - core31.warning(`Failed to save: ${typedError.message}`); + core32.warning(`Failed to save: ${typedError.message}`); } else if (typedError.name === ReserveCacheError2.name) { - core31.info(`Failed to save: ${typedError.message}`); + core32.info(`Failed to save: ${typedError.message}`); } else if (typedError.name === FinalizeCacheError.name) { - core31.warning(typedError.message); + core32.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core31.error(`Failed to save: ${typedError.message}`); + core32.error(`Failed to save: ${typedError.message}`); } else { - core31.warning(`Failed to save: ${typedError.message}`); + core32.warning(`Failed to save: ${typedError.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core31.debug(`Failed to delete archive: ${error3}`); + core32.debug(`Failed to delete archive: ${error3}`); } } return cacheId; @@ -82569,7 +82569,7 @@ var require_retry_helper = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RetryHelper = void 0; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var RetryHelper = class { constructor(maxAttempts, minSeconds, maxSeconds) { if (maxAttempts < 1) { @@ -82592,10 +82592,10 @@ var require_retry_helper = __commonJS({ if (isRetryable && !isRetryable(err)) { throw err; } - core31.info(err.message); + core32.info(err.message); } const seconds = this.getSleepAmount(); - core31.info(`Waiting ${seconds} seconds before trying again`); + core32.info(`Waiting ${seconds} seconds before trying again`); yield this.sleep(seconds); attempt++; } @@ -82698,7 +82698,7 @@ var require_tool_cache = __commonJS({ exports2.findFromManifest = findFromManifest; exports2.isExplicitVersion = isExplicitVersion; exports2.evaluateVersions = evaluateVersions; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var io9 = __importStar2(require_io()); var crypto3 = __importStar2(require("crypto")); var fs32 = __importStar2(require("fs")); @@ -82727,8 +82727,8 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { dest = dest || path30.join(_getTempDirectory(), crypto3.randomUUID()); yield io9.mkdirP(path30.dirname(dest)); - core31.debug(`Downloading ${url2}`); - core31.debug(`Destination ${dest}`); + core32.debug(`Downloading ${url2}`); + core32.debug(`Destination ${dest}`); const maxAttempts = 3; const minSeconds = _getGlobal("TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS", 10); const maxSeconds = _getGlobal("TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS", 20); @@ -82754,7 +82754,7 @@ var require_tool_cache = __commonJS({ allowRetries: false }); if (auth2) { - core31.debug("set auth"); + core32.debug("set auth"); if (headers === void 0) { headers = {}; } @@ -82763,7 +82763,7 @@ var require_tool_cache = __commonJS({ const response = yield http.get(url2, headers); if (response.message.statusCode !== 200) { const err = new HTTPError2(response.message.statusCode); - core31.debug(`Failed to download from "${url2}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); + core32.debug(`Failed to download from "${url2}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); throw err; } const pipeline2 = util3.promisify(stream2.pipeline); @@ -82772,16 +82772,16 @@ var require_tool_cache = __commonJS({ let succeeded = false; try { yield pipeline2(readStream, fs32.createWriteStream(dest)); - core31.debug("download complete"); + core32.debug("download complete"); succeeded = true; return dest; } finally { if (!succeeded) { - core31.debug("download failed"); + core32.debug("download failed"); try { yield io9.rmRF(dest); } catch (err) { - core31.debug(`Failed to delete '${dest}'. ${err.message}`); + core32.debug(`Failed to delete '${dest}'. ${err.message}`); } } } @@ -82796,7 +82796,7 @@ var require_tool_cache = __commonJS({ process.chdir(dest); if (_7zPath) { try { - const logLevel = core31.isDebug() ? "-bb1" : "-bb0"; + const logLevel = core32.isDebug() ? "-bb1" : "-bb0"; const args = [ "x", // eXtract files with full paths @@ -82849,7 +82849,7 @@ var require_tool_cache = __commonJS({ throw new Error("parameter 'file' is required"); } dest = yield _createExtractFolder(dest); - core31.debug("Checking tar --version"); + core32.debug("Checking tar --version"); let versionOutput = ""; yield (0, exec_1.exec)("tar --version", [], { ignoreReturnCode: true, @@ -82859,7 +82859,7 @@ var require_tool_cache = __commonJS({ stderr: (data) => versionOutput += data.toString() } }); - core31.debug(versionOutput.trim()); + core32.debug(versionOutput.trim()); const isGnuTar = versionOutput.toUpperCase().includes("GNU TAR"); let args; if (flags instanceof Array) { @@ -82867,7 +82867,7 @@ var require_tool_cache = __commonJS({ } else { args = [flags]; } - if (core31.isDebug() && !flags.includes("v")) { + if (core32.isDebug() && !flags.includes("v")) { args.push("-v"); } let destArg = dest; @@ -82898,7 +82898,7 @@ var require_tool_cache = __commonJS({ args = [flags]; } args.push("-x", "-C", dest, "-f", file); - if (core31.isDebug()) { + if (core32.isDebug()) { args.push("-v"); } const xarPath = yield io9.which("xar", true); @@ -82941,7 +82941,7 @@ var require_tool_cache = __commonJS({ "-Command", pwshCommand ]; - core31.debug(`Using pwsh at path: ${pwshPath}`); + core32.debug(`Using pwsh at path: ${pwshPath}`); yield (0, exec_1.exec)(`"${pwshPath}"`, args); } else { const powershellCommand = [ @@ -82961,7 +82961,7 @@ var require_tool_cache = __commonJS({ powershellCommand ]; const powershellPath = yield io9.which("powershell", true); - core31.debug(`Using powershell at path: ${powershellPath}`); + core32.debug(`Using powershell at path: ${powershellPath}`); yield (0, exec_1.exec)(`"${powershellPath}"`, args); } }); @@ -82970,7 +82970,7 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { const unzipPath = yield io9.which("unzip", true); const args = [file]; - if (!core31.isDebug()) { + if (!core32.isDebug()) { args.unshift("-q"); } args.unshift("-o"); @@ -82981,8 +82981,8 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { version = semver11.clean(version) || version; arch2 = arch2 || os7.arch(); - core31.debug(`Caching tool ${tool} ${version} ${arch2}`); - core31.debug(`source dir: ${sourceDir}`); + core32.debug(`Caching tool ${tool} ${version} ${arch2}`); + core32.debug(`source dir: ${sourceDir}`); if (!fs32.statSync(sourceDir).isDirectory()) { throw new Error("sourceDir is not a directory"); } @@ -82999,14 +82999,14 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { version = semver11.clean(version) || version; arch2 = arch2 || os7.arch(); - core31.debug(`Caching tool ${tool} ${version} ${arch2}`); - core31.debug(`source file: ${sourceFile}`); + core32.debug(`Caching tool ${tool} ${version} ${arch2}`); + core32.debug(`source file: ${sourceFile}`); if (!fs32.statSync(sourceFile).isFile()) { throw new Error("sourceFile is not a file"); } const destFolder = yield _createToolPath(tool, version, arch2); const destPath = path30.join(destFolder, targetFile); - core31.debug(`destination file ${destPath}`); + core32.debug(`destination file ${destPath}`); yield io9.cp(sourceFile, destPath); _completeToolPath(tool, version, arch2); return destFolder; @@ -83029,12 +83029,12 @@ var require_tool_cache = __commonJS({ if (versionSpec) { versionSpec = semver11.clean(versionSpec) || ""; const cachePath = path30.join(_getCacheDirectory(), toolName, versionSpec, arch2); - core31.debug(`checking cache: ${cachePath}`); + core32.debug(`checking cache: ${cachePath}`); if (fs32.existsSync(cachePath) && fs32.existsSync(`${cachePath}.complete`)) { - core31.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch2}`); + core32.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch2}`); toolPath = cachePath; } else { - core31.debug("not found"); + core32.debug("not found"); } } return toolPath; @@ -83063,7 +83063,7 @@ var require_tool_cache = __commonJS({ const http = new httpm.HttpClient("tool-cache"); const headers = {}; if (auth2) { - core31.debug("set auth"); + core32.debug("set auth"); headers.authorization = auth2; } const response = yield http.getJson(treeUrl, headers); @@ -83084,7 +83084,7 @@ var require_tool_cache = __commonJS({ try { releases = JSON.parse(versionsRaw); } catch (_a2) { - core31.debug("Invalid json"); + core32.debug("Invalid json"); } } return releases; @@ -83108,7 +83108,7 @@ var require_tool_cache = __commonJS({ function _createToolPath(tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { const folderPath = path30.join(_getCacheDirectory(), tool, semver11.clean(version) || version, arch2 || ""); - core31.debug(`destination ${folderPath}`); + core32.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io9.rmRF(folderPath); yield io9.rmRF(markerPath); @@ -83120,18 +83120,18 @@ var require_tool_cache = __commonJS({ const folderPath = path30.join(_getCacheDirectory(), tool, semver11.clean(version) || version, arch2 || ""); const markerPath = `${folderPath}.complete`; fs32.writeFileSync(markerPath, ""); - core31.debug("finished caching tool"); + core32.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { const c = semver11.clean(versionSpec) || ""; - core31.debug(`isExplicit: ${c}`); + core32.debug(`isExplicit: ${c}`); const valid4 = semver11.valid(c) != null; - core31.debug(`explicit? ${valid4}`); + core32.debug(`explicit? ${valid4}`); return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; - core31.debug(`evaluating ${versions.length} versions`); + core32.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { if (semver11.gt(a, b)) { return 1; @@ -83147,9 +83147,9 @@ var require_tool_cache = __commonJS({ } } if (version) { - core31.debug(`matched: ${version}`); + core32.debug(`matched: ${version}`); } else { - core31.debug("match not found"); + core32.debug("match not found"); } return version; } @@ -88742,14 +88742,14 @@ var require_retention = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getExpiration = void 0; var generated_1 = require_generated(); - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); function getExpiration(retentionDays) { if (!retentionDays) { return void 0; } const maxRetentionDays = getRetentionDays(); if (maxRetentionDays && maxRetentionDays < retentionDays) { - core31.warning(`Retention days cannot be greater than the maximum allowed retention set within the repository. Using ${maxRetentionDays} instead.`); + core32.warning(`Retention days cannot be greater than the maximum allowed retention set within the repository. Using ${maxRetentionDays} instead.`); retentionDays = maxRetentionDays; } const expirationDate = /* @__PURE__ */ new Date(); @@ -89087,7 +89087,7 @@ var require_util11 = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.maskSecretUrls = exports2.maskSigUrl = exports2.getBackendIdsFromToken = void 0; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var config_1 = require_config2(); var jwt_decode_1 = __importDefault2(require_jwt_decode_cjs()); var core_1 = require_core(); @@ -89114,8 +89114,8 @@ var require_util11 = __commonJS({ workflowRunBackendId: scopeParts[1], workflowJobRunBackendId: scopeParts[2] }; - core31.debug(`Workflow Run Backend ID: ${ids.workflowRunBackendId}`); - core31.debug(`Workflow Job Run Backend ID: ${ids.workflowJobRunBackendId}`); + core32.debug(`Workflow Run Backend ID: ${ids.workflowRunBackendId}`); + core32.debug(`Workflow Job Run Backend ID: ${ids.workflowJobRunBackendId}`); return ids; } throw InvalidJwtError; @@ -89475,7 +89475,7 @@ var require_blob_upload = __commonJS({ exports2.uploadZipToBlobStorage = void 0; var storage_blob_1 = require_commonjs15(); var config_1 = require_config2(); - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var crypto3 = __importStar2(require("crypto")); var stream2 = __importStar2(require("stream")); var errors_1 = require_errors3(); @@ -89501,9 +89501,9 @@ var require_blob_upload = __commonJS({ const bufferSize = (0, config_1.getUploadChunkSize)(); const blobClient = new storage_blob_1.BlobClient(authenticatedUploadURL); const blockBlobClient = blobClient.getBlockBlobClient(); - core31.debug(`Uploading artifact zip to blob storage with maxConcurrency: ${maxConcurrency}, bufferSize: ${bufferSize}`); + core32.debug(`Uploading artifact zip to blob storage with maxConcurrency: ${maxConcurrency}, bufferSize: ${bufferSize}`); const uploadCallback = (progress) => { - core31.info(`Uploaded bytes ${progress.loadedBytes}`); + core32.info(`Uploaded bytes ${progress.loadedBytes}`); uploadByteCount = progress.loadedBytes; lastProgressTime = Date.now(); }; @@ -89517,7 +89517,7 @@ var require_blob_upload = __commonJS({ const hashStream = crypto3.createHash("sha256"); zipUploadStream.pipe(uploadStream); zipUploadStream.pipe(hashStream).setEncoding("hex"); - core31.info("Beginning upload of artifact content to blob storage"); + core32.info("Beginning upload of artifact content to blob storage"); try { yield Promise.race([ blockBlobClient.uploadStream(uploadStream, bufferSize, maxConcurrency, options), @@ -89531,12 +89531,12 @@ var require_blob_upload = __commonJS({ } finally { abortController.abort(); } - core31.info("Finished uploading artifact content to blob storage!"); + core32.info("Finished uploading artifact content to blob storage!"); hashStream.end(); sha256Hash = hashStream.read(); - core31.info(`SHA256 digest of uploaded artifact zip is ${sha256Hash}`); + core32.info(`SHA256 digest of uploaded artifact zip is ${sha256Hash}`); if (uploadByteCount === 0) { - core31.warning(`No data was uploaded to blob storage. Reported upload byte count is 0.`); + core32.warning(`No data was uploaded to blob storage. Reported upload byte count is 0.`); } return { uploadSize: uploadByteCount, @@ -102358,7 +102358,7 @@ var require_stream2 = __commonJS({ var { pipeline: pipeline2 } = require_pipeline4(); var { destroyer } = require_destroy2(); var eos = require_end_of_stream(); - var promises6 = require_promises(); + var promises7 = require_promises(); var utils = require_utils7(); var Stream = module2.exports = require_legacy().Stream; Stream.isDestroyed = utils.isDestroyed; @@ -102432,21 +102432,21 @@ var require_stream2 = __commonJS({ configurable: true, enumerable: true, get() { - return promises6; + return promises7; } }); ObjectDefineProperty(pipeline2, customPromisify, { __proto__: null, enumerable: true, get() { - return promises6.pipeline; + return promises7.pipeline; } }); ObjectDefineProperty(eos, customPromisify, { __proto__: null, enumerable: true, get() { - return promises6.finished; + return promises7.finished; } }); Stream.Stream = Stream; @@ -102465,7 +102465,7 @@ var require_ours = __commonJS({ "use strict"; var Stream = require("stream"); if (Stream && process.env.READABLE_STREAM === "disable") { - const promises6 = Stream.promises; + const promises7 = Stream.promises; module2.exports._uint8ArrayToBuffer = Stream._uint8ArrayToBuffer; module2.exports._isUint8Array = Stream._isUint8Array; module2.exports.isDisturbed = Stream.isDisturbed; @@ -102485,13 +102485,13 @@ var require_ours = __commonJS({ configurable: true, enumerable: true, get() { - return promises6; + return promises7; } }); module2.exports.Stream = Stream.Stream; } else { const CustomStream = require_stream2(); - const promises6 = require_promises(); + const promises7 = require_promises(); const originalDestroy = CustomStream.Readable.destroy; module2.exports = CustomStream.Readable; module2.exports._uint8ArrayToBuffer = CustomStream._uint8ArrayToBuffer; @@ -102514,7 +102514,7 @@ var require_ours = __commonJS({ configurable: true, enumerable: true, get() { - return promises6; + return promises7; } }); module2.exports.Stream = CustomStream.Stream; @@ -111170,7 +111170,7 @@ var require_zip2 = __commonJS({ var stream2 = __importStar2(require("stream")); var promises_1 = require("fs/promises"); var archiver = __importStar2(require_archiver()); - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var config_1 = require_config2(); exports2.DEFAULT_COMPRESSION_LEVEL = 6; var ZipUploadStream = class extends stream2.Transform { @@ -111187,7 +111187,7 @@ var require_zip2 = __commonJS({ exports2.ZipUploadStream = ZipUploadStream; function createZipUploadStream(uploadSpecification_1) { return __awaiter2(this, arguments, void 0, function* (uploadSpecification, compressionLevel = exports2.DEFAULT_COMPRESSION_LEVEL) { - core31.debug(`Creating Artifact archive with compressionLevel: ${compressionLevel}`); + core32.debug(`Creating Artifact archive with compressionLevel: ${compressionLevel}`); const zip = archiver.create("zip", { highWaterMark: (0, config_1.getUploadChunkSize)(), zlib: { level: compressionLevel } @@ -111211,8 +111211,8 @@ var require_zip2 = __commonJS({ } const bufferSize = (0, config_1.getUploadChunkSize)(); const zipUploadStream = new ZipUploadStream(bufferSize); - core31.debug(`Zip write high watermark value ${zipUploadStream.writableHighWaterMark}`); - core31.debug(`Zip read high watermark value ${zipUploadStream.readableHighWaterMark}`); + core32.debug(`Zip write high watermark value ${zipUploadStream.writableHighWaterMark}`); + core32.debug(`Zip read high watermark value ${zipUploadStream.readableHighWaterMark}`); zip.pipe(zipUploadStream); zip.finalize(); return zipUploadStream; @@ -111220,24 +111220,24 @@ var require_zip2 = __commonJS({ } exports2.createZipUploadStream = createZipUploadStream; var zipErrorCallback = (error3) => { - core31.error("An error has occurred while creating the zip file for upload"); - core31.info(error3); + core32.error("An error has occurred while creating the zip file for upload"); + core32.info(error3); throw new Error("An error has occurred during zip creation for the artifact"); }; var zipWarningCallback = (error3) => { if (error3.code === "ENOENT") { - core31.warning("ENOENT warning during artifact zip creation. No such file or directory"); - core31.info(error3); + core32.warning("ENOENT warning during artifact zip creation. No such file or directory"); + core32.info(error3); } else { - core31.warning(`A non-blocking warning has occurred during artifact zip creation: ${error3.code}`); - core31.info(error3); + core32.warning(`A non-blocking warning has occurred during artifact zip creation: ${error3.code}`); + core32.info(error3); } }; var zipFinishCallback = () => { - core31.debug("Zip stream for upload has finished."); + core32.debug("Zip stream for upload has finished."); }; var zipEndCallback = () => { - core31.debug("Zip stream for upload has ended."); + core32.debug("Zip stream for upload has ended."); }; } }); @@ -111302,7 +111302,7 @@ var require_upload_artifact = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.uploadArtifact = void 0; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var retention_1 = require_retention(); var path_and_artifact_name_validation_1 = require_path_and_artifact_name_validation(); var artifact_twirp_client_1 = require_artifact_twirp_client2(); @@ -111349,13 +111349,13 @@ var require_upload_artifact = __commonJS({ value: `sha256:${uploadResult.sha256Hash}` }); } - core31.info(`Finalizing artifact upload`); + core32.info(`Finalizing artifact upload`); const finalizeArtifactResp = yield artifactClient.FinalizeArtifact(finalizeArtifactReq); if (!finalizeArtifactResp.ok) { throw new errors_1.InvalidResponseError("FinalizeArtifact: response from backend was not ok"); } const artifactId = BigInt(finalizeArtifactResp.artifactId); - core31.info(`Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`); + core32.info(`Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`); return { size: uploadResult.uploadSize, digest: uploadResult.sha256Hash, @@ -118079,7 +118079,7 @@ var require_download_artifact = __commonJS({ var crypto3 = __importStar2(require("crypto")); var stream2 = __importStar2(require("stream")); var github5 = __importStar2(require_github2()); - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var httpClient = __importStar2(require_lib()); var unzip_stream_1 = __importDefault2(require_unzip()); var user_agent_1 = require_user_agent2(); @@ -118115,7 +118115,7 @@ var require_download_artifact = __commonJS({ return yield streamExtractExternal(url2, directory); } catch (error3) { retryCount++; - core31.debug(`Failed to download artifact after ${retryCount} retries due to ${error3.message}. Retrying in 5 seconds...`); + core32.debug(`Failed to download artifact after ${retryCount} retries due to ${error3.message}. Retrying in 5 seconds...`); yield new Promise((resolve14) => setTimeout(resolve14, 5e3)); } } @@ -118145,7 +118145,7 @@ var require_download_artifact = __commonJS({ extractStream.on("data", () => { timer.refresh(); }).on("error", (error3) => { - core31.debug(`response.message: Artifact download failed: ${error3.message}`); + core32.debug(`response.message: Artifact download failed: ${error3.message}`); clearTimeout(timer); reject(error3); }).pipe(unzip_stream_1.default.Extract({ path: directory })).on("close", () => { @@ -118153,7 +118153,7 @@ var require_download_artifact = __commonJS({ if (hashStream) { hashStream.end(); sha256Digest = hashStream.read(); - core31.info(`SHA256 digest of downloaded artifact is ${sha256Digest}`); + core32.info(`SHA256 digest of downloaded artifact is ${sha256Digest}`); } resolve14({ sha256Digest: `sha256:${sha256Digest}` }); }).on("error", (error3) => { @@ -118168,7 +118168,7 @@ var require_download_artifact = __commonJS({ const downloadPath = yield resolveOrCreateDirectory(options === null || options === void 0 ? void 0 : options.path); const api = github5.getOctokit(token); let digestMismatch = false; - core31.info(`Downloading artifact '${artifactId}' from '${repositoryOwner}/${repositoryName}'`); + core32.info(`Downloading artifact '${artifactId}' from '${repositoryOwner}/${repositoryName}'`); const { headers, status } = yield api.rest.actions.downloadArtifact({ owner: repositoryOwner, repo: repositoryName, @@ -118185,16 +118185,16 @@ var require_download_artifact = __commonJS({ if (!location) { throw new Error(`Unable to redirect to artifact download url`); } - core31.info(`Redirecting to blob download url: ${scrubQueryParameters(location)}`); + core32.info(`Redirecting to blob download url: ${scrubQueryParameters(location)}`); try { - core31.info(`Starting download of artifact to: ${downloadPath}`); + core32.info(`Starting download of artifact to: ${downloadPath}`); const extractResponse = yield streamExtract(location, downloadPath); - core31.info(`Artifact download completed successfully.`); + core32.info(`Artifact download completed successfully.`); if (options === null || options === void 0 ? void 0 : options.expectedHash) { if ((options === null || options === void 0 ? void 0 : options.expectedHash) !== extractResponse.sha256Digest) { digestMismatch = true; - core31.debug(`Computed digest: ${extractResponse.sha256Digest}`); - core31.debug(`Expected digest: ${options.expectedHash}`); + core32.debug(`Computed digest: ${extractResponse.sha256Digest}`); + core32.debug(`Expected digest: ${options.expectedHash}`); } } } catch (error3) { @@ -118221,7 +118221,7 @@ var require_download_artifact = __commonJS({ Are you trying to download from a different run? Try specifying a github-token with \`actions:read\` scope.`); } if (artifacts.length > 1) { - core31.warning("Multiple artifacts found, defaulting to first."); + core32.warning("Multiple artifacts found, defaulting to first."); } const signedReq = { workflowRunBackendId: artifacts[0].workflowRunBackendId, @@ -118229,16 +118229,16 @@ Are you trying to download from a different run? Try specifying a github-token w name: artifacts[0].name }; const { signedUrl } = yield artifactClient.GetSignedArtifactURL(signedReq); - core31.info(`Redirecting to blob download url: ${scrubQueryParameters(signedUrl)}`); + core32.info(`Redirecting to blob download url: ${scrubQueryParameters(signedUrl)}`); try { - core31.info(`Starting download of artifact to: ${downloadPath}`); + core32.info(`Starting download of artifact to: ${downloadPath}`); const extractResponse = yield streamExtract(signedUrl, downloadPath); - core31.info(`Artifact download completed successfully.`); + core32.info(`Artifact download completed successfully.`); if (options === null || options === void 0 ? void 0 : options.expectedHash) { if ((options === null || options === void 0 ? void 0 : options.expectedHash) !== extractResponse.sha256Digest) { digestMismatch = true; - core31.debug(`Computed digest: ${extractResponse.sha256Digest}`); - core31.debug(`Expected digest: ${options.expectedHash}`); + core32.debug(`Computed digest: ${extractResponse.sha256Digest}`); + core32.debug(`Expected digest: ${options.expectedHash}`); } } } catch (error3) { @@ -118251,10 +118251,10 @@ Are you trying to download from a different run? Try specifying a github-token w function resolveOrCreateDirectory() { return __awaiter2(this, arguments, void 0, function* (downloadPath = (0, config_1.getGitHubWorkspaceDir)()) { if (!(yield exists(downloadPath))) { - core31.debug(`Artifact destination folder does not exist, creating: ${downloadPath}`); + core32.debug(`Artifact destination folder does not exist, creating: ${downloadPath}`); yield promises_1.default.mkdir(downloadPath, { recursive: true }); } else { - core31.debug(`Artifact destination folder already exists: ${downloadPath}`); + core32.debug(`Artifact destination folder already exists: ${downloadPath}`); } return downloadPath; }); @@ -118295,7 +118295,7 @@ var require_retry_options = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getRetryOptions = void 0; - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var defaultMaxRetryNumber = 5; var defaultExemptStatusCodes = [400, 401, 403, 404, 422]; function getRetryOptions(defaultOptions, retries = defaultMaxRetryNumber, exemptStatusCodes = defaultExemptStatusCodes) { @@ -118310,7 +118310,7 @@ var require_retry_options = __commonJS({ retryOptions.doNotRetry = exemptStatusCodes; } const requestOptions = Object.assign(Object.assign({}, defaultOptions.request), { retries }); - core31.debug(`GitHub client configured with: (retries: ${requestOptions.retries}, retry-exempt-status-code: ${(_a2 = retryOptions.doNotRetry) !== null && _a2 !== void 0 ? _a2 : "octokit default: [400, 401, 403, 404, 422]"})`); + core32.debug(`GitHub client configured with: (retries: ${requestOptions.retries}, retry-exempt-status-code: ${(_a2 = retryOptions.doNotRetry) !== null && _a2 !== void 0 ? _a2 : "octokit default: [400, 401, 403, 404, 422]"})`); return [retryOptions, requestOptions]; } exports2.getRetryOptions = getRetryOptions; @@ -118467,7 +118467,7 @@ var require_get_artifact = __commonJS({ exports2.getArtifactInternal = exports2.getArtifactPublic = void 0; var github_1 = require_github2(); var plugin_retry_1 = require_dist_node12(); - var core31 = __importStar2(require_core()); + var core32 = __importStar2(require_core()); var utils_1 = require_utils9(); var retry_options_1 = require_retry_options(); var plugin_request_log_1 = require_dist_node11(); @@ -118505,7 +118505,7 @@ var require_get_artifact = __commonJS({ let artifact2 = getArtifactResp.data.artifacts[0]; if (getArtifactResp.data.artifacts.length > 1) { artifact2 = getArtifactResp.data.artifacts.sort((a, b) => b.id - a.id)[0]; - core31.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.id})`); + core32.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.id})`); } return { artifact: { @@ -118538,7 +118538,7 @@ var require_get_artifact = __commonJS({ let artifact2 = res.artifacts[0]; if (res.artifacts.length > 1) { artifact2 = res.artifacts.sort((a, b) => Number(b.databaseId) - Number(a.databaseId))[0]; - core31.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.databaseId})`); + core32.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.databaseId})`); } return { artifact: { @@ -121646,7 +121646,7 @@ var require_core3 = __commonJS({ ExitCode2[ExitCode2["Success"] = 0] = "Success"; ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; })(ExitCode || (exports2.ExitCode = ExitCode = {})); - function exportVariable16(name, val) { + function exportVariable17(name, val) { const convertedVal = (0, utils_1.toCommandValue)(val); process.env[name] = convertedVal; const filePath = process.env["GITHUB_ENV"] || ""; @@ -121655,7 +121655,7 @@ var require_core3 = __commonJS({ } (0, command_1.issueCommand)("set-env", { name }, convertedVal); } - exports2.exportVariable = exportVariable16; + exports2.exportVariable = exportVariable17; function setSecret2(secret) { (0, command_1.issueCommand)("add-mask", {}, secret); } @@ -123292,7 +123292,7 @@ var require_requestUtils2 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.retryHttpClientRequest = exports2.retry = void 0; var utils_1 = require_utils11(); - var core31 = __importStar2(require_core3()); + var core32 = __importStar2(require_core3()); var config_variables_1 = require_config_variables(); function retry2(name, operation, customErrorMessages, maxAttempts) { return __awaiter2(this, void 0, void 0, function* () { @@ -123319,13 +123319,13 @@ var require_requestUtils2 = __commonJS({ errorMessage = error3.message; } if (!isRetryable) { - core31.info(`${name} - Error is not retryable`); + core32.info(`${name} - Error is not retryable`); if (response) { (0, utils_1.displayHttpDiagnostics)(response); } break; } - core31.info(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); + core32.info(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); yield (0, utils_1.sleep)((0, utils_1.getExponentialRetryTimeInMilliseconds)(attempt)); attempt++; } @@ -123409,7 +123409,7 @@ var require_upload_http_client = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.UploadHttpClient = void 0; var fs32 = __importStar2(require("fs")); - var core31 = __importStar2(require_core3()); + var core32 = __importStar2(require_core3()); var tmp = __importStar2(require_tmp_promise()); var stream2 = __importStar2(require("stream")); var utils_1 = require_utils11(); @@ -123474,7 +123474,7 @@ var require_upload_http_client = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { const FILE_CONCURRENCY = (0, config_variables_1.getUploadFileConcurrency)(); const MAX_CHUNK_SIZE = (0, config_variables_1.getUploadChunkSize)(); - core31.debug(`File Concurrency: ${FILE_CONCURRENCY}, and Chunk Size: ${MAX_CHUNK_SIZE}`); + core32.debug(`File Concurrency: ${FILE_CONCURRENCY}, and Chunk Size: ${MAX_CHUNK_SIZE}`); const parameters = []; let continueOnError = true; if (options) { @@ -123511,15 +123511,15 @@ var require_upload_http_client = __commonJS({ } const startTime = perf_hooks_1.performance.now(); const uploadFileResult = yield this.uploadFileAsync(index2, currentFileParameters); - if (core31.isDebug()) { - core31.debug(`File: ${++completedFiles}/${filesToUpload.length}. ${currentFileParameters.file} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish upload`); + if (core32.isDebug()) { + core32.debug(`File: ${++completedFiles}/${filesToUpload.length}. ${currentFileParameters.file} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish upload`); } uploadFileSize += uploadFileResult.successfulUploadSize; totalFileSize += uploadFileResult.totalSize; if (uploadFileResult.isSuccess === false) { failedItemsToReport.push(currentFileParameters.file); if (!continueOnError) { - core31.error(`aborting artifact upload`); + core32.error(`aborting artifact upload`); abortPendingFileUploads = true; } } @@ -123528,7 +123528,7 @@ var require_upload_http_client = __commonJS({ }))); this.statusReporter.stop(); this.uploadHttpManager.disposeAndReplaceAllClients(); - core31.info(`Total size of all the files uploaded is ${uploadFileSize} bytes`); + core32.info(`Total size of all the files uploaded is ${uploadFileSize} bytes`); return { uploadSize: uploadFileSize, totalSize: totalFileSize, @@ -123554,16 +123554,16 @@ var require_upload_http_client = __commonJS({ let uploadFileSize = 0; let isGzip = true; if (!isFIFO && totalFileSize < 65536) { - core31.debug(`${parameters.file} is less than 64k in size. Creating a gzip file in-memory to potentially reduce the upload size`); + core32.debug(`${parameters.file} is less than 64k in size. Creating a gzip file in-memory to potentially reduce the upload size`); const buffer = yield (0, upload_gzip_1.createGZipFileInBuffer)(parameters.file); let openUploadStream; if (totalFileSize < buffer.byteLength) { - core31.debug(`The gzip file created for ${parameters.file} did not help with reducing the size of the file. The original file will be uploaded as-is`); + core32.debug(`The gzip file created for ${parameters.file} did not help with reducing the size of the file. The original file will be uploaded as-is`); openUploadStream = () => fs32.createReadStream(parameters.file); isGzip = false; uploadFileSize = totalFileSize; } else { - core31.debug(`A gzip file created for ${parameters.file} helped with reducing the size of the original file. The file will be uploaded using gzip.`); + core32.debug(`A gzip file created for ${parameters.file} helped with reducing the size of the original file. The file will be uploaded using gzip.`); openUploadStream = () => { const passThrough = new stream2.PassThrough(); passThrough.end(buffer); @@ -123575,7 +123575,7 @@ var require_upload_http_client = __commonJS({ if (!result) { isUploadSuccessful = false; failedChunkSizes += uploadFileSize; - core31.warning(`Aborting upload for ${parameters.file} due to failure`); + core32.warning(`Aborting upload for ${parameters.file} due to failure`); } return { isSuccess: isUploadSuccessful, @@ -123584,16 +123584,16 @@ var require_upload_http_client = __commonJS({ }; } else { const tempFile = yield tmp.file(); - core31.debug(`${parameters.file} is greater than 64k in size. Creating a gzip file on-disk ${tempFile.path} to potentially reduce the upload size`); + core32.debug(`${parameters.file} is greater than 64k in size. Creating a gzip file on-disk ${tempFile.path} to potentially reduce the upload size`); uploadFileSize = yield (0, upload_gzip_1.createGZipFileOnDisk)(parameters.file, tempFile.path); let uploadFilePath = tempFile.path; if (!isFIFO && totalFileSize < uploadFileSize) { - core31.debug(`The gzip file created for ${parameters.file} did not help with reducing the size of the file. The original file will be uploaded as-is`); + core32.debug(`The gzip file created for ${parameters.file} did not help with reducing the size of the file. The original file will be uploaded as-is`); uploadFileSize = totalFileSize; uploadFilePath = parameters.file; isGzip = false; } else { - core31.debug(`The gzip file created for ${parameters.file} is smaller than the original file. The file will be uploaded using gzip.`); + core32.debug(`The gzip file created for ${parameters.file} is smaller than the original file. The file will be uploaded using gzip.`); } let abortFileUpload = false; while (offset < uploadFileSize) { @@ -123613,7 +123613,7 @@ var require_upload_http_client = __commonJS({ if (!result) { isUploadSuccessful = false; failedChunkSizes += chunkSize; - core31.warning(`Aborting upload for ${parameters.file} due to failure`); + core32.warning(`Aborting upload for ${parameters.file} due to failure`); abortFileUpload = true; } else { if (uploadFileSize > 8388608) { @@ -123621,7 +123621,7 @@ var require_upload_http_client = __commonJS({ } } } - core31.debug(`deleting temporary gzip file ${tempFile.path}`); + core32.debug(`deleting temporary gzip file ${tempFile.path}`); yield tempFile.cleanup(); return { isSuccess: isUploadSuccessful, @@ -123660,7 +123660,7 @@ var require_upload_http_client = __commonJS({ if (response) { (0, utils_1.displayHttpDiagnostics)(response); } - core31.info(`Retry limit has been reached for chunk at offset ${start} to ${resourceUrl}`); + core32.info(`Retry limit has been reached for chunk at offset ${start} to ${resourceUrl}`); return true; } return false; @@ -123668,14 +123668,14 @@ var require_upload_http_client = __commonJS({ const backOff = (retryAfterValue) => __awaiter2(this, void 0, void 0, function* () { this.uploadHttpManager.disposeAndReplaceClient(httpClientIndex); if (retryAfterValue) { - core31.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the upload`); + core32.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the upload`); yield (0, utils_1.sleep)(retryAfterValue); } else { const backoffTime = (0, utils_1.getExponentialRetryTimeInMilliseconds)(retryCount); - core31.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the upload at offset ${start}`); + core32.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the upload at offset ${start}`); yield (0, utils_1.sleep)(backoffTime); } - core31.info(`Finished backoff for retry #${retryCount}, continuing with upload`); + core32.info(`Finished backoff for retry #${retryCount}, continuing with upload`); return; }); while (retryCount <= retryLimit) { @@ -123683,7 +123683,7 @@ var require_upload_http_client = __commonJS({ try { response = yield uploadChunkRequest(); } catch (error3) { - core31.info(`An error has been caught http-client index ${httpClientIndex}, retrying the upload`); + core32.info(`An error has been caught http-client index ${httpClientIndex}, retrying the upload`); console.log(error3); if (incrementAndCheckRetryLimit()) { return false; @@ -123695,13 +123695,13 @@ var require_upload_http_client = __commonJS({ if ((0, utils_1.isSuccessStatusCode)(response.message.statusCode)) { return true; } else if ((0, utils_1.isRetryableStatusCode)(response.message.statusCode)) { - core31.info(`A ${response.message.statusCode} status code has been received, will attempt to retry the upload`); + core32.info(`A ${response.message.statusCode} status code has been received, will attempt to retry the upload`); if (incrementAndCheckRetryLimit(response)) { return false; } (0, utils_1.isThrottledStatusCode)(response.message.statusCode) ? yield backOff((0, utils_1.tryGetRetryAfterValueTimeInMilliseconds)(response.message.headers)) : yield backOff(); } else { - core31.error(`Unexpected response. Unable to upload chunk to ${resourceUrl}`); + core32.error(`Unexpected response. Unable to upload chunk to ${resourceUrl}`); (0, utils_1.displayHttpDiagnostics)(response); return false; } @@ -123719,7 +123719,7 @@ var require_upload_http_client = __commonJS({ resourceUrl.searchParams.append("artifactName", artifactName); const parameters = { Size: size }; const data = JSON.stringify(parameters, null, 2); - core31.debug(`URL is ${resourceUrl.toString()}`); + core32.debug(`URL is ${resourceUrl.toString()}`); const client = this.uploadHttpManager.getClient(0); const headers = (0, utils_1.getUploadHeaders)("application/json", false); const customErrorMessages = /* @__PURE__ */ new Map([ @@ -123732,7 +123732,7 @@ var require_upload_http_client = __commonJS({ return client.patch(resourceUrl.toString(), data, headers); }), customErrorMessages); yield response.readBody(); - core31.debug(`Artifact ${artifactName} has been successfully uploaded, total size in bytes: ${size}`); + core32.debug(`Artifact ${artifactName} has been successfully uploaded, total size in bytes: ${size}`); }); } }; @@ -123801,7 +123801,7 @@ var require_download_http_client = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DownloadHttpClient = void 0; var fs32 = __importStar2(require("fs")); - var core31 = __importStar2(require_core3()); + var core32 = __importStar2(require_core3()); var zlib3 = __importStar2(require("zlib")); var utils_1 = require_utils11(); var url_1 = require("url"); @@ -123855,11 +123855,11 @@ var require_download_http_client = __commonJS({ downloadSingleArtifact(downloadItems) { return __awaiter2(this, void 0, void 0, function* () { const DOWNLOAD_CONCURRENCY = (0, config_variables_1.getDownloadFileConcurrency)(); - core31.debug(`Download file concurrency is set to ${DOWNLOAD_CONCURRENCY}`); + core32.debug(`Download file concurrency is set to ${DOWNLOAD_CONCURRENCY}`); const parallelDownloads = [...new Array(DOWNLOAD_CONCURRENCY).keys()]; let currentFile = 0; let downloadedFiles = 0; - core31.info(`Total number of files that will be downloaded: ${downloadItems.length}`); + core32.info(`Total number of files that will be downloaded: ${downloadItems.length}`); this.statusReporter.setTotalNumberOfFilesToProcess(downloadItems.length); this.statusReporter.start(); yield Promise.all(parallelDownloads.map((index2) => __awaiter2(this, void 0, void 0, function* () { @@ -123868,8 +123868,8 @@ var require_download_http_client = __commonJS({ currentFile += 1; const startTime = perf_hooks_1.performance.now(); yield this.downloadIndividualFile(index2, currentFileToDownload.sourceLocation, currentFileToDownload.targetPath); - if (core31.isDebug()) { - core31.debug(`File: ${++downloadedFiles}/${downloadItems.length}. ${currentFileToDownload.targetPath} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish downloading`); + if (core32.isDebug()) { + core32.debug(`File: ${++downloadedFiles}/${downloadItems.length}. ${currentFileToDownload.targetPath} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish downloading`); } this.statusReporter.incrementProcessedCount(); } @@ -123907,19 +123907,19 @@ var require_download_http_client = __commonJS({ } else { this.downloadHttpManager.disposeAndReplaceClient(httpClientIndex); if (retryAfterValue) { - core31.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the download`); + core32.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the download`); yield (0, utils_1.sleep)(retryAfterValue); } else { const backoffTime = (0, utils_1.getExponentialRetryTimeInMilliseconds)(retryCount); - core31.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the download`); + core32.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the download`); yield (0, utils_1.sleep)(backoffTime); } - core31.info(`Finished backoff for retry #${retryCount}, continuing with download`); + core32.info(`Finished backoff for retry #${retryCount}, continuing with download`); } }); const isAllBytesReceived = (expected, received) => { if (!expected || !received || process.env["ACTIONS_ARTIFACT_SKIP_DOWNLOAD_VALIDATION"]) { - core31.info("Skipping download validation."); + core32.info("Skipping download validation."); return true; } return parseInt(expected) === received; @@ -123940,7 +123940,7 @@ var require_download_http_client = __commonJS({ try { response = yield makeDownloadRequest(); } catch (error3) { - core31.info("An error occurred while attempting to download a file"); + core32.info("An error occurred while attempting to download a file"); console.log(error3); yield backOff(); continue; @@ -123960,7 +123960,7 @@ var require_download_http_client = __commonJS({ } } if (forceRetry || (0, utils_1.isRetryableStatusCode)(response.message.statusCode)) { - core31.info(`A ${response.message.statusCode} response code has been received while attempting to download an artifact`); + core32.info(`A ${response.message.statusCode} response code has been received while attempting to download an artifact`); resetDestinationStream(downloadPath); (0, utils_1.isThrottledStatusCode)(response.message.statusCode) ? yield backOff((0, utils_1.tryGetRetryAfterValueTimeInMilliseconds)(response.message.headers)) : yield backOff(); } else { @@ -123982,29 +123982,29 @@ var require_download_http_client = __commonJS({ if (isGzip) { const gunzip = zlib3.createGunzip(); response.message.on("error", (error3) => { - core31.info(`An error occurred while attempting to read the response stream`); + core32.info(`An error occurred while attempting to read the response stream`); gunzip.close(); destinationStream.close(); reject(error3); }).pipe(gunzip).on("error", (error3) => { - core31.info(`An error occurred while attempting to decompress the response stream`); + core32.info(`An error occurred while attempting to decompress the response stream`); destinationStream.close(); reject(error3); }).pipe(destinationStream).on("close", () => { resolve14(); }).on("error", (error3) => { - core31.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); + core32.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); reject(error3); }); } else { response.message.on("error", (error3) => { - core31.info(`An error occurred while attempting to read the response stream`); + core32.info(`An error occurred while attempting to read the response stream`); destinationStream.close(); reject(error3); }).pipe(destinationStream).on("close", () => { resolve14(); }).on("error", (error3) => { - core31.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); + core32.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); reject(error3); }); } @@ -124143,7 +124143,7 @@ var require_artifact_client = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DefaultArtifactClient = void 0; - var core31 = __importStar2(require_core3()); + var core32 = __importStar2(require_core3()); var upload_specification_1 = require_upload_specification(); var upload_http_client_1 = require_upload_http_client(); var utils_1 = require_utils11(); @@ -124164,7 +124164,7 @@ var require_artifact_client = __commonJS({ */ uploadArtifact(name, files, rootDirectory, options) { return __awaiter2(this, void 0, void 0, function* () { - core31.info(`Starting artifact upload + core32.info(`Starting artifact upload For more detailed logs during the artifact upload process, enable step-debugging: https://docs.github.com/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging#enabling-step-debug-logging`); (0, path_and_artifact_name_validation_1.checkArtifactName)(name); const uploadSpecification = (0, upload_specification_1.getUploadSpecification)(name, rootDirectory, files); @@ -124176,24 +124176,24 @@ For more detailed logs during the artifact upload process, enable step-debugging }; const uploadHttpClient = new upload_http_client_1.UploadHttpClient(); if (uploadSpecification.length === 0) { - core31.warning(`No files found that can be uploaded`); + core32.warning(`No files found that can be uploaded`); } else { const response = yield uploadHttpClient.createArtifactInFileContainer(name, options); if (!response.fileContainerResourceUrl) { - core31.debug(response.toString()); + core32.debug(response.toString()); throw new Error("No URL provided by the Artifact Service to upload an artifact to"); } - core31.debug(`Upload Resource URL: ${response.fileContainerResourceUrl}`); - core31.info(`Container for artifact "${name}" successfully created. Starting upload of file(s)`); + core32.debug(`Upload Resource URL: ${response.fileContainerResourceUrl}`); + core32.info(`Container for artifact "${name}" successfully created. Starting upload of file(s)`); const uploadResult = yield uploadHttpClient.uploadArtifactToFileContainer(response.fileContainerResourceUrl, uploadSpecification, options); - core31.info(`File upload process has finished. Finalizing the artifact upload`); + core32.info(`File upload process has finished. Finalizing the artifact upload`); yield uploadHttpClient.patchArtifactSize(uploadResult.totalSize, name); if (uploadResult.failedItems.length > 0) { - core31.info(`Upload finished. There were ${uploadResult.failedItems.length} items that failed to upload`); + core32.info(`Upload finished. There were ${uploadResult.failedItems.length} items that failed to upload`); } else { - core31.info(`Artifact has been finalized. All files have been successfully uploaded!`); + core32.info(`Artifact has been finalized. All files have been successfully uploaded!`); } - core31.info(` + core32.info(` The raw size of all the files that were specified for upload is ${uploadResult.totalSize} bytes The size of all the files that were uploaded is ${uploadResult.uploadSize} bytes. This takes into account any gzip compression used to reduce the upload size, time and storage @@ -124227,10 +124227,10 @@ Note: The size of downloaded zips can differ significantly from the reported siz path30 = (0, path_1.resolve)(path30); const downloadSpecification = (0, download_specification_1.getDownloadSpecification)(name, items.value, path30, (options === null || options === void 0 ? void 0 : options.createArtifactFolder) || false); if (downloadSpecification.filesToDownload.length === 0) { - core31.info(`No downloadable files were found for the artifact: ${artifactToDownload.name}`); + core32.info(`No downloadable files were found for the artifact: ${artifactToDownload.name}`); } else { yield (0, utils_1.createDirectoriesForArtifact)(downloadSpecification.directoryStructure); - core31.info("Directory structure has been set up for the artifact"); + core32.info("Directory structure has been set up for the artifact"); yield (0, utils_1.createEmptyFilesForArtifact)(downloadSpecification.emptyFilesToCreate); yield downloadHttpClient.downloadSingleArtifact(downloadSpecification.filesToDownload); } @@ -124246,7 +124246,7 @@ Note: The size of downloaded zips can differ significantly from the reported siz const response = []; const artifacts = yield downloadHttpClient.listArtifacts(); if (artifacts.count === 0) { - core31.info("Unable to find any artifacts for the associated workflow"); + core32.info("Unable to find any artifacts for the associated workflow"); return response; } if (!path30) { @@ -124258,11 +124258,11 @@ Note: The size of downloaded zips can differ significantly from the reported siz while (downloadedArtifacts < artifacts.count) { const currentArtifactToDownload = artifacts.value[downloadedArtifacts]; downloadedArtifacts += 1; - core31.info(`starting download of artifact ${currentArtifactToDownload.name} : ${downloadedArtifacts}/${artifacts.count}`); + core32.info(`starting download of artifact ${currentArtifactToDownload.name} : ${downloadedArtifacts}/${artifacts.count}`); const items = yield downloadHttpClient.getContainerItems(currentArtifactToDownload.name, currentArtifactToDownload.fileContainerResourceUrl); const downloadSpecification = (0, download_specification_1.getDownloadSpecification)(currentArtifactToDownload.name, items.value, path30, true); if (downloadSpecification.filesToDownload.length === 0) { - core31.info(`No downloadable files were found for any artifact ${currentArtifactToDownload.name}`); + core32.info(`No downloadable files were found for any artifact ${currentArtifactToDownload.name}`); } else { yield (0, utils_1.createDirectoriesForArtifact)(downloadSpecification.directoryStructure); yield (0, utils_1.createEmptyFilesForArtifact)(downloadSpecification.emptyFilesToCreate); @@ -142142,7 +142142,7 @@ module.exports = __toCommonJS(entry_points_exports); var fs23 = __toESM(require("fs")); var import_path5 = __toESM(require("path")); var import_perf_hooks4 = require("perf_hooks"); -var core16 = __toESM(require_core()); +var core17 = __toESM(require_core()); // src/action-common.ts var core8 = __toESM(require_core()); @@ -145993,7 +145993,7 @@ async function checkForTimeout() { process.exit(); } } -function isHostedRunner() { +function looksLikeHostedRunner() { return ( // Name of the runner on hosted Windows runners process.env["RUNNER_NAME"]?.includes("Hosted Agent") || // Name of the runner on hosted POSIX runners @@ -146320,6 +146320,9 @@ var getFileType = async (filePath) => { function isSelfHostedRunner(env = getEnv()) { return env.getOptional("RUNNER_ENVIRONMENT" /* RUNNER_ENVIRONMENT */) === "self-hosted"; } +function isGitHubHostedRunner(env = getEnv()) { + return env.getOptional("RUNNER_ENVIRONMENT" /* RUNNER_ENVIRONMENT */) === "github-hosted"; +} function isDynamicWorkflow(env = getEnv()) { return getWorkflowEventName(env) === "dynamic"; } @@ -147884,6 +147887,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_MULTIPLE_ANALYSIS_KINDS", minimumVersion: void 0 }, + ["cleanup_toolcache_bundles" /* CleanupToolcacheBundles */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_CLEANUP_TOOLCACHE_BUNDLES", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", @@ -148616,12 +148624,12 @@ var import_perf_hooks3 = require("perf_hooks"); var io5 = __toESM(require_io()); // src/autobuild.ts -var core13 = __toESM(require_core()); +var core14 = __toESM(require_core()); // src/codeql.ts var fs16 = __toESM(require("fs")); var path15 = __toESM(require("path")); -var core12 = __toESM(require_core()); +var core13 = __toESM(require_core()); var toolrunner3 = __toESM(require_toolrunner()); // src/cli-errors.ts @@ -148924,7 +148932,7 @@ function createCacheKeyHash(components) { function getDependencyCachingEnabled() { const dependencyCaching = getOptionalInput("dependency-caching") || process.env["CODEQL_ACTION_DEPENDENCY_CACHING" /* DEPENDENCY_CACHING */]; if (dependencyCaching !== void 0) return getCachingKind(dependencyCaching); - if (!isHostedRunner()) return "none" /* None */; + if (!looksLikeHostedRunner()) return "none" /* None */; if (!isDefaultSetup()) return "none" /* None */; return "none" /* None */; } @@ -150771,7 +150779,7 @@ async function validateOverlayDatabaseMode(overlayDatabaseMode, useOverlayDataba async function isTrapCachingEnabled(features, overlayDatabaseMode) { const trapCaching = getOptionalInput("trap-caching"); if (trapCaching !== void 0) return trapCaching === "true"; - if (!isHostedRunner()) return false; + if (!looksLikeHostedRunner()) return false; if (overlayDatabaseMode !== "none" /* None */ && await features.getValue("overlay_analysis_disable_trap_caching" /* OverlayAnalysisDisableTrapCaching */)) { return false; } @@ -151195,6 +151203,7 @@ async function logGeneratedFilesTelemetry(config, duration, generatedFilesCount) // src/setup-codeql.ts var fs14 = __toESM(require("fs")); var path13 = __toESM(require("path")); +var core12 = __toESM(require_core()); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); var semver9 = __toESM(require_semver2()); @@ -151777,14 +151786,99 @@ async function downloadAndExtractZstdWithStreaming(codeqlURL, dest, authorizatio } await extractTarZst(response, dest, tarVersion, logger); } -function getToolcacheDirectory(version) { +function getToolcacheToolDirectory() { return path12.join( getRequiredEnvParam("RUNNER_TOOL_CACHE"), - TOOLCACHE_TOOL_NAME, - semver8.clean(version) || version, + TOOLCACHE_TOOL_NAME + ); +} +function getToolcacheVersionDirectoryName(version) { + return semver8.clean(version) || version; +} +function getToolcacheDirectory(version) { + return path12.join( + getToolcacheToolDirectory(), + getToolcacheVersionDirectoryName(version), os4.arch() || "" ); } +function isToolcacheOnWorkspaceFilesystem(logger) { + try { + return fs13.statSync(getRequiredEnvParam("RUNNER_TOOL_CACHE")).dev === fs13.statSync(getRequiredEnvParam("GITHUB_WORKSPACE")).dev; + } catch (e) { + logger.debug( + `Could not determine whether the toolcache is on the same filesystem as the workspace: ${getErrorMessage(e)}` + ); + return false; + } +} +async function deleteToolcacheBundles(logger) { + let toolDirectory; + try { + toolDirectory = getToolcacheToolDirectory(); + } catch (e) { + logger.info( + `Unable to reclaim disk space from the toolcache: ${getErrorMessage(e)}` + ); + return { deletedVersions: [], failed: true }; + } + try { + if ((await fs13.promises.lstat(toolDirectory)).isSymbolicLink()) { + logger.info( + `Not deleting the CodeQL tools from the toolcache since '${toolDirectory}' is a symlink.` + ); + return { deletedVersions: [], failed: true }; + } + } catch (e) { + if (e?.code === "ENOENT") { + logger.debug( + `There are no CodeQL tools at '${toolDirectory}' to delete from the toolcache.` + ); + return { deletedVersions: [], failed: false }; + } + logger.info( + `Failed to inspect the CodeQL tools at '${toolDirectory}': ${getErrorMessage(e)}` + ); + return { deletedVersions: [], failed: true }; + } + try { + const entries = await fs13.promises.readdir(toolDirectory, { + withFileTypes: true + }); + const deletedVersions = []; + let failed = false; + for (const entry of entries) { + const versionDirectory = path12.join(toolDirectory, entry.name); + if (!entry.isDirectory()) { + logger.debug( + `Not deleting '${versionDirectory}' from the toolcache since it is not a directory.` + ); + continue; + } + try { + await fs13.promises.rm(versionDirectory, { + force: true, + recursive: true + }); + deletedVersions.push(entry.name); + logger.info( + `Deleted the CodeQL tools at '${versionDirectory}' from the toolcache to free up disk space.` + ); + } catch (e) { + failed = true; + logger.info( + `Failed to delete the CodeQL tools at '${versionDirectory}' from the toolcache: ${getErrorMessage(e)}` + ); + } + } + return { deletedVersions: deletedVersions.sort(), failed }; + } catch (e) { + logger.info( + `Failed to read the CodeQL tools at '${toolDirectory}' from the toolcache: ${getErrorMessage(e)}` + ); + return { deletedVersions: [], failed: true }; + } +} function writeToolcacheMarkerFile(extractedPath, logger) { const markerFilePath = `${extractedPath}.complete`; fs13.writeFileSync(markerFilePath, ""); @@ -152258,7 +152352,7 @@ async function tryGetFallbackToolcacheVersion(cliVersion2, tagName, logger) { ); return fallbackVersion; } -var downloadCodeQL = async function(codeqlURL, compressionMethod, maybeBundleVersion, maybeCliVersion, apiDetails, tarVersion, tempDir, logger) { +var downloadCodeQL = async function(codeqlURL, compressionMethod, maybeBundleVersion, maybeCliVersion, apiDetails, tarVersion, tempDir, features, logger) { const parsedCodeQLURL = new URL(codeqlURL); const searchParams = new URLSearchParams(parsedCodeQLURL.search); const headers = { @@ -152280,6 +152374,7 @@ var downloadCodeQL = async function(codeqlURL, compressionMethod, maybeBundleVer logger ); const extractedBundlePath = toolcacheInfo?.path ?? getTempExtractionDir(tempDir); + await tryDeleteToolcacheBundles({ env: getEnv(), features, logger }); const statusReport = await downloadAndExtract( codeqlURL, compressionMethod, @@ -152320,6 +152415,30 @@ function getToolcacheDestinationInfo(maybeBundleVersion, maybeCliVersion, logger } return void 0; } +async function tryDeleteToolcacheBundles({ + env, + features, + logger +}) { + if (env.getOptional("CODEQL_ACTION_HAS_SET_UP_CODEQL" /* HAS_SET_UP_CODEQL */) !== void 0) { + logger.debug( + "Not deleting the CodeQL tools from the toolcache since a previous step in this job has already set up CodeQL." + ); + return; + } + if (!isGitHubHostedRunner() || !isToolcacheOnWorkspaceFilesystem(logger) || !await features.getValue("cleanup_toolcache_bundles" /* CleanupToolcacheBundles */)) { + return; + } + const result = await deleteToolcacheBundles(logger); + addNoLanguageDiagnostic( + void 0, + makeTelemetryDiagnostic( + "codeql-action/toolcache-bundle-cleanup", + "Toolcache CodeQL bundle cleanup", + { ...result } + ) + ); +} function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { if (!cliVersion2?.match(/^[0-9]+\.[0-9]+\.[0-9]+$/)) { return convertToSemVer(bundleVersion2, logger); @@ -152374,6 +152493,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau apiDetails, zstdAvailability.version, tempDir, + features, logger ); toolsVersion = result.toolsVersion; @@ -152385,6 +152505,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau default: assertNever(source); } + core12.exportVariable("CODEQL_ACTION_HAS_SET_UP_CODEQL" /* HAS_SET_UP_CODEQL */, "true"); return { codeqlFolder, toolsDownloadStatusReport, @@ -152601,7 +152722,7 @@ async function getCodeQLForCmd(logger, cmd, checkVersion) { return result; }, async printVersion() { - core12.info(JSON.stringify(await this.getVersion(), null, 2)); + core13.info(JSON.stringify(await this.getVersion(), null, 2)); }, async supportsFeature(feature) { return isSupportedToolsFeature(await this.getVersion(), feature); @@ -152986,12 +153107,12 @@ async function getCodeQLForCmd(logger, cmd, checkVersion) { ); } else if (checkVersion && process.env["CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */] !== "true" && !await codeQlVersionAtLeast(codeql, CODEQL_NEXT_MINIMUM_VERSION)) { const result = await codeql.getVersion(); - core12.warning( + core13.warning( `CodeQL CLI version ${result.version} was discontinued on ${GHES_MOST_RECENT_DEPRECATION_DATE} alongside GitHub Enterprise Server ${GHES_VERSION_MOST_RECENTLY_DEPRECATED} and will not be supported by the next minor release of the CodeQL Action. Please update to CodeQL CLI version ${CODEQL_NEXT_MINIMUM_VERSION} or later. For instance, if you have specified a custom version of the CLI using the 'tools' input to the 'init' Action, you can remove this input to use the default version. Alternatively, if you want to continue using CodeQL CLI version ${result.version}, you can replace 'github/codeql-action/*@v${getActionVersion().split(".")[0]}' by 'github/codeql-action/*@v${getActionVersion()}' in your code scanning workflow to continue using this version of the CodeQL Action.` ); - core12.exportVariable("CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */, "true"); + core13.exportVariable("CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */, "true"); } return codeql; } @@ -153160,16 +153281,16 @@ async function setupCppAutobuild(codeql, logger) { logger.info( `Disabling ${featureName} as we are on a self-hosted runner.${getWorkflowEventName() !== "dynamic" ? ` To override this, set the ${envVar} environment variable to 'true' in your workflow. See ${"https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow" /* DEFINE_ENV_VARIABLES */} for more information.` : ""}` ); - core13.exportVariable(envVar, "false"); + core14.exportVariable(envVar, "false"); } else { logger.info( `Enabling ${featureName}. This can be disabled by setting the ${envVar} environment variable to 'false'. See ${"https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow" /* DEFINE_ENV_VARIABLES */} for more information.` ); - core13.exportVariable(envVar, "true"); + core14.exportVariable(envVar, "true"); } } else { logger.info(`Disabling ${featureName}.`); - core13.exportVariable(envVar, "false"); + core14.exportVariable(envVar, "false"); } } async function runAutobuild(config, language, logger) { @@ -153184,7 +153305,7 @@ async function runAutobuild(config, language, logger) { await codeQL.runAutobuild(config, language); } if (language === "go" /* go */) { - core13.exportVariable("CODEQL_ACTION_DID_AUTOBUILD_GOLANG" /* DID_AUTOBUILD_GOLANG */, "true"); + core14.exportVariable("CODEQL_ACTION_DID_AUTOBUILD_GOLANG" /* DID_AUTOBUILD_GOLANG */, "true"); } logger.endGroup(); } @@ -154041,7 +154162,7 @@ var fs22 = __toESM(require("fs")); var path19 = __toESM(require("path")); var url = __toESM(require("url")); var import_zlib = __toESM(require("zlib")); -var core15 = __toESM(require_core()); +var core16 = __toESM(require_core()); var jsonschema2 = __toESM(require_lib2()); // src/fingerprints.ts @@ -155169,7 +155290,7 @@ async function addFingerprints(sarifLog, sourceRoot, logger) { // src/init.ts var fs20 = __toESM(require("fs")); var path18 = __toESM(require("path")); -var core14 = __toESM(require_core()); +var core15 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github3 = __toESM(require_github()); var io6 = __toESM(require_io()); @@ -155391,7 +155512,7 @@ To opt out of this change, switch to an advanced setup workflow and ${envVarOptO To opt out of this change, ${envVarOptOut}`; } logger.warning(message); - core14.exportVariable("CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION" /* DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION */, "true"); + core15.exportVariable("CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION" /* DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION */, "true"); } // src/sarif/index.ts @@ -155505,7 +155626,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo logger.warning( `Uploading multiple SARIF runs with the same category is deprecated ${deprecationWarningMessage}. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}` ); - core15.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); + core16.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); } return combineSarifFiles(sarifFiles, logger); } @@ -155606,13 +155727,13 @@ async function uploadPayload(payload, repositoryNwo, logger, analysis) { if (httpError !== void 0) { switch (httpError.status) { case 403: - core15.warning(httpError.message || GENERIC_403_MSG); + core16.warning(httpError.message || GENERIC_403_MSG); break; case 404: - core15.warning(httpError.message || GENERIC_404_MSG); + core16.warning(httpError.message || GENERIC_404_MSG); break; default: - core15.warning(httpError.message); + core16.warning(httpError.message); break; } } @@ -156050,7 +156171,7 @@ function validateUniqueCategory(sarifLog, sentinelPrefix) { `Aborting upload: only one run of the codeql/analyze or codeql/upload-sarif actions is allowed per job per tool/category. The easiest fix is to specify a unique value for the \`category\` input. If .runs[].automationDetails.id is specified in the sarif file, that will take precedence over your configured \`category\`. Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})` ); } - core15.exportVariable(sentinelEnvVar, sentinelEnvVar); + core16.exportVariable(sentinelEnvVar, sentinelEnvVar); } } function sanitize(str) { @@ -156268,7 +156389,7 @@ async function run({ startedAt, logger }) { } const apiDetails = getApiDetails(); const outputDir = getRequiredInput("output"); - core16.exportVariable("CODEQL_ACTION_SARIF_RESULTS_OUTPUT_DIR" /* SARIF_RESULTS_OUTPUT_DIR */, outputDir); + core17.exportVariable("CODEQL_ACTION_SARIF_RESULTS_OUTPUT_DIR" /* SARIF_RESULTS_OUTPUT_DIR */, outputDir); const threads = getThreadsFlag( getOptionalInput("threads") || process.env["CODEQL_THREADS"], logger @@ -156320,8 +156441,8 @@ async function run({ startedAt, logger }) { for (const language of config.languages) { dbLocations[language] = getCodeQLDatabasePath(config, language); } - core16.setOutput("db-locations", dbLocations); - core16.setOutput("sarif-output", import_path5.default.resolve(outputDir)); + core17.setOutput("db-locations", dbLocations); + core17.setOutput("sarif-output", import_path5.default.resolve(outputDir)); const uploadKind = getUploadValue( getOptionalInput("upload") ); @@ -156338,13 +156459,13 @@ async function run({ startedAt, logger }) { getOptionalInput("post-processed-sarif-path") ); if (uploadResults["code-scanning" /* CodeScanning */] !== void 0) { - core16.setOutput( + core17.setOutput( "sarif-id", uploadResults["code-scanning" /* CodeScanning */].sarifID ); } if (uploadResults["code-quality" /* CodeQuality */] !== void 0) { - core16.setOutput( + core17.setOutput( "quality-sarif-id", uploadResults["code-quality" /* CodeQuality */].sarifID ); @@ -156387,15 +156508,15 @@ async function run({ startedAt, logger }) { ); } if (getOptionalInput("expect-error") === "true") { - core16.setFailed( + core17.setFailed( `expect-error input was set to true but no error was thrown.` ); } - core16.exportVariable("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */, "true"); + core17.exportVariable("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */, "true"); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); if (getOptionalInput("expect-error") !== "true" || hasBadExpectErrorInput()) { - core16.setFailed(error3.message); + core17.setFailed(error3.message); } await sendStatusReport2( startedAt, @@ -156470,14 +156591,14 @@ async function runWrapper() { // src/analyze-action-post.ts var fs27 = __toESM(require("fs")); -var core18 = __toESM(require_core()); +var core19 = __toESM(require_core()); // src/debug-artifacts.ts var fs26 = __toESM(require("fs")); var path23 = __toESM(require("path")); var artifact = __toESM(require_artifact2()); var artifactLegacy = __toESM(require_artifact_client2()); -var core17 = __toESM(require_core()); +var core18 = __toESM(require_core()); // node_modules/archiver/lib/core.js var import_fs2 = require("fs"); @@ -161263,10 +161384,10 @@ function getArtifactSuffix(matrix) { for (const matrixKey of Object.keys(matrixObject).sort()) suffix += `-${matrixObject[matrixKey]}`; } else { - core17.warning("User-specified `matrix` input is not an object."); + core18.warning("User-specified `matrix` input is not an object."); } } catch { - core17.warning( + core18.warning( "Could not parse user-specified `matrix` input into JSON. The debug artifact will not be named with the user's `matrix` input." ); } @@ -161276,7 +161397,7 @@ function getArtifactSuffix(matrix) { async function uploadDebugArtifacts(logger, toUpload, rootDir, artifactName, ghVariant, codeQlVersion) { const uploadSupported = isSafeArtifactUpload(codeQlVersion); if (!uploadSupported) { - core17.info( + core18.info( `Skipping debug artifact upload because the current CLI does not support safe upload. Please upgrade to CLI v${SafeArtifactUploadVersion} or later.` ); return "upload-not-supported"; @@ -161289,7 +161410,7 @@ async function uploadArtifacts(logger, toUpload, rootDir, artifactName, ghVarian } if (isInTestMode()) { await scanArtifactsForTokens(toUpload, logger); - core17.exportVariable("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); + core18.exportVariable("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); } const suffix = getArtifactSuffix(getOptionalInput("matrix")); const artifactUploader = await getArtifactUploaderClient(logger, ghVariant); @@ -161305,7 +161426,7 @@ async function uploadArtifacts(logger, toUpload, rootDir, artifactName, ghVarian ); return "upload-successful"; } catch (e) { - core17.warning(`Failed to upload debug artifacts: ${e}`); + core18.warning(`Failed to upload debug artifacts: ${e}`); return "upload-failed"; } } @@ -161328,7 +161449,7 @@ async function createPartialDatabaseBundle(config, language) { config.dbLocation, `${config.debugDatabaseName}-${language}-partial.zip` ); - core17.info( + core18.info( `${config.debugDatabaseName}-${language} is not finalized. Uploading partial database bundle at ${databaseBundlePath}...` ); if (fs26.existsSync(databaseBundlePath)) { @@ -161398,14 +161519,14 @@ async function runWrapper2() { } } } catch (error3) { - core18.setFailed( + core19.setFailed( `analyze post-action step failed: ${getErrorMessage(error3)}` ); } } // src/autobuild-action.ts -var core19 = __toESM(require_core()); +var core20 = __toESM(require_core()); async function sendCompletedStatusReport(config, logger, startedAt, allLanguages, failingLanguage, cause) { initializeEnvironment(getActionVersion()); const status = getActionsStatus(cause, failingLanguage); @@ -161471,7 +161592,7 @@ async function run2({ startedAt, logger }) { await endTracingForCluster(codeql, config, logger); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core19.setFailed( + core20.setFailed( `We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. ${error3.message}` ); await sendCompletedStatusReport( @@ -161484,7 +161605,7 @@ async function run2({ startedAt, logger }) { ); return; } - core19.exportVariable("CODEQL_ACTION_AUTOBUILD_DID_COMPLETE_SUCCESSFULLY" /* AUTOBUILD_DID_COMPLETE_SUCCESSFULLY */, "true"); + core20.exportVariable("CODEQL_ACTION_AUTOBUILD_DID_COMPLETE_SUCCESSFULLY" /* AUTOBUILD_DID_COMPLETE_SUCCESSFULLY */, "true"); await sendCompletedStatusReport(config, logger, startedAt, languages ?? []); } var autobuild = { @@ -161498,7 +161619,7 @@ async function runWrapper3() { // src/init-action.ts var fs29 = __toESM(require("fs")); var path25 = __toESM(require("path")); -var core21 = __toESM(require_core()); +var core22 = __toESM(require_core()); var io7 = __toESM(require_io()); var semver10 = __toESM(require_semver2()); @@ -161540,7 +161661,7 @@ async function getToolsInput(action, repositoryProperties) { var fs28 = __toESM(require("fs")); var path24 = __toESM(require("path")); var import_zlib3 = __toESM(require("zlib")); -var core20 = __toESM(require_core()); +var core21 = __toESM(require_core()); function toCodedErrors(errors) { return Object.entries(errors).reduce( (acc, [code, message]) => { @@ -161663,7 +161784,7 @@ async function validateWorkflow(codeql, logger) { } catch (e) { return `error: formatWorkflowErrors() failed: ${String(e)}`; } - core20.warning(message); + core21.warning(message); } return formatWorkflowCause(workflowErrors); } @@ -161792,7 +161913,7 @@ function getCheckoutPathInputOrThrow(workflow, jobName, matrixVars) { } async function checkWorkflow(logger, codeql) { if (!isDynamicWorkflow() && process.env["CODEQL_ACTION_SKIP_WORKFLOW_VALIDATION" /* SKIP_WORKFLOW_VALIDATION */] !== "true") { - core20.startGroup("Validating workflow"); + core21.startGroup("Validating workflow"); const validateWorkflowResult = await internal2.validateWorkflow( codeql, logger @@ -161804,7 +161925,7 @@ async function checkWorkflow(logger, codeql) { `Unable to validate code scanning workflow: ${validateWorkflowResult}` ); } - core20.endGroup(); + core21.endGroup(); } } var internal2 = { @@ -161921,7 +162042,7 @@ async function run3(actionState) { logger ); const repositoryProperties = repositoryPropertiesResult.orElse({}); - core21.exportVariable("CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */, "true"); + core22.exportVariable("CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */, "true"); sourceRoot = path25.resolve( getRequiredEnvParam("GITHUB_WORKSPACE"), getOptionalInput("source-root") || "" @@ -161986,12 +162107,12 @@ async function run3(actionState) { ); } if (semver10.lt(actualVer, publicPreview)) { - core21.exportVariable("CODEQL_ENABLE_EXPERIMENTAL_FEATURES" /* EXPERIMENTAL_FEATURES */, "true"); + core22.exportVariable("CODEQL_ENABLE_EXPERIMENTAL_FEATURES" /* EXPERIMENTAL_FEATURES */, "true"); logger.info("Experimental Rust analysis enabled"); } } analysisKinds = await getAnalysisKinds(logger, features); - const debugMode = getOptionalInput("debug") === "true" || core21.isDebug(); + const debugMode = getOptionalInput("debug") === "true" || core22.isDebug(); const fileCoverageResult = await getFileCoverageInformationEnabled( debugMode, codeql, @@ -162061,7 +162182,7 @@ async function run3(actionState) { await checkInstallPython311(config.languages, codeql); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core21.setFailed(error3.message); + core22.setFailed(error3.message); const statusReportBase = await createStatusReportBase( "init" /* Init */, error3 instanceof ConfigurationError ? "user-error" : "aborted", @@ -162103,8 +162224,8 @@ async function run3(actionState) { } const goFlags = process.env["GOFLAGS"]; if (goFlags) { - core21.exportVariable("GOFLAGS", goFlags); - core21.warning( + core22.exportVariable("GOFLAGS", goFlags); + core22.warning( "Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action." ); } @@ -162123,7 +162244,7 @@ async function run3(actionState) { "bin" ); fs29.mkdirSync(tempBinPath, { recursive: true }); - core21.addPath(tempBinPath); + core22.addPath(tempBinPath); const goWrapperPath = path25.resolve(tempBinPath, "go"); fs29.writeFileSync( goWrapperPath, @@ -162132,14 +162253,14 @@ async function run3(actionState) { exec ${goBinaryPath} "$@"` ); fs29.chmodSync(goWrapperPath, "755"); - core21.exportVariable("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goWrapperPath); + core22.exportVariable("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goWrapperPath); } catch (e) { logger.warning( `Analyzing Go on Linux, but failed to install wrapper script. Tracing custom builds may fail: ${e}` ); } } else { - core21.exportVariable("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goBinaryPath); + core22.exportVariable("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goBinaryPath); } } catch (e) { logger.warning( @@ -162166,23 +162287,23 @@ exec ${goBinaryPath} "$@"` } } } - core21.exportVariable( + core22.exportVariable( "CODEQL_RAM", process.env["CODEQL_RAM"] || getCodeQLMemoryLimit(getOptionalInput("ram"), logger).toString() ); - core21.exportVariable( + core22.exportVariable( "CODEQL_THREADS", process.env["CODEQL_THREADS"] || getThreadsFlagValue(getOptionalInput("threads"), logger).toString() ); if (await features.getValue("disable_kotlin_analysis_enabled" /* DisableKotlinAnalysisEnabled */)) { - core21.exportVariable("CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", "true"); + core22.exportVariable("CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", "true"); } if (await features.getValue("force_jgit" /* ForceJGit */)) { - core21.exportVariable("CODEQL_GIT_BACKEND", "jgit"); + core22.exportVariable("CODEQL_GIT_BACKEND", "jgit"); } const kotlinLimitVar = "CODEQL_EXTRACTOR_KOTLIN_OVERRIDE_MAXIMUM_VERSION_LIMIT"; if (await codeQlVersionAtLeast(codeql, "2.20.3") && !await codeQlVersionAtLeast(codeql, "2.20.4")) { - core21.exportVariable(kotlinLimitVar, "2.1.20"); + core22.exportVariable(kotlinLimitVar, "2.1.20"); } if (shouldRestoreCache(config.dependencyCachingEnabled)) { const dependencyCachingResult = await downloadDependencyCaches( @@ -162209,7 +162330,7 @@ exec ${goBinaryPath} "$@"` `${"CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */} is already set to '${process.env["CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */]}', so the Action will not override it.` ); } else if (await codeQlVersionAtLeast(codeql, CODEQL_VERSION_JAR_MINIMIZATION) && config.dependencyCachingEnabled && config.buildMode === "none" /* None */ && config.languages.includes("java" /* java */)) { - core21.exportVariable( + core22.exportVariable( "CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */, "true" ); @@ -162251,23 +162372,23 @@ exec ${goBinaryPath} "$@"` const tracerConfig = await getCombinedTracerConfig(codeql, config); if (tracerConfig !== void 0) { for (const [key, value] of Object.entries(tracerConfig.env)) { - core21.exportVariable(key, value); + core22.exportVariable(key, value); } } if (await features.getValue("java_network_debugging" /* JavaNetworkDebugging */)) { const existingJavaToolOptions = getOptionalEnvVar("JAVA_TOOL_OPTIONS" /* JAVA_TOOL_OPTIONS */) || ""; - core21.exportVariable( + core22.exportVariable( "JAVA_TOOL_OPTIONS" /* JAVA_TOOL_OPTIONS */, `${existingJavaToolOptions} -Djavax.net.debug=all` ); } flushDiagnostics(config); await saveConfig(config, logger); - core21.setOutput("codeql-path", config.codeQLCmd); - core21.setOutput("codeql-version", (await codeql.getVersion()).version); + core22.setOutput("codeql-path", config.codeQLCmd); + core22.setOutput("codeql-version", (await codeql.getVersion()).version); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core21.setFailed(error3.message); + core22.setFailed(error3.message); await sendCompletedStatusReport2( startedAt, config, @@ -162311,7 +162432,7 @@ async function runWrapper4() { } // src/init-action-post.ts -var core22 = __toESM(require_core()); +var core23 = __toESM(require_core()); // src/init-action-post-helper.ts var fs30 = __toESM(require("fs")); @@ -162661,7 +162782,7 @@ async function run4(startedAt) { } } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core22.setFailed(error3.message); + core23.setFailed(error3.message); const statusReportBase2 = await createStatusReportBase( "init-post" /* InitPost */, getActionsStatus(error3), @@ -162706,14 +162827,14 @@ function getFinalJobStatus(config) { } let jobStatus; if (process.env["CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */] === "true") { - core22.exportVariable("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */); + core23.exportVariable("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */); jobStatus = "JOB_STATUS_SUCCESS" /* SuccessStatus */; } else if (config !== void 0) { jobStatus = "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */; } else { jobStatus = "JOB_STATUS_UNKNOWN" /* UnknownStatus */; } - core22.exportVariable("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus); + core23.exportVariable("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus); return jobStatus; } function getJobStatusFromEnvironment() { @@ -162732,7 +162853,7 @@ async function runWrapper5() { try { await run4(startedAt); } catch (error3) { - core22.setFailed(`init post action failed: ${wrapError(error3).message}`); + core23.setFailed(`init post action failed: ${wrapError(error3).message}`); await sendUnhandledErrorStatusReport( "init-post" /* InitPost */, startedAt, @@ -162743,7 +162864,7 @@ async function runWrapper5() { } // src/resolve-environment-action.ts -var core23 = __toESM(require_core()); +var core24 = __toESM(require_core()); // src/resolve-environment.ts async function runResolveBuildEnvironment(cmd, logger, workingDir, language) { @@ -162790,16 +162911,16 @@ async function run5(startedAt) { workingDirectory, getRequiredInput("language") ); - core23.setOutput(ENVIRONMENT_OUTPUT_NAME, result); + core24.setOutput(ENVIRONMENT_OUTPUT_NAME, result); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); if (error3 instanceof CliError) { - core23.setOutput(ENVIRONMENT_OUTPUT_NAME, {}); + core24.setOutput(ENVIRONMENT_OUTPUT_NAME, {}); logger.warning( `Failed to resolve a build environment suitable for automatically building your code. ${error3.message}` ); } else { - core23.setFailed( + core24.setFailed( `Failed to resolve a build environment suitable for automatically building your code. ${error3.message}` ); const statusReportBase2 = await createStatusReportBase( @@ -162836,7 +162957,7 @@ async function runWrapper6() { try { await run5(startedAt); } catch (error3) { - core23.setFailed( + core24.setFailed( `${"resolve-environment" /* ResolveEnvironment */} action failed: ${getErrorMessage( error3 )}` @@ -162852,7 +162973,7 @@ async function runWrapper6() { } // src/setup-codeql-action.ts -var core24 = __toESM(require_core()); +var core25 = __toESM(require_core()); async function sendCompletedStatusReport3(startedAt, toolsInput, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, logger, error3) { const statusReportBase = await createStatusReportBase( "setup-codeql" /* SetupCodeQL */, @@ -162960,12 +163081,12 @@ async function run6(actionState) { toolsDownloadStatusReport = initCodeQLResult.toolsDownloadStatusReport; toolsVersion = initCodeQLResult.toolsVersion; toolsSource = initCodeQLResult.toolsSource; - core24.setOutput("codeql-path", codeql.getPath()); - core24.setOutput("codeql-version", (await codeql.getVersion()).version); - core24.exportVariable("CODEQL_ACTION_SETUP_CODEQL_HAS_RUN" /* SETUP_CODEQL_ACTION_HAS_RUN */, "true"); + core25.setOutput("codeql-path", codeql.getPath()); + core25.setOutput("codeql-version", (await codeql.getVersion()).version); + core25.exportVariable("CODEQL_ACTION_SETUP_CODEQL_HAS_RUN" /* SETUP_CODEQL_ACTION_HAS_RUN */, "true"); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core24.setFailed(error3.message); + core25.setFailed(error3.message); const statusReportBase = await createStatusReportBase( "setup-codeql" /* SetupCodeQL */, error3 instanceof ConfigurationError ? "user-error" : "failure", @@ -163003,15 +163124,15 @@ async function runWrapper7() { // src/start-proxy-action.ts var import_child_process2 = require("child_process"); var path29 = __toESM(require("path")); -var core27 = __toESM(require_core()); +var core28 = __toESM(require_core()); // src/start-proxy.ts var path27 = __toESM(require("path")); -var core26 = __toESM(require_core()); +var core27 = __toESM(require_core()); var toolcache4 = __toESM(require_tool_cache()); // src/start-proxy/validation.ts -var core25 = __toESM(require_core()); +var core26 = __toESM(require_core()); function cloneCredential(schema, obj) { const result = {}; for (const key of Object.keys(schema)) { @@ -163030,14 +163151,14 @@ function getAuthConfig(config) { } if (isToken(config)) { if (isDefined2(config.token)) { - core25.setSecret(config.token); + core26.setSecret(config.token); } return cloneCredential(tokenSchema, config); } else { let username = void 0; let password = void 0; if ("password" in config && isString(config.password)) { - core25.setSecret(config.password); + core26.setSecret(config.password); password = config.password; } if ("username" in config && isString(config.username)) { @@ -163093,7 +163214,7 @@ function getSafeErrorMessage(error3) { } async function sendFailedStatusReport(logger, startedAt, language, unwrappedError) { const error3 = wrapError(unwrappedError); - core26.setFailed(`start-proxy action failed: ${error3.message}`); + core27.setFailed(`start-proxy action failed: ${error3.message}`); const statusReportMessage = getSafeErrorMessage(error3); const errorStatusReportBase = await createStatusReportBase( "start-proxy" /* StartProxy */, @@ -163667,7 +163788,7 @@ async function run7(action) { persistInputs(); const tempDir = getTemporaryDirectory(); const proxyLogFilePath = path29.resolve(tempDir, "proxy.log"); - core27.saveState("proxy-log-file", proxyLogFilePath); + core28.saveState("proxy-log-file", proxyLogFilePath); const repositoryNwo = getRepositoryNwo(); const gitHubVersion = await getGitHubVersion(); features = initFeatures( @@ -163692,7 +163813,7 @@ async function run7(action) { `Credentials loaded for the following registries: ${credentials.map((c) => credentialToStr(c)).join("\n")}` ); - if (core27.isDebug() || isInTestMode()) { + if (core28.isDebug() || isInTestMode()) { try { await checkProxyEnvironment(logger, language); } catch (err) { @@ -163751,7 +163872,7 @@ async function startProxy(binPath, config, logFilePath, logger) { ); subprocess.unref(); if (subprocess.pid) { - core27.saveState("proxy-process-pid", `${subprocess.pid}`); + core28.saveState("proxy-process-pid", `${subprocess.pid}`); } subprocess.on("error", (error3) => { subprocessError = error3; @@ -163770,25 +163891,25 @@ async function startProxy(binPath, config, logFilePath, logger) { throw subprocessError; } logger.info(`Proxy started on ${host}:${port}`); - core27.setOutput("proxy_host", host); - core27.setOutput("proxy_port", port.toString()); - core27.setOutput("proxy_ca_certificate", config.ca.cert); + core28.setOutput("proxy_host", host); + core28.setOutput("proxy_port", port.toString()); + core28.setOutput("proxy_ca_certificate", config.ca.cert); const registry_urls = config.all_credentials.filter((credential) => credential.url !== void 0).map((credential) => ({ type: credential.type, url: credential.url, "replaces-base": credential["replaces-base"] })); - core27.setOutput("proxy_urls", JSON.stringify(registry_urls)); + core28.setOutput("proxy_urls", JSON.stringify(registry_urls)); return { host, port, cert: config.ca.cert, registries: registry_urls }; } // src/start-proxy-action-post.ts -var core28 = __toESM(require_core()); +var core29 = __toESM(require_core()); async function runWrapper9() { const logger = getActionsLogger(); try { restoreInputs(); - const pid = core28.getState("proxy-process-pid"); + const pid = core29.getState("proxy-process-pid"); if (pid) { process.kill(Number(pid)); } @@ -163796,8 +163917,8 @@ async function runWrapper9() { getTemporaryDirectory(), logger ); - if (config?.debugMode || core28.isDebug()) { - const logFilePath = core28.getState("proxy-log-file"); + if (config?.debugMode || core29.isDebug()) { + const logFilePath = core29.getState("proxy-log-file"); logger.info( "Debug mode is on. Uploading proxy log as Actions debugging artifact..." ); @@ -163825,7 +163946,7 @@ async function runWrapper9() { } // src/upload-sarif-action.ts -var core29 = __toESM(require_core()); +var core30 = __toESM(require_core()); async function sendSuccessStatusReport2(startedAt, uploadStats, logger) { const statusReportBase = await createStatusReportBase( "upload-sarif" /* UploadSarif */, @@ -163885,11 +164006,11 @@ async function run8({ startedAt, logger }) { } const codeScanningResult = uploadResults["code-scanning" /* CodeScanning */]; if (codeScanningResult !== void 0) { - core29.setOutput("sarif-id", codeScanningResult.sarifID); + core30.setOutput("sarif-id", codeScanningResult.sarifID); } - core29.setOutput("sarif-ids", JSON.stringify(uploadResults)); + core30.setOutput("sarif-ids", JSON.stringify(uploadResults)); if (shouldSkipSarifUpload()) { - core29.debug( + core30.debug( "SARIF upload disabled by an environment variable. Waiting for processing is disabled." ); } else if (getRequiredInput("wait-for-processing") === "true") { @@ -163909,7 +164030,7 @@ async function run8({ startedAt, logger }) { } catch (unwrappedError) { const error3 = isThirdPartyAnalysis("upload-sarif" /* UploadSarif */) && unwrappedError instanceof InvalidSarifUploadError ? new ConfigurationError(unwrappedError.message) : wrapError(unwrappedError); const message = error3.message; - core29.setFailed(message); + core30.setFailed(message); const errorStatusReportBase = await createStatusReportBase( "upload-sarif" /* UploadSarif */, getActionsStatus(error3), @@ -163935,7 +164056,7 @@ async function runWrapper10() { } // src/upload-sarif-action-post.ts -var core30 = __toESM(require_core()); +var core31 = __toESM(require_core()); async function runWrapper11() { try { restoreInputs(); @@ -163944,7 +164065,7 @@ async function runWrapper11() { checkGitHubVersionInRange(gitHubVersion, logger); if (process.env["CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */] !== "true") { if (gitHubVersion.type === void 0) { - core30.warning( + core31.warning( `Did not upload debug artifacts because cannot determine the GitHub variant running.` ); return; @@ -163961,7 +164082,7 @@ async function runWrapper11() { ); } } catch (error3) { - core30.setFailed( + core31.setFailed( `upload-sarif post-action step failed: ${getErrorMessage(error3)}` ); } diff --git a/pr-checks/checks/multi-language-autodetect.yml b/pr-checks/checks/multi-language-autodetect.yml index b57e90ab4c..b9d80d1077 100644 --- a/pr-checks/checks/multi-language-autodetect.yml +++ b/pr-checks/checks/multi-language-autodetect.yml @@ -15,6 +15,7 @@ operatingSystems: - stable-v2.21.4 - stable-v2.22.4 env: + CODEQL_ACTION_CLEANUP_TOOLCACHE_BUNDLES: true CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true installGo: true installDotNet: true diff --git a/src/actions-util.ts b/src/actions-util.ts index dd5124620d..eb7d92b517 100644 --- a/src/actions-util.ts +++ b/src/actions-util.ts @@ -283,6 +283,19 @@ export function isSelfHostedRunner(env: Env = getEnv()) { return env.getOptional(ActionsEnvVars.RUNNER_ENVIRONMENT) === "self-hosted"; } +/** + * Whether the job is running on a runner that GitHub hosts, and whose toolcache is therefore thrown + * away once the job has finished. + * + * Unlike `looksLikeHostedRunner`, this is based on what the service reports for the job rather than + * on how the runner's filesystem happens to be laid out, so it does not match self-hosted runners + * that are configured to resemble hosted ones, such as those that mount a persistent volume at + * `/opt/hostedtoolcache`. + */ +export function isGitHubHostedRunner(env: Env = getEnv()) { + return env.getOptional(ActionsEnvVars.RUNNER_ENVIRONMENT) === "github-hosted"; +} + /** Determines whether the workflow trigger is `dynamic`. */ export function isDynamicWorkflow(env: Env = getEnv()): boolean { return getWorkflowEventName(env) === "dynamic"; diff --git a/src/caching-utils.ts b/src/caching-utils.ts index 33dac7cfb4..d5cdb84452 100644 --- a/src/caching-utils.ts +++ b/src/caching-utils.ts @@ -5,7 +5,7 @@ import * as core from "@actions/core"; import { getOptionalInput, isDefaultSetup } from "./actions-util"; import { EnvVar } from "./environment"; import { Logger } from "./logging"; -import { isHostedRunner, tryGetFolderBytes } from "./util"; +import { looksLikeHostedRunner, tryGetFolderBytes } from "./util"; /** * Returns the total size of all the specified paths. @@ -109,7 +109,7 @@ export function getDependencyCachingEnabled(): CachingKind { if (dependencyCaching !== undefined) return getCachingKind(dependencyCaching); // On self-hosted runners which may have dependencies installed centrally, disable caching by default - if (!isHostedRunner()) return CachingKind.None; + if (!looksLikeHostedRunner()) return CachingKind.None; // Disable in advanced workflows by default. if (!isDefaultSetup()) return CachingKind.None; diff --git a/src/config-utils.ts b/src/config-utils.ts index 0a6ced00aa..288b4f02fb 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -90,9 +90,8 @@ import { Result, Success, Failure, - isHostedRunner, + looksLikeHostedRunner, } from "./util"; - export { type Config } from "./config/action-config"; /** @@ -938,7 +937,7 @@ export async function isTrapCachingEnabled( if (trapCaching !== undefined) return trapCaching === "true"; // On self-hosted runners which may have slow network access, disable TRAP caching by default. - if (!isHostedRunner()) return false; + if (!looksLikeHostedRunner()) return false; // If overlay analysis is enabled, then disable TRAP caching since overlay analysis supersedes it. // This change is gated behind a feature flag. diff --git a/src/environment.ts b/src/environment.ts index 29665512c2..bf4bb4f717 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -63,6 +63,12 @@ export enum EnvVar { /** Whether the CodeQL Action has already warned the user about low disk space. */ HAS_WARNED_ABOUT_DISK_SPACE = "CODEQL_ACTION_HAS_WARNED_ABOUT_DISK_SPACE", + /** + * Whether a step in this job has already set up CodeQL. Steps that run afterwards may be holding + * a path into the toolcache, so we must not delete anything from it. + */ + HAS_SET_UP_CODEQL = "CODEQL_ACTION_HAS_SET_UP_CODEQL", + /** Whether the `setup-codeql` action has been run. */ SETUP_CODEQL_ACTION_HAS_RUN = "CODEQL_ACTION_SETUP_CODEQL_HAS_RUN", diff --git a/src/feature-flags.ts b/src/feature-flags.ts index 7abccf60cb..da7bcceade 100644 --- a/src/feature-flags.ts +++ b/src/feature-flags.ts @@ -74,6 +74,11 @@ export enum Feature { AllowMergeConfigFiles = "allow_merge_config_files", /** Controls whether we allow multiple values for the `analysis-kinds` input. */ AllowMultipleAnalysisKinds = "allow_multiple_analysis_kinds", + /** + * Controls whether we delete CodeQL bundles that we are not going to use from the toolcache + * before downloading a different bundle, in order to reclaim disk space. + */ + CleanupToolcacheBundles = "cleanup_toolcache_bundles", CleanupTrapCaches = "cleanup_trap_caches", /** Whether to allow the `config-file` input to be specified via a repository property. */ ConfigFileRepositoryProperty = "config_file_repository_property", @@ -211,6 +216,11 @@ export const featureConfig = { envVar: "CODEQL_ACTION_ALLOW_MULTIPLE_ANALYSIS_KINDS", minimumVersion: undefined, }, + [Feature.CleanupToolcacheBundles]: { + defaultValue: false, + envVar: "CODEQL_ACTION_CLEANUP_TOOLCACHE_BUNDLES", + minimumVersion: undefined, + }, [Feature.CleanupTrapCaches]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/src/setup-codeql.test.ts b/src/setup-codeql.test.ts index 5751688fa5..9fab50f004 100644 --- a/src/setup-codeql.test.ts +++ b/src/setup-codeql.test.ts @@ -1,3 +1,5 @@ +import * as fs from "fs"; +import * as os from "os"; import * as path from "path"; import * as github from "@actions/github"; @@ -7,7 +9,8 @@ import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; import * as api from "./api-client"; -import { EnvVar } from "./environment"; +import * as diagnostics from "./diagnostics"; +import { ActionsEnvVars, EnvVar } from "./environment"; import { Feature } from "./feature-flags"; import { getRunnerLogger } from "./logging"; import { getCacheRestoreKeyPrefix } from "./overlay/caching"; @@ -27,6 +30,7 @@ import { setupActionsVars, setupTests, } from "./testing-utils"; +import * as toolsDownload from "./tools-download"; import { getErrorMessage, GitHubVariant, @@ -939,3 +943,509 @@ test.serial( ]); }, ); + +/** The CLI version that the toolcache cleanup tests download. */ +const CLEANUP_CLI_VERSION = "2.21.0"; +/** The bundle version that the toolcache cleanup tests download. */ +const CLEANUP_BUNDLE_VERSION = "20240101"; +/** A version of the CodeQL tools that is already in the toolcache but that we are not going to use. */ +const CLEANUP_STALE_VERSION = "2.20.0"; + +/** Creates a directory in the toolcache that looks like a tool that `tool-cache` has cached. */ +function createToolcacheEntry( + toolcacheRoot: string, + tool: string, + version: string, +): string { + const versionDirectory = path.join(toolcacheRoot, tool, version); + const archDirectory = path.join(versionDirectory, os.arch()); + fs.mkdirSync(archDirectory, { recursive: true }); + fs.writeFileSync(path.join(archDirectory, "contents"), "x".repeat(1024)); + fs.writeFileSync(`${archDirectory}.complete`, ""); + return versionDirectory; +} + +/** + * Stubs out the download and the diagnostic sink, then downloads the CodeQL tools into a toolcache + * rooted at `toolcacheRoot`. + * + * @returns the attributes of the toolcache cleanup diagnostic, or `undefined` if we didn't emit one. + */ +async function runDownloadCodeQL( + toolcacheRoot: string, + features: Feature[], + bundleVersion: string | undefined = CLEANUP_BUNDLE_VERSION, +): Promise { + sinon + .stub(toolsDownload, "downloadAndExtract") + .callsFake(async (_url, _compressionMethod, dest) => { + // The real implementation creates the destination directory, which matters here because the + // cleanup deletes it first and `writeToolcacheMarkerFile` writes into its parent afterwards. + fs.mkdirSync(dest, { recursive: true }); + return { totalDurationMs: 1 }; + }); + const addDiagnostic = sinon.stub(diagnostics, "addNoLanguageDiagnostic"); + + await setupCodeql.downloadCodeQL( + "https://example.com/codeql-bundle.tar.gz", + "gzip", + bundleVersion, + CLEANUP_CLI_VERSION, + SAMPLE_DOTCOM_API_DETAILS, + undefined, // tarVersion + toolcacheRoot, // tempDir + createFeatures(features), + getRunnerLogger(true), + ); + + const diagnostic = addDiagnostic + .getCalls() + .map((call) => call.args[1]) + .find((d) => d.source?.id === "codeql-action/toolcache-bundle-cleanup"); + + return diagnostic?.attributes as + | toolsDownload.ToolcacheCleanupResult + | undefined; +} + +/** + * Sets up a toolcache containing the version of the CodeQL tools that we are about to download, a + * different version of the CodeQL tools, and an unrelated tool, then downloads the CodeQL tools. + */ +async function testToolcacheCleanup( + t: ExecutionContext, + { + features, + runnerEnvironment, + setUp, + }: { + features: Feature[]; + runnerEnvironment: string | undefined; + setUp?: () => void; + }, + check: (context: { + cleanupDiagnostic: toolsDownload.ToolcacheCleanupResult | undefined; + destinationDirectory: string; + staleDirectory: string; + }) => void, +) { + await withTmpDir(async (tmpDir) => { + setupActionsVars(tmpDir, tmpDir); + if (runnerEnvironment === undefined) { + delete process.env[ActionsEnvVars.RUNNER_ENVIRONMENT]; + } else { + process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnvironment; + } + setUp?.(); + + // The extraction of the bundle would normally create this directory. + const destinationDirectory = createToolcacheEntry( + tmpDir, + "CodeQL", + CLEANUP_CLI_VERSION, + ); + const staleDirectory = createToolcacheEntry( + tmpDir, + "CodeQL", + CLEANUP_STALE_VERSION, + ); + const otherToolDirectory = createToolcacheEntry(tmpDir, "Node", "20.0.0"); + + const cleanupDiagnostic = await runDownloadCodeQL(tmpDir, features); + + t.true( + fs.existsSync(otherToolDirectory), + "Should never delete other tools from the toolcache.", + ); + + check({ cleanupDiagnostic, destinationDirectory, staleDirectory }); + }); +} + +test.serial( + "downloadCodeQL does not clean up the toolcache when the feature flag is disabled", + async (t) => { + await testToolcacheCleanup( + t, + { features: [], runnerEnvironment: "github-hosted" }, + ({ cleanupDiagnostic, destinationDirectory, staleDirectory }) => { + t.true(fs.existsSync(staleDirectory)); + t.true(fs.existsSync(destinationDirectory)); + t.is(cleanupDiagnostic, undefined); + }, + ); + }, +); + +test.serial( + "downloadCodeQL does not clean up the toolcache when the runner is not GitHub-hosted", + async (t) => { + await testToolcacheCleanup( + t, + { + features: [Feature.CleanupToolcacheBundles], + runnerEnvironment: "self-hosted", + }, + ({ cleanupDiagnostic, destinationDirectory, staleDirectory }) => { + t.true(fs.existsSync(staleDirectory)); + t.true(fs.existsSync(destinationDirectory)); + t.is(cleanupDiagnostic, undefined); + }, + ); + }, +); + +test.serial( + "downloadCodeQL does not clean up the toolcache when the runner environment is unknown", + async (t) => { + // A runner that doesn't report its environment must be treated as not GitHub-hosted, since its + // toolcache may well outlive the job. + await testToolcacheCleanup( + t, + { + features: [Feature.CleanupToolcacheBundles], + runnerEnvironment: undefined, + }, + ({ cleanupDiagnostic, destinationDirectory, staleDirectory }) => { + t.true(fs.existsSync(staleDirectory)); + t.true(fs.existsSync(destinationDirectory)); + t.is(cleanupDiagnostic, undefined); + }, + ); + }, +); + +test.serial( + "downloadCodeQL deletes other CodeQL bundles from the toolcache when enabled on a GitHub-hosted runner", + async (t) => { + await testToolcacheCleanup( + t, + { + features: [Feature.CleanupToolcacheBundles], + runnerEnvironment: "github-hosted", + }, + ({ cleanupDiagnostic, destinationDirectory, staleDirectory }) => { + t.false( + fs.existsSync(staleDirectory), + "Should delete the version directory, including the `tool-cache` marker file it contains.", + ); + t.false( + fs.existsSync(path.join(destinationDirectory, os.arch(), "contents")), + "Should also delete a partial entry for the version we are about to download, rather " + + "than extracting over it.", + ); + t.deepEqual(cleanupDiagnostic, { + deletedVersions: [CLEANUP_STALE_VERSION, CLEANUP_CLI_VERSION].sort(), + failed: false, + }); + }, + ); + }, +); + +test.serial( + "downloadCodeQL reports no deleted versions when the toolcache has no CodeQL bundles", + async (t) => { + await withTmpDir(async (tmpDir) => { + setupActionsVars(tmpDir, tmpDir); + process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = "github-hosted"; + + // A toolcache with other tools in it, but no CodeQL. + const otherToolDirectory = createToolcacheEntry(tmpDir, "Node", "20.0.0"); + + const cleanupDiagnostic = await runDownloadCodeQL(tmpDir, [ + Feature.CleanupToolcacheBundles, + ]); + + t.true(fs.existsSync(otherToolDirectory)); + t.deepEqual(cleanupDiagnostic, { deletedVersions: [], failed: false }); + }); + }, +); + +test.serial( + "downloadCodeQL continues when deleting a CodeQL bundle from the toolcache fails", + async (t) => { + await withTmpDir(async (tmpDir) => { + setupActionsVars(tmpDir, tmpDir); + process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = "github-hosted"; + + createToolcacheEntry(tmpDir, "CodeQL", CLEANUP_CLI_VERSION); + const staleDirectory = createToolcacheEntry( + tmpDir, + "CodeQL", + CLEANUP_STALE_VERSION, + ); + + const rmStub = sinon + .stub(fs.promises, "rm") + .rejects(new Error("EACCES: permission denied")); + + const cleanupDiagnostic = await runDownloadCodeQL(tmpDir, [ + Feature.CleanupToolcacheBundles, + ]); + + // Restore before `withTmpDir` cleans up after itself. + rmStub.restore(); + + t.true(fs.existsSync(staleDirectory)); + t.deepEqual( + cleanupDiagnostic, + { deletedVersions: [], failed: true }, + "Should not report versions that we failed to delete.", + ); + }); + }, +); + +test.serial( + "deleteToolcacheBundles reports a failure when the toolcache location is unknown", + async (t) => { + delete process.env[ActionsEnvVars.RUNNER_TOOL_CACHE]; + + const result = await toolsDownload.deleteToolcacheBundles( + getRunnerLogger(true), + ); + + t.deepEqual( + result, + { deletedVersions: [], failed: true }, + "Should report a failure rather than throwing, so the download can continue.", + ); + }, +); + +test.serial( + "downloadCodeQL does not follow a symlinked CodeQL toolcache directory", + async (t) => { + await withTmpDir(async (tmpDir) => { + const toolcacheRoot = path.join(tmpDir, "toolcache"); + setupActionsVars(tmpDir, toolcacheRoot); + process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = "github-hosted"; + + // Somewhere the toolcache cleanup must never reach. + const outsideDirectory = path.join(tmpDir, "outside"); + createToolcacheEntry(outsideDirectory, "CodeQL", CLEANUP_STALE_VERSION); + createToolcacheEntry(outsideDirectory, "CodeQL", CLEANUP_CLI_VERSION); + + fs.mkdirSync(toolcacheRoot, { recursive: true }); + fs.symlinkSync( + path.join(outsideDirectory, "CodeQL"), + path.join(toolcacheRoot, "CodeQL"), + ); + + const cleanupDiagnostic = await runDownloadCodeQL(toolcacheRoot, [ + Feature.CleanupToolcacheBundles, + ]); + + t.true( + fs.existsSync( + path.join(outsideDirectory, "CodeQL", CLEANUP_STALE_VERSION), + ), + "Should not delete anything through a symlinked CodeQL directory.", + ); + t.deepEqual(cleanupDiagnostic, { deletedVersions: [], failed: true }); + }); + }, +); + +test.serial( + "downloadCodeQL does not clean up the toolcache once a step has already set up CodeQL", + async (t) => { + // `.github/workflows/codeql.yml` sets up CodeQL twice and then runs both returned paths. If the + // second setup downloads, it must not delete the bundle the first one handed out. + await testToolcacheCleanup( + t, + { + features: [Feature.CleanupToolcacheBundles], + runnerEnvironment: "github-hosted", + setUp: () => { + process.env[EnvVar.HAS_SET_UP_CODEQL] = "true"; + }, + }, + ({ cleanupDiagnostic, destinationDirectory, staleDirectory }) => { + t.true(fs.existsSync(staleDirectory)); + t.true(fs.existsSync(destinationDirectory)); + t.is(cleanupDiagnostic, undefined); + }, + ); + }, +); + +test.serial( + "setupCodeQLBundle records that this job has set up CodeQL", + async (t) => { + await withTmpDir(async (tmpDir) => { + setupActionsVars(tmpDir, tmpDir); + delete process.env[EnvVar.HAS_SET_UP_CODEQL]; + + sinon.stub(setupCodeql, "downloadCodeQL").resolves({ + codeqlFolder: "codeql", + statusReport: { totalDurationMs: 1 }, + toolsVersion: LINKED_CLI_VERSION.cliVersion, + }); + + await setupCodeql.setupCodeQLBundle( + "linked", + SAMPLE_DOTCOM_API_DETAILS, + tmpDir, + GitHubVariant.DOTCOM, + SAMPLE_DEFAULT_CLI_VERSION, + undefined, // rawLanguages + false, // useOverlayAwareDefaultCliVersion + createFeatures([]), + getRunnerLogger(true), + ); + + t.is( + process.env[EnvVar.HAS_SET_UP_CODEQL], + "true", + "A later step must be able to tell that the toolcache is in use.", + ); + }); + }, +); + +test.serial( + "downloadCodeQL cleans up the toolcache even when the download will not be cached", + async (t) => { + // A `tools` URL we can't derive a bundle version from is extracted to a temporary directory + // rather than the toolcache, but the toolcache is on the same filesystem, so emptying it still + // frees up space for the analysis. + await withTmpDir(async (tmpDir) => { + setupActionsVars(tmpDir, tmpDir); + process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = "github-hosted"; + + const staleDirectory = createToolcacheEntry( + tmpDir, + "CodeQL", + CLEANUP_STALE_VERSION, + ); + + const cleanupDiagnostic = await runDownloadCodeQL( + tmpDir, + [Feature.CleanupToolcacheBundles], + undefined, // bundleVersion + ); + + t.false(fs.existsSync(staleDirectory)); + t.deepEqual(cleanupDiagnostic, { + deletedVersions: [CLEANUP_STALE_VERSION], + failed: false, + }); + }); + }, +); + +test.serial( + "downloadCodeQL reports a failure when the toolcache cannot be inspected", + async (t) => { + await withTmpDir(async (tmpDir) => { + setupActionsVars(tmpDir, tmpDir); + process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = "github-hosted"; + + createToolcacheEntry(tmpDir, "CodeQL", CLEANUP_STALE_VERSION); + + const lstatStub = sinon.stub(fs.promises, "lstat").rejects( + Object.assign(new Error("permission denied"), { + code: "EACCES", + }), + ); + + const cleanupDiagnostic = await runDownloadCodeQL(tmpDir, [ + Feature.CleanupToolcacheBundles, + ]); + + lstatStub.restore(); + + t.deepEqual( + cleanupDiagnostic, + { deletedVersions: [], failed: true }, + "An error other than the toolcache being absent must not be reported as success.", + ); + }); + }, +); + +test.serial( + "downloadCodeQL does not clean up a toolcache on a different filesystem to the workspace", + async (t) => { + // Some runner images keep the toolcache on a different volume to the workspace, in which case + // deleting the tools frees up disk space that the analysis cannot use. + await withTmpDir(async (tmpDir) => { + setupActionsVars(tmpDir, tmpDir); + process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = "github-hosted"; + + const staleDirectory = createToolcacheEntry( + tmpDir, + "CodeQL", + CLEANUP_STALE_VERSION, + ); + + sinon + .stub(toolsDownload, "isToolcacheOnWorkspaceFilesystem") + .returns(false); + + const cleanupDiagnostic = await runDownloadCodeQL(tmpDir, [ + Feature.CleanupToolcacheBundles, + ]); + + t.true(fs.existsSync(staleDirectory)); + t.is(cleanupDiagnostic, undefined); + }); + }, +); + +test.serial( + "isToolcacheOnWorkspaceFilesystem assumes a different filesystem when it cannot tell", + async (t) => { + await withTmpDir(async (tmpDir) => { + const logger = getRunnerLogger(true); + + setupActionsVars(tmpDir, tmpDir); + t.true(toolsDownload.isToolcacheOnWorkspaceFilesystem(logger)); + + // If we can't tell, we assume the toolcache is not somewhere we can reclaim space from. + process.env[ActionsEnvVars.RUNNER_TOOL_CACHE] = path.join( + tmpDir, + "does-not-exist", + ); + t.false(toolsDownload.isToolcacheOnWorkspaceFilesystem(logger)); + }); + }, +); + +test.serial( + "downloadCodeQL does not delete through a symlinked version directory", + async (t) => { + await withTmpDir(async (tmpDir) => { + const toolcacheRoot = path.join(tmpDir, "toolcache"); + setupActionsVars(tmpDir, toolcacheRoot); + process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = "github-hosted"; + + createToolcacheEntry(toolcacheRoot, "CodeQL", CLEANUP_STALE_VERSION); + + // Somewhere outside the toolcache that a version directory points at. + const outsideDirectory = path.join(tmpDir, "outside"); + fs.mkdirSync(outsideDirectory, { recursive: true }); + fs.writeFileSync(path.join(outsideDirectory, "contents"), "x"); + fs.symlinkSync( + outsideDirectory, + path.join(toolcacheRoot, "CodeQL", "9.9.9"), + ); + + const cleanupDiagnostic = await runDownloadCodeQL(toolcacheRoot, [ + Feature.CleanupToolcacheBundles, + ]); + + t.true( + fs.existsSync(path.join(outsideDirectory, "contents")), + "Should not delete anything through a symlinked version directory.", + ); + t.deepEqual(cleanupDiagnostic, { + deletedVersions: [CLEANUP_STALE_VERSION], + failed: false, + }); + }); + }, +); diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 9b2f6dc067..3a99e04aab 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -2,14 +2,17 @@ import * as fs from "fs"; import { OutgoingHttpHeaders } from "http"; import * as path from "path"; +import * as core from "@actions/core"; import * as toolcache from "@actions/tool-cache"; import { default as deepEqual } from "fast-deep-equal"; import * as semver from "semver"; import { v4 as uuidV4 } from "uuid"; +import { ActionState } from "./action-common"; import { isAnalyzingPullRequest, isDynamicWorkflow, + isGitHubHostedRunner, isRunningLocalAction, } from "./actions-util"; import * as api from "./api-client"; @@ -19,6 +22,7 @@ import { makeDiagnostic, makeTelemetryDiagnostic, } from "./diagnostics"; +import { EnvVar, getEnv } from "./environment"; import { CODEQL_VERSION_ZSTD_BUNDLE, CodeQLDefaultVersionInfo, @@ -30,8 +34,10 @@ import { Logger } from "./logging"; import { getCodeQlVersionsForOverlayBaseDatabases } from "./overlay/caching"; import * as tar from "./tar"; import { + deleteToolcacheBundles, downloadAndExtract, getToolcacheDirectory, + isToolcacheOnWorkspaceFilesystem, ToolsDownloadStatusReport, writeToolcacheMarkerFile, } from "./tools-download"; @@ -784,6 +790,7 @@ export const downloadCodeQL = async function ( apiDetails: api.GitHubApiDetails, tarVersion: tar.TarVersion | undefined, tempDir: string, + features: FeatureEnablement, logger: Logger, ): Promise<{ codeqlFolder: string; @@ -817,6 +824,8 @@ export const downloadCodeQL = async function ( const extractedBundlePath = toolcacheInfo?.path ?? getTempExtractionDir(tempDir); + await tryDeleteToolcacheBundles({ env: getEnv(), features, logger }); + const statusReport = await downloadAndExtract( codeqlURL, compressionMethod, @@ -869,6 +878,48 @@ function getToolcacheDestinationInfo( return undefined; } +/** + * Reclaims disk space by deleting the CodeQL tools from the toolcache, if enabled. + * + * On GitHub-hosted runners the toolcache shares a filesystem with the workspace, so tools left in + * the toolcache take up space that the analysis could use instead. This holds wherever we extract + * the tools we are obtaining, since the toolcache is on that filesystem either way. + */ +async function tryDeleteToolcacheBundles({ + env, + features, + logger, +}: ActionState<["Logger", "ReadOnlyEnv", "FeatureFlags"]>): Promise { + // A step that has already set up CodeQL may hand out a path into the toolcache that a later step + // runs, so only the first step to set it up can know that nothing else relies on the toolcache. + if (env.getOptional(EnvVar.HAS_SET_UP_CODEQL) !== undefined) { + logger.debug( + "Not deleting the CodeQL tools from the toolcache since a previous step in this job has " + + "already set up CodeQL.", + ); + return; + } + + if ( + !isGitHubHostedRunner() || + !isToolcacheOnWorkspaceFilesystem(logger) || + !(await features.getValue(Feature.CleanupToolcacheBundles)) + ) { + return; + } + + const result = await deleteToolcacheBundles(logger); + + addNoLanguageDiagnostic( + undefined, + makeTelemetryDiagnostic( + "codeql-action/toolcache-bundle-cleanup", + "Toolcache CodeQL bundle cleanup", + { ...result }, + ), + ); +} + export function getCodeQLURLVersion(url: string): string { const match = url.match(/\/codeql-bundle-(.*)\//); if (match === null || match.length < 2) { @@ -978,6 +1029,7 @@ export async function setupCodeQLBundle( apiDetails, zstdAvailability.version, tempDir, + features, logger, ); toolsVersion = result.toolsVersion; @@ -989,6 +1041,11 @@ export async function setupCodeQLBundle( default: util.assertNever(source); } + + // Record that this job now has a copy of the CodeQL tools, so that a later step doesn't delete + // the toolcache out from under the path we are about to return. + core.exportVariable(EnvVar.HAS_SET_UP_CODEQL, "true"); + return { codeqlFolder, toolsDownloadStatusReport, diff --git a/src/tools-download.ts b/src/tools-download.ts index d7a978908b..cf51c213c1 100644 --- a/src/tools-download.ts +++ b/src/tools-download.ts @@ -197,16 +197,153 @@ async function downloadAndExtractZstdWithStreaming( await tar.extractTarZst(response, dest, tarVersion, logger); } -/** Gets the path to the toolcache directory for the specified version of the CodeQL tools. */ -export function getToolcacheDirectory(version: string): string { +/** Gets the path to the toolcache directory that holds all versions of the CodeQL tools. */ +function getToolcacheToolDirectory(): string { return path.join( getRequiredEnvParam("RUNNER_TOOL_CACHE"), TOOLCACHE_TOOL_NAME, - semver.clean(version) || version, + ); +} + +/** Gets the name of the toolcache directory that holds the given version of the CodeQL tools. */ +function getToolcacheVersionDirectoryName(version: string): string { + return semver.clean(version) || version; +} + +/** Gets the path to the toolcache directory for the specified version of the CodeQL tools. */ +export function getToolcacheDirectory(version: string): string { + return path.join( + getToolcacheToolDirectory(), + getToolcacheVersionDirectoryName(version), os.arch() || "", ); } +/** + * Whether the toolcache is on the same filesystem as the workspace, and so whether deleting the + * tools frees up disk space that the analysis can use. + * + * These are separate volumes on some runner images. Windows runners, for example, keep the + * toolcache on `C:` while the workspace is on `D:`. + */ +export function isToolcacheOnWorkspaceFilesystem(logger: Logger): boolean { + try { + return ( + fs.statSync(getRequiredEnvParam("RUNNER_TOOL_CACHE")).dev === + fs.statSync(getRequiredEnvParam("GITHUB_WORKSPACE")).dev + ); + } catch (e) { + logger.debug( + `Could not determine whether the toolcache is on the same filesystem as the workspace: ${getErrorMessage(e)}`, + ); + return false; + } +} + +/** The outcome of trying to reclaim disk space by deleting the CodeQL tools from the toolcache. */ +export interface ToolcacheCleanupResult { + /** The versions of the CodeQL tools that were deleted. */ + deletedVersions: string[]; + /** + * Whether we hit an error while trying to delete the tools. Distinguishes a toolcache that had + * nothing to reclaim from one we failed to clean up. + */ + failed: boolean; +} + +/** + * Deletes every version of the CodeQL tools from the toolcache. + * + * Only safe to call when we are about to download the tools, since that means we did not resolve + * them from the toolcache and so nothing in there is in use by this job. + * + * This only ever touches the CodeQL directory of the toolcache, and is best-effort: any failure is + * logged rather than propagated, since the caller can proceed without the disk space. + * + * @returns the versions that were deleted, and whether we hit an error while trying. + */ +export async function deleteToolcacheBundles( + logger: Logger, +): Promise { + let toolDirectory: string; + + try { + toolDirectory = getToolcacheToolDirectory(); + } catch (e) { + logger.info( + `Unable to reclaim disk space from the toolcache: ${getErrorMessage(e)}`, + ); + return { deletedVersions: [], failed: true }; + } + + try { + // Refuse to follow a symlinked CodeQL directory, so that we can only ever delete paths that are + // really inside the toolcache. + if ((await fs.promises.lstat(toolDirectory)).isSymbolicLink()) { + logger.info( + `Not deleting the CodeQL tools from the toolcache since '${toolDirectory}' is a symlink.`, + ); + return { deletedVersions: [], failed: true }; + } + } catch (e: any) { + if (e?.code === "ENOENT") { + logger.debug( + `There are no CodeQL tools at '${toolDirectory}' to delete from the toolcache.`, + ); + return { deletedVersions: [], failed: false }; + } + logger.info( + `Failed to inspect the CodeQL tools at '${toolDirectory}': ${getErrorMessage(e)}`, + ); + return { deletedVersions: [], failed: true }; + } + + try { + const entries = await fs.promises.readdir(toolDirectory, { + withFileTypes: true, + }); + + const deletedVersions: string[] = []; + let failed = false; + + for (const entry of entries) { + const versionDirectory = path.join(toolDirectory, entry.name); + + // `isDirectory` is false for a symlink, so we never delete a version directory that is + // really somewhere else. + if (!entry.isDirectory()) { + logger.debug( + `Not deleting '${versionDirectory}' from the toolcache since it is not a directory.`, + ); + continue; + } + + try { + await fs.promises.rm(versionDirectory, { + force: true, + recursive: true, + }); + deletedVersions.push(entry.name); + logger.info( + `Deleted the CodeQL tools at '${versionDirectory}' from the toolcache to free up disk space.`, + ); + } catch (e) { + failed = true; + logger.info( + `Failed to delete the CodeQL tools at '${versionDirectory}' from the toolcache: ${getErrorMessage(e)}`, + ); + } + } + + return { deletedVersions: deletedVersions.sort(), failed }; + } catch (e) { + logger.info( + `Failed to read the CodeQL tools at '${toolDirectory}' from the toolcache: ${getErrorMessage(e)}`, + ); + return { deletedVersions: [], failed: true }; + } +} + export function writeToolcacheMarkerFile( extractedPath: string, logger: Logger, diff --git a/src/util.ts b/src/util.ts index 2d910dec3b..f6258b2853 100644 --- a/src/util.ts +++ b/src/util.ts @@ -842,9 +842,13 @@ export async function checkForTimeout() { * directory with the name hostedtoolcache which is present on * GitHub-hosted runners. * - * @returns true iff the runner is hosted by GitHub + * Since this is a heuristic over how the runner happens to be named and laid out, it also matches + * self-hosted runners that are configured to resemble hosted ones. Prefer + * `isGitHubHostedRunner` when you need the answer the Actions service reports. + * + * @returns true iff the runner looks like it is hosted by GitHub */ -export function isHostedRunner() { +export function looksLikeHostedRunner() { return ( // Name of the runner on hosted Windows runners process.env["RUNNER_NAME"]?.includes("Hosted Agent") ||