diff --git a/lib/start-proxy-action.js b/lib/start-proxy-action.js index 13996a08fe..713e45b7c2 100644 --- a/lib/start-proxy-action.js +++ b/lib/start-proxy-action.js @@ -21339,7 +21339,7 @@ var require_core = __commonJS({ exports2.startGroup = startGroup3; exports2.endGroup = endGroup3; exports2.group = group; - exports2.saveState = saveState3; + exports2.saveState = saveState4; exports2.getState = getState2; exports2.getIDToken = getIDToken; var command_1 = require_command(); @@ -21453,7 +21453,7 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); return result; }); } - function saveState3(name, value) { + function saveState4(name, value) { const filePath = process.env["GITHUB_STATE"] || ""; if (filePath) { return (0, file_command_1.issueFileCommand)("STATE", (0, file_command_1.prepareKeyValueMessage)(name, value)); @@ -47449,7 +47449,7 @@ var require_internal_glob_options_helper = __commonJS({ })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getOptions = getOptions; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); function getOptions(copy) { const result = { followSymbolicLinks: true, @@ -47461,23 +47461,23 @@ var require_internal_glob_options_helper = __commonJS({ if (copy) { if (typeof copy.followSymbolicLinks === "boolean") { result.followSymbolicLinks = copy.followSymbolicLinks; - core12.debug(`followSymbolicLinks '${result.followSymbolicLinks}'`); + core13.debug(`followSymbolicLinks '${result.followSymbolicLinks}'`); } if (typeof copy.implicitDescendants === "boolean") { result.implicitDescendants = copy.implicitDescendants; - core12.debug(`implicitDescendants '${result.implicitDescendants}'`); + core13.debug(`implicitDescendants '${result.implicitDescendants}'`); } if (typeof copy.matchDirectories === "boolean") { result.matchDirectories = copy.matchDirectories; - core12.debug(`matchDirectories '${result.matchDirectories}'`); + core13.debug(`matchDirectories '${result.matchDirectories}'`); } if (typeof copy.omitBrokenSymbolicLinks === "boolean") { result.omitBrokenSymbolicLinks = copy.omitBrokenSymbolicLinks; - core12.debug(`omitBrokenSymbolicLinks '${result.omitBrokenSymbolicLinks}'`); + core13.debug(`omitBrokenSymbolicLinks '${result.omitBrokenSymbolicLinks}'`); } if (typeof copy.excludeHiddenFiles === "boolean") { result.excludeHiddenFiles = copy.excludeHiddenFiles; - core12.debug(`excludeHiddenFiles '${result.excludeHiddenFiles}'`); + core13.debug(`excludeHiddenFiles '${result.excludeHiddenFiles}'`); } } return result; @@ -49105,7 +49105,7 @@ var require_internal_globber = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DefaultGlobber = void 0; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); var fs3 = __importStar2(require("fs")); var globOptionsHelper = __importStar2(require_internal_glob_options_helper()); var path5 = __importStar2(require("path")); @@ -49158,7 +49158,7 @@ var require_internal_globber = __commonJS({ } const stack = []; for (const searchPath of patternHelper.getSearchPaths(patterns)) { - core12.debug(`Search path '${searchPath}'`); + core13.debug(`Search path '${searchPath}'`); try { yield __await2(fs3.promises.lstat(searchPath)); } catch (err) { @@ -49233,7 +49233,7 @@ var require_internal_globber = __commonJS({ } catch (err) { if (err.code === "ENOENT") { if (options.omitBrokenSymbolicLinks) { - core12.debug(`Broken symlink '${item.path}'`); + core13.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.`); @@ -49249,7 +49249,7 @@ var require_internal_globber = __commonJS({ traversalChain.pop(); } if (traversalChain.some((x) => x === realPath)) { - core12.debug(`Symlink cycle detected for path '${item.path}' and realpath '${realPath}'`); + core13.debug(`Symlink cycle detected for path '${item.path}' and realpath '${realPath}'`); return void 0; } traversalChain.push(realPath); @@ -49352,7 +49352,7 @@ var require_internal_hash_files = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.hashFiles = hashFiles; var crypto2 = __importStar2(require("crypto")); - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); var fs3 = __importStar2(require("fs")); var stream = __importStar2(require("stream")); var util = __importStar2(require("util")); @@ -49361,7 +49361,7 @@ var require_internal_hash_files = __commonJS({ return __awaiter2(this, arguments, void 0, function* (globber, currentWorkspace, verbose = false) { var _a, e_1, _b, _c; var _d; - const writeDelegate = verbose ? core12.info : core12.debug; + const writeDelegate = verbose ? core13.info : core13.debug; let hasMatch = false; const githubWorkspace = currentWorkspace ? currentWorkspace : (_d = process.env["GITHUB_WORKSPACE"]) !== null && _d !== void 0 ? _d : process.cwd(); const result = crypto2.createHash("sha256"); @@ -50752,7 +50752,7 @@ var require_cacheUtils = __commonJS({ exports2.assertDefined = assertDefined; exports2.getCacheVersion = getCacheVersion; exports2.getRuntimeToken = getRuntimeToken; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); var exec3 = __importStar2(require_exec()); var glob = __importStar2(require_glob()); var io5 = __importStar2(require_io()); @@ -50803,7 +50803,7 @@ var require_cacheUtils = __commonJS({ _e = false; const file = _c; const relativeFile = path5.relative(workspace, file).replace(new RegExp(`\\${path5.sep}`, "g"), "/"); - core12.debug(`Matched: ${relativeFile}`); + core13.debug(`Matched: ${relativeFile}`); if (relativeFile === "") { paths.push("."); } else { @@ -50831,7 +50831,7 @@ var require_cacheUtils = __commonJS({ return __awaiter2(this, arguments, void 0, function* (app, additionalArgs = []) { let versionOutput = ""; additionalArgs.push("--version"); - core12.debug(`Checking ${app} ${additionalArgs.join(" ")}`); + core13.debug(`Checking ${app} ${additionalArgs.join(" ")}`); try { yield exec3.exec(`${app}`, additionalArgs, { ignoreReturnCode: true, @@ -50842,10 +50842,10 @@ var require_cacheUtils = __commonJS({ } }); } catch (err) { - core12.debug(err.message); + core13.debug(err.message); } versionOutput = versionOutput.trim(); - core12.debug(versionOutput); + core13.debug(versionOutput); return versionOutput; }); } @@ -50853,7 +50853,7 @@ var require_cacheUtils = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); const version = semver6.clean(versionOutput); - core12.debug(`zstd version: ${version}`); + core13.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; } else { @@ -90509,7 +90509,7 @@ var require_uploadUtils = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.UploadProgress = void 0; exports2.uploadCacheArchiveSDK = uploadCacheArchiveSDK; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); var storage_blob_1 = require_commonjs15(); var errors_1 = require_errors3(); var UploadProgress = class { @@ -90551,7 +90551,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); - core12.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`); + core13.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`); if (this.isDone()) { this.displayedComplete = true; } @@ -90608,14 +90608,14 @@ var require_uploadUtils = __commonJS({ }; try { uploadProgress.startDisplayTimer(); - core12.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`); + core13.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) { - core12.warning(`uploadCacheArchiveSDK: internal error uploading cache archive: ${error3.message}`); + core13.warning(`uploadCacheArchiveSDK: internal error uploading cache archive: ${error3.message}`); throw error3; } finally { uploadProgress.stopDisplayTimer(); @@ -90700,7 +90700,7 @@ var require_requestUtils = __commonJS({ exports2.retry = retry2; exports2.retryTypedResponse = retryTypedResponse; exports2.retryHttpClientResponse = retryHttpClientResponse; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); var http_client_1 = require_lib(); var constants_1 = require_constants12(); function isSuccessStatusCode(statusCode) { @@ -90758,9 +90758,9 @@ var require_requestUtils = __commonJS({ isRetryable = isRetryableStatusCode(statusCode); errorMessage = `Cache service responded with ${statusCode}`; } - core12.debug(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); + core13.debug(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); if (!isRetryable) { - core12.debug(`${name} - Error is not retryable`); + core13.debug(`${name} - Error is not retryable`); break; } yield sleep(delay2); @@ -91019,7 +91019,7 @@ var require_downloadUtils = __commonJS({ exports2.downloadCacheHttpClient = downloadCacheHttpClient; exports2.downloadCacheHttpClientConcurrent = downloadCacheHttpClientConcurrent; exports2.downloadCacheStorageSDK = downloadCacheStorageSDK; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); var http_client_1 = require_lib(); var storage_blob_1 = require_commonjs15(); var buffer = __importStar2(require("buffer")); @@ -91057,7 +91057,7 @@ var require_downloadUtils = __commonJS({ this.segmentIndex = this.segmentIndex + 1; this.segmentSize = segmentSize; this.receivedBytes = 0; - core12.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`); + core13.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`); } /** * Sets the number of bytes received for the current segment. @@ -91091,7 +91091,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); - core12.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`); + core13.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`); if (this.isDone()) { this.displayedComplete = true; } @@ -91141,7 +91141,7 @@ var require_downloadUtils = __commonJS({ })); downloadResponse.message.socket.setTimeout(constants_1.SocketTimeout, () => { downloadResponse.message.destroy(); - core12.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`); + core13.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`); }); yield pipeResponseToStream(downloadResponse, writeStream); const contentLengthHeader = downloadResponse.message.headers["content-length"]; @@ -91152,7 +91152,7 @@ var require_downloadUtils = __commonJS({ throw new Error(`Incomplete download. Expected file size: ${expectedLength}, actual file size: ${actualLength}`); } } else { - core12.debug("Unable to validate download, no Content-Length header"); + core13.debug("Unable to validate download, no Content-Length header"); } }); } @@ -91270,7 +91270,7 @@ var require_downloadUtils = __commonJS({ const properties = yield client.getProperties(); const contentLength = (_a = properties.contentLength) !== null && _a !== void 0 ? _a : -1; if (contentLength < 0) { - core12.debug("Unable to determine content length, downloading file with http-client..."); + core13.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); @@ -91360,7 +91360,7 @@ var require_options = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getUploadOptions = getUploadOptions; exports2.getDownloadOptions = getDownloadOptions; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); function getUploadOptions(copy) { const result = { useAzureSdk: false, @@ -91380,9 +91380,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; - core12.debug(`Use Azure SDK: ${result.useAzureSdk}`); - core12.debug(`Upload concurrency: ${result.uploadConcurrency}`); - core12.debug(`Upload chunk size: ${result.uploadChunkSize}`); + core13.debug(`Use Azure SDK: ${result.useAzureSdk}`); + core13.debug(`Upload concurrency: ${result.uploadConcurrency}`); + core13.debug(`Upload chunk size: ${result.uploadChunkSize}`); return result; } function getDownloadOptions(copy) { @@ -91418,12 +91418,12 @@ var require_options = __commonJS({ if (segmentDownloadTimeoutMins && !isNaN(Number(segmentDownloadTimeoutMins)) && isFinite(Number(segmentDownloadTimeoutMins))) { result.segmentTimeoutInMs = Number(segmentDownloadTimeoutMins) * 60 * 1e3; } - core12.debug(`Use Azure SDK: ${result.useAzureSdk}`); - core12.debug(`Download concurrency: ${result.downloadConcurrency}`); - core12.debug(`Request timeout (ms): ${result.timeoutInMs}`); - core12.debug(`Cache segment download timeout mins env var: ${process.env["SEGMENT_DOWNLOAD_TIMEOUT_MINS"]}`); - core12.debug(`Segment download timeout (ms): ${result.segmentTimeoutInMs}`); - core12.debug(`Lookup only: ${result.lookupOnly}`); + core13.debug(`Use Azure SDK: ${result.useAzureSdk}`); + core13.debug(`Download concurrency: ${result.downloadConcurrency}`); + core13.debug(`Request timeout (ms): ${result.timeoutInMs}`); + core13.debug(`Cache segment download timeout mins env var: ${process.env["SEGMENT_DOWNLOAD_TIMEOUT_MINS"]}`); + core13.debug(`Segment download timeout (ms): ${result.segmentTimeoutInMs}`); + core13.debug(`Lookup only: ${result.lookupOnly}`); return result; } } @@ -91617,7 +91617,7 @@ var require_cacheHttpClient = __commonJS({ exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; exports2.saveCache = saveCache4; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); var fs3 = __importStar2(require("fs")); @@ -91635,7 +91635,7 @@ var require_cacheHttpClient = __commonJS({ throw new Error("Cache Service Url not found, unable to restore cache."); } const url = `${baseUrl}_apis/artifactcache/${resource}`; - core12.debug(`Resource Url: ${url}`); + core13.debug(`Resource Url: ${url}`); return url; } function createAcceptHeader(type2, apiVersion) { @@ -91663,7 +91663,7 @@ var require_cacheHttpClient = __commonJS({ return httpClient.getJson(getCacheApiUrl(resource)); })); if (response.statusCode === 204) { - if (core12.isDebug()) { + if (core13.isDebug()) { yield printCachesListForDiagnostics(keys[0], httpClient, version); } return null; @@ -91676,9 +91676,9 @@ var require_cacheHttpClient = __commonJS({ if (!cacheDownloadUrl) { throw new Error("Cache not found."); } - core12.setSecret(cacheDownloadUrl); - core12.debug(`Cache Result:`); - core12.debug(JSON.stringify(cacheResult)); + core13.setSecret(cacheDownloadUrl); + core13.debug(`Cache Result:`); + core13.debug(JSON.stringify(cacheResult)); return cacheResult; }); } @@ -91692,10 +91692,10 @@ var require_cacheHttpClient = __commonJS({ const cacheListResult = response.result; const totalCount = cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.totalCount; if (totalCount && totalCount > 0) { - core12.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 + core13.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) || []) { - core12.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}`); + core13.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}`); } } } @@ -91738,7 +91738,7 @@ Other caches with similar key:`); } function uploadChunk(httpClient, resourceUrl, openStream, start, end) { return __awaiter2(this, void 0, void 0, function* () { - core12.debug(`Uploading chunk of size ${end - start + 1} bytes at offset ${start} with content range: ${getContentRange(start, end)}`); + core13.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) @@ -91760,7 +91760,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()]; - core12.debug("Awaiting all uploads"); + core13.debug("Awaiting all uploads"); let offset = 0; try { yield Promise.all(parallelUploads.map(() => __awaiter2(this, void 0, void 0, function* () { @@ -91803,16 +91803,16 @@ Other caches with similar key:`); yield (0, uploadUtils_1.uploadCacheArchiveSDK)(signedUploadURL, archivePath, options); } else { const httpClient = createHttpClient(); - core12.debug("Upload cache"); + core13.debug("Upload cache"); yield uploadFile(httpClient, cacheId, archivePath, options); - core12.debug("Commiting cache"); + core13.debug("Commiting cache"); const cacheSize = utils.getArchiveFileSizeInBytes(archivePath); - core12.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`); + core13.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.`); } - core12.info("Cache saved successfully"); + core13.info("Cache saved successfully"); } }); } @@ -97295,7 +97295,7 @@ var require_cache5 = __commonJS({ exports2.isFeatureAvailable = isFeatureAvailable; exports2.restoreCache = restoreCache4; exports2.saveCache = saveCache4; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); var path5 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); var cacheHttpClient = __importStar2(require_cacheHttpClient()); @@ -97354,7 +97354,7 @@ var require_cache5 = __commonJS({ function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); - core12.debug(`Cache service version: ${cacheServiceVersion}`); + core13.debug(`Cache service version: ${cacheServiceVersion}`); checkPaths(paths); switch (cacheServiceVersion) { case "v2": @@ -97369,8 +97369,8 @@ var require_cache5 = __commonJS({ return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { restoreKeys = restoreKeys || []; const keys = [primaryKey, ...restoreKeys]; - core12.debug("Resolved Keys:"); - core12.debug(JSON.stringify(keys)); + core13.debug("Resolved Keys:"); + core13.debug(JSON.stringify(keys)); if (keys.length > 10) { throw new ValidationError(`Key Validation Error: Keys are limited to a maximum of 10.`); } @@ -97388,19 +97388,19 @@ var require_cache5 = __commonJS({ return void 0; } if (options === null || options === void 0 ? void 0 : options.lookupOnly) { - core12.info("Lookup only - skipping download"); + core13.info("Lookup only - skipping download"); return cacheEntry.cacheKey; } archivePath = path5.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); - core12.debug(`Archive Path: ${archivePath}`); + core13.debug(`Archive Path: ${archivePath}`); yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options); - if (core12.isDebug()) { + if (core13.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core12.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); + core13.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); yield (0, tar_1.extractTar)(archivePath, compressionMethod); - core12.info("Cache restored successfully"); + core13.info("Cache restored successfully"); return cacheEntry.cacheKey; } catch (error3) { const typedError = error3; @@ -97408,16 +97408,16 @@ var require_cache5 = __commonJS({ throw error3; } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core12.error(`Failed to restore: ${error3.message}`); + core13.error(`Failed to restore: ${error3.message}`); } else { - core12.warning(`Failed to restore: ${error3.message}`); + core13.warning(`Failed to restore: ${error3.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core12.debug(`Failed to delete archive: ${error3}`); + core13.debug(`Failed to delete archive: ${error3}`); } } return void 0; @@ -97428,8 +97428,8 @@ var require_cache5 = __commonJS({ options = Object.assign(Object.assign({}, options), { useAzureSdk: true }); restoreKeys = restoreKeys || []; const keys = [primaryKey, ...restoreKeys]; - core12.debug("Resolved Keys:"); - core12.debug(JSON.stringify(keys)); + core13.debug("Resolved Keys:"); + core13.debug(JSON.stringify(keys)); if (keys.length > 10) { throw new ValidationError(`Key Validation Error: Keys are limited to a maximum of 10.`); } @@ -97447,30 +97447,30 @@ var require_cache5 = __commonJS({ }; const response = yield twirpClient.GetCacheEntryDownloadURL(request3); if (!response.ok) { - core12.debug(`Cache not found for version ${request3.version} of keys: ${keys.join(", ")}`); + core13.debug(`Cache not found for version ${request3.version} of keys: ${keys.join(", ")}`); return void 0; } const isRestoreKeyMatch = request3.key !== response.matchedKey; if (isRestoreKeyMatch) { - core12.info(`Cache hit for restore-key: ${response.matchedKey}`); + core13.info(`Cache hit for restore-key: ${response.matchedKey}`); } else { - core12.info(`Cache hit for: ${response.matchedKey}`); + core13.info(`Cache hit for: ${response.matchedKey}`); } if (options === null || options === void 0 ? void 0 : options.lookupOnly) { - core12.info("Lookup only - skipping download"); + core13.info("Lookup only - skipping download"); return response.matchedKey; } archivePath = path5.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); - core12.debug(`Archive path: ${archivePath}`); - core12.debug(`Starting download of archive to: ${archivePath}`); + core13.debug(`Archive path: ${archivePath}`); + core13.debug(`Starting download of archive to: ${archivePath}`); yield cacheHttpClient.downloadCache(response.signedDownloadUrl, archivePath, options); const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core12.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); - if (core12.isDebug()) { + core13.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); + if (core13.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } yield (0, tar_1.extractTar)(archivePath, compressionMethod); - core12.info("Cache restored successfully"); + core13.info("Cache restored successfully"); return response.matchedKey; } catch (error3) { const typedError = error3; @@ -97478,9 +97478,9 @@ var require_cache5 = __commonJS({ throw error3; } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core12.error(`Failed to restore: ${error3.message}`); + core13.error(`Failed to restore: ${error3.message}`); } else { - core12.warning(`Failed to restore: ${error3.message}`); + core13.warning(`Failed to restore: ${error3.message}`); } } } finally { @@ -97489,7 +97489,7 @@ var require_cache5 = __commonJS({ yield utils.unlinkFile(archivePath); } } catch (error3) { - core12.debug(`Failed to delete archive: ${error3}`); + core13.debug(`Failed to delete archive: ${error3}`); } } return void 0; @@ -97498,7 +97498,7 @@ var require_cache5 = __commonJS({ function saveCache4(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); - core12.debug(`Cache service version: ${cacheServiceVersion}`); + core13.debug(`Cache service version: ${cacheServiceVersion}`); checkPaths(paths); checkKey(key); switch (cacheServiceVersion) { @@ -97516,26 +97516,26 @@ var require_cache5 = __commonJS({ const compressionMethod = yield utils.getCompressionMethod(); let cacheId = -1; const cachePaths = yield utils.resolvePaths(paths); - core12.debug("Cache Paths:"); - core12.debug(`${JSON.stringify(cachePaths)}`); + core13.debug("Cache Paths:"); + core13.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 = path5.join(archiveFolder, utils.getCacheFileName(compressionMethod)); - core12.debug(`Archive Path: ${archivePath}`); + core13.debug(`Archive Path: ${archivePath}`); try { yield (0, tar_1.createTar)(archiveFolder, cachePaths, compressionMethod); - if (core12.isDebug()) { + if (core13.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const fileSizeLimit = 10 * 1024 * 1024 * 1024; const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core12.debug(`File Size: ${archiveFileSize}`); + core13.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.`); } - core12.debug("Reserving Cache"); + core13.debug("Reserving Cache"); const reserveCacheResponse = yield cacheHttpClient.reserveCache(key, paths, { compressionMethod, enableCrossOsArchive, @@ -97548,26 +97548,26 @@ var require_cache5 = __commonJS({ } else { throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${(_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message}`); } - core12.debug(`Saving Cache (ID: ${cacheId})`); + core13.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 === ReserveCacheError.name) { - core12.info(`Failed to save: ${typedError.message}`); + core13.info(`Failed to save: ${typedError.message}`); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core12.error(`Failed to save: ${typedError.message}`); + core13.error(`Failed to save: ${typedError.message}`); } else { - core12.warning(`Failed to save: ${typedError.message}`); + core13.warning(`Failed to save: ${typedError.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core12.debug(`Failed to delete archive: ${error3}`); + core13.debug(`Failed to delete archive: ${error3}`); } } return cacheId; @@ -97580,23 +97580,23 @@ var require_cache5 = __commonJS({ const twirpClient = cacheTwirpClient.internalCacheTwirpClient(); let cacheId = -1; const cachePaths = yield utils.resolvePaths(paths); - core12.debug("Cache Paths:"); - core12.debug(`${JSON.stringify(cachePaths)}`); + core13.debug("Cache Paths:"); + core13.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 = path5.join(archiveFolder, utils.getCacheFileName(compressionMethod)); - core12.debug(`Archive Path: ${archivePath}`); + core13.debug(`Archive Path: ${archivePath}`); try { yield (0, tar_1.createTar)(archiveFolder, cachePaths, compressionMethod); - if (core12.isDebug()) { + if (core13.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core12.debug(`File Size: ${archiveFileSize}`); + core13.debug(`File Size: ${archiveFileSize}`); options.archiveSizeBytes = archiveFileSize; - core12.debug("Reserving Cache"); + core13.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); const request3 = { key, @@ -97607,16 +97607,16 @@ var require_cache5 = __commonJS({ const response = yield twirpClient.CreateCacheEntry(request3); if (!response.ok) { if (response.message) { - core12.warning(`Cache reservation failed: ${response.message}`); + core13.warning(`Cache reservation failed: ${response.message}`); } throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error3) { - core12.debug(`Failed to reserve cache: ${error3}`); + core13.debug(`Failed to reserve cache: ${error3}`); throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache.`); } - core12.debug(`Attempting to upload cache located at: ${archivePath}`); + core13.debug(`Attempting to upload cache located at: ${archivePath}`); yield cacheHttpClient.saveCache(cacheId, archivePath, signedUploadUrl, options); const finalizeRequest = { key, @@ -97624,7 +97624,7 @@ var require_cache5 = __commonJS({ sizeBytes: `${archiveFileSize}` }; const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); - core12.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); + core13.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { if (finalizeResponse.message) { throw new FinalizeCacheError(finalizeResponse.message); @@ -97637,21 +97637,21 @@ var require_cache5 = __commonJS({ if (typedError.name === ValidationError.name) { throw error3; } else if (typedError.name === ReserveCacheError.name) { - core12.info(`Failed to save: ${typedError.message}`); + core13.info(`Failed to save: ${typedError.message}`); } else if (typedError.name === FinalizeCacheError.name) { - core12.warning(typedError.message); + core13.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core12.error(`Failed to save: ${typedError.message}`); + core13.error(`Failed to save: ${typedError.message}`); } else { - core12.warning(`Failed to save: ${typedError.message}`); + core13.warning(`Failed to save: ${typedError.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core12.debug(`Failed to delete archive: ${error3}`); + core13.debug(`Failed to delete archive: ${error3}`); } } return cacheId; @@ -97878,7 +97878,7 @@ var require_retry_helper = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RetryHelper = void 0; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); var RetryHelper = class { constructor(maxAttempts, minSeconds, maxSeconds) { if (maxAttempts < 1) { @@ -97901,10 +97901,10 @@ var require_retry_helper = __commonJS({ if (isRetryable && !isRetryable(err)) { throw err; } - core12.info(err.message); + core13.info(err.message); } const seconds = this.getSleepAmount(); - core12.info(`Waiting ${seconds} seconds before trying again`); + core13.info(`Waiting ${seconds} seconds before trying again`); yield this.sleep(seconds); attempt++; } @@ -98007,7 +98007,7 @@ var require_tool_cache = __commonJS({ exports2.findFromManifest = findFromManifest; exports2.isExplicitVersion = isExplicitVersion; exports2.evaluateVersions = evaluateVersions; - var core12 = __importStar2(require_core()); + var core13 = __importStar2(require_core()); var io5 = __importStar2(require_io()); var crypto2 = __importStar2(require("crypto")); var fs3 = __importStar2(require("fs")); @@ -98036,8 +98036,8 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { dest = dest || path5.join(_getTempDirectory(), crypto2.randomUUID()); yield io5.mkdirP(path5.dirname(dest)); - core12.debug(`Downloading ${url}`); - core12.debug(`Destination ${dest}`); + core13.debug(`Downloading ${url}`); + core13.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); @@ -98063,7 +98063,7 @@ var require_tool_cache = __commonJS({ allowRetries: false }); if (auth2) { - core12.debug("set auth"); + core13.debug("set auth"); if (headers === void 0) { headers = {}; } @@ -98072,7 +98072,7 @@ var require_tool_cache = __commonJS({ const response = yield http.get(url, headers); if (response.message.statusCode !== 200) { const err = new HTTPError2(response.message.statusCode); - core12.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); + core13.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); throw err; } const pipeline = util.promisify(stream.pipeline); @@ -98081,16 +98081,16 @@ var require_tool_cache = __commonJS({ let succeeded = false; try { yield pipeline(readStream, fs3.createWriteStream(dest)); - core12.debug("download complete"); + core13.debug("download complete"); succeeded = true; return dest; } finally { if (!succeeded) { - core12.debug("download failed"); + core13.debug("download failed"); try { yield io5.rmRF(dest); } catch (err) { - core12.debug(`Failed to delete '${dest}'. ${err.message}`); + core13.debug(`Failed to delete '${dest}'. ${err.message}`); } } } @@ -98105,7 +98105,7 @@ var require_tool_cache = __commonJS({ process.chdir(dest); if (_7zPath) { try { - const logLevel = core12.isDebug() ? "-bb1" : "-bb0"; + const logLevel = core13.isDebug() ? "-bb1" : "-bb0"; const args = [ "x", // eXtract files with full paths @@ -98158,7 +98158,7 @@ var require_tool_cache = __commonJS({ throw new Error("parameter 'file' is required"); } dest = yield _createExtractFolder(dest); - core12.debug("Checking tar --version"); + core13.debug("Checking tar --version"); let versionOutput = ""; yield (0, exec_1.exec)("tar --version", [], { ignoreReturnCode: true, @@ -98168,7 +98168,7 @@ var require_tool_cache = __commonJS({ stderr: (data) => versionOutput += data.toString() } }); - core12.debug(versionOutput.trim()); + core13.debug(versionOutput.trim()); const isGnuTar = versionOutput.toUpperCase().includes("GNU TAR"); let args; if (flags instanceof Array) { @@ -98176,7 +98176,7 @@ var require_tool_cache = __commonJS({ } else { args = [flags]; } - if (core12.isDebug() && !flags.includes("v")) { + if (core13.isDebug() && !flags.includes("v")) { args.push("-v"); } let destArg = dest; @@ -98207,7 +98207,7 @@ var require_tool_cache = __commonJS({ args = [flags]; } args.push("-x", "-C", dest, "-f", file); - if (core12.isDebug()) { + if (core13.isDebug()) { args.push("-v"); } const xarPath = yield io5.which("xar", true); @@ -98250,7 +98250,7 @@ var require_tool_cache = __commonJS({ "-Command", pwshCommand ]; - core12.debug(`Using pwsh at path: ${pwshPath}`); + core13.debug(`Using pwsh at path: ${pwshPath}`); yield (0, exec_1.exec)(`"${pwshPath}"`, args); } else { const powershellCommand = [ @@ -98270,7 +98270,7 @@ var require_tool_cache = __commonJS({ powershellCommand ]; const powershellPath = yield io5.which("powershell", true); - core12.debug(`Using powershell at path: ${powershellPath}`); + core13.debug(`Using powershell at path: ${powershellPath}`); yield (0, exec_1.exec)(`"${powershellPath}"`, args); } }); @@ -98279,7 +98279,7 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { const unzipPath = yield io5.which("unzip", true); const args = [file]; - if (!core12.isDebug()) { + if (!core13.isDebug()) { args.unshift("-q"); } args.unshift("-o"); @@ -98290,8 +98290,8 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { version = semver6.clean(version) || version; arch = arch || os2.arch(); - core12.debug(`Caching tool ${tool} ${version} ${arch}`); - core12.debug(`source dir: ${sourceDir}`); + core13.debug(`Caching tool ${tool} ${version} ${arch}`); + core13.debug(`source dir: ${sourceDir}`); if (!fs3.statSync(sourceDir).isDirectory()) { throw new Error("sourceDir is not a directory"); } @@ -98308,14 +98308,14 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { version = semver6.clean(version) || version; arch = arch || os2.arch(); - core12.debug(`Caching tool ${tool} ${version} ${arch}`); - core12.debug(`source file: ${sourceFile}`); + core13.debug(`Caching tool ${tool} ${version} ${arch}`); + core13.debug(`source file: ${sourceFile}`); if (!fs3.statSync(sourceFile).isFile()) { throw new Error("sourceFile is not a file"); } const destFolder = yield _createToolPath(tool, version, arch); const destPath = path5.join(destFolder, targetFile); - core12.debug(`destination file ${destPath}`); + core13.debug(`destination file ${destPath}`); yield io5.cp(sourceFile, destPath); _completeToolPath(tool, version, arch); return destFolder; @@ -98338,12 +98338,12 @@ var require_tool_cache = __commonJS({ if (versionSpec) { versionSpec = semver6.clean(versionSpec) || ""; const cachePath = path5.join(_getCacheDirectory(), toolName, versionSpec, arch); - core12.debug(`checking cache: ${cachePath}`); + core13.debug(`checking cache: ${cachePath}`); if (fs3.existsSync(cachePath) && fs3.existsSync(`${cachePath}.complete`)) { - core12.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); + core13.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); toolPath = cachePath; } else { - core12.debug("not found"); + core13.debug("not found"); } } return toolPath; @@ -98372,7 +98372,7 @@ var require_tool_cache = __commonJS({ const http = new httpm.HttpClient("tool-cache"); const headers = {}; if (auth2) { - core12.debug("set auth"); + core13.debug("set auth"); headers.authorization = auth2; } const response = yield http.getJson(treeUrl, headers); @@ -98393,7 +98393,7 @@ var require_tool_cache = __commonJS({ try { releases = JSON.parse(versionsRaw); } catch (_a) { - core12.debug("Invalid json"); + core13.debug("Invalid json"); } } return releases; @@ -98417,7 +98417,7 @@ var require_tool_cache = __commonJS({ function _createToolPath(tool, version, arch) { return __awaiter2(this, void 0, void 0, function* () { const folderPath = path5.join(_getCacheDirectory(), tool, semver6.clean(version) || version, arch || ""); - core12.debug(`destination ${folderPath}`); + core13.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io5.rmRF(folderPath); yield io5.rmRF(markerPath); @@ -98429,18 +98429,18 @@ var require_tool_cache = __commonJS({ const folderPath = path5.join(_getCacheDirectory(), tool, semver6.clean(version) || version, arch || ""); const markerPath = `${folderPath}.complete`; fs3.writeFileSync(markerPath, ""); - core12.debug("finished caching tool"); + core13.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { const c = semver6.clean(versionSpec) || ""; - core12.debug(`isExplicit: ${c}`); + core13.debug(`isExplicit: ${c}`); const valid2 = semver6.valid(c) != null; - core12.debug(`explicit? ${valid2}`); + core13.debug(`explicit? ${valid2}`); return valid2; } function evaluateVersions(versions, versionSpec) { let version = ""; - core12.debug(`evaluating ${versions.length} versions`); + core13.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { if (semver6.gt(a, b)) { return 1; @@ -98456,9 +98456,9 @@ var require_tool_cache = __commonJS({ } } if (version) { - core12.debug(`matched: ${version}`); + core13.debug(`matched: ${version}`); } else { - core12.debug("match not found"); + core13.debug("match not found"); } return version; } @@ -117564,9 +117564,8 @@ var require_lib3 = __commonJS({ }); // src/start-proxy-action.ts -var import_child_process = require("child_process"); var path4 = __toESM(require("path")); -var core11 = __toESM(require_core()); +var core12 = __toESM(require_core()); // src/actions-util.ts var core4 = __toESM(require_core()); @@ -122156,6 +122155,75 @@ async function checkProxyEnvironment(logger, language) { } } +// src/start-proxy/launcher.ts +var import_child_process = require("child_process"); +var core11 = __toESM(require_core()); +var MAX_START_PROXY_ATTEMPTS = 5; +var PROXY_STARTUP_DELAY_MS = 1e3; +var EPHEMERAL_PORT_MIN = 49152; +var EPHEMERAL_PORT_MAX = 65535; +function getRandomEphemeralPort() { + return Math.floor( + Math.random() * (EPHEMERAL_PORT_MAX - EPHEMERAL_PORT_MIN) + EPHEMERAL_PORT_MIN + ); +} +async function startProxy(binPath, config, logFilePath, logger, spawn = import_child_process.spawn) { + const host = "127.0.0.1"; + let port = EPHEMERAL_PORT_MIN; + let subprocess = void 0; + let tries = MAX_START_PROXY_ATTEMPTS; + let subprocessError = void 0; + let lastExitCode; + while (tries-- > 0 && !subprocess && !subprocessError) { + subprocess = spawn( + binPath, + ["-addr", `${host}:${port}`, "-config", "-", "-logfile", logFilePath], + { + detached: true, + stdio: ["pipe", "ignore", "ignore"] + } + ); + subprocess.unref(); + if (subprocess.pid) { + core11.saveState("proxy-process-pid", `${subprocess.pid}`); + } + subprocess.on("error", (error3) => { + subprocessError = error3; + subprocess = void 0; + }); + subprocess.on("exit", (code) => { + lastExitCode = code; + port = getRandomEphemeralPort(); + subprocess = void 0; + }); + subprocess.stdin?.write(JSON.stringify(config)); + subprocess.stdin?.end(); + await delay(PROXY_STARTUP_DELAY_MS); + if (subprocess?.exitCode !== null && subprocess?.exitCode !== void 0) { + lastExitCode = subprocess.exitCode; + port = getRandomEphemeralPort(); + subprocess = void 0; + } + } + if (subprocessError) { + throw subprocessError; + } + if (!subprocess) { + const baseMessage = `Failed to start proxy after ${MAX_START_PROXY_ATTEMPTS} attempts` + (lastExitCode !== void 0 && lastExitCode !== null ? ` (last exit code: ${lastExitCode})` : "") + "."; + throw new Error(baseMessage); + } + logger.info(`Proxy started on ${host}:${port}`); + core11.setOutput("proxy_host", host); + core11.setOutput("proxy_port", port.toString()); + core11.setOutput("proxy_ca_certificate", config.ca.cert); + const registryUrls = config.all_credentials.filter((credential) => credential.url !== void 0).map((credential) => ({ + type: credential.type, + url: credential.url + })); + core11.setOutput("proxy_urls", JSON.stringify(registryUrls)); + return { host, port, cert: config.ca.cert, registries: registryUrls }; +} + // src/start-proxy/reachability.ts var https = __toESM(require("https")); var import_https_proxy_agent = __toESM(require_dist2()); @@ -122251,7 +122319,7 @@ async function run(startedAt) { persistInputs(); const tempDir = getTemporaryDirectory(); const proxyLogFilePath = path4.resolve(tempDir, "proxy.log"); - core11.saveState("proxy-log-file", proxyLogFilePath); + core12.saveState("proxy-log-file", proxyLogFilePath); const repositoryNwo = getRepositoryNwo(); const gitHubVersion = await getGitHubVersion(); features = initFeatures( @@ -122276,7 +122344,7 @@ async function run(startedAt) { `Credentials loaded for the following registries: ${credentials.map((c) => credentialToStr(c)).join("\n")}` ); - if (core11.isDebug() || isInTestMode()) { + if (core12.isDebug() || isInTestMode()) { try { await checkProxyEnvironment(logger, language); } catch (err) { @@ -122316,7 +122384,7 @@ async function runWrapper() { try { await run(startedAt); } catch (error3) { - core11.setFailed(`start-proxy action failed: ${getErrorMessage(error3)}`); + core12.setFailed(`start-proxy action failed: ${getErrorMessage(error3)}`); await sendUnhandledErrorStatusReport( "start-proxy" /* StartProxy */, startedAt, @@ -122325,52 +122393,6 @@ async function runWrapper() { ); } } -async function startProxy(binPath, config, logFilePath, logger) { - const host = "127.0.0.1"; - let port = 49152; - let subprocess = void 0; - let tries = 5; - let subprocessError = void 0; - while (tries-- > 0 && !subprocess && !subprocessError) { - subprocess = (0, import_child_process.spawn)( - binPath, - ["-addr", `${host}:${port}`, "-config", "-", "-logfile", logFilePath], - { - detached: true, - stdio: ["pipe", "ignore", "ignore"] - } - ); - subprocess.unref(); - if (subprocess.pid) { - core11.saveState("proxy-process-pid", `${subprocess.pid}`); - } - subprocess.on("error", (error3) => { - subprocessError = error3; - }); - subprocess.on("exit", (code) => { - if (code !== 0) { - port = Math.floor(Math.random() * (65535 - 49152) + 49152); - subprocess = void 0; - } - }); - subprocess.stdin?.write(JSON.stringify(config)); - subprocess.stdin?.end(); - await delay(1e3); - } - if (subprocessError) { - throw subprocessError; - } - logger.info(`Proxy started on ${host}:${port}`); - core11.setOutput("proxy_host", host); - core11.setOutput("proxy_port", port.toString()); - core11.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 - })); - core11.setOutput("proxy_urls", JSON.stringify(registry_urls)); - return { host, port, cert: config.ca.cert, registries: registry_urls }; -} void runWrapper(); /*! Bundled license information: diff --git a/src/start-proxy-action.ts b/src/start-proxy-action.ts index 438d565ae8..6f30c3f7f8 100644 --- a/src/start-proxy-action.ts +++ b/src/start-proxy-action.ts @@ -1,4 +1,3 @@ -import { ChildProcess, spawn } from "child_process"; import * as path from "path"; import * as core from "@actions/core"; @@ -7,7 +6,7 @@ import * as actionsUtil from "./actions-util"; import { getGitHubVersion } from "./api-client"; import { FeatureEnablement, initFeatures } from "./feature-flags"; import { KnownLanguage } from "./languages"; -import { getActionsLogger, Logger } from "./logging"; +import { getActionsLogger } from "./logging"; import { getRepositoryNwo } from "./repository"; import { credentialToStr, @@ -15,14 +14,13 @@ import { getProxyBinaryPath, getSafeErrorMessage, parseLanguage, - ProxyInfo, + ProxyConfig, sendFailedStatusReport, sendSuccessStatusReport, - Registry, - ProxyConfig, } from "./start-proxy"; import { generateCertificateAuthority } from "./start-proxy/ca"; import { checkProxyEnvironment } from "./start-proxy/environment"; +import { startProxy } from "./start-proxy/launcher"; import { checkConnections } from "./start-proxy/reachability"; import { ActionName, sendUnhandledErrorStatusReport } from "./status-report"; import * as util from "./util"; @@ -140,63 +138,4 @@ async function runWrapper() { } } -async function startProxy( - binPath: string, - config: ProxyConfig, - logFilePath: string, - logger: Logger, -): Promise { - const host = "127.0.0.1"; - let port = 49152; - let subprocess: ChildProcess | undefined = undefined; - let tries = 5; - let subprocessError: Error | undefined = undefined; - while (tries-- > 0 && !subprocess && !subprocessError) { - subprocess = spawn( - binPath, - ["-addr", `${host}:${port}`, "-config", "-", "-logfile", logFilePath], - { - detached: true, - stdio: ["pipe", "ignore", "ignore"], - }, - ); - subprocess.unref(); - if (subprocess.pid) { - core.saveState("proxy-process-pid", `${subprocess.pid}`); - } - subprocess.on("error", (error) => { - subprocessError = error; - }); - subprocess.on("exit", (code) => { - if (code !== 0) { - // If the proxy failed to start, try a different port from the ephemeral range [49152, 65535] - port = Math.floor(Math.random() * (65535 - 49152) + 49152); - subprocess = undefined; - } - }); - subprocess.stdin?.write(JSON.stringify(config)); - subprocess.stdin?.end(); - // Wait a little to allow the proxy to start - await util.delay(1000); - } - if (subprocessError) { - // eslint-disable-next-line @typescript-eslint/only-throw-error - throw subprocessError; - } - logger.info(`Proxy started on ${host}:${port}`); - core.setOutput("proxy_host", host); - core.setOutput("proxy_port", port.toString()); - core.setOutput("proxy_ca_certificate", config.ca.cert); - - const registry_urls: Registry[] = config.all_credentials - .filter((credential) => credential.url !== undefined) - .map((credential) => ({ - type: credential.type, - url: credential.url, - })); - core.setOutput("proxy_urls", JSON.stringify(registry_urls)); - - return { host, port, cert: config.ca.cert, registries: registry_urls }; -} - void runWrapper(); diff --git a/src/start-proxy/launcher.test.ts b/src/start-proxy/launcher.test.ts new file mode 100644 index 0000000000..2a9df002a7 --- /dev/null +++ b/src/start-proxy/launcher.test.ts @@ -0,0 +1,151 @@ +import { ChildProcess } from "child_process"; +import { EventEmitter } from "events"; + +import * as core from "@actions/core"; +import test from "ava"; +import sinon from "sinon"; + +import { getRunnerLogger } from "../logging"; +import { setupTests } from "../testing-utils"; +import { ProxyConfig } from "../start-proxy"; +import { startProxy } from "./launcher"; + +setupTests(test); + +class FakeChildProcess extends EventEmitter { + public pid: number | undefined = 1234; + public exitCode: number | null = null; + public stdin: { write: sinon.SinonStub; end: sinon.SinonStub }; + + constructor() { + super(); + this.stdin = { + write: sinon.stub().returns(true), + end: sinon.stub(), + }; + } + + unref() { + return undefined; + } +} + +function makeConfig(): ProxyConfig { + return { + all_credentials: [ + { + type: "npm_registry", + host: "npm.pkg.github.com", + url: "https://npm.pkg.github.com", + token: "secret-token", + }, + { + type: "maven_repository", + host: "maven.pkg.github.com", + url: undefined, + }, + ], + ca: { + cert: "CERT", + key: "KEY", + }, + }; +} + +test("startProxy throws explicit error when retries are exhausted", async (t) => { + const fakeSpawn = sinon.stub().callsFake(() => { + const process = new FakeChildProcess(); + // Emit exit on next event loop iteration, ensuring it fires during the delay + setImmediate(() => { + process.emit("exit", 1); + }); + return process as unknown as ChildProcess; + }); + const setOutputStub = sinon.stub(core, "setOutput"); + sinon.stub(core, "saveState"); + + const error = await t.throwsAsync(() => + startProxy( + "proxy-bin", + makeConfig(), + "proxy.log", + getRunnerLogger(true), + fakeSpawn as any, + ), + ); + + t.truthy(error); + t.true( + error!.message.includes("Failed to start proxy after 5 attempts"), + `Expected "Failed to start proxy after 5 attempts" but got: ${error?.message}`, + ); + t.true( + error!.message.includes("last exit code: 1"), + `Expected exit code in message but got: ${error?.message}`, + ); + t.true(setOutputStub.notCalled); +}); + +test("startProxy rethrows spawn errors", async (t) => { + const expectedError = new Error("spawn failed"); + const fakeSpawn = sinon.stub().callsFake(() => { + const process = new FakeChildProcess(); + // Emit error on next event loop iteration + setImmediate(() => { + process.emit("error", expectedError); + }); + return process as unknown as ChildProcess; + }); + sinon.stub(core, "setOutput"); + sinon.stub(core, "saveState"); + + const error = await t.throwsAsync(() => + startProxy( + "proxy-bin", + makeConfig(), + "proxy.log", + getRunnerLogger(true), + fakeSpawn as any, + ), + ); + + t.is(error, expectedError); +}); + +test("startProxy succeeds and sets outputs when process remains alive", async (t) => { + const fakeSpawn = sinon.stub().callsFake(() => { + const process = new FakeChildProcess(); + process.exitCode = null; // Explicitly null: process stays alive + // Don't emit any events - process should remain active + return process as unknown as ChildProcess; + }); + const setOutputStub = sinon.stub(core, "setOutput"); + sinon.stub(core, "saveState"); + + const proxyInfo = await startProxy( + "proxy-bin", + makeConfig(), + "proxy.log", + getRunnerLogger(true), + fakeSpawn as any, + ); + + t.is(proxyInfo.host, "127.0.0.1"); + t.is(proxyInfo.port, 49152); + t.is(proxyInfo.cert, "CERT"); + t.deepEqual(proxyInfo.registries, [ + { + type: "npm_registry", + url: "https://npm.pkg.github.com", + }, + ]); + + sinon.assert.calledWith(setOutputStub, "proxy_host", "127.0.0.1"); + sinon.assert.calledWith(setOutputStub, "proxy_port", "49152"); + sinon.assert.calledWith(setOutputStub, "proxy_ca_certificate", "CERT"); + sinon.assert.calledWith( + setOutputStub, + "proxy_urls", + JSON.stringify([{ type: "npm_registry", url: "https://npm.pkg.github.com" }]), + ); +}); diff --git a/src/start-proxy/launcher.ts b/src/start-proxy/launcher.ts new file mode 100644 index 0000000000..9526ced334 --- /dev/null +++ b/src/start-proxy/launcher.ts @@ -0,0 +1,99 @@ +import { ChildProcess, spawn as nodeSpawn } from "child_process"; + +import * as core from "@actions/core"; + +import { Logger } from "../logging"; +import { ProxyConfig, ProxyInfo, Registry } from "../start-proxy"; +import * as util from "../util"; + +const MAX_START_PROXY_ATTEMPTS = 5; +const PROXY_STARTUP_DELAY_MS = 1000; +const EPHEMERAL_PORT_MIN = 49152; +const EPHEMERAL_PORT_MAX = 65535; + +type SpawnFn = typeof nodeSpawn; + +function getRandomEphemeralPort(): number { + return Math.floor( + Math.random() * (EPHEMERAL_PORT_MAX - EPHEMERAL_PORT_MIN) + + EPHEMERAL_PORT_MIN, + ); +} + +export async function startProxy( + binPath: string, + config: ProxyConfig, + logFilePath: string, + logger: Logger, + spawn: SpawnFn = nodeSpawn, +): Promise { + const host = "127.0.0.1"; + let port = EPHEMERAL_PORT_MIN; + let subprocess: ChildProcess | undefined = undefined; + let tries = MAX_START_PROXY_ATTEMPTS; + let subprocessError: Error | undefined = undefined; + let lastExitCode: number | null | undefined; + + while (tries-- > 0 && !subprocess && !subprocessError) { + subprocess = spawn( + binPath, + ["-addr", `${host}:${port}`, "-config", "-", "-logfile", logFilePath], + { + detached: true, + stdio: ["pipe", "ignore", "ignore"], + }, + ); + subprocess.unref(); + if (subprocess.pid) { + core.saveState("proxy-process-pid", `${subprocess.pid}`); + } + subprocess.on("error", (error) => { + subprocessError = error; + subprocess = undefined; + }); + subprocess.on("exit", (code) => { + lastExitCode = code; + port = getRandomEphemeralPort(); + subprocess = undefined; + }); + subprocess.stdin?.write(JSON.stringify(config)); + subprocess.stdin?.end(); + + await util.delay(PROXY_STARTUP_DELAY_MS); + + if (subprocess?.exitCode !== null && subprocess?.exitCode !== undefined) { + lastExitCode = subprocess.exitCode; + port = getRandomEphemeralPort(); + subprocess = undefined; + } + } + + if (subprocessError) { + throw subprocessError; + } + + if (!subprocess) { + const baseMessage = + `Failed to start proxy after ${MAX_START_PROXY_ATTEMPTS} attempts` + + (lastExitCode !== undefined && lastExitCode !== null + ? ` (last exit code: ${lastExitCode})` + : "") + + "."; + throw new Error(baseMessage); + } + + logger.info(`Proxy started on ${host}:${port}`); + core.setOutput("proxy_host", host); + core.setOutput("proxy_port", port.toString()); + core.setOutput("proxy_ca_certificate", config.ca.cert); + + const registryUrls: Registry[] = config.all_credentials + .filter((credential) => credential.url !== undefined) + .map((credential) => ({ + type: credential.type, + url: credential.url, + })); + core.setOutput("proxy_urls", JSON.stringify(registryUrls)); + + return { host, port, cert: config.ca.cert, registries: registryUrls }; +} \ No newline at end of file