diff --git a/.github/workflows/__go-tracing-autobuilder.yml b/.github/workflows/__go-tracing-autobuilder.yml index ccbb1b5a6..fb471c5ea 100644 --- a/.github/workflows/__go-tracing-autobuilder.yml +++ b/.github/workflows/__go-tracing-autobuilder.yml @@ -44,8 +44,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.19.4 - os: ubuntu-latest version: stable-v2.20.7 - os: ubuntu-latest @@ -56,6 +54,8 @@ jobs: version: stable-v2.23.9 - os: ubuntu-latest version: stable-v2.24.3 + - os: ubuntu-latest + version: stable-v2.25.6 - os: ubuntu-latest version: default - os: ubuntu-latest diff --git a/.github/workflows/__go-tracing-custom-build-steps.yml b/.github/workflows/__go-tracing-custom-build-steps.yml index 2acc617cb..b3b043def 100644 --- a/.github/workflows/__go-tracing-custom-build-steps.yml +++ b/.github/workflows/__go-tracing-custom-build-steps.yml @@ -44,8 +44,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.19.4 - os: ubuntu-latest version: stable-v2.20.7 - os: ubuntu-latest @@ -56,6 +54,8 @@ jobs: version: stable-v2.23.9 - os: ubuntu-latest version: stable-v2.24.3 + - os: ubuntu-latest + version: stable-v2.25.6 - os: ubuntu-latest version: default - os: ubuntu-latest diff --git a/.github/workflows/__go-tracing-legacy-workflow.yml b/.github/workflows/__go-tracing-legacy-workflow.yml index a43705b70..20bdea695 100644 --- a/.github/workflows/__go-tracing-legacy-workflow.yml +++ b/.github/workflows/__go-tracing-legacy-workflow.yml @@ -44,8 +44,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.19.4 - os: ubuntu-latest version: stable-v2.20.7 - os: ubuntu-latest @@ -56,6 +54,8 @@ jobs: version: stable-v2.23.9 - os: ubuntu-latest version: stable-v2.24.3 + - os: ubuntu-latest + version: stable-v2.25.6 - os: ubuntu-latest version: default - os: ubuntu-latest diff --git a/.github/workflows/__multi-language-autodetect.yml b/.github/workflows/__multi-language-autodetect.yml index 0a0f201ea..320138bb4 100644 --- a/.github/workflows/__multi-language-autodetect.yml +++ b/.github/workflows/__multi-language-autodetect.yml @@ -54,10 +54,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.19.4 - - os: macos-15-xlarge - version: stable-v2.19.4 - os: ubuntu-latest version: stable-v2.20.7 - os: macos-15-xlarge @@ -78,6 +74,10 @@ jobs: version: stable-v2.24.3 - os: macos-latest-xlarge version: stable-v2.24.3 + - os: ubuntu-latest + version: stable-v2.25.6 + - os: macos-latest-xlarge + version: stable-v2.25.6 - os: ubuntu-latest version: default - os: macos-latest-xlarge @@ -116,13 +116,14 @@ jobs: version: ${{ matrix.version }} use-all-platform-bundle: 'false' setup-kotlin: 'true' - - name: Install Python 3.13 for older CLI versions - # We need Python 3.13 for older CLI versions because they are not compatible with Python 3.14 or newer. + - name: Install Python 3.13.15 for older CLI versions + # Older CLI versions don't work with Python 3.13.16 or newer because their Python extractor + # imports `importlib._bootstrap._ERR_MSG`, which those Python versions no longer define. # See https://github.com/github/codeql-action/pull/3212 if: matrix.version != 'nightly-latest' && matrix.version != 'linked' uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: - python-version: '3.13' + python-version: '3.13.15' - name: Use Xcode 16 # Only the older CodeQL CLI versions need Xcode 16, and these run on macOS 15. diff --git a/.github/workflows/__rust.yml b/.github/workflows/__rust.yml index b3638ca6d..f26b4eb2e 100644 --- a/.github/workflows/__rust.yml +++ b/.github/workflows/__rust.yml @@ -35,7 +35,7 @@ jobs: matrix: include: - os: ubuntu-latest - version: stable-v2.19.4 + version: stable-v2.20.7 - os: ubuntu-latest version: stable-v2.22.1 - os: ubuntu-latest diff --git a/.github/workflows/debug-artifacts-failure-safe.yml b/.github/workflows/debug-artifacts-failure-safe.yml index f67cef5c7..936fe6e95 100644 --- a/.github/workflows/debug-artifacts-failure-safe.yml +++ b/.github/workflows/debug-artifacts-failure-safe.yml @@ -30,7 +30,7 @@ jobs: fail-fast: false matrix: version: - - stable-v2.20.3 + - stable-v2.20.7 - default - linked - nightly-latest diff --git a/.github/workflows/debug-artifacts-safe.yml b/.github/workflows/debug-artifacts-safe.yml index c27f19511..8792aea32 100644 --- a/.github/workflows/debug-artifacts-safe.yml +++ b/.github/workflows/debug-artifacts-safe.yml @@ -29,7 +29,7 @@ jobs: fail-fast: false matrix: version: - - stable-v2.20.3 + - stable-v2.20.7 - default - linked - nightly-latest @@ -85,7 +85,7 @@ jobs: uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - name: Check expected artifacts exist run: | - VERSIONS="stable-v2.20.3 default linked nightly-latest" + VERSIONS="stable-v2.20.7 default linked nightly-latest" LANGUAGES="cpp csharp go java javascript python" for version in $VERSIONS; do pushd "./my-debug-artifacts-${version//./}" diff --git a/CHANGELOG.md b/CHANGELOG.md index f8bc73a5f..8ce2edd61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,13 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th ## [UNRELEASED] +- _Breaking change_: Bump the minimum required CodeQL bundle version to 2.20.7. [#4205](https://github.com/github/codeql-action/pull/4205) + +## 4.38.3 - 08 Oct 2026 + - _Upcoming breaking change_: CodeQL version 2.21.2 and earlier were discontinued on 24 September 2026 alongside GitHub Enterprise Server 3.17, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4188](https://github.com/github/codeql-action/pull/4188) - Update default CodeQL bundle version to [2.27.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.2). [#4203](https://github.com/github/codeql-action/pull/4203) +- Fixed a bug where the decision of whether to use a per-language bundle did not account for custom configurations that reference queries outside of compiled CodeQL packs. This issue was caught during internal testing and did not affect any customer repositories. We will resume the roll out of per-language bundles in the coming weeks. [#4184](https://github.com/github/codeql-action/pull/4184) ## 4.38.2 - 24 Sept 2026 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 216097f89..1436c9bb3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,6 +53,7 @@ Here are a few things you can do that will increase the likelihood of your pull - Write tests. - Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests. - Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). +- For user-facing changes, add a change-note file. See [unreleased-change-notes/README.md](unreleased-change-notes/README.md). ## Releasing (write access required) diff --git a/ava.setup.mjs b/ava.setup.mjs index e6c370e01..b40599112 100644 --- a/ava.setup.mjs +++ b/ava.setup.mjs @@ -1,3 +1,4 @@ import pkg from "./package.json" with { type: "json" }; globalThis.__CODEQL_ACTION_VERSION__ = pkg.version; +globalThis.__CODEQL_ACTION_TEST_ENV__ = "unit-test"; diff --git a/build.mjs b/build.mjs index a0c3c0618..ecbe5be84 100644 --- a/build.mjs +++ b/build.mjs @@ -78,7 +78,7 @@ const UPLOAD_LIB_SRC = "./src/upload-lib"; * * The virtual module additionally re-exports `upload-lib` under the `uploadLib` namespace so that * external consumers can access it via the small `lib/upload-lib.js` stub emitted below. - * + * * A tiny stub file is emitted for each Action entrypoint, and one for `upload-lib`. Each stub * imports the shared bundle and calls/re-exports from the respective entry point. * @@ -212,6 +212,7 @@ const context = await esbuild.context({ target: ["node20"], define: { __CODEQL_ACTION_VERSION__: JSON.stringify(pkg.version), + __CODEQL_ACTION_TEST_ENV__: JSON.stringify(""), }, metafile: true, }); diff --git a/eslint.config.mjs b/eslint.config.mjs index 34fe49a9d..c3f288c0d 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -140,6 +140,17 @@ export default [ "no-async-foreach/no-async-foreach": "error", "no-sequences": "error", "no-shadow": "off", + + // A basic check that we don't use `exportVariable` from `@actions/core`. + "no-restricted-syntax": [ + "error", + { + selector: "MemberExpression[property.name='exportVariable']", + message: + "Use the `export` method of an `Env` instance or `exportEnvVar` from `environment.ts` instead.", + }, + ], + // This is overly restrictive with unsetting `EnvVar`s "@typescript-eslint/no-dynamic-delete": "off", "@typescript-eslint/no-shadow": "error", @@ -157,6 +168,15 @@ export default [ ], }, }, + { + files: ["src/environment.ts"], + + // We allow `exportVariable` from `@actions/core` to be used in this file + // since it defines the wrapper around it that other modules use. + rules: { + "no-restricted-syntax": "off", + }, + }, { files: ["**/*.ts", "**/*.js"], diff --git a/lib/entry-points.js b/lib/entry-points.js index 93084ea9b..373cdedc0 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 = exportVariable17; + exports2.exportVariable = exportVariable2; exports2.setSecret = setSecret2; exports2.addPath = addPath2; exports2.getInput = getInput2; @@ -21656,8 +21656,8 @@ var require_core = __commonJS({ exports2.warning = warning14; exports2.notice = notice; exports2.info = info8; - exports2.startGroup = startGroup4; - exports2.endGroup = endGroup4; + exports2.startGroup = startGroup3; + exports2.endGroup = endGroup3; exports2.group = group; exports2.saveState = saveState3; exports2.getState = getState3; @@ -21673,7 +21673,7 @@ var require_core = __commonJS({ ExitCode2[ExitCode2["Success"] = 0] = "Success"; ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; })(ExitCode || (exports2.ExitCode = ExitCode = {})); - function exportVariable17(name, val) { + function exportVariable2(name, val) { const convertedVal = (0, utils_1.toCommandValue)(val); process.env[name] = convertedVal; const filePath = process.env["GITHUB_ENV"] || ""; @@ -21755,20 +21755,20 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); function info8(message) { process.stdout.write(message + os7.EOL); } - function startGroup4(name) { + function startGroup3(name) { (0, command_1.issue)("group", name); } - function endGroup4() { + function endGroup3() { (0, command_1.issue)("endgroup"); } function group(name, fn) { return __awaiter2(this, void 0, void 0, function* () { - startGroup4(name); + startGroup3(name); let result; try { result = yield fn(); } finally { - endGroup4(); + endGroup3(); } return result; }); @@ -27216,8 +27216,8 @@ var require_gte = __commonJS({ "node_modules/semver/functions/gte.js"(exports2, module2) { "use strict"; var compare3 = require_compare(); - var gte8 = (a, b, loose) => compare3(a, b, loose) >= 0; - module2.exports = gte8; + var gte7 = (a, b, loose) => compare3(a, b, loose) >= 0; + module2.exports = gte7; } }); @@ -27238,7 +27238,7 @@ var require_cmp = __commonJS({ var eq = require_eq(); var neq = require_neq(); var gt = require_gt(); - var gte8 = require_gte(); + var gte7 = require_gte(); var lt2 = require_lt(); var lte2 = require_lte(); var cmp = (a, op, b, loose) => { @@ -27268,7 +27268,7 @@ var require_cmp = __commonJS({ case ">": return gt(a, b, loose); case ">=": - return gte8(a, b, loose); + return gte7(a, b, loose); case "<": return lt2(a, b, loose); case "<=": @@ -28076,7 +28076,7 @@ var require_outside = __commonJS({ var gt = require_gt(); var lt2 = require_lt(); var lte2 = require_lte(); - var gte8 = require_gte(); + var gte7 = require_gte(); var outside = (version, range2, hilo, options) => { version = new SemVer(version, options); range2 = new Range2(range2, options); @@ -28091,7 +28091,7 @@ var require_outside = __commonJS({ break; case "<": gtfn = lt2; - ltefn = gte8; + ltefn = gte7; ltfn = gt; comp = "<"; ecomp = "<="; @@ -28406,7 +28406,7 @@ var require_semver2 = __commonJS({ var lt2 = require_lt(); var eq = require_eq(); var neq = require_neq(); - var gte8 = require_gte(); + var gte7 = require_gte(); var lte2 = require_lte(); var cmp = require_cmp(); var coerce3 = require_coerce(); @@ -28445,7 +28445,7 @@ var require_semver2 = __commonJS({ lt: lt2, eq, neq, - gte: gte8, + gte: gte7, lte: lte2, cmp, coerce: coerce3, @@ -31294,7 +31294,7 @@ var require_internal_glob_options_helper = __commonJS({ })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getOptions = getOptions; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); function getOptions(copy) { const result = { followSymbolicLinks: true, @@ -31306,23 +31306,23 @@ var require_internal_glob_options_helper = __commonJS({ if (copy) { if (typeof copy.followSymbolicLinks === "boolean") { result.followSymbolicLinks = copy.followSymbolicLinks; - core32.debug(`followSymbolicLinks '${result.followSymbolicLinks}'`); + core29.debug(`followSymbolicLinks '${result.followSymbolicLinks}'`); } if (typeof copy.implicitDescendants === "boolean") { result.implicitDescendants = copy.implicitDescendants; - core32.debug(`implicitDescendants '${result.implicitDescendants}'`); + core29.debug(`implicitDescendants '${result.implicitDescendants}'`); } if (typeof copy.matchDirectories === "boolean") { result.matchDirectories = copy.matchDirectories; - core32.debug(`matchDirectories '${result.matchDirectories}'`); + core29.debug(`matchDirectories '${result.matchDirectories}'`); } if (typeof copy.omitBrokenSymbolicLinks === "boolean") { result.omitBrokenSymbolicLinks = copy.omitBrokenSymbolicLinks; - core32.debug(`omitBrokenSymbolicLinks '${result.omitBrokenSymbolicLinks}'`); + core29.debug(`omitBrokenSymbolicLinks '${result.omitBrokenSymbolicLinks}'`); } if (typeof copy.excludeHiddenFiles === "boolean") { result.excludeHiddenFiles = copy.excludeHiddenFiles; - core32.debug(`excludeHiddenFiles '${result.excludeHiddenFiles}'`); + core29.debug(`excludeHiddenFiles '${result.excludeHiddenFiles}'`); } } return result; @@ -31736,7 +31736,7 @@ var require_brace_expansion = __commonJS({ function lte2(i, y) { return i <= y; } - function gte8(i, y) { + function gte7(i, y) { return i >= y; } function combine2(acc, base, pre, values, max, maxLength, dropEmpties, outBase) { @@ -31769,7 +31769,7 @@ var require_brace_expansion = __commonJS({ var reverse = y < x; if (reverse) { incr *= -1; - test = gte8; + test = gte7; } var pad = n.some(isPadded2); var length = 0; @@ -33064,7 +33064,7 @@ var require_internal_globber = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DefaultGlobber = void 0; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var fs32 = __importStar2(require("fs")); var globOptionsHelper = __importStar2(require_internal_glob_options_helper()); var path30 = __importStar2(require("path")); @@ -33117,7 +33117,7 @@ var require_internal_globber = __commonJS({ } const stack = []; for (const searchPath of patternHelper.getSearchPaths(patterns)) { - core32.debug(`Search path '${searchPath}'`); + core29.debug(`Search path '${searchPath}'`); try { yield __await2(fs32.promises.lstat(searchPath)); } catch (err) { @@ -33192,7 +33192,7 @@ var require_internal_globber = __commonJS({ } catch (err) { if (err.code === "ENOENT") { if (options.omitBrokenSymbolicLinks) { - core32.debug(`Broken symlink '${item.path}'`); + core29.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.`); @@ -33208,7 +33208,7 @@ var require_internal_globber = __commonJS({ traversalChain.pop(); } if (traversalChain.some((x) => x === realPath)) { - core32.debug(`Symlink cycle detected for path '${item.path}' and realpath '${realPath}'`); + core29.debug(`Symlink cycle detected for path '${item.path}' and realpath '${realPath}'`); return void 0; } traversalChain.push(realPath); @@ -33311,7 +33311,7 @@ var require_internal_hash_files = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.hashFiles = hashFiles2; var crypto3 = __importStar2(require("crypto")); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var fs32 = __importStar2(require("fs")); var stream2 = __importStar2(require("stream")); var util4 = __importStar2(require("util")); @@ -33320,7 +33320,7 @@ var require_internal_hash_files = __commonJS({ return __awaiter2(this, arguments, void 0, function* (globber, currentWorkspace, verbose = false) { var _a6, e_1, _b2, _c2; var _d2; - const writeDelegate = verbose ? core32.info : core32.debug; + const writeDelegate = verbose ? core29.info : core29.debug; let hasMatch = false; const githubWorkspace = currentWorkspace ? currentWorkspace : (_d2 = process.env["GITHUB_WORKSPACE"]) !== null && _d2 !== void 0 ? _d2 : process.cwd(); const result = crypto3.createHash("sha256"); @@ -33921,8 +33921,8 @@ var require_semver3 = __commonJS({ function neq(a, b, loose) { return compare3(a, b, loose) !== 0; } - exports2.gte = gte8; - function gte8(a, b, loose) { + exports2.gte = gte7; + function gte7(a, b, loose) { return compare3(a, b, loose) >= 0; } exports2.lte = lte2; @@ -33953,7 +33953,7 @@ var require_semver3 = __commonJS({ case ">": return gt(a, b, loose); case ">=": - return gte8(a, b, loose); + return gte7(a, b, loose); case "<": return lt2(a, b, loose); case "<=": @@ -34498,7 +34498,7 @@ var require_semver3 = __commonJS({ break; case "<": gtfn = lt2; - ltefn = gte8; + ltefn = gte7; ltfn = gt; comp = "<"; ecomp = "<="; @@ -34712,14 +34712,14 @@ var require_cacheUtils = __commonJS({ exports2.assertDefined = assertDefined; exports2.getCacheVersion = getCacheVersion; exports2.getRuntimeToken = getRuntimeToken; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var exec3 = __importStar2(require_exec()); var glob2 = __importStar2(require_glob()); var io9 = __importStar2(require_io()); var crypto3 = __importStar2(require("crypto")); var fs32 = __importStar2(require("fs")); var path30 = __importStar2(require("path")); - var semver12 = __importStar2(require_semver3()); + var semver11 = __importStar2(require_semver3()); var util4 = __importStar2(require("util")); var constants_1 = require_constants7(); var versionSalt = "1.0"; @@ -34763,7 +34763,7 @@ var require_cacheUtils = __commonJS({ _e2 = false; const file = _c2; const relativeFile = path30.relative(workspace, file).replace(new RegExp(`\\${path30.sep}`, "g"), "/"); - core32.debug(`Matched: ${relativeFile}`); + core29.debug(`Matched: ${relativeFile}`); if (relativeFile === "") { paths.push("."); } else { @@ -34791,7 +34791,7 @@ var require_cacheUtils = __commonJS({ return __awaiter2(this, arguments, void 0, function* (app, additionalArgs = []) { let versionOutput = ""; additionalArgs.push("--version"); - core32.debug(`Checking ${app} ${additionalArgs.join(" ")}`); + core29.debug(`Checking ${app} ${additionalArgs.join(" ")}`); try { yield exec3.exec(`${app}`, additionalArgs, { ignoreReturnCode: true, @@ -34802,18 +34802,18 @@ var require_cacheUtils = __commonJS({ } }); } catch (err) { - core32.debug(err.message); + core29.debug(err.message); } versionOutput = versionOutput.trim(); - core32.debug(versionOutput); + core29.debug(versionOutput); return versionOutput; }); } function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver12.clean(versionOutput); - core32.debug(`zstd version: ${version}`); + const version = semver11.clean(versionOutput); + core29.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; } else { @@ -99036,7 +99036,7 @@ var require_uploadUtils = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.UploadProgress = void 0; exports2.uploadCacheArchiveSDK = uploadCacheArchiveSDK; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var storage_blob_1 = require_commonjs15(); var errors_1 = require_errors2(); var UploadProgress = class { @@ -99078,7 +99078,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); - core32.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`); + core29.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`); if (this.isDone()) { this.displayedComplete = true; } @@ -99135,14 +99135,14 @@ var require_uploadUtils = __commonJS({ }; try { uploadProgress.startDisplayTimer(); - core32.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`); + core29.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) { - core32.warning(`uploadCacheArchiveSDK: internal error uploading cache archive: ${error3.message}`); + core29.warning(`uploadCacheArchiveSDK: internal error uploading cache archive: ${error3.message}`); throw error3; } finally { uploadProgress.stopDisplayTimer(); @@ -99227,7 +99227,7 @@ var require_requestUtils = __commonJS({ exports2.retry = retry2; exports2.retryTypedResponse = retryTypedResponse; exports2.retryHttpClientResponse = retryHttpClientResponse; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var http_client_1 = require_lib(); var constants_1 = require_constants7(); function isSuccessStatusCode(statusCode) { @@ -99285,9 +99285,9 @@ var require_requestUtils = __commonJS({ isRetryable = isRetryableStatusCode(statusCode); errorMessage = `Cache service responded with ${statusCode}`; } - core32.debug(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); + core29.debug(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); if (!isRetryable) { - core32.debug(`${name} - Error is not retryable`); + core29.debug(`${name} - Error is not retryable`); break; } yield sleep(delay2); @@ -99546,7 +99546,7 @@ var require_downloadUtils = __commonJS({ exports2.downloadCacheHttpClient = downloadCacheHttpClient; exports2.downloadCacheHttpClientConcurrent = downloadCacheHttpClientConcurrent; exports2.downloadCacheStorageSDK = downloadCacheStorageSDK; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var http_client_1 = require_lib(); var storage_blob_1 = require_commonjs15(); var buffer = __importStar2(require("buffer")); @@ -99584,7 +99584,7 @@ var require_downloadUtils = __commonJS({ this.segmentIndex = this.segmentIndex + 1; this.segmentSize = segmentSize; this.receivedBytes = 0; - core32.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`); + core29.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`); } /** * Sets the number of bytes received for the current segment. @@ -99618,7 +99618,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); - core32.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`); + core29.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`); if (this.isDone()) { this.displayedComplete = true; } @@ -99668,7 +99668,7 @@ var require_downloadUtils = __commonJS({ })); downloadResponse.message.socket.setTimeout(constants_1.SocketTimeout, () => { downloadResponse.message.destroy(); - core32.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`); + core29.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`); }); yield pipeResponseToStream(downloadResponse, writeStream); const contentLengthHeader = downloadResponse.message.headers["content-length"]; @@ -99679,7 +99679,7 @@ var require_downloadUtils = __commonJS({ throw new Error(`Incomplete download. Expected file size: ${expectedLength}, actual file size: ${actualLength}`); } } else { - core32.debug("Unable to validate download, no Content-Length header"); + core29.debug("Unable to validate download, no Content-Length header"); } }); } @@ -99797,7 +99797,7 @@ var require_downloadUtils = __commonJS({ const properties = yield client.getProperties(); const contentLength = (_a6 = properties.contentLength) !== null && _a6 !== void 0 ? _a6 : -1; if (contentLength < 0) { - core32.debug("Unable to determine content length, downloading file with http-client..."); + core29.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); @@ -99887,7 +99887,7 @@ var require_options = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getUploadOptions = getUploadOptions; exports2.getDownloadOptions = getDownloadOptions; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); function getUploadOptions(copy) { const result = { useAzureSdk: false, @@ -99907,9 +99907,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; - core32.debug(`Use Azure SDK: ${result.useAzureSdk}`); - core32.debug(`Upload concurrency: ${result.uploadConcurrency}`); - core32.debug(`Upload chunk size: ${result.uploadChunkSize}`); + core29.debug(`Use Azure SDK: ${result.useAzureSdk}`); + core29.debug(`Upload concurrency: ${result.uploadConcurrency}`); + core29.debug(`Upload chunk size: ${result.uploadChunkSize}`); return result; } function getDownloadOptions(copy) { @@ -99945,12 +99945,12 @@ var require_options = __commonJS({ if (segmentDownloadTimeoutMins && !isNaN(Number(segmentDownloadTimeoutMins)) && isFinite(Number(segmentDownloadTimeoutMins))) { result.segmentTimeoutInMs = Number(segmentDownloadTimeoutMins) * 60 * 1e3; } - 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}`); + core29.debug(`Use Azure SDK: ${result.useAzureSdk}`); + core29.debug(`Download concurrency: ${result.downloadConcurrency}`); + core29.debug(`Request timeout (ms): ${result.timeoutInMs}`); + core29.debug(`Cache segment download timeout mins env var: ${process.env["SEGMENT_DOWNLOAD_TIMEOUT_MINS"]}`); + core29.debug(`Segment download timeout (ms): ${result.segmentTimeoutInMs}`); + core29.debug(`Lookup only: ${result.lookupOnly}`); return result; } } @@ -100161,7 +100161,7 @@ var require_cacheHttpClient = __commonJS({ exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; exports2.saveCache = saveCache5; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); var fs32 = __importStar2(require("fs")); @@ -100180,7 +100180,7 @@ var require_cacheHttpClient = __commonJS({ throw new Error("Cache Service Url not found, unable to restore cache."); } const url2 = `${baseUrl}_apis/artifactcache/${resource}`; - core32.debug(`Resource Url: ${url2}`); + core29.debug(`Resource Url: ${url2}`); return url2; } function createAcceptHeader(type, apiVersion) { @@ -100209,7 +100209,7 @@ var require_cacheHttpClient = __commonJS({ return httpClient.getJson(getCacheApiUrl(resource)); })); if (response.statusCode === 204) { - if (core32.isDebug()) { + if (core29.isDebug()) { yield printCachesListForDiagnostics(keys[0], httpClient, version); } return null; @@ -100226,9 +100226,9 @@ var require_cacheHttpClient = __commonJS({ if (!cacheDownloadUrl) { throw new Error("Cache not found."); } - core32.setSecret(cacheDownloadUrl); - core32.debug(`Cache Result:`); - core32.debug(JSON.stringify(cacheResult)); + core29.setSecret(cacheDownloadUrl); + core29.debug(`Cache Result:`); + core29.debug(JSON.stringify(cacheResult)); return cacheResult; }); } @@ -100242,10 +100242,10 @@ var require_cacheHttpClient = __commonJS({ const cacheListResult = response.result; const totalCount = cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.totalCount; if (totalCount && totalCount > 0) { - 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 + core29.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) || []) { - 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}`); + core29.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}`); } } } @@ -100288,7 +100288,7 @@ Other caches with similar key:`); } function uploadChunk(httpClient, resourceUrl, openStream, start, end) { return __awaiter2(this, void 0, void 0, function* () { - core32.debug(`Uploading chunk of size ${end - start + 1} bytes at offset ${start} with content range: ${getContentRange(start, end)}`); + core29.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) @@ -100310,7 +100310,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()]; - core32.debug("Awaiting all uploads"); + core29.debug("Awaiting all uploads"); let offset = 0; try { yield Promise.all(parallelUploads.map(() => __awaiter2(this, void 0, void 0, function* () { @@ -100353,16 +100353,16 @@ Other caches with similar key:`); yield (0, uploadUtils_1.uploadCacheArchiveSDK)(signedUploadURL, archivePath, options); } else { const httpClient = createHttpClient(); - core32.debug("Upload cache"); + core29.debug("Upload cache"); yield uploadFile(httpClient, cacheId, archivePath, options); - core32.debug("Commiting cache"); + core29.debug("Commiting cache"); const cacheSize = utils.getArchiveFileSizeInBytes(archivePath); - core32.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`); + core29.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.`); } - core32.info("Cache saved successfully"); + core29.info("Cache saved successfully"); } }); } @@ -105845,7 +105845,7 @@ var require_cache4 = __commonJS({ exports2.isFeatureAvailable = isFeatureAvailable; exports2.restoreCache = restoreCache5; exports2.saveCache = saveCache5; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var path30 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); var cacheHttpClient = __importStar2(require_cacheHttpClient()); @@ -105923,12 +105923,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)(); - core32.debug(`Cache service version: ${cacheServiceVersion}`); + core29.debug(`Cache service version: ${cacheServiceVersion}`); checkPaths(paths); const cacheMode = (0, config_1.getCacheMode)(); if (!(0, config_1.isCacheReadable)(cacheMode)) { - 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}'.`); + core29.info(`Cache restore skipped: the effective cache-mode '${cacheMode}' does not permit reads.`); + core29.debug(`Skipped restore for paths [${paths.join(", ")}] with primary key '${primaryKey}'.`); return void 0; } switch (cacheServiceVersion) { @@ -105945,8 +105945,8 @@ var require_cache4 = __commonJS({ var _a6; restoreKeys = restoreKeys || []; const keys = [primaryKey, ...restoreKeys]; - core32.debug("Resolved Keys:"); - core32.debug(JSON.stringify(keys)); + core29.debug("Resolved Keys:"); + core29.debug(JSON.stringify(keys)); if (keys.length > 10) { throw new ValidationError(`Key Validation Error: Keys are limited to a maximum of 10.`); } @@ -105973,19 +105973,19 @@ var require_cache4 = __commonJS({ return void 0; } if (options === null || options === void 0 ? void 0 : options.lookupOnly) { - core32.info("Lookup only - skipping download"); + core29.info("Lookup only - skipping download"); return cacheEntry.cacheKey; } archivePath = path30.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); - core32.debug(`Archive Path: ${archivePath}`); + core29.debug(`Archive Path: ${archivePath}`); yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options); - if (core32.isDebug()) { + if (core29.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core32.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); + core29.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); yield (0, tar_1.extractTar)(archivePath, compressionMethod); - core32.info("Cache restored successfully"); + core29.info("Cache restored successfully"); return cacheEntry.cacheKey; } catch (error3) { const typedError = error3; @@ -105993,16 +105993,16 @@ var require_cache4 = __commonJS({ throw error3; } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core32.error(`Failed to restore: ${error3.message}`); + core29.error(`Failed to restore: ${error3.message}`); } else { - core32.warning(`Failed to restore: ${error3.message}`); + core29.warning(`Failed to restore: ${error3.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core32.debug(`Failed to delete archive: ${error3}`); + core29.debug(`Failed to delete archive: ${error3}`); } } return void 0; @@ -106014,8 +106014,8 @@ var require_cache4 = __commonJS({ options = Object.assign(Object.assign({}, options), { useAzureSdk: true }); restoreKeys = restoreKeys || []; const keys = [primaryKey, ...restoreKeys]; - core32.debug("Resolved Keys:"); - core32.debug(JSON.stringify(keys)); + core29.debug("Resolved Keys:"); + core29.debug(JSON.stringify(keys)); if (keys.length > 10) { throw new ValidationError(`Key Validation Error: Keys are limited to a maximum of 10.`); } @@ -106042,30 +106042,30 @@ var require_cache4 = __commonJS({ throw error3; } if (!response.ok) { - core32.debug(`Cache not found for version ${request3.version} of keys: ${keys.join(", ")}`); + core29.debug(`Cache not found for version ${request3.version} of keys: ${keys.join(", ")}`); return void 0; } const isRestoreKeyMatch = request3.key !== response.matchedKey; if (isRestoreKeyMatch) { - core32.info(`Cache hit for restore-key: ${response.matchedKey}`); + core29.info(`Cache hit for restore-key: ${response.matchedKey}`); } else { - core32.info(`Cache hit for: ${response.matchedKey}`); + core29.info(`Cache hit for: ${response.matchedKey}`); } if (options === null || options === void 0 ? void 0 : options.lookupOnly) { - core32.info("Lookup only - skipping download"); + core29.info("Lookup only - skipping download"); return response.matchedKey; } archivePath = path30.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); - core32.debug(`Archive path: ${archivePath}`); - core32.debug(`Starting download of archive to: ${archivePath}`); + core29.debug(`Archive path: ${archivePath}`); + core29.debug(`Starting download of archive to: ${archivePath}`); yield cacheHttpClient.downloadCache(response.signedDownloadUrl, archivePath, options); const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core32.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); - if (core32.isDebug()) { + core29.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); + if (core29.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } yield (0, tar_1.extractTar)(archivePath, compressionMethod); - core32.info("Cache restored successfully"); + core29.info("Cache restored successfully"); return response.matchedKey; } catch (error3) { const typedError = error3; @@ -106073,9 +106073,9 @@ var require_cache4 = __commonJS({ throw error3; } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core32.error(`Failed to restore: ${error3.message}`); + core29.error(`Failed to restore: ${error3.message}`); } else { - core32.warning(`Failed to restore: ${error3.message}`); + core29.warning(`Failed to restore: ${error3.message}`); } } } finally { @@ -106084,7 +106084,7 @@ var require_cache4 = __commonJS({ yield utils.unlinkFile(archivePath); } } catch (error3) { - core32.debug(`Failed to delete archive: ${error3}`); + core29.debug(`Failed to delete archive: ${error3}`); } } return void 0; @@ -106093,13 +106093,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)(); - core32.debug(`Cache service version: ${cacheServiceVersion}`); + core29.debug(`Cache service version: ${cacheServiceVersion}`); checkPaths(paths); checkKey(key); const cacheMode = (0, config_1.getCacheMode)(); if (!(0, config_1.isCacheWritable)(cacheMode)) { - 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}'.`); + core29.info(`Cache save skipped: the effective cache-mode '${cacheMode}' does not permit writes.`); + core29.debug(`Skipped save for paths [${paths.join(", ")}] with key '${key}'.`); return -1; } switch (cacheServiceVersion) { @@ -106117,26 +106117,26 @@ var require_cache4 = __commonJS({ const compressionMethod = yield utils.getCompressionMethod(); let cacheId = -1; const cachePaths = yield utils.resolvePaths(paths); - core32.debug("Cache Paths:"); - core32.debug(`${JSON.stringify(cachePaths)}`); + core29.debug("Cache Paths:"); + core29.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)); - core32.debug(`Archive Path: ${archivePath}`); + core29.debug(`Archive Path: ${archivePath}`); try { yield (0, tar_1.createTar)(archiveFolder, cachePaths, compressionMethod); - if (core32.isDebug()) { + if (core29.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const fileSizeLimit = 10 * 1024 * 1024 * 1024; const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core32.debug(`File Size: ${archiveFileSize}`); + core29.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.`); } - core32.debug("Reserving Cache"); + core29.debug("Reserving Cache"); const reserveCacheResponse = yield cacheHttpClient.reserveCache(key, paths, { compressionMethod, enableCrossOsArchive, @@ -106153,28 +106153,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}`); } - core32.debug(`Saving Cache (ID: ${cacheId})`); + core29.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) { - core32.warning(`Failed to save: ${typedError.message}`); + core29.warning(`Failed to save: ${typedError.message}`); } else if (typedError.name === ReserveCacheError2.name) { - core32.info(`Failed to save: ${typedError.message}`); + core29.info(`Failed to save: ${typedError.message}`); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core32.error(`Failed to save: ${typedError.message}`); + core29.error(`Failed to save: ${typedError.message}`); } else { - core32.warning(`Failed to save: ${typedError.message}`); + core29.warning(`Failed to save: ${typedError.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core32.debug(`Failed to delete archive: ${error3}`); + core29.debug(`Failed to delete archive: ${error3}`); } } return cacheId; @@ -106188,23 +106188,23 @@ var require_cache4 = __commonJS({ const twirpClient = cacheTwirpClient.internalCacheTwirpClient(); let cacheId = -1; const cachePaths = yield utils.resolvePaths(paths); - core32.debug("Cache Paths:"); - core32.debug(`${JSON.stringify(cachePaths)}`); + core29.debug("Cache Paths:"); + core29.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)); - core32.debug(`Archive Path: ${archivePath}`); + core29.debug(`Archive Path: ${archivePath}`); try { yield (0, tar_1.createTar)(archiveFolder, cachePaths, compressionMethod); - if (core32.isDebug()) { + if (core29.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core32.debug(`File Size: ${archiveFileSize}`); + core29.debug(`File Size: ${archiveFileSize}`); options.archiveSizeBytes = archiveFileSize; - core32.debug("Reserving Cache"); + core29.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); const request3 = { key, @@ -106215,20 +106215,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)) { - core32.warning(`Cache reservation failed: ${response.message}`); + core29.warning(`Cache reservation failed: ${response.message}`); } throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error3) { - core32.debug(`Failed to reserve cache: ${error3}`); + core29.debug(`Failed to reserve cache: ${error3}`); const errorMessage = (_a6 = error3 === null || error3 === void 0 ? void 0 : error3.message) !== null && _a6 !== void 0 ? _a6 : ""; 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.`); } - core32.debug(`Attempting to upload cache located at: ${archivePath}`); + core29.debug(`Attempting to upload cache located at: ${archivePath}`); yield cacheHttpClient.saveCache(cacheId, archivePath, signedUploadUrl, options); const finalizeRequest = { key, @@ -106236,7 +106236,7 @@ var require_cache4 = __commonJS({ sizeBytes: `${archiveFileSize}` }; const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); - core32.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); + core29.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { if (finalizeResponse.message) { throw new FinalizeCacheError(finalizeResponse.message); @@ -106249,23 +106249,23 @@ var require_cache4 = __commonJS({ if (typedError.name === ValidationError.name) { throw error3; } else if (typedError.name === CacheWriteDeniedError.name) { - core32.warning(`Failed to save: ${typedError.message}`); + core29.warning(`Failed to save: ${typedError.message}`); } else if (typedError.name === ReserveCacheError2.name) { - core32.info(`Failed to save: ${typedError.message}`); + core29.info(`Failed to save: ${typedError.message}`); } else if (typedError.name === FinalizeCacheError.name) { - core32.warning(typedError.message); + core29.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core32.error(`Failed to save: ${typedError.message}`); + core29.error(`Failed to save: ${typedError.message}`); } else { - core32.warning(`Failed to save: ${typedError.message}`); + core29.warning(`Failed to save: ${typedError.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core32.debug(`Failed to delete archive: ${error3}`); + core29.debug(`Failed to delete archive: ${error3}`); } } return cacheId; @@ -106346,7 +106346,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver12 = __importStar2(require_semver2()); + var semver11 = __importStar2(require_semver2()); var core_1 = require_core(); var os7 = require("os"); var cp = require("child_process"); @@ -106360,7 +106360,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver12.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver11.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -106369,7 +106369,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver12.satisfies(osVersion, item.platform_version); + chk = semver11.satisfies(osVersion, item.platform_version); } } return chk; @@ -106492,7 +106492,7 @@ var require_retry_helper = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RetryHelper = void 0; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var RetryHelper = class { constructor(maxAttempts, minSeconds, maxSeconds) { if (maxAttempts < 1) { @@ -106515,10 +106515,10 @@ var require_retry_helper = __commonJS({ if (isRetryable && !isRetryable(err)) { throw err; } - core32.info(err.message); + core29.info(err.message); } const seconds = this.getSleepAmount(); - core32.info(`Waiting ${seconds} seconds before trying again`); + core29.info(`Waiting ${seconds} seconds before trying again`); yield this.sleep(seconds); attempt++; } @@ -106621,7 +106621,7 @@ var require_tool_cache = __commonJS({ exports2.findFromManifest = findFromManifest; exports2.isExplicitVersion = isExplicitVersion; exports2.evaluateVersions = evaluateVersions; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var io9 = __importStar2(require_io()); var crypto3 = __importStar2(require("crypto")); var fs32 = __importStar2(require("fs")); @@ -106629,7 +106629,7 @@ var require_tool_cache = __commonJS({ var os7 = __importStar2(require("os")); var path30 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver12 = __importStar2(require_semver2()); + var semver11 = __importStar2(require_semver2()); var stream2 = __importStar2(require("stream")); var util4 = __importStar2(require("util")); var assert_1 = require("assert"); @@ -106650,8 +106650,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)); - core32.debug(`Downloading ${url2}`); - core32.debug(`Destination ${dest}`); + core29.debug(`Downloading ${url2}`); + core29.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); @@ -106677,7 +106677,7 @@ var require_tool_cache = __commonJS({ allowRetries: false }); if (auth2) { - core32.debug("set auth"); + core29.debug("set auth"); if (headers === void 0) { headers = {}; } @@ -106686,7 +106686,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); - core32.debug(`Failed to download from "${url2}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); + core29.debug(`Failed to download from "${url2}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); throw err; } const pipeline2 = util4.promisify(stream2.pipeline); @@ -106695,16 +106695,16 @@ var require_tool_cache = __commonJS({ let succeeded = false; try { yield pipeline2(readStream, fs32.createWriteStream(dest)); - core32.debug("download complete"); + core29.debug("download complete"); succeeded = true; return dest; } finally { if (!succeeded) { - core32.debug("download failed"); + core29.debug("download failed"); try { yield io9.rmRF(dest); } catch (err) { - core32.debug(`Failed to delete '${dest}'. ${err.message}`); + core29.debug(`Failed to delete '${dest}'. ${err.message}`); } } } @@ -106719,7 +106719,7 @@ var require_tool_cache = __commonJS({ process.chdir(dest); if (_7zPath) { try { - const logLevel = core32.isDebug() ? "-bb1" : "-bb0"; + const logLevel = core29.isDebug() ? "-bb1" : "-bb0"; const args = [ "x", // eXtract files with full paths @@ -106772,7 +106772,7 @@ var require_tool_cache = __commonJS({ throw new Error("parameter 'file' is required"); } dest = yield _createExtractFolder(dest); - core32.debug("Checking tar --version"); + core29.debug("Checking tar --version"); let versionOutput = ""; yield (0, exec_1.exec)("tar --version", [], { ignoreReturnCode: true, @@ -106782,7 +106782,7 @@ var require_tool_cache = __commonJS({ stderr: (data) => versionOutput += data.toString() } }); - core32.debug(versionOutput.trim()); + core29.debug(versionOutput.trim()); const isGnuTar = versionOutput.toUpperCase().includes("GNU TAR"); let args; if (flags instanceof Array) { @@ -106790,7 +106790,7 @@ var require_tool_cache = __commonJS({ } else { args = [flags]; } - if (core32.isDebug() && !flags.includes("v")) { + if (core29.isDebug() && !flags.includes("v")) { args.push("-v"); } let destArg = dest; @@ -106821,7 +106821,7 @@ var require_tool_cache = __commonJS({ args = [flags]; } args.push("-x", "-C", dest, "-f", file); - if (core32.isDebug()) { + if (core29.isDebug()) { args.push("-v"); } const xarPath = yield io9.which("xar", true); @@ -106864,7 +106864,7 @@ var require_tool_cache = __commonJS({ "-Command", pwshCommand ]; - core32.debug(`Using pwsh at path: ${pwshPath}`); + core29.debug(`Using pwsh at path: ${pwshPath}`); yield (0, exec_1.exec)(`"${pwshPath}"`, args); } else { const powershellCommand = [ @@ -106884,7 +106884,7 @@ var require_tool_cache = __commonJS({ powershellCommand ]; const powershellPath = yield io9.which("powershell", true); - core32.debug(`Using powershell at path: ${powershellPath}`); + core29.debug(`Using powershell at path: ${powershellPath}`); yield (0, exec_1.exec)(`"${powershellPath}"`, args); } }); @@ -106893,7 +106893,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 (!core32.isDebug()) { + if (!core29.isDebug()) { args.unshift("-q"); } args.unshift("-o"); @@ -106902,10 +106902,10 @@ var require_tool_cache = __commonJS({ } function cacheDir2(sourceDir, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver12.clean(version) || version; + version = semver11.clean(version) || version; arch2 = arch2 || os7.arch(); - core32.debug(`Caching tool ${tool} ${version} ${arch2}`); - core32.debug(`source dir: ${sourceDir}`); + core29.debug(`Caching tool ${tool} ${version} ${arch2}`); + core29.debug(`source dir: ${sourceDir}`); if (!fs32.statSync(sourceDir).isDirectory()) { throw new Error("sourceDir is not a directory"); } @@ -106920,16 +106920,16 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver12.clean(version) || version; + version = semver11.clean(version) || version; arch2 = arch2 || os7.arch(); - core32.debug(`Caching tool ${tool} ${version} ${arch2}`); - core32.debug(`source file: ${sourceFile}`); + core29.debug(`Caching tool ${tool} ${version} ${arch2}`); + core29.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); - core32.debug(`destination file ${destPath}`); + core29.debug(`destination file ${destPath}`); yield io9.cp(sourceFile, destPath); _completeToolPath(tool, version, arch2); return destFolder; @@ -106950,14 +106950,14 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver12.clean(versionSpec) || ""; + versionSpec = semver11.clean(versionSpec) || ""; const cachePath = path30.join(_getCacheDirectory(), toolName, versionSpec, arch2); - core32.debug(`checking cache: ${cachePath}`); + core29.debug(`checking cache: ${cachePath}`); if (fs32.existsSync(cachePath) && fs32.existsSync(`${cachePath}.complete`)) { - core32.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch2}`); + core29.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch2}`); toolPath = cachePath; } else { - core32.debug("not found"); + core29.debug("not found"); } } return toolPath; @@ -106986,7 +106986,7 @@ var require_tool_cache = __commonJS({ const http = new httpm.HttpClient("tool-cache"); const headers = {}; if (auth2) { - core32.debug("set auth"); + core29.debug("set auth"); headers.authorization = auth2; } const response = yield http.getJson(treeUrl, headers); @@ -107007,7 +107007,7 @@ var require_tool_cache = __commonJS({ try { releases = JSON.parse(versionsRaw); } catch (_a6) { - core32.debug("Invalid json"); + core29.debug("Invalid json"); } } return releases; @@ -107030,8 +107030,8 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path30.join(_getCacheDirectory(), tool, semver12.clean(version) || version, arch2 || ""); - core32.debug(`destination ${folderPath}`); + const folderPath = path30.join(_getCacheDirectory(), tool, semver11.clean(version) || version, arch2 || ""); + core29.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io9.rmRF(folderPath); yield io9.rmRF(markerPath); @@ -107040,39 +107040,39 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch2) { - const folderPath = path30.join(_getCacheDirectory(), tool, semver12.clean(version) || version, arch2 || ""); + const folderPath = path30.join(_getCacheDirectory(), tool, semver11.clean(version) || version, arch2 || ""); const markerPath = `${folderPath}.complete`; fs32.writeFileSync(markerPath, ""); - core32.debug("finished caching tool"); + core29.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver12.clean(versionSpec) || ""; - core32.debug(`isExplicit: ${c}`); - const valid4 = semver12.valid(c) != null; - core32.debug(`explicit? ${valid4}`); + const c = semver11.clean(versionSpec) || ""; + core29.debug(`isExplicit: ${c}`); + const valid4 = semver11.valid(c) != null; + core29.debug(`explicit? ${valid4}`); return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; - core32.debug(`evaluating ${versions.length} versions`); + core29.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver12.gt(a, b)) { + if (semver11.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver12.satisfies(potential, versionSpec); + const satisfied = semver11.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; } } if (version) { - core32.debug(`matched: ${version}`); + core29.debug(`matched: ${version}`); } else { - core32.debug("match not found"); + core29.debug("match not found"); } return version; } @@ -112665,14 +112665,14 @@ var require_retention = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getExpiration = void 0; var generated_1 = require_generated(); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); function getExpiration(retentionDays) { if (!retentionDays) { return void 0; } const maxRetentionDays = getRetentionDays(); if (maxRetentionDays && maxRetentionDays < retentionDays) { - core32.warning(`Retention days cannot be greater than the maximum allowed retention set within the repository. Using ${maxRetentionDays} instead.`); + core29.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(); @@ -113010,7 +113010,7 @@ var require_util11 = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.maskSecretUrls = exports2.maskSigUrl = exports2.getBackendIdsFromToken = void 0; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var config_1 = require_config2(); var jwt_decode_1 = __importDefault2(require_jwt_decode_cjs()); var core_1 = require_core(); @@ -113037,8 +113037,8 @@ var require_util11 = __commonJS({ workflowRunBackendId: scopeParts[1], workflowJobRunBackendId: scopeParts[2] }; - core32.debug(`Workflow Run Backend ID: ${ids.workflowRunBackendId}`); - core32.debug(`Workflow Job Run Backend ID: ${ids.workflowJobRunBackendId}`); + core29.debug(`Workflow Run Backend ID: ${ids.workflowRunBackendId}`); + core29.debug(`Workflow Job Run Backend ID: ${ids.workflowJobRunBackendId}`); return ids; } throw InvalidJwtError; @@ -113398,7 +113398,7 @@ var require_blob_upload = __commonJS({ exports2.uploadZipToBlobStorage = void 0; var storage_blob_1 = require_commonjs15(); var config_1 = require_config2(); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var crypto3 = __importStar2(require("crypto")); var stream2 = __importStar2(require("stream")); var errors_1 = require_errors3(); @@ -113424,9 +113424,9 @@ var require_blob_upload = __commonJS({ const bufferSize = (0, config_1.getUploadChunkSize)(); const blobClient = new storage_blob_1.BlobClient(authenticatedUploadURL); const blockBlobClient = blobClient.getBlockBlobClient(); - core32.debug(`Uploading artifact zip to blob storage with maxConcurrency: ${maxConcurrency}, bufferSize: ${bufferSize}`); + core29.debug(`Uploading artifact zip to blob storage with maxConcurrency: ${maxConcurrency}, bufferSize: ${bufferSize}`); const uploadCallback = (progress) => { - core32.info(`Uploaded bytes ${progress.loadedBytes}`); + core29.info(`Uploaded bytes ${progress.loadedBytes}`); uploadByteCount = progress.loadedBytes; lastProgressTime = Date.now(); }; @@ -113440,7 +113440,7 @@ var require_blob_upload = __commonJS({ const hashStream = crypto3.createHash("sha256"); zipUploadStream.pipe(uploadStream); zipUploadStream.pipe(hashStream).setEncoding("hex"); - core32.info("Beginning upload of artifact content to blob storage"); + core29.info("Beginning upload of artifact content to blob storage"); try { yield Promise.race([ blockBlobClient.uploadStream(uploadStream, bufferSize, maxConcurrency, options), @@ -113454,12 +113454,12 @@ var require_blob_upload = __commonJS({ } finally { abortController.abort(); } - core32.info("Finished uploading artifact content to blob storage!"); + core29.info("Finished uploading artifact content to blob storage!"); hashStream.end(); sha256Hash = hashStream.read(); - core32.info(`SHA256 digest of uploaded artifact zip is ${sha256Hash}`); + core29.info(`SHA256 digest of uploaded artifact zip is ${sha256Hash}`); if (uploadByteCount === 0) { - core32.warning(`No data was uploaded to blob storage. Reported upload byte count is 0.`); + core29.warning(`No data was uploaded to blob storage. Reported upload byte count is 0.`); } return { uploadSize: uploadByteCount, @@ -113555,7 +113555,7 @@ var require_brace_expansion2 = __commonJS({ function lte2(i, y) { return i <= y; } - function gte8(i, y) { + function gte7(i, y) { return i >= y; } function combine2(acc, pre, values, max, maxLength, dropEmpties) { @@ -113587,7 +113587,7 @@ var require_brace_expansion2 = __commonJS({ var reverse = y < x; if (reverse) { incr *= -1; - test = gte8; + test = gte7; } var pad = n.some(isPadded2); var length = 0; @@ -135113,7 +135113,7 @@ var require_zip2 = __commonJS({ var stream2 = __importStar2(require("stream")); var promises_1 = require("fs/promises"); var archiver = __importStar2(require_archiver()); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var config_1 = require_config2(); exports2.DEFAULT_COMPRESSION_LEVEL = 6; var ZipUploadStream = class extends stream2.Transform { @@ -135130,7 +135130,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) { - core32.debug(`Creating Artifact archive with compressionLevel: ${compressionLevel}`); + core29.debug(`Creating Artifact archive with compressionLevel: ${compressionLevel}`); const zip = archiver.create("zip", { highWaterMark: (0, config_1.getUploadChunkSize)(), zlib: { level: compressionLevel } @@ -135154,8 +135154,8 @@ var require_zip2 = __commonJS({ } const bufferSize = (0, config_1.getUploadChunkSize)(); const zipUploadStream = new ZipUploadStream(bufferSize); - core32.debug(`Zip write high watermark value ${zipUploadStream.writableHighWaterMark}`); - core32.debug(`Zip read high watermark value ${zipUploadStream.readableHighWaterMark}`); + core29.debug(`Zip write high watermark value ${zipUploadStream.writableHighWaterMark}`); + core29.debug(`Zip read high watermark value ${zipUploadStream.readableHighWaterMark}`); zip.pipe(zipUploadStream); zip.finalize(); return zipUploadStream; @@ -135163,24 +135163,24 @@ var require_zip2 = __commonJS({ } exports2.createZipUploadStream = createZipUploadStream; var zipErrorCallback = (error3) => { - core32.error("An error has occurred while creating the zip file for upload"); - core32.info(error3); + core29.error("An error has occurred while creating the zip file for upload"); + core29.info(error3); throw new Error("An error has occurred during zip creation for the artifact"); }; var zipWarningCallback = (error3) => { if (error3.code === "ENOENT") { - core32.warning("ENOENT warning during artifact zip creation. No such file or directory"); - core32.info(error3); + core29.warning("ENOENT warning during artifact zip creation. No such file or directory"); + core29.info(error3); } else { - core32.warning(`A non-blocking warning has occurred during artifact zip creation: ${error3.code}`); - core32.info(error3); + core29.warning(`A non-blocking warning has occurred during artifact zip creation: ${error3.code}`); + core29.info(error3); } }; var zipFinishCallback = () => { - core32.debug("Zip stream for upload has finished."); + core29.debug("Zip stream for upload has finished."); }; var zipEndCallback = () => { - core32.debug("Zip stream for upload has ended."); + core29.debug("Zip stream for upload has ended."); }; } }); @@ -135245,7 +135245,7 @@ var require_upload_artifact = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.uploadArtifact = void 0; - var core32 = __importStar2(require_core()); + var core29 = __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(); @@ -135292,13 +135292,13 @@ var require_upload_artifact = __commonJS({ value: `sha256:${uploadResult.sha256Hash}` }); } - core32.info(`Finalizing artifact upload`); + core29.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); - core32.info(`Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`); + core29.info(`Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`); return { size: uploadResult.uploadSize, digest: uploadResult.sha256Hash, @@ -142022,7 +142022,7 @@ var require_download_artifact = __commonJS({ var crypto3 = __importStar2(require("crypto")); var stream2 = __importStar2(require("stream")); var github5 = __importStar2(require_github2()); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var httpClient = __importStar2(require_lib()); var unzip_stream_1 = __importDefault2(require_unzip()); var user_agent_1 = require_user_agent2(); @@ -142058,7 +142058,7 @@ var require_download_artifact = __commonJS({ return yield streamExtractExternal(url2, directory); } catch (error3) { retryCount++; - core32.debug(`Failed to download artifact after ${retryCount} retries due to ${error3.message}. Retrying in 5 seconds...`); + core29.debug(`Failed to download artifact after ${retryCount} retries due to ${error3.message}. Retrying in 5 seconds...`); yield new Promise((resolve14) => setTimeout(resolve14, 5e3)); } } @@ -142088,7 +142088,7 @@ var require_download_artifact = __commonJS({ extractStream.on("data", () => { timer.refresh(); }).on("error", (error3) => { - core32.debug(`response.message: Artifact download failed: ${error3.message}`); + core29.debug(`response.message: Artifact download failed: ${error3.message}`); clearTimeout(timer); reject(error3); }).pipe(unzip_stream_1.default.Extract({ path: directory })).on("close", () => { @@ -142096,7 +142096,7 @@ var require_download_artifact = __commonJS({ if (hashStream) { hashStream.end(); sha256Digest = hashStream.read(); - core32.info(`SHA256 digest of downloaded artifact is ${sha256Digest}`); + core29.info(`SHA256 digest of downloaded artifact is ${sha256Digest}`); } resolve14({ sha256Digest: `sha256:${sha256Digest}` }); }).on("error", (error3) => { @@ -142111,7 +142111,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; - core32.info(`Downloading artifact '${artifactId}' from '${repositoryOwner}/${repositoryName}'`); + core29.info(`Downloading artifact '${artifactId}' from '${repositoryOwner}/${repositoryName}'`); const { headers, status } = yield api.rest.actions.downloadArtifact({ owner: repositoryOwner, repo: repositoryName, @@ -142128,16 +142128,16 @@ var require_download_artifact = __commonJS({ if (!location) { throw new Error(`Unable to redirect to artifact download url`); } - core32.info(`Redirecting to blob download url: ${scrubQueryParameters(location)}`); + core29.info(`Redirecting to blob download url: ${scrubQueryParameters(location)}`); try { - core32.info(`Starting download of artifact to: ${downloadPath}`); + core29.info(`Starting download of artifact to: ${downloadPath}`); const extractResponse = yield streamExtract(location, downloadPath); - core32.info(`Artifact download completed successfully.`); + core29.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; - core32.debug(`Computed digest: ${extractResponse.sha256Digest}`); - core32.debug(`Expected digest: ${options.expectedHash}`); + core29.debug(`Computed digest: ${extractResponse.sha256Digest}`); + core29.debug(`Expected digest: ${options.expectedHash}`); } } } catch (error3) { @@ -142164,7 +142164,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) { - core32.warning("Multiple artifacts found, defaulting to first."); + core29.warning("Multiple artifacts found, defaulting to first."); } const signedReq = { workflowRunBackendId: artifacts[0].workflowRunBackendId, @@ -142172,16 +142172,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); - core32.info(`Redirecting to blob download url: ${scrubQueryParameters(signedUrl)}`); + core29.info(`Redirecting to blob download url: ${scrubQueryParameters(signedUrl)}`); try { - core32.info(`Starting download of artifact to: ${downloadPath}`); + core29.info(`Starting download of artifact to: ${downloadPath}`); const extractResponse = yield streamExtract(signedUrl, downloadPath); - core32.info(`Artifact download completed successfully.`); + core29.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; - core32.debug(`Computed digest: ${extractResponse.sha256Digest}`); - core32.debug(`Expected digest: ${options.expectedHash}`); + core29.debug(`Computed digest: ${extractResponse.sha256Digest}`); + core29.debug(`Expected digest: ${options.expectedHash}`); } } } catch (error3) { @@ -142194,10 +142194,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))) { - core32.debug(`Artifact destination folder does not exist, creating: ${downloadPath}`); + core29.debug(`Artifact destination folder does not exist, creating: ${downloadPath}`); yield promises_1.default.mkdir(downloadPath, { recursive: true }); } else { - core32.debug(`Artifact destination folder already exists: ${downloadPath}`); + core29.debug(`Artifact destination folder already exists: ${downloadPath}`); } return downloadPath; }); @@ -142238,7 +142238,7 @@ var require_retry_options = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getRetryOptions = void 0; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var defaultMaxRetryNumber = 5; var defaultExemptStatusCodes = [400, 401, 403, 404, 422]; function getRetryOptions(defaultOptions, retries = defaultMaxRetryNumber, exemptStatusCodes = defaultExemptStatusCodes) { @@ -142253,7 +142253,7 @@ var require_retry_options = __commonJS({ retryOptions.doNotRetry = exemptStatusCodes; } const requestOptions = Object.assign(Object.assign({}, defaultOptions.request), { retries }); - core32.debug(`GitHub client configured with: (retries: ${requestOptions.retries}, retry-exempt-status-code: ${(_a6 = retryOptions.doNotRetry) !== null && _a6 !== void 0 ? _a6 : "octokit default: [400, 401, 403, 404, 422]"})`); + core29.debug(`GitHub client configured with: (retries: ${requestOptions.retries}, retry-exempt-status-code: ${(_a6 = retryOptions.doNotRetry) !== null && _a6 !== void 0 ? _a6 : "octokit default: [400, 401, 403, 404, 422]"})`); return [retryOptions, requestOptions]; } exports2.getRetryOptions = getRetryOptions; @@ -142410,7 +142410,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 core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var utils_1 = require_utils10(); var retry_options_1 = require_retry_options(); var plugin_request_log_1 = require_dist_node11(); @@ -142448,7 +142448,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]; - core32.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.id})`); + core29.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.id})`); } return { artifact: { @@ -142481,7 +142481,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]; - core32.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.databaseId})`); + core29.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.databaseId})`); } return { artifact: { @@ -145589,7 +145589,7 @@ var require_core3 = __commonJS({ ExitCode2[ExitCode2["Success"] = 0] = "Success"; ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; })(ExitCode || (exports2.ExitCode = ExitCode = {})); - function exportVariable17(name, val) { + function exportVariable2(name, val) { const convertedVal = (0, utils_1.toCommandValue)(val); process.env[name] = convertedVal; const filePath = process.env["GITHUB_ENV"] || ""; @@ -145598,7 +145598,7 @@ var require_core3 = __commonJS({ } (0, command_1.issueCommand)("set-env", { name }, convertedVal); } - exports2.exportVariable = exportVariable17; + exports2.exportVariable = exportVariable2; function setSecret2(secret) { (0, command_1.issueCommand)("add-mask", {}, secret); } @@ -145686,22 +145686,22 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); process.stdout.write(message + os7.EOL); } exports2.info = info8; - function startGroup4(name) { + function startGroup3(name) { (0, command_1.issue)("group", name); } - exports2.startGroup = startGroup4; - function endGroup4() { + exports2.startGroup = startGroup3; + function endGroup3() { (0, command_1.issue)("endgroup"); } - exports2.endGroup = endGroup4; + exports2.endGroup = endGroup3; function group(name, fn) { return __awaiter2(this, void 0, void 0, function* () { - startGroup4(name); + startGroup3(name); let result; try { result = yield fn(); } finally { - endGroup4(); + endGroup3(); } return result; }); @@ -147235,7 +147235,7 @@ var require_requestUtils2 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.retryHttpClientRequest = exports2.retry = void 0; var utils_1 = require_utils12(); - var core32 = __importStar2(require_core3()); + var core29 = __importStar2(require_core3()); var config_variables_1 = require_config_variables(); function retry2(name, operation, customErrorMessages, maxAttempts) { return __awaiter2(this, void 0, void 0, function* () { @@ -147262,13 +147262,13 @@ var require_requestUtils2 = __commonJS({ errorMessage = error3.message; } if (!isRetryable) { - core32.info(`${name} - Error is not retryable`); + core29.info(`${name} - Error is not retryable`); if (response) { (0, utils_1.displayHttpDiagnostics)(response); } break; } - core32.info(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); + core29.info(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); yield (0, utils_1.sleep)((0, utils_1.getExponentialRetryTimeInMilliseconds)(attempt)); attempt++; } @@ -147352,7 +147352,7 @@ var require_upload_http_client = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.UploadHttpClient = void 0; var fs32 = __importStar2(require("fs")); - var core32 = __importStar2(require_core3()); + var core29 = __importStar2(require_core3()); var tmp2 = __importStar2(require_tmp_promise()); var stream2 = __importStar2(require("stream")); var utils_1 = require_utils12(); @@ -147417,7 +147417,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)(); - core32.debug(`File Concurrency: ${FILE_CONCURRENCY}, and Chunk Size: ${MAX_CHUNK_SIZE}`); + core29.debug(`File Concurrency: ${FILE_CONCURRENCY}, and Chunk Size: ${MAX_CHUNK_SIZE}`); const parameters = []; let continueOnError = true; if (options) { @@ -147454,15 +147454,15 @@ var require_upload_http_client = __commonJS({ } const startTime = perf_hooks_1.performance.now(); const uploadFileResult = yield this.uploadFileAsync(index2, currentFileParameters); - if (core32.isDebug()) { - core32.debug(`File: ${++completedFiles}/${filesToUpload.length}. ${currentFileParameters.file} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish upload`); + if (core29.isDebug()) { + core29.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) { - core32.error(`aborting artifact upload`); + core29.error(`aborting artifact upload`); abortPendingFileUploads = true; } } @@ -147471,7 +147471,7 @@ var require_upload_http_client = __commonJS({ }))); this.statusReporter.stop(); this.uploadHttpManager.disposeAndReplaceAllClients(); - core32.info(`Total size of all the files uploaded is ${uploadFileSize} bytes`); + core29.info(`Total size of all the files uploaded is ${uploadFileSize} bytes`); return { uploadSize: uploadFileSize, totalSize: totalFileSize, @@ -147497,16 +147497,16 @@ var require_upload_http_client = __commonJS({ let uploadFileSize = 0; let isGzip = true; if (!isFIFO && totalFileSize < 65536) { - core32.debug(`${parameters.file} is less than 64k in size. Creating a gzip file in-memory to potentially reduce the upload size`); + core29.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) { - 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`); + core29.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 { - 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.`); + core29.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); @@ -147518,7 +147518,7 @@ var require_upload_http_client = __commonJS({ if (!result) { isUploadSuccessful = false; failedChunkSizes += uploadFileSize; - core32.warning(`Aborting upload for ${parameters.file} due to failure`); + core29.warning(`Aborting upload for ${parameters.file} due to failure`); } return { isSuccess: isUploadSuccessful, @@ -147527,16 +147527,16 @@ var require_upload_http_client = __commonJS({ }; } else { const tempFile = yield tmp2.file(); - core32.debug(`${parameters.file} is greater than 64k in size. Creating a gzip file on-disk ${tempFile.path} to potentially reduce the upload size`); + core29.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) { - 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`); + core29.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 { - core32.debug(`The gzip file created for ${parameters.file} is smaller than the original file. The file will be uploaded using gzip.`); + core29.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) { @@ -147556,7 +147556,7 @@ var require_upload_http_client = __commonJS({ if (!result) { isUploadSuccessful = false; failedChunkSizes += chunkSize; - core32.warning(`Aborting upload for ${parameters.file} due to failure`); + core29.warning(`Aborting upload for ${parameters.file} due to failure`); abortFileUpload = true; } else { if (uploadFileSize > 8388608) { @@ -147564,7 +147564,7 @@ var require_upload_http_client = __commonJS({ } } } - core32.debug(`deleting temporary gzip file ${tempFile.path}`); + core29.debug(`deleting temporary gzip file ${tempFile.path}`); yield tempFile.cleanup(); return { isSuccess: isUploadSuccessful, @@ -147603,7 +147603,7 @@ var require_upload_http_client = __commonJS({ if (response) { (0, utils_1.displayHttpDiagnostics)(response); } - core32.info(`Retry limit has been reached for chunk at offset ${start} to ${resourceUrl}`); + core29.info(`Retry limit has been reached for chunk at offset ${start} to ${resourceUrl}`); return true; } return false; @@ -147611,14 +147611,14 @@ var require_upload_http_client = __commonJS({ const backOff = (retryAfterValue) => __awaiter2(this, void 0, void 0, function* () { this.uploadHttpManager.disposeAndReplaceClient(httpClientIndex); if (retryAfterValue) { - core32.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the upload`); + core29.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); - core32.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the upload at offset ${start}`); + core29.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the upload at offset ${start}`); yield (0, utils_1.sleep)(backoffTime); } - core32.info(`Finished backoff for retry #${retryCount}, continuing with upload`); + core29.info(`Finished backoff for retry #${retryCount}, continuing with upload`); return; }); while (retryCount <= retryLimit) { @@ -147626,7 +147626,7 @@ var require_upload_http_client = __commonJS({ try { response = yield uploadChunkRequest(); } catch (error3) { - core32.info(`An error has been caught http-client index ${httpClientIndex}, retrying the upload`); + core29.info(`An error has been caught http-client index ${httpClientIndex}, retrying the upload`); console.log(error3); if (incrementAndCheckRetryLimit()) { return false; @@ -147638,13 +147638,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)) { - core32.info(`A ${response.message.statusCode} status code has been received, will attempt to retry the upload`); + core29.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 { - core32.error(`Unexpected response. Unable to upload chunk to ${resourceUrl}`); + core29.error(`Unexpected response. Unable to upload chunk to ${resourceUrl}`); (0, utils_1.displayHttpDiagnostics)(response); return false; } @@ -147662,7 +147662,7 @@ var require_upload_http_client = __commonJS({ resourceUrl.searchParams.append("artifactName", artifactName); const parameters = { Size: size }; const data = JSON.stringify(parameters, null, 2); - core32.debug(`URL is ${resourceUrl.toString()}`); + core29.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([ @@ -147675,7 +147675,7 @@ var require_upload_http_client = __commonJS({ return client.patch(resourceUrl.toString(), data, headers); }), customErrorMessages); yield response.readBody(); - core32.debug(`Artifact ${artifactName} has been successfully uploaded, total size in bytes: ${size}`); + core29.debug(`Artifact ${artifactName} has been successfully uploaded, total size in bytes: ${size}`); }); } }; @@ -147744,7 +147744,7 @@ var require_download_http_client = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DownloadHttpClient = void 0; var fs32 = __importStar2(require("fs")); - var core32 = __importStar2(require_core3()); + var core29 = __importStar2(require_core3()); var zlib3 = __importStar2(require("zlib")); var utils_1 = require_utils12(); var url_1 = require("url"); @@ -147798,11 +147798,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)(); - core32.debug(`Download file concurrency is set to ${DOWNLOAD_CONCURRENCY}`); + core29.debug(`Download file concurrency is set to ${DOWNLOAD_CONCURRENCY}`); const parallelDownloads = [...new Array(DOWNLOAD_CONCURRENCY).keys()]; let currentFile = 0; let downloadedFiles = 0; - core32.info(`Total number of files that will be downloaded: ${downloadItems.length}`); + core29.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* () { @@ -147811,8 +147811,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 (core32.isDebug()) { - core32.debug(`File: ${++downloadedFiles}/${downloadItems.length}. ${currentFileToDownload.targetPath} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish downloading`); + if (core29.isDebug()) { + core29.debug(`File: ${++downloadedFiles}/${downloadItems.length}. ${currentFileToDownload.targetPath} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish downloading`); } this.statusReporter.incrementProcessedCount(); } @@ -147850,19 +147850,19 @@ var require_download_http_client = __commonJS({ } else { this.downloadHttpManager.disposeAndReplaceClient(httpClientIndex); if (retryAfterValue) { - core32.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the download`); + core29.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); - core32.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the download`); + core29.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the download`); yield (0, utils_1.sleep)(backoffTime); } - core32.info(`Finished backoff for retry #${retryCount}, continuing with download`); + core29.info(`Finished backoff for retry #${retryCount}, continuing with download`); } }); const isAllBytesReceived = (expected, received) => { if (!expected || !received || process.env["ACTIONS_ARTIFACT_SKIP_DOWNLOAD_VALIDATION"]) { - core32.info("Skipping download validation."); + core29.info("Skipping download validation."); return true; } return parseInt(expected) === received; @@ -147883,7 +147883,7 @@ var require_download_http_client = __commonJS({ try { response = yield makeDownloadRequest(); } catch (error3) { - core32.info("An error occurred while attempting to download a file"); + core29.info("An error occurred while attempting to download a file"); console.log(error3); yield backOff(); continue; @@ -147903,7 +147903,7 @@ var require_download_http_client = __commonJS({ } } if (forceRetry || (0, utils_1.isRetryableStatusCode)(response.message.statusCode)) { - core32.info(`A ${response.message.statusCode} response code has been received while attempting to download an artifact`); + core29.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 { @@ -147925,29 +147925,29 @@ var require_download_http_client = __commonJS({ if (isGzip) { const gunzip = zlib3.createGunzip(); response.message.on("error", (error3) => { - core32.info(`An error occurred while attempting to read the response stream`); + core29.info(`An error occurred while attempting to read the response stream`); gunzip.close(); destinationStream.close(); reject(error3); }).pipe(gunzip).on("error", (error3) => { - core32.info(`An error occurred while attempting to decompress the response stream`); + core29.info(`An error occurred while attempting to decompress the response stream`); destinationStream.close(); reject(error3); }).pipe(destinationStream).on("close", () => { resolve14(); }).on("error", (error3) => { - core32.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); + core29.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); reject(error3); }); } else { response.message.on("error", (error3) => { - core32.info(`An error occurred while attempting to read the response stream`); + core29.info(`An error occurred while attempting to read the response stream`); destinationStream.close(); reject(error3); }).pipe(destinationStream).on("close", () => { resolve14(); }).on("error", (error3) => { - core32.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); + core29.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); reject(error3); }); } @@ -148086,7 +148086,7 @@ var require_artifact_client = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DefaultArtifactClient = void 0; - var core32 = __importStar2(require_core3()); + var core29 = __importStar2(require_core3()); var upload_specification_1 = require_upload_specification(); var upload_http_client_1 = require_upload_http_client(); var utils_1 = require_utils12(); @@ -148107,7 +148107,7 @@ var require_artifact_client = __commonJS({ */ uploadArtifact(name, files, rootDirectory, options) { return __awaiter2(this, void 0, void 0, function* () { - core32.info(`Starting artifact upload + core29.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); @@ -148119,24 +148119,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) { - core32.warning(`No files found that can be uploaded`); + core29.warning(`No files found that can be uploaded`); } else { const response = yield uploadHttpClient.createArtifactInFileContainer(name, options); if (!response.fileContainerResourceUrl) { - core32.debug(response.toString()); + core29.debug(response.toString()); throw new Error("No URL provided by the Artifact Service to upload an artifact to"); } - core32.debug(`Upload Resource URL: ${response.fileContainerResourceUrl}`); - core32.info(`Container for artifact "${name}" successfully created. Starting upload of file(s)`); + core29.debug(`Upload Resource URL: ${response.fileContainerResourceUrl}`); + core29.info(`Container for artifact "${name}" successfully created. Starting upload of file(s)`); const uploadResult = yield uploadHttpClient.uploadArtifactToFileContainer(response.fileContainerResourceUrl, uploadSpecification, options); - core32.info(`File upload process has finished. Finalizing the artifact upload`); + core29.info(`File upload process has finished. Finalizing the artifact upload`); yield uploadHttpClient.patchArtifactSize(uploadResult.totalSize, name); if (uploadResult.failedItems.length > 0) { - core32.info(`Upload finished. There were ${uploadResult.failedItems.length} items that failed to upload`); + core29.info(`Upload finished. There were ${uploadResult.failedItems.length} items that failed to upload`); } else { - core32.info(`Artifact has been finalized. All files have been successfully uploaded!`); + core29.info(`Artifact has been finalized. All files have been successfully uploaded!`); } - core32.info(` + core29.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 @@ -148170,10 +148170,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) { - core32.info(`No downloadable files were found for the artifact: ${artifactToDownload.name}`); + core29.info(`No downloadable files were found for the artifact: ${artifactToDownload.name}`); } else { yield (0, utils_1.createDirectoriesForArtifact)(downloadSpecification.directoryStructure); - core32.info("Directory structure has been set up for the artifact"); + core29.info("Directory structure has been set up for the artifact"); yield (0, utils_1.createEmptyFilesForArtifact)(downloadSpecification.emptyFilesToCreate); yield downloadHttpClient.downloadSingleArtifact(downloadSpecification.filesToDownload); } @@ -148189,7 +148189,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) { - core32.info("Unable to find any artifacts for the associated workflow"); + core29.info("Unable to find any artifacts for the associated workflow"); return response; } if (!path30) { @@ -148201,11 +148201,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; - core32.info(`starting download of artifact ${currentArtifactToDownload.name} : ${downloadedArtifacts}/${artifacts.count}`); + core29.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) { - core32.info(`No downloadable files were found for any artifact ${currentArtifactToDownload.name}`); + core29.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); @@ -166085,20 +166085,26 @@ module.exports = __toCommonJS(entry_points_exports); var fs23 = __toESM(require("fs")); var import_path5 = __toESM(require("path")); var import_perf_hooks6 = require("perf_hooks"); -var core17 = __toESM(require_core()); +var core14 = __toESM(require_core()); // src/action-common.ts -var core8 = __toESM(require_core()); +var core9 = __toESM(require_core()); // src/actions-util.ts var fs2 = __toESM(require("fs")); var path2 = __toESM(require("path")); -var core3 = __toESM(require_core()); +var core4 = __toESM(require_core()); var toolrunner = __toESM(require_toolrunner()); var github = __toESM(require_github()); var io2 = __toESM(require_io()); +// src/config/action-config.ts +function hasConfigKey(config, key) { + return config[key] !== void 0; +} + // src/environment.ts +var core = __toESM(require_core()); function getRequiredEnvVar(env, paramName) { const value = env[paramName]; if (value === void 0 || value.length === 0) { @@ -166144,6 +166150,24 @@ var ReadOnlyEnv = class { entries() { return Object.entries(this.vars); } + /** + * Gets a value indicating whether we should skip uploads of + * all kinds (SARIF results, status reports, DBs, ...). + * + * This is not guaranteed to be set in all test environments. + */ + isSkippingUploadsInTests() { + return this.getOptional("CODEQL_ACTION_TEST_MODE" /* TEST_MODE */) === "true"; + } + /** + * Gets a value indicative of whether we are in a testing environment + * by testing whether the value of the `NODE_ENV` variable is "test". + * This is expected to be the case if e.g. `ava` is running the tests + * or if this instance was constructed by `getTestEnv`. + */ + isTestingEnv() { + return false; + } }; var Env = class extends ReadOnlyEnv { changed = false; @@ -166152,6 +166176,20 @@ var Env = class extends ReadOnlyEnv { this.vars[name] = value; this.changed = true; } + /** + * Wrapper around `core.exportVariable` which does not call `core.exportVariable` + * when running unit tests. This is important, because otherwise `core.exportVariable` + * sets environment variables for other steps in a workflow when we run unit tests in CI. + * + * @param name The name of the environment variable to set and export. + * @param val The value to set and export for the environment variable. + */ + export(name, val) { + this.set(name, val); + if (!this.isTestingEnv()) { + core.exportVariable(name, val); + } + } /** Gets a value indicating whether `set` was called at least once. */ hasChanged() { return this.changed; @@ -166160,6 +166198,17 @@ var Env = class extends ReadOnlyEnv { function getEnv(env = process.env) { return new Env(env); } +function isInTestMode() { + return getEnv().isSkippingUploadsInTests(); +} +function exportEnvVar(name, val) { + const env = getEnv(); + if (typeof val === "string") { + env.export(name, val); + } else { + env.export(name, JSON.stringify(val)); + } +} // src/util.ts var fs = __toESM(require("fs")); @@ -166167,17 +166216,17 @@ var fsPromises = __toESM(require("fs/promises")); var os = __toESM(require("os")); var path = __toESM(require("path")); var import_perf_hooks = require("perf_hooks"); -var core2 = __toESM(require_core()); +var core3 = __toESM(require_core()); var io = __toESM(require_io()); // node_modules/get-folder-size/index.js var import_node_path = require("node:path"); async function getFolderSize(itemPath, options) { - return await core(itemPath, options, { errors: true }); + return await core2(itemPath, options, { errors: true }); } -getFolderSize.loose = async (itemPath, options) => await core(itemPath, options); -getFolderSize.strict = async (itemPath, options) => await core(itemPath, options, { strict: true }); -async function core(rootItemPath, options = {}, returnType = {}) { +getFolderSize.loose = async (itemPath, options) => await core2(itemPath, options); +getFolderSize.strict = async (itemPath, options) => await core2(itemPath, options, { strict: true }); +async function core2(rootItemPath, options = {}, returnType = {}) { const fs32 = options.fs || await import("node:fs/promises"); let folderSize = 0n; const foundInos = /* @__PURE__ */ new Set(); @@ -169780,7 +169829,7 @@ function checkGitHubVersionInRange(version, logger2) { ); } hasBeenWarnedAboutVersion = true; - core2.exportVariable(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); + exportEnvVar(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); } function apiVersionInRange(version, minimumVersion2, maximumVersion2) { if (!semver.satisfies(version, `>=${minimumVersion2}`)) { @@ -169802,11 +169851,11 @@ function assertNever(value) { throw new ExhaustivityCheckingError(value); } function initializeEnvironment(version) { - core2.exportVariable("CODEQL_ACTION_FEATURE_MULTI_LANGUAGE" /* FEATURE_MULTI_LANGUAGE */, "false"); - core2.exportVariable("CODEQL_ACTION_FEATURE_SANDWICH" /* FEATURE_SANDWICH */, "false"); - core2.exportVariable("CODEQL_ACTION_FEATURE_SARIF_COMBINE" /* FEATURE_SARIF_COMBINE */, "true"); - core2.exportVariable("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true"); - core2.exportVariable("CODEQL_ACTION_VERSION" /* VERSION */, version); + exportEnvVar("CODEQL_ACTION_FEATURE_MULTI_LANGUAGE" /* FEATURE_MULTI_LANGUAGE */, "false"); + exportEnvVar("CODEQL_ACTION_FEATURE_SANDWICH" /* FEATURE_SANDWICH */, "false"); + exportEnvVar("CODEQL_ACTION_FEATURE_SARIF_COMBINE" /* FEATURE_SARIF_COMBINE */, "true"); + exportEnvVar("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true"); + exportEnvVar("CODEQL_ACTION_VERSION" /* VERSION */, version); } var HTTPError = class extends Error { status; @@ -169874,9 +169923,6 @@ async function delay(milliseconds, opts) { function isGoodVersion(versionSpec) { return !BROKEN_VERSIONS.includes(versionSpec); } -function isInTestMode() { - return process.env["CODEQL_ACTION_TEST_MODE" /* TEST_MODE */] === "true"; -} function shouldSkipSarifUpload() { return isInTestMode() || process.env["CODEQL_ACTION_SKIP_SARIF_UPLOAD" /* SKIP_SARIF_UPLOAD */] === "true"; } @@ -169942,7 +169988,7 @@ async function waitForResultWithTimeLimit(timeoutMs, promise, onTimeout) { } async function checkForTimeout() { if (hadTimeout === true) { - core2.info( + core3.info( "A timeout occurred, force exiting the process after 30 seconds to prevent hanging." ); await delay(3e4, { allowProcessExit: true }); @@ -169993,7 +170039,7 @@ async function checkDiskUsage(logger2) { } else { logger2.debug(message); } - core2.exportVariable("CODEQL_ACTION_HAS_WARNED_ABOUT_DISK_SPACE" /* HAS_WARNED_ABOUT_DISK_SPACE */, "true"); + exportEnvVar("CODEQL_ACTION_HAS_WARNED_ABOUT_DISK_SPACE" /* HAS_WARNED_ABOUT_DISK_SPACE */, "true"); } return { numAvailableBytes: diskUsage.bavail * blockSizeInBytes, @@ -170013,10 +170059,10 @@ function checkActionVersion(version, githubVersion) { semver.coerce(githubVersion.version) ?? "0.0.0", ">=3.20" )) { - core2.warning( + core3.warning( "CodeQL Action v3 will be deprecated in December 2026. Please update all occurrences of the CodeQL Action in your workflow files to v4. For more information, see https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/" ); - core2.exportVariable("CODEQL_ACTION_DID_LOG_VERSION_DEPRECATION" /* LOG_VERSION_DEPRECATION */, "true"); + exportEnvVar("CODEQL_ACTION_DID_LOG_VERSION_DEPRECATION" /* LOG_VERSION_DEPRECATION */, "true"); } } } @@ -170120,19 +170166,18 @@ var Failure = class { function getActionsEnv() { return { getRequiredInput, - getOptionalInput, - exportVariable: core3.exportVariable + getOptionalInput }; } var getRequiredInput = function(name) { - const value = core3.getInput(name); + const value = core4.getInput(name); if (!value) { throw new ConfigurationError(`Input required and not supplied: ${name}`); } return value; }; var getOptionalInput = function(name) { - const value = core3.getInput(name); + const value = core4.getInput(name); return value.length > 0 ? value : void 0; }; function getTemporaryDirectory(env = getEnv()) { @@ -170143,7 +170188,7 @@ function getDiffRangesJsonFilePath(env = getEnv()) { return path2.join(getTemporaryDirectory(env), PR_DIFF_RANGE_JSON_FILENAME); } function getActionVersion() { - return "4.38.3"; + return "4.39.0"; } function getWorkflowEventName(env = getEnv()) { return env.getRequired("GITHUB_EVENT_NAME" /* GITHUB_EVENT_NAME */); @@ -170167,27 +170212,33 @@ function getWorkflowEvent(env = getEnv()) { ); } } -async function printDebugLogs(config) { +async function printDebugLogs(logger2, config) { + if (!hasConfigKey(config, "languages") || !hasConfigKey(config, "dbLocation")) { + logger2.debug( + `Not printing debug logs, because the configuration does not include the 'languages' or 'dbLocation' fields.` + ); + return; + } for (const language of config.languages) { const databaseDirectory = getCodeQLDatabasePath(config, language); const logsDirectory = path2.join(databaseDirectory, "log"); if (!doesDirectoryExist(logsDirectory)) { - core3.info(`Directory ${logsDirectory} does not exist.`); + logger2.info(`Directory ${logsDirectory} does not exist.`); continue; } const walkLogFiles = (dir) => { const entries = fs2.readdirSync(dir, { withFileTypes: true }); if (entries.length === 0) { - core3.info(`No debug logs found at directory ${logsDirectory}.`); + logger2.info(`No debug logs found at directory ${logsDirectory}.`); } for (const entry of entries) { if (entry.isFile()) { const absolutePath = path2.resolve(dir, entry.name); - core3.startGroup( + logger2.startGroup( `CodeQL Debug Logs - ${language} - ${entry.name} from file at path ${absolutePath}` ); - process.stdout.write(fs2.readFileSync(absolutePath)); - core3.endGroup(); + logger2.info(fs2.readFileSync(absolutePath, "utf-8")); + logger2.endGroup(); } else if (entry.isDirectory()) { walkLogFiles(path2.resolve(dir, entry.name)); } @@ -170208,7 +170259,7 @@ function getUploadValue(input) { case "never": return "never"; default: - core3.warning( + core4.warning( `Unrecognized 'upload' input to 'analyze' Action: ${input}. Defaulting to 'always'.` ); return "always"; @@ -170277,7 +170328,7 @@ var getFileType = async (filePath) => { }).exec(); return stdout.trim(); } catch (e) { - core3.info( + core4.info( `Could not determine type of ${filePath} from ${stdout}. ${stderr}` ); throw e; @@ -170362,11 +170413,11 @@ var persistInputs = function(env = getEnv()) { const inputEnvironmentVariables = entries.filter( ([name]) => name.startsWith("INPUT_") ); - core3.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables)); + core4.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables)); }; function restoreInputs(logger2) { try { - const persistedInputsValue = core3.getState(persistedInputsKey); + const persistedInputsValue = core4.getState(persistedInputsKey); if (persistedInputsValue) { const persistedInputs = JSON.parse(persistedInputsValue); for (const [name, value] of persistedInputs) { @@ -170434,32 +170485,32 @@ function fixCodeQualityCategory(logger2, category, env = getEnv()) { } // src/logging.ts -var core4 = __toESM(require_core()); +var core5 = __toESM(require_core()); function getActionsLogger() { return { - debug: core4.debug, - info: core4.info, - warning: core4.warning, - error: core4.error, - isDebug: core4.isDebug, - startGroup: core4.startGroup, - endGroup: core4.endGroup + debug: core5.debug, + info: core5.info, + warning: core5.warning, + error: core5.error, + isDebug: core5.isDebug, + startGroup: core5.startGroup, + endGroup: core5.endGroup }; } function withGroup(groupName, f) { - core4.startGroup(groupName); + core5.startGroup(groupName); try { return f(); } finally { - core4.endGroup(); + core5.endGroup(); } } async function withGroupAsync(groupName, f) { - core4.startGroup(groupName); + core5.startGroup(groupName); try { return await f(); } finally { - core4.endGroup(); + core5.endGroup(); } } function formatDuration(durationMs) { @@ -170476,7 +170527,7 @@ function formatDuration(durationMs) { // src/status-report.ts var os3 = __toESM(require("os")); -var core7 = __toESM(require_core()); +var core8 = __toESM(require_core()); // node_modules/uuid/dist-node/regex.js var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i; @@ -170532,7 +170583,7 @@ function _v4(options, buf, offset) { var v4_default = v4; // src/api-client.ts -var core5 = __toESM(require_core()); +var core6 = __toESM(require_core()); var githubUtils = __toESM(require_utils4()); // node_modules/@octokit/plugin-retry/dist-bundle/index.js @@ -170683,10 +170734,10 @@ function createApiClientWithDetails(apiDetails, { allowExternal = false, proxy = baseUrl: apiDetails.apiURL, userAgent: `CodeQL-Action/${getActionVersion()}`, log: { - debug: core5.debug, - info: core5.info, - warn: core5.warning, - error: core5.error + debug: core6.debug, + info: core6.info, + warn: core6.warning, + error: core6.error }, request: requestOptions, retry: { @@ -170773,7 +170824,7 @@ async function getAnalysisKey() { const workflowPath = await getWorkflowRelativePath(); const jobName = getRequiredEnvParam("GITHUB_JOB"); analysisKey = `${workflowPath}:${jobName}`; - core5.exportVariable("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); + exportEnvVar("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); return analysisKey; } async function getAutomationID() { @@ -170952,7 +171003,7 @@ function parseRegistriesWithoutCredentials(registriesInput) { var fs4 = __toESM(require("fs")); var os2 = __toESM(require("os")); var path4 = __toESM(require("path")); -var core6 = __toESM(require_core()); +var core7 = __toESM(require_core()); var toolrunner2 = __toESM(require_toolrunner()); var io3 = __toESM(require_io()); var semver2 = __toESM(require_semver2()); @@ -170983,7 +171034,7 @@ async function getGitVersionOrThrow() { var runGitCommand = async function(workingDirectory, args, customErrorMessage, options) { let stdout = ""; let stderr = ""; - core6.debug(`Running git command: git ${args.join(" ")}`); + core7.debug(`Running git command: git ${args.join(" ")}`); try { await new toolrunner2.ToolRunner(await io3.which("git", true), args, { silent: true, @@ -171004,7 +171055,7 @@ var runGitCommand = async function(workingDirectory, args, customErrorMessage, o if (stderr.includes("not a git repository")) { reason = "The checkout path provided to the action does not appear to be a git repository."; } - core6.info(`git call failed. ${customErrorMessage} Error: ${reason}`); + core7.info(`git call failed. ${customErrorMessage} Error: ${reason}`); throw error3; } }; @@ -171167,7 +171218,7 @@ async function getRef() { ) !== head; if (hasChangedRef) { const newRef = ref.replace(pull_ref_regex, "refs/pull/$1/head"); - core6.debug( + core7.debug( `No longer on merge commit, rewriting ref from ${ref} to ${newRef}.` ); return newRef; @@ -171361,9 +171412,14 @@ function getAddressString(address) { } // src/status-report.ts +var ACTION_DISPLAY_NAMES = { + ["finish" /* Analyze */]: "analyze", + ["init-post" /* InitPost */]: "init post" +}; function getDisplayActionName(actionName) { - if (actionName === "finish" /* Analyze */) { - return "analyze"; + const displayName = ACTION_DISPLAY_NAMES[actionName]; + if (displayName !== void 0) { + return displayName; } return actionName; } @@ -171375,7 +171431,7 @@ function getJobUUID(action) { } const jobRunUuid = v4_default(); action.logger.info(`Job run UUID is ${jobRunUuid}.`); - action.actions.exportVariable("CODEQL_ACTION_JOB_RUN_UUID" /* JOB_RUN_UUID */, jobRunUuid); + action.env.export("CODEQL_ACTION_JOB_RUN_UUID" /* JOB_RUN_UUID */, jobRunUuid); return jobRunUuid; } function isFirstPartyAnalysis(actionName) { @@ -171417,12 +171473,12 @@ function getJobStatusDisplayName(status) { } function setJobStatusIfUnsuccessful(actionStatus) { if (actionStatus === "user-error") { - core7.exportVariable( + exportEnvVar( "CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */] ?? "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */ ); } else if (actionStatus === "failure" || actionStatus === "aborted") { - core7.exportVariable( + exportEnvVar( "CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */] ?? "JOB_STATUS_FAILURE" /* FailureStatus */ ); @@ -171469,7 +171525,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi let workflowStartedAt = process.env["CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */]; if (workflowStartedAt === void 0) { workflowStartedAt = actionStartedAt.toISOString(); - core7.exportVariable("CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */, workflowStartedAt); + exportEnvVar("CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */, workflowStartedAt); } const runnerOs = getRequiredEnvParam("RUNNER_OS"); const codeQlCliVersion = getCachedCodeQlVersion( @@ -171479,7 +171535,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi const actionRef = process.env["GITHUB_ACTION_REF"] || ""; const testingEnvironment = getTestingEnvironment(); if (testingEnvironment) { - core7.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment); + exportEnvVar("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment); } const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true"; const statusReport = { @@ -171564,9 +171620,9 @@ var INCOMPATIBLE_MSG = "CodeQL Action version is incompatible with the API endpo async function sendStatusReport(statusReport) { setJobStatusIfUnsuccessful(statusReport.status); const statusReportJSON = JSON.stringify(statusReport); - core7.debug(`Sending status report: ${statusReportJSON}`); + core8.debug(`Sending status report: ${statusReportJSON}`); if (isInTestMode()) { - core7.debug("In test mode. Status reports are not uploaded."); + core8.debug("In test mode. Status reports are not uploaded."); return; } const nwo = getRepositoryNwo(); @@ -171586,28 +171642,28 @@ async function sendStatusReport(statusReport) { switch (httpError.status) { case 403: if (getWorkflowEventName() === "push" && process.env["GITHUB_ACTOR"] === "dependabot[bot]") { - core7.warning( + core8.warning( `Workflows triggered by Dependabot on the "push" event run with read-only access. Uploading CodeQL results requires write access. To use CodeQL with Dependabot, please ensure you are using the "pull_request" event for this workflow and avoid triggering on the "push" event for Dependabot branches. See ${"https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#scanning-on-push" /* SCANNING_ON_PUSH */} for more information on how to configure these events.` ); } else { - core7.warning( + core8.warning( `This run of the CodeQL Action does not have permission to access the CodeQL Action API endpoints. This could be because the Action is running on a pull request from a fork. If not, please ensure the workflow has at least the 'security-events: read' permission. Details: ${httpError.message}` ); } return; case 404: - core7.warning(httpError.message); + core8.warning(httpError.message); return; case 422: if (getRequiredEnvParam("GITHUB_SERVER_URL") !== GITHUB_DOTCOM_URL) { - core7.debug(INCOMPATIBLE_MSG); + core8.debug(INCOMPATIBLE_MSG); } else { - core7.debug(OUT_OF_DATE_MSG); + core8.debug(OUT_OF_DATE_MSG); } return; } } - core7.warning( + core8.warning( `An unexpected error occurred when sending a status report: ${getErrorMessage( e )}` @@ -171686,6 +171742,9 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error } // src/action-common.ts +function extendActionState(state, extra) { + return { ...state, ...extra }; +} async function runInActions(action) { const startedAt = /* @__PURE__ */ new Date(); const logger2 = getActionsLogger(); @@ -171704,7 +171763,7 @@ async function runInActions(action) { getJobUUID(actionState); await action.run(actionState); } catch (error3) { - core8.setFailed( + core9.setFailed( `${getDisplayActionName(action.name)} action failed: ${getErrorMessage(error3)}` ); const statusReportError = action.transformTelemetryError !== void 0 ? action.transformTelemetryError(wrapError(error3)) : error3; @@ -171720,7 +171779,7 @@ async function runInActions(action) { // src/feature-flags.ts var fs6 = __toESM(require("fs")); var path6 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); // src/defaults.json var bundleVersion = "codeql-bundle-v2.27.2"; @@ -171840,14 +171899,9 @@ async function getDiffRangeFilePaths(sourceRoot, logger2) { } // src/tools-features.ts -var semver3 = __toESM(require_semver2()); function isSupportedToolsFeature(versionInfo, feature) { return !!versionInfo.features && versionInfo.features[feature]; } -var SafeArtifactUploadVersion = "2.20.3"; -function isSafeArtifactUpload(codeQlVersion) { - return !codeQlVersion ? true : semver3.gte(codeQlVersion, SafeArtifactUploadVersion); -} // src/feature-flags.ts var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_"; @@ -171887,7 +171941,7 @@ var featureConfig = { defaultValue: false, envVar: "CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES", legacyApi: true, - minimumVersion: "2.15.0" + minimumVersion: void 0 }, ["csharp_cache_bmn" /* CsharpCacheBuildModeNone */]: { defaultValue: false, @@ -172298,7 +172352,7 @@ var GitHubFeatureFlags = class { DEFAULT_VERSION_FEATURE_FLAG_PREFIX.length, f.length - DEFAULT_VERSION_FEATURE_FLAG_SUFFIX.length ).replace(/_/g, "."); - if (!semver4.valid(version)) { + if (!semver3.valid(version)) { this.logger.warning( `Ignoring feature flag ${f} as it does not specify a valid CodeQL version.` ); @@ -172315,7 +172369,7 @@ var GitHubFeatureFlags = class { const response = await this.getAllFeatures(); const sortedCliVersions = Object.entries(response).map( ([f, isEnabled]) => isEnabled ? this.getCliVersionFromFeatureFlag(f) : void 0 - ).filter((f) => f !== void 0).sort(semver4.rcompare); + ).filter((f) => f !== void 0).sort(semver3.rcompare); if (sortedCliVersions.length === 0) { this.logger.warning( `Feature flags do not specify a default CLI version. Falling back to the CLI version shipped with the Action. This is ${cliVersion}.` @@ -172609,13 +172663,10 @@ var path16 = __toESM(require("path")); var import_perf_hooks5 = require("perf_hooks"); var io5 = __toESM(require_io()); -// src/autobuild.ts -var core14 = __toESM(require_core()); - // src/codeql.ts var fs16 = __toESM(require("fs")); var path15 = __toESM(require("path")); -var core13 = __toESM(require_core()); +var core12 = __toESM(require_core()); var toolrunner3 = __toESM(require_toolrunner()); // src/cli-errors.ts @@ -172871,11 +172922,10 @@ function wrapCliConfigurationError(cliError) { var fs10 = __toESM(require("fs")); var path11 = __toESM(require("path")); var import_perf_hooks2 = require("perf_hooks"); -var core10 = __toESM(require_core()); // src/caching-utils.ts var crypto2 = __toESM(require("crypto")); -var core9 = __toESM(require_core()); +var core10 = __toESM(require_core()); async function getTotalCacheSize(paths, logger2, quiet = false) { const sizes = await Promise.all( paths.map((cacheDir2) => tryGetFolderBytes(cacheDir2, logger2, quiet)) @@ -172904,7 +172954,7 @@ function getCachingKind(input) { case "restore": return "restore" /* Restore */; default: - core9.warning( + core10.warning( `Unrecognized 'dependency-caching' input: ${input}. Defaulting to 'none'.` ); return "none" /* None */; @@ -172926,7 +172976,7 @@ function getDependencyCachingEnabled() { // src/config/db-config.ts var path8 = __toESM(require("path")); var jsonschema = __toESM(require_lib2()); -var semver5 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); // src/diagnostics.ts var import_fs = require("fs"); @@ -173341,7 +173391,7 @@ function parsePacksSpecification(packStr) { } if (version) { try { - new semver5.Range(version); + new semver4.Range(version); } catch { throw new ConfigurationError(getPacksStrInvalid(packStr)); } @@ -174786,10 +174836,10 @@ async function setCppTrapCachingEnvironmentVariables(config, logger2) { ); } else if (config.trapCaches["cpp" /* cpp */]) { logger2.info("Enabling TRAP caching for C/C++."); - core10.exportVariable(envVar, "true"); + exportEnvVar(envVar, "true"); } else { logger2.debug(`Disabling TRAP caching for C/C++.`); - core10.exportVariable(envVar, "false"); + exportEnvVar(envVar, "false"); } } } @@ -175019,20 +175069,47 @@ function getLocalConfig(logger2, configFile, validateConfig) { function getPathToParsedConfigFile(tempDir) { return path11.join(tempDir, "config"); } -async function saveConfig(config, logger2) { +function getPathToFailedConfigFile(tempDir) { + return path11.join(tempDir, "failed-config"); +} +function saveConfigFile(logger2, configFilePath, config) { const configString = JSON.stringify(config); - const configFile = getPathToParsedConfigFile(config.tempDir); - fs10.mkdirSync(path11.dirname(configFile), { recursive: true }); - fs10.writeFileSync(configFile, configString, "utf8"); + fs10.mkdirSync(path11.dirname(configFilePath), { recursive: true }); + fs10.writeFileSync(configFilePath, configString, "utf8"); logger2.debug("Saved config:"); logger2.debug(configString); } -async function getConfig(tempDir, logger2) { - const configFile = getPathToParsedConfigFile(tempDir); - if (!fs10.existsSync(configFile)) { +async function saveConfig(config, logger2) { + const configFile = getPathToParsedConfigFile(config.tempDir); + saveConfigFile(logger2, configFile, config); +} +function saveAbortedInitConfig(action, config) { + if (action.name !== "init" /* Init */) { + throw new Error( + `Internal error: 'saveAbortedInitConfig' should only be called by '${"init" /* Init */}', but was called by '${action.name}'.` + ); + } + const failedConfig = { + version: config.version, + tempDir: config.tempDir, + codeQLCmd: config.codeQLCmd, + debugMode: config.debugMode, + gitHubVersion: config.gitHubVersion, + languages: config.languages, + analysisKinds: config.analysisKinds + }; + action.logger.debug(`Saving config for failed init step.`); + saveConfigFile( + action.logger, + getPathToFailedConfigFile(config.tempDir), + failedConfig + ); +} +function readConfigFile(logger2, configFilePath) { + if (!fs10.existsSync(configFilePath)) { return void 0; } - const configString = fs10.readFileSync(configFile, "utf8"); + const configString = fs10.readFileSync(configFilePath, "utf8"); logger2.debug("Loaded config:"); logger2.debug(configString); const config = JSON.parse(configString); @@ -175053,6 +175130,18 @@ async function getConfig(tempDir, logger2) { } return config; } +async function getConfig(tempDir, logger2) { + const configFile = getPathToParsedConfigFile(tempDir); + return readConfigFile(logger2, configFile); +} +function getAbortedInitConfig(action, tempDir) { + if (action.name !== "init-post" /* InitPost */) { + throw new Error( + `Internal error: 'getAbortedInitConfig' should only be called by '${"init-post" /* InitPost */}', but was called by '${action.name}'.` + ); + } + return readConfigFile(action.logger, getPathToFailedConfigFile(tempDir)); +} async function generateRegistries(registriesInput, tempDir, logger2) { const registries = parseRegistries(registriesInput); let registriesAuthTokens; @@ -175193,10 +175282,9 @@ async function logGeneratedFilesTelemetry(config, duration, generatedFilesCount) var fs14 = __toESM(require("fs")); var path13 = __toESM(require("path")); var import_perf_hooks4 = require("perf_hooks"); -var core12 = __toESM(require_core()); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver10 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); // src/codeql-bundle.ts function getCodeQLBundleName(compressionMethod, platform2, language) { @@ -175230,7 +175318,7 @@ function getCodeQLBundleFromUrl(url2) { // src/overlay/caching.ts var fs11 = __toESM(require("fs")); var actionsCache3 = __toESM(require_cache4()); -var semver6 = __toESM(require_semver2()); +var semver5 = __toESM(require_semver2()); var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; var CACHE_VERSION2 = 1; @@ -175507,7 +175595,7 @@ async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger2) { if (!cache.key) continue; const suffix = cache.key.substring(cacheKeyPrefix.length); const match2 = suffix.match(versionRegex); - if (match2 && semver6.valid(match2[1])) { + if (match2 && semver5.valid(match2[1])) { versionSet.add(match2[1]); } } @@ -175517,7 +175605,7 @@ async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger2) { ); return []; } - const versions = [...versionSet].sort(semver6.rcompare); + const versions = [...versionSet].sort(semver5.rcompare); logger2.info( `Found overlay databases for the following CodeQL versions in the Actions cache: ${versions.join(", ")}` ); @@ -175525,7 +175613,7 @@ async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger2) { } // src/per-language-bundles.ts -var semver7 = __toESM(require_semver2()); +var semver6 = __toESM(require_semver2()); // src/platform.ts function getBundlePlatform(platform2 = process.platform, arch2 = process.arch) { @@ -175632,7 +175720,7 @@ async function getPerLanguageBundleLanguage({ if (cliVersion2 === void 0) { return explain("the requested CLI version is unknown"); } - if (!semver7.gte(cliVersion2, MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION)) { + if (!semver6.gte(cliVersion2, MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION)) { return explain( `the requested CodeQL version ${cliVersion2} is older than ${MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION}, which is the first version for which per-language bundles are published` ); @@ -175658,7 +175746,7 @@ var stream = __toESM(require("stream")); var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver8 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); var MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3"; var MIN_REQUIRED_GNU_TAR_VERSION = "1.31"; async function getTarVersion() { @@ -175700,9 +175788,9 @@ async function isZstdAvailable(logger2) { case "gnu": return { available: foundZstdBinary && // GNU tar only uses major and minor version numbers - semver8.gte( - semver8.coerce(version), - semver8.coerce(MIN_REQUIRED_GNU_TAR_VERSION) + semver7.gte( + semver7.coerce(version), + semver7.coerce(MIN_REQUIRED_GNU_TAR_VERSION) ), foundZstdBinary, version: tarVersion @@ -175711,7 +175799,7 @@ async function isZstdAvailable(logger2) { return { available: foundZstdBinary && // Do a loose comparison since these version numbers don't contain // a patch version number. - semver8.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), + semver7.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), foundZstdBinary, version: tarVersion }; @@ -175820,7 +175908,7 @@ var core11 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver9 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; var STREAMING_STALL_TIMEOUT_MS = 5 * 60 * 1e3; var TOOLCACHE_TOOL_NAME = "CodeQL"; @@ -175946,7 +176034,7 @@ function getToolcacheToolDirectory(env) { ); } function getToolcacheVersionDirectoryName(version) { - return semver9.clean(version) || version; + return semver8.clean(version) || version; } function getToolcacheDirectory(version) { return path12.join( @@ -176126,13 +176214,13 @@ function tryGetTagNameFromUrl(url2, logger2) { return match2[1]; } function convertToSemVer(version, logger2) { - if (!semver10.valid(version)) { + if (!semver9.valid(version)) { logger2.debug( `Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.` ); version = `0.0.0-${version}`; } - const s = semver10.clean(version); + const s = semver9.clean(version); if (!s) { throw new Error(`Bundle version ${version} is not in SemVer format.`); } @@ -176348,7 +176436,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, othe url2 = toolsInput; if (tagName) { const bundleVersion3 = tryGetBundleVersionFromTagName(tagName, logger2); - if (bundleVersion3 !== void 0 && semver10.valid(bundleVersion3)) { + if (bundleVersion3 !== void 0 && semver9.valid(bundleVersion3)) { cliVersion2 = convertToSemVer(bundleVersion3, logger2); } } @@ -176681,7 +176769,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"); + exportEnvVar("CODEQL_ACTION_HAS_SET_UP_CODEQL" /* HAS_SET_UP_CODEQL */, "true"); return { codeqlFolder, toolsDownloadStatusReport, @@ -176730,7 +176818,7 @@ async function downloadCodeQLBundle(action, source, apiDetails, tarVersion, temp async function useZstdBundle(cliVersion2, tarSupportsZstd) { return ( // In testing, gzip performs better than zstd on Windows. - process.platform !== "win32" && tarSupportsZstd && semver10.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) + process.platform !== "win32" && tarSupportsZstd && semver9.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) ); } function getTempExtractionDir(tempDir) { @@ -176784,7 +176872,7 @@ async function getLatestNightlyBundle(action, rawLanguages, otherLanguagePacksRe } } function getLatestToolcacheVersion(logger2) { - const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver10.compare(b, a)); + const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver9.compare(b, a)); logger2.debug( `Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify( allVersions @@ -176872,7 +176960,7 @@ async function getCombinedTracerConfig(logger2, codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; -var CODEQL_MINIMUM_VERSION = "2.19.4"; +var CODEQL_MINIMUM_VERSION = "2.20.7"; var CODEQL_NEXT_MINIMUM_VERSION = "2.21.3"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.17"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-09-24"; @@ -176962,7 +177050,7 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion) { return result; }, async printVersion() { - core13.info(JSON.stringify(await this.getVersion(), null, 2)); + core12.info(JSON.stringify(await this.getVersion(), null, 2)); }, async supportsFeature(feature) { return isSupportedToolsFeature(await this.getVersion(), feature); @@ -177355,12 +177443,12 @@ Output was: ${extractorPath}` ); } 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(); - core13.warning( + core12.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.` ); - core13.exportVariable("CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */, "true"); + exportEnvVar("CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */, "true"); } return codeql; } @@ -177513,7 +177601,7 @@ async function determineAutobuildLanguages(codeql, config, logger2) { } return languages; } -async function setupCppAutobuild(codeql, logger2) { +async function setupCppAutobuild(logger2) { const envVar = featureConfig["cpp_dependency_installation_enabled" /* CppDependencyInstallation */].envVar; const featureName = "C++ automatic installation of dependencies"; const gitHubVersion = await getGitHubVersion(); @@ -177524,28 +177612,28 @@ async function setupCppAutobuild(codeql, logger2) { getTemporaryDirectory(), logger2 ); - if (await features.getValue("cpp_dependency_installation_enabled" /* CppDependencyInstallation */, codeql)) { + if (await features.getValue("cpp_dependency_installation_enabled" /* CppDependencyInstallation */)) { if (process.env["RUNNER_ENVIRONMENT" /* RUNNER_ENVIRONMENT */] === "self-hosted" && process.env[envVar] !== "true") { logger2.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.` : ""}` ); - core14.exportVariable(envVar, "false"); + exportEnvVar(envVar, "false"); } else { logger2.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.` ); - core14.exportVariable(envVar, "true"); + exportEnvVar(envVar, "true"); } } else { logger2.info(`Disabling ${featureName}.`); - core14.exportVariable(envVar, "false"); + exportEnvVar(envVar, "false"); } } async function runAutobuild(config, language, logger2) { logger2.startGroup(`Attempting to automatically build ${language} code`); const codeQL = await getCodeQL(logger2, config.codeQLCmd); if (language === "cpp" /* cpp */) { - await setupCppAutobuild(codeQL, logger2); + await setupCppAutobuild(logger2); } if (config.buildMode) { await codeQL.extractUsingBuildMode(config, language); @@ -177553,7 +177641,7 @@ async function runAutobuild(config, language, logger2) { await codeQL.runAutobuild(config, language); } if (language === "go" /* go */) { - core14.exportVariable("CODEQL_ACTION_DID_AUTOBUILD_GOLANG" /* DID_AUTOBUILD_GOLANG */, "true"); + exportEnvVar("CODEQL_ACTION_DID_AUTOBUILD_GOLANG" /* DID_AUTOBUILD_GOLANG */, "true"); } logger2.endGroup(); } @@ -177869,7 +177957,7 @@ async function runExtraction(codeql, features, config, logger2) { } if (config.buildMode) { if (language === "cpp" /* cpp */ && config.buildMode === "autobuild" /* Autobuild */) { - await setupCppAutobuild(codeql, logger2); + await setupCppAutobuild(logger2); } if (language === "java" /* java */ && config.buildMode === "none" /* None */) { process.env["CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_DEPENDENCY_DIR"] = getJavaTempDependencyDir(); @@ -178401,7 +178489,7 @@ var fs22 = __toESM(require("fs")); var path19 = __toESM(require("path")); var url = __toESM(require("url")); var import_zlib = __toESM(require("zlib")); -var core16 = __toESM(require_core()); +var core13 = __toESM(require_core()); var jsonschema2 = __toESM(require_lib2()); // src/fingerprints.ts @@ -179529,7 +179617,6 @@ async function addFingerprints(sarifLog, sourceRoot, logger2) { // src/init.ts var fs20 = __toESM(require("fs")); var path18 = __toESM(require("path")); -var core15 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github3 = __toESM(require_github()); var io6 = __toESM(require_io()); @@ -179752,7 +179839,7 @@ To opt out of this change, switch to an advanced setup workflow and ${envVarOptO To opt out of this change, ${envVarOptOut}`; } logger2.warning(message); - core15.exportVariable("CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION" /* DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION */, "true"); + exportEnvVar("CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION" /* DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION */, "true"); } // src/sarif/index.ts @@ -179872,7 +179959,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo logger2.warning( `Uploading multiple SARIF runs with the same category is deprecated ${deprecationWarningMessage}. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}` ); - core16.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); + exportEnvVar("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); } return combineSarifFiles(sarifFiles, logger2); } @@ -179975,13 +180062,13 @@ async function uploadPayload(payload, repositoryNwo, logger2, analysis) { if (httpError !== void 0) { switch (httpError.status) { case 403: - core16.warning(httpError.message || GENERIC_403_MSG); + core13.warning(httpError.message || GENERIC_403_MSG); break; case 404: - core16.warning(httpError.message || GENERIC_404_MSG); + core13.warning(httpError.message || GENERIC_404_MSG); break; default: - core16.warning(httpError.message); + core13.warning(httpError.message); break; } } @@ -180419,7 +180506,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"})` ); } - core16.exportVariable(sentinelEnvVar, sentinelEnvVar); + exportEnvVar(sentinelEnvVar, sentinelEnvVar); } } function sanitize(str) { @@ -180591,6 +180678,7 @@ async function runAutobuildIfLegacyGoWorkflow(config, logger2) { } async function run({ startedAt, + env, logger: logger2, actions }) { @@ -180629,11 +180717,6 @@ async function run({ "`expect-error` input parameter is for internal use only. It should only be set by codeql-action or a fork." ); } - if (process.env.CODEQL_PROXY_HOST === "" && !await codeQlVersionAtLeast(codeql, "2.20.7")) { - delete process.env.CODEQL_PROXY_HOST; - delete process.env.CODEQL_PROXY_PORT; - delete process.env.CODEQL_PROXY_CA_CERTIFICATE; - } if (getOptionalInput("cleanup-level")) { logger2.info( "The 'cleanup-level' input is ignored since the CodeQL Action now automatically manages database cleanup. This input can safely be removed from your workflow." @@ -180641,7 +180724,7 @@ async function run({ } const apiDetails = getApiDetails(); const outputDir = getRequiredInput("output"); - core17.exportVariable("CODEQL_ACTION_SARIF_RESULTS_OUTPUT_DIR" /* SARIF_RESULTS_OUTPUT_DIR */, outputDir); + env.export("CODEQL_ACTION_SARIF_RESULTS_OUTPUT_DIR" /* SARIF_RESULTS_OUTPUT_DIR */, outputDir); const threads = getThreadsFlag( getOptionalInput("threads") || process.env["CODEQL_THREADS"], logger2 @@ -180697,8 +180780,8 @@ async function run({ for (const language of config.languages) { dbLocations[language] = getCodeQLDatabasePath(config, language); } - core17.setOutput("db-locations", dbLocations); - core17.setOutput("sarif-output", import_path5.default.resolve(outputDir)); + core14.setOutput("db-locations", dbLocations); + core14.setOutput("sarif-output", import_path5.default.resolve(outputDir)); const uploadKind = getUploadValue( getOptionalInput("upload") ); @@ -180714,13 +180797,13 @@ async function run({ getOptionalInput("post-processed-sarif-path") ); if (uploadResults["code-scanning" /* CodeScanning */] !== void 0) { - core17.setOutput( + core14.setOutput( "sarif-id", uploadResults["code-scanning" /* CodeScanning */].sarifID ); } if (uploadResults["code-quality" /* CodeQuality */] !== void 0) { - core17.setOutput( + core14.setOutput( "quality-sarif-id", uploadResults["code-quality" /* CodeQuality */].sarifID ); @@ -180768,15 +180851,15 @@ async function run({ ); } if (getOptionalInput("expect-error") === "true") { - core17.setFailed( + core14.setFailed( `expect-error input was set to true but no error was thrown.` ); } - core17.exportVariable("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */, "true"); + env.export("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */, "true"); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); if (getOptionalInput("expect-error") !== "true" || hasBadExpectErrorInput()) { - core17.setFailed(error3.message); + core14.setFailed(error3.message); } await sendStatusReport2( startedAt, @@ -180851,14 +180934,14 @@ async function runWrapper() { // src/analyze-action-post.ts var fs27 = __toESM(require("fs")); -var core19 = __toESM(require_core()); +var core16 = __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 core18 = __toESM(require_core()); +var core15 = __toESM(require_core()); // node_modules/archiver/lib/core.js var import_fs2 = require("fs"); @@ -181002,7 +181085,7 @@ function isPadded(el) { function lte(i, y) { return i <= y; } -function gte7(i, y) { +function gte6(i, y) { return i >= y; } function combine(acc, pre, values, max, maxLength, dropEmpties) { @@ -181037,7 +181120,7 @@ function expandSequence(body, isAlphaSequence, max, maxLength) { const reverse = y < x; if (reverse) { incr *= -1; - test = gte7; + test = gte6; } const pad = n.some(isPadded); let length = 0; @@ -185498,7 +185581,7 @@ async function scanArtifactsForTokens(filesToScan, logger2) { function sanitizeArtifactName(name) { return name.replace(/[^a-zA-Z0-9_-]+/g, ""); } -async function uploadCombinedSarifArtifacts(logger2, gitHubVariant, codeQlVersion) { +async function uploadCombinedSarifArtifacts(logger2, gitHubVariant) { const tempDir = getTemporaryDirectory(); if (process.env["CODEQL_ACTION_DEBUG_COMBINED_SARIF"] === "true") { await withGroup("Uploading combined SARIF debug artifact", async () => { @@ -185517,13 +185600,12 @@ async function uploadCombinedSarifArtifacts(logger2, gitHubVariant, codeQlVersio } } try { - await uploadDebugArtifacts( + await uploadArtifacts( logger2, toUpload, baseTempDir, "combined-sarif-artifacts", - gitHubVariant, - codeQlVersion + gitHubVariant ); } catch (e) { logger2.warning( @@ -185582,7 +185664,7 @@ async function tryBundleDatabase(codeql, config, language, logger2) { return void 0; } } -async function tryUploadAllAvailableDebugArtifacts(codeql, config, logger2, codeQlVersion) { +async function tryUploadAllAvailableDebugArtifacts(codeql, config, logger2) { const filesToUpload = []; try { for (const language of config.languages) { @@ -185635,13 +185717,12 @@ async function tryUploadAllAvailableDebugArtifacts(codeql, config, logger2, code try { await withGroup( "Uploading debug artifacts", - async () => uploadDebugArtifacts( + async () => uploadArtifacts( logger2, filesToUpload, config.dbLocation, config.debugArtifactName, - config.gitHubVersion.type, - codeQlVersion + config.gitHubVersion.type ) ); } catch (e) { @@ -185659,33 +185740,23 @@ function getArtifactSuffix(matrix) { for (const matrixKey of Object.keys(matrixObject).sort()) suffix += `-${matrixObject[matrixKey]}`; } else { - core18.warning("User-specified `matrix` input is not an object."); + core15.warning("User-specified `matrix` input is not an object."); } } catch { - core18.warning( + core15.warning( "Could not parse user-specified `matrix` input into JSON. The debug artifact will not be named with the user's `matrix` input." ); } } return suffix; } -async function uploadDebugArtifacts(logger2, toUpload, rootDir, artifactName, ghVariant, codeQlVersion) { - const uploadSupported = isSafeArtifactUpload(codeQlVersion); - if (!uploadSupported) { - 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"; - } - return uploadArtifacts(logger2, toUpload, rootDir, artifactName, ghVariant); -} async function uploadArtifacts(logger2, toUpload, rootDir, artifactName, ghVariant) { if (toUpload.length === 0) { return "no-artifacts-to-upload"; } if (isInTestMode()) { await scanArtifactsForTokens(toUpload, logger2); - core18.exportVariable("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); + exportEnvVar("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); } const suffix = getArtifactSuffix(getOptionalInput("matrix")); const artifactUploader = await getArtifactUploaderClient(logger2, ghVariant); @@ -185701,7 +185772,7 @@ async function uploadArtifacts(logger2, toUpload, rootDir, artifactName, ghVaria ); return "upload-successful"; } catch (e) { - core18.warning(`Failed to upload debug artifacts: ${e}`); + core15.warning(`Failed to upload debug artifacts: ${e}`); return "upload-failed"; } } @@ -185724,7 +185795,7 @@ async function createPartialDatabaseBundle(config, language) { config.dbLocation, `${config.debugDatabaseName}-${language}-partial.zip` ); - core18.info( + core15.info( `${config.debugDatabaseName}-${language} is not finalized. Uploading partial database bundle at ${databaseBundlePath}...` ); if (fs26.existsSync(databaseBundlePath)) { @@ -185769,12 +185840,9 @@ async function runWrapper2() { logger2 ); if (config !== void 0) { - const codeql = await getCodeQL(logger2, config.codeQLCmd); - const version = await codeql.getVersion(); await uploadCombinedSarifArtifacts( logger2, - config.gitHubVersion.type, - version.version + config.gitHubVersion.type ); } } @@ -185794,14 +185862,14 @@ async function runWrapper2() { } } } catch (error3) { - core19.setFailed( + core16.setFailed( `analyze post-action step failed: ${getErrorMessage(error3)}` ); } } // src/autobuild-action.ts -var core20 = __toESM(require_core()); +var core17 = __toESM(require_core()); async function sendCompletedStatusReport(config, logger2, startedAt, allLanguages, failingLanguage, cause) { initializeEnvironment(getActionVersion()); const status = getActionsStatus(cause, failingLanguage); @@ -185824,7 +185892,11 @@ async function sendCompletedStatusReport(config, logger2, startedAt, allLanguage await sendStatusReport(statusReport); } } -async function run2({ startedAt, logger: logger2 }) { +async function run2({ + startedAt, + env, + logger: logger2 +}) { let config; let currentLanguage; let languages; @@ -185867,7 +185939,7 @@ async function run2({ startedAt, logger: logger2 }) { await endTracingForCluster(codeql, config, logger2); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core20.setFailed( + core17.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( @@ -185880,7 +185952,7 @@ async function run2({ startedAt, logger: logger2 }) { ); return; } - core20.exportVariable("CODEQL_ACTION_AUTOBUILD_DID_COMPLETE_SUCCESSFULLY" /* AUTOBUILD_DID_COMPLETE_SUCCESSFULLY */, "true"); + env.export("CODEQL_ACTION_AUTOBUILD_DID_COMPLETE_SUCCESSFULLY" /* AUTOBUILD_DID_COMPLETE_SUCCESSFULLY */, "true"); await sendCompletedStatusReport(config, logger2, startedAt, languages ?? []); } var autobuild = { @@ -185894,9 +185966,9 @@ async function runWrapper3() { // src/init-action.ts var fs29 = __toESM(require("fs")); var path25 = __toESM(require("path")); -var core22 = __toESM(require_core()); +var core19 = __toESM(require_core()); var io7 = __toESM(require_io()); -var semver11 = __toESM(require_semver2()); +var semver10 = __toESM(require_semver2()); // src/config/inputs.ts async function getToolsInput(action, repositoryProperties) { @@ -185954,7 +186026,7 @@ function createInitToolsDownloadFields(report, toolsFeatureFlagsValid) { var fs28 = __toESM(require("fs")); var path24 = __toESM(require("path")); var import_zlib3 = __toESM(require("zlib")); -var core21 = __toESM(require_core()); +var core18 = __toESM(require_core()); function toCodedErrors(errors) { return Object.entries(errors).reduce( (acc, [code, message]) => { @@ -186077,7 +186149,7 @@ async function validateWorkflow(codeql, logger2) { } catch (e) { return `error: formatWorkflowErrors() failed: ${String(e)}`; } - core21.warning(message); + core18.warning(message); } return formatWorkflowCause(workflowErrors); } @@ -186206,7 +186278,7 @@ function getCheckoutPathInputOrThrow(workflow, jobName, matrixVars) { } async function checkWorkflow(logger2, codeql) { if (!isDynamicWorkflow() && process.env["CODEQL_ACTION_SKIP_WORKFLOW_VALIDATION" /* SKIP_WORKFLOW_VALIDATION */] !== "true") { - core21.startGroup("Validating workflow"); + core18.startGroup("Validating workflow"); const validateWorkflowResult = await internal2.validateWorkflow( codeql, logger2 @@ -186218,7 +186290,7 @@ async function checkWorkflow(logger2, codeql) { `Unable to validate code scanning workflow: ${validateWorkflowResult}` ); } - core21.endGroup(); + core18.endGroup(); } } var internal2 = { @@ -186326,7 +186398,7 @@ async function run3(actionState) { logger2 ); const repositoryProperties = repositoryPropertiesResult.orElse({}); - core22.exportVariable("CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */, "true"); + actionState.env.export("CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */, "true"); sourceRoot = path25.resolve( actionState.env.getRequired("GITHUB_WORKSPACE" /* GITHUB_WORKSPACE */), getOptionalInput("source-root") || "" @@ -186339,7 +186411,9 @@ async function run3(actionState) { `Failed to parse analysis kinds for 'starting' status report: ${getErrorMessage(err)}` ); } - const actionStateWithFeatures = { ...actionState, features }; + const actionStateWithFeatures = extendActionState(actionState, { + features + }); configFile = await getConfigFileInput( actionStateWithFeatures, repositoryProperties, @@ -186397,21 +186471,15 @@ async function run3(actionState) { // requested rust - don't enable it via language autodetection. getRawLanguagesNoAutodetect(getOptionalInput("languages")).includes("rust" /* rust */) ) { - const experimental = "2.19.3"; const publicPreview = "2.22.1"; const actualVer = (await codeql.getVersion()).version; - if (semver11.lt(actualVer, experimental)) { - throw new ConfigurationError( - `Rust analysis is supported by CodeQL CLI version ${experimental} or higher, but found version ${actualVer}` - ); - } - if (semver11.lt(actualVer, publicPreview)) { - core22.exportVariable("CODEQL_ENABLE_EXPERIMENTAL_FEATURES" /* EXPERIMENTAL_FEATURES */, "true"); + if (semver10.lt(actualVer, publicPreview)) { + actionState.env.export("CODEQL_ENABLE_EXPERIMENTAL_FEATURES" /* EXPERIMENTAL_FEATURES */, "true"); logger2.info("Experimental Rust analysis enabled"); } } analysisKinds = await getAnalysisKinds(logger2, features); - const debugMode = getOptionalInput("debug") === "true" || core22.isDebug(); + const debugMode = getOptionalInput("debug") === "true" || core19.isDebug(); const fileCoverageResult = await getFileCoverageInformationEnabled( debugMode, codeql, @@ -186482,8 +186550,17 @@ async function run3(actionState) { } await checkInstallPython311(config.languages, codeql); } catch (unwrappedError) { + if (config !== void 0) { + try { + saveAbortedInitConfig(actionState, config); + } catch (configSaveError) { + logger2.warning( + `Unable to save configuration for '${"init-post" /* InitPost */}' step: ${getErrorMessage(configSaveError)}` + ); + } + } const error3 = wrapError(unwrappedError); - core22.setFailed(error3.message); + core19.setFailed(error3.message); const statusReportBase = await createStatusReportBase( "init" /* Init */, error3 instanceof ConfigurationError ? "user-error" : "aborted", @@ -186523,10 +186600,10 @@ async function run3(actionState) { if (config.overlayDatabaseMode !== "overlay" /* Overlay */) { cleanupDatabaseClusterDirectory(config, logger2); } - const goFlags = process.env["GOFLAGS"]; + const goFlags = actionState.env.getOptional("GOFLAGS"); if (goFlags) { - core22.exportVariable("GOFLAGS", goFlags); - core22.warning( + actionState.env.export("GOFLAGS", goFlags); + core19.warning( "Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action." ); } @@ -186545,7 +186622,7 @@ async function run3(actionState) { "bin" ); fs29.mkdirSync(tempBinPath, { recursive: true }); - core22.addPath(tempBinPath); + core19.addPath(tempBinPath); const goWrapperPath = path25.resolve(tempBinPath, "go"); fs29.writeFileSync( goWrapperPath, @@ -186554,14 +186631,14 @@ async function run3(actionState) { exec ${goBinaryPath} "$@"` ); fs29.chmodSync(goWrapperPath, "755"); - core22.exportVariable("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goWrapperPath); + actionState.env.export("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goWrapperPath); } catch (e) { logger2.warning( `Analyzing Go on Linux, but failed to install wrapper script. Tracing custom builds may fail: ${e}` ); } } else { - core22.exportVariable("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goBinaryPath); + actionState.env.export("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goBinaryPath); } } catch (e) { logger2.warning( @@ -186588,23 +186665,22 @@ exec ${goBinaryPath} "$@"` } } } - core22.exportVariable( + actionState.env.export( "CODEQL_RAM", process.env["CODEQL_RAM"] || getCodeQLMemoryLimit(getOptionalInput("ram"), logger2).toString() ); - core22.exportVariable( + actionState.env.export( "CODEQL_THREADS", process.env["CODEQL_THREADS"] || getThreadsFlagValue(getOptionalInput("threads"), logger2).toString() ); if (await features.getValue("disable_kotlin_analysis_enabled" /* DisableKotlinAnalysisEnabled */)) { - core22.exportVariable("CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", "true"); + actionState.env.export( + "CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", + "true" + ); } if (await features.getValue("force_jgit" /* ForceJGit */)) { - 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")) { - core22.exportVariable(kotlinLimitVar, "2.1.20"); + actionState.env.export("CODEQL_GIT_BACKEND", "jgit"); } if (shouldRestoreCache(config.dependencyCachingEnabled)) { const dependencyCachingResult = await downloadDependencyCaches( @@ -186631,7 +186707,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 */)) { - core22.exportVariable( + actionState.env.export( "CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */, "true" ); @@ -186673,23 +186749,23 @@ exec ${goBinaryPath} "$@"` const tracerConfig = await getCombinedTracerConfig(logger2, codeql, config); if (tracerConfig !== void 0) { for (const [key, value] of Object.entries(tracerConfig.env)) { - core22.exportVariable(key, value); + actionState.env.export(key, value); } } if (await features.getValue("java_network_debugging" /* JavaNetworkDebugging */)) { - const existingJavaToolOptions = getOptionalEnvVar("JAVA_TOOL_OPTIONS" /* JAVA_TOOL_OPTIONS */) || ""; - core22.exportVariable( + const existingJavaToolOptions = actionState.env.getOptional("JAVA_TOOL_OPTIONS" /* JAVA_TOOL_OPTIONS */) ?? ""; + actionState.env.export( "JAVA_TOOL_OPTIONS" /* JAVA_TOOL_OPTIONS */, `${existingJavaToolOptions} -Djavax.net.debug=all` ); } flushDiagnostics(config); await saveConfig(config, logger2); - core22.setOutput("codeql-path", config.codeQLCmd); - core22.setOutput("codeql-version", (await codeql.getVersion()).version); + core19.setOutput("codeql-path", config.codeQLCmd); + core19.setOutput("codeql-version", (await codeql.getVersion()).version); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core22.setFailed(error3.message); + core19.setFailed(error3.message); await sendCompletedStatusReport2( startedAt, config, @@ -186733,7 +186809,7 @@ async function runWrapper4() { } // src/init-action-post.ts -var core23 = __toESM(require_core()); +var core20 = __toESM(require_core()); // src/init-action-post-helper.ts var fs30 = __toESM(require("fs")); @@ -186911,20 +186987,14 @@ async function uploadFailureInfo(uploadAllAvailableDebugArtifacts, printDebugLog ); } } - if (config.debugMode) { + if (config.debugMode && hasConfigKey(config, "dbLocation")) { logger2.info( "Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts..." ); - const version = await codeql.getVersion(); - await uploadAllAvailableDebugArtifacts( - codeql, - config, - logger2, - version.version - ); - await printDebugLogs2(config); + await uploadAllAvailableDebugArtifacts(codeql, config, logger2); + await printDebugLogs2(logger2, config); } - if (isSelfHostedRunner()) { + if (isSelfHostedRunner() && config.dbLocation) { try { fs30.rmSync(config.dbLocation, { recursive: true, @@ -186939,6 +187009,10 @@ async function uploadFailureInfo(uploadAllAvailableDebugArtifacts, printDebugLog `Failed to clean up database cluster directory ${config.dbLocation}. Details: ${e}` ); } + } else if (config.dbLocation === void 0) { + logger2.debug( + "Skipping cleanup of database cluster directory since the configuration does not include a database path." + ); } else { logger2.debug( "Skipping cleanup of database cluster directory since we are running on a GitHub-hosted runner which will be automatically cleaned up." @@ -186962,6 +187036,11 @@ function isConclusiveJobStatus(jobStatus) { async function recordOverlayStatus(codeql, config, features, jobStatus, env, logger2) { if (config.overlayDatabaseMode !== "overlay-base" /* OverlayBase */ || env.getOptional("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */) === "true" || !await features.getValue("overlay_analysis_status_save" /* OverlayAnalysisStatusSave */)) { return; + } else if (config.languages === void 0) { + logger2.debug( + "Not recording overlay status, because the configuration contains no 'languages'." + ); + return; } if (!isConclusiveJobStatus(jobStatus) && !didCodeQlReportError(env)) { logger2.info( @@ -187064,15 +187143,19 @@ async function removeUploadedSarif(uploadFailedSarifResult, logger2) { } // src/init-action-post.ts -async function run4(startedAt) { - const logger2 = getActionsLogger(); +async function run4(action) { + const logger2 = action.logger; let config; let uploadFailedSarifResult; let dependencyCachingUsage; try { const jobStatus2 = getOptionalInput("job-status"); restoreInputs(logger2); - config = await getConfig(getTemporaryDirectory(), logger2); + const tmpDir = getTemporaryDirectory(); + config = await getConfig(tmpDir, logger2); + if (config === void 0) { + config = getAbortedInitConfig(action, tmpDir); + } const gitHubVersion = config?.gitHubVersion ?? await getGitHubVersion(); checkGitHubVersionInRange(gitHubVersion, logger2); const repositoryNwo = getRepositoryNwo(); @@ -187096,20 +187179,20 @@ async function run4(startedAt) { repositoryNwo, features, jobStatus2, - getEnv(), + action.env, logger2 ); - if (await isAnalyzingDefaultBranch() && config.dependencyCachingEnabled !== "none" /* None */) { + if (await isAnalyzingDefaultBranch() && hasConfigKey(config, "dependencyCachingEnabled") && config.dependencyCachingEnabled !== "none" /* None */) { dependencyCachingUsage = await getDependencyCacheUsage(logger2); } } } catch (unwrappedError) { const error3 = wrapApiConfigurationError(wrapError(unwrappedError)); - core23.setFailed(error3.message); + core20.setFailed(error3.message); const statusReportBase2 = await createStatusReportBase( - "init-post" /* InitPost */, + action.name, getActionsStatus(error3), - startedAt, + action.startedAt, config, await checkDiskUsage(logger2), logger2, @@ -187121,12 +187204,12 @@ async function run4(startedAt) { } return; } - const jobStatus = getFinalJobStatus(config); + const jobStatus = getFinalJobStatus(action, config); logger2.info(`CodeQL job status was ${getJobStatusDisplayName(jobStatus)}.`); const statusReportBase = await createStatusReportBase( - "init-post" /* InitPost */, + action.name, "success", - startedAt, + action.startedAt, config, await checkDiskUsage(logger2), logger2 @@ -187143,25 +187226,25 @@ async function run4(startedAt) { logger2.info("Status report sent for init-post step."); } } -function getFinalJobStatus(config) { - const existingJobStatus = getJobStatusFromEnvironment(); +function getFinalJobStatus(action, config) { + const existingJobStatus = getJobStatusFromEnvironment(action.env); if (existingJobStatus !== void 0) { return existingJobStatus; } let jobStatus; - if (process.env["CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */] === "true") { - core23.exportVariable("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */); + if (action.env.getOptional("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */) === "true") { + action.env.export("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */); jobStatus = "JOB_STATUS_SUCCESS" /* SuccessStatus */; } else if (config !== void 0) { jobStatus = "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */; } else { jobStatus = "JOB_STATUS_UNKNOWN" /* UnknownStatus */; } - core23.exportVariable("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus); + action.env.export("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus); return jobStatus; } -function getJobStatusFromEnvironment() { - const jobStatusFromEnvironment = process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */]; +function getJobStatusFromEnvironment(env) { + const jobStatusFromEnvironment = env.getOptional("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */); if (jobStatusFromEnvironment !== void 0) { if (Object.values(JobStatus).includes(jobStatusFromEnvironment)) { return jobStatusFromEnvironment; @@ -187170,24 +187253,16 @@ function getJobStatusFromEnvironment() { } return void 0; } +var initPost = { + name: "init-post" /* InitPost */, + run: run4 +}; async function runWrapper5() { - const startedAt = /* @__PURE__ */ new Date(); - const logger2 = getActionsLogger(); - try { - await run4(startedAt); - } catch (error3) { - core23.setFailed(`init post action failed: ${wrapError(error3).message}`); - await sendUnhandledErrorStatusReport( - "init-post" /* InitPost */, - startedAt, - error3, - logger2 - ); - } + return await runInActions(initPost); } // src/resolve-environment-action.ts -var core24 = __toESM(require_core()); +var core21 = __toESM(require_core()); // src/resolve-environment.ts async function runResolveBuildEnvironment(cmd, logger2, workingDir, language) { @@ -187234,16 +187309,16 @@ async function run5(startedAt) { workingDirectory, getRequiredInput("language") ); - core24.setOutput(ENVIRONMENT_OUTPUT_NAME, result); + core21.setOutput(ENVIRONMENT_OUTPUT_NAME, result); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); if (error3 instanceof CliError) { - core24.setOutput(ENVIRONMENT_OUTPUT_NAME, {}); + core21.setOutput(ENVIRONMENT_OUTPUT_NAME, {}); logger2.warning( `Failed to resolve a build environment suitable for automatically building your code. ${error3.message}` ); } else { - core24.setFailed( + core21.setFailed( `Failed to resolve a build environment suitable for automatically building your code. ${error3.message}` ); const statusReportBase2 = await createStatusReportBase( @@ -187280,7 +187355,7 @@ async function runWrapper6() { try { await run5(startedAt); } catch (error3) { - core24.setFailed( + core21.setFailed( `${"resolve-environment" /* ResolveEnvironment */} action failed: ${getErrorMessage( error3 )}` @@ -187296,7 +187371,7 @@ async function runWrapper6() { } // src/setup-codeql-action.ts -var core25 = __toESM(require_core()); +var core22 = __toESM(require_core()); async function sendCompletedStatusReport3(startedAt, toolsInput, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, logger2, error3) { const statusReportBase = await createStatusReportBase( "setup-codeql" /* SetupCodeQL */, @@ -187358,7 +187433,9 @@ async function run6(actionState) { logger2 ); const repositoryProperties = repositoryPropertiesResult.orElse({}); - const actionStateWithFeatures = { ...actionState, features }; + const actionStateWithFeatures = extendActionState(actionState, { + features + }); const statusReportBase = await createStatusReportBase( "setup-codeql" /* SetupCodeQL */, "starting", @@ -187400,12 +187477,12 @@ async function run6(actionState) { toolsDownloadStatusReport = initCodeQLResult.toolsDownloadStatusReport; toolsVersion = initCodeQLResult.toolsVersion; toolsSource = initCodeQLResult.toolsSource; - 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"); + core22.setOutput("codeql-path", codeql.getPath()); + core22.setOutput("codeql-version", (await codeql.getVersion()).version); + actionState.env.export("CODEQL_ACTION_SETUP_CODEQL_HAS_RUN" /* SETUP_CODEQL_ACTION_HAS_RUN */, "true"); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core25.setFailed(error3.message); + core22.setFailed(error3.message); const statusReportBase = await createStatusReportBase( "setup-codeql" /* SetupCodeQL */, error3 instanceof ConfigurationError ? "user-error" : "failure", @@ -187443,15 +187520,15 @@ async function runWrapper7() { // src/start-proxy-action.ts var import_child_process2 = require("child_process"); var path29 = __toESM(require("path")); -var core28 = __toESM(require_core()); +var core25 = __toESM(require_core()); // src/start-proxy.ts var path27 = __toESM(require("path")); -var core27 = __toESM(require_core()); +var core24 = __toESM(require_core()); var toolcache4 = __toESM(require_tool_cache()); // src/start-proxy/validation.ts -var core26 = __toESM(require_core()); +var core23 = __toESM(require_core()); function cloneCredential(schema, obj) { const result = {}; for (const key of Object.keys(schema)) { @@ -187470,14 +187547,14 @@ function getAuthConfig(config) { } if (isToken(config)) { if (isDefined2(config.token)) { - core26.setSecret(config.token); + core23.setSecret(config.token); } return cloneCredential(tokenSchema, config); } else { let username = void 0; let password = void 0; if ("password" in config && isString(config.password)) { - core26.setSecret(config.password); + core23.setSecret(config.password); password = config.password; } if ("username" in config && isString(config.username)) { @@ -187533,7 +187610,7 @@ function getSafeErrorMessage(error3) { } async function sendFailedStatusReport(logger2, startedAt, language, unwrappedError) { const error3 = wrapError(unwrappedError); - core27.setFailed(`start-proxy action failed: ${error3.message}`); + core24.setFailed(`start-proxy action failed: ${error3.message}`); const statusReportMessage = getSafeErrorMessage(error3); const errorStatusReportBase = await createStatusReportBase( "start-proxy" /* StartProxy */, @@ -188114,7 +188191,7 @@ async function run7(action) { persistInputs(); const tempDir = getTemporaryDirectory(); const proxyLogFilePath = path29.resolve(tempDir, "proxy.log"); - core28.saveState("proxy-log-file", proxyLogFilePath); + core25.saveState("proxy-log-file", proxyLogFilePath); const repositoryNwo = getRepositoryNwo(); const gitHubVersion = await getGitHubVersion(); features = initFeatures( @@ -188139,7 +188216,7 @@ async function run7(action) { `Credentials loaded for the following registries: ${credentials.map((c) => credentialToStr(c)).join("\n")}` ); - if (core28.isDebug() || isInTestMode()) { + if (core25.isDebug() || isInTestMode()) { try { await checkProxyEnvironment(logger2, language); } catch (err) { @@ -188153,7 +188230,8 @@ async function run7(action) { all_credentials: credentials, ca }; - const proxyBin = await getProxyBinaryPath({ ...action, features }); + const actionWithFeatures = extendActionState(action, { features }); + const proxyBin = await getProxyBinaryPath(actionWithFeatures); const proxyInfo = await startProxy( proxyBin, proxyConfig, @@ -188198,7 +188276,7 @@ async function startProxy(binPath, config, logFilePath, logger2) { ); subprocess.unref(); if (subprocess.pid) { - core28.saveState("proxy-process-pid", `${subprocess.pid}`); + core25.saveState("proxy-process-pid", `${subprocess.pid}`); } subprocess.on("error", (error3) => { subprocessError = error3; @@ -188217,25 +188295,25 @@ async function startProxy(binPath, config, logFilePath, logger2) { throw subprocessError; } logger2.info(`Proxy started on ${host}:${port}`); - core28.setOutput("proxy_host", host); - core28.setOutput("proxy_port", port.toString()); - core28.setOutput("proxy_ca_certificate", config.ca.cert); + core25.setOutput("proxy_host", host); + core25.setOutput("proxy_port", port.toString()); + core25.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"] })); - core28.setOutput("proxy_urls", JSON.stringify(registry_urls)); + core25.setOutput("proxy_urls", JSON.stringify(registry_urls)); return { host, port, cert: config.ca.cert, registries: registry_urls }; } // src/start-proxy-action-post.ts -var core29 = __toESM(require_core()); +var core26 = __toESM(require_core()); async function runWrapper9() { const logger2 = getActionsLogger(); try { restoreInputs(logger2); - const pid = core29.getState("proxy-process-pid"); + const pid = core26.getState("proxy-process-pid"); if (pid) { process.kill(Number(pid)); } @@ -188243,8 +188321,8 @@ async function runWrapper9() { getTemporaryDirectory(), logger2 ); - if (config?.debugMode || core29.isDebug()) { - const logFilePath = core29.getState("proxy-log-file"); + if (config?.debugMode || core26.isDebug()) { + const logFilePath = core26.getState("proxy-log-file"); logger2.info( "Debug mode is on. Uploading proxy log as Actions debugging artifact..." ); @@ -188266,7 +188344,7 @@ async function runWrapper9() { } // src/upload-sarif-action.ts -var core30 = __toESM(require_core()); +var core27 = __toESM(require_core()); async function sendSuccessStatusReport2(startedAt, uploadStats, logger2) { const statusReportBase = await createStatusReportBase( "upload-sarif" /* UploadSarif */, @@ -188326,11 +188404,11 @@ async function run8({ startedAt, logger: logger2 }) { } const codeScanningResult = uploadResults["code-scanning" /* CodeScanning */]; if (codeScanningResult !== void 0) { - core30.setOutput("sarif-id", codeScanningResult.sarifID); + core27.setOutput("sarif-id", codeScanningResult.sarifID); } - core30.setOutput("sarif-ids", JSON.stringify(uploadResults)); + core27.setOutput("sarif-ids", JSON.stringify(uploadResults)); if (shouldSkipSarifUpload()) { - core30.debug( + core27.debug( "SARIF upload disabled by an environment variable. Waiting for processing is disabled." ); } else if (getRequiredInput("wait-for-processing") === "true") { @@ -188350,7 +188428,7 @@ async function run8({ startedAt, logger: logger2 }) { } catch (unwrappedError) { const error3 = isThirdPartyAnalysis("upload-sarif" /* UploadSarif */) && unwrappedError instanceof InvalidSarifUploadError ? new ConfigurationError(unwrappedError.message) : wrapError(unwrappedError); const message = error3.message; - core30.setFailed(message); + core27.setFailed(message); const errorStatusReportBase = await createStatusReportBase( "upload-sarif" /* UploadSarif */, getActionsStatus(error3), @@ -188376,7 +188454,7 @@ async function runWrapper10() { } // src/upload-sarif-action-post.ts -var core31 = __toESM(require_core()); +var core28 = __toESM(require_core()); async function runWrapper11() { try { const logger2 = getActionsLogger(); @@ -188385,24 +188463,18 @@ async function runWrapper11() { checkGitHubVersionInRange(gitHubVersion, logger2); if (process.env["CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */] !== "true") { if (gitHubVersion.type === void 0) { - core31.warning( + core28.warning( `Did not upload debug artifacts because cannot determine the GitHub variant running.` ); return; } await withGroup( "Uploading combined SARIF debug artifact", - () => uploadCombinedSarifArtifacts( - logger2, - gitHubVersion.type, - // The codeqlVersion is not applicable for uploading non-codeql sarif. - // We can assume all versions are safe to upload. - void 0 - ) + () => uploadCombinedSarifArtifacts(logger2, gitHubVersion.type) ); } } catch (error3) { - core31.setFailed( + core28.setFailed( `upload-sarif post-action step failed: ${getErrorMessage(error3)}` ); } diff --git a/package-lock.json b/package-lock.json index 7a3074c86..c9d3e8986 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeql", - "version": "4.38.3", + "version": "4.39.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeql", - "version": "4.38.3", + "version": "4.39.0", "license": "MIT", "workspaces": [ "pr-checks" @@ -58,7 +58,7 @@ "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-github": "^6.1.2", "eslint-plugin-import-x": "^4.17.1", - "eslint-plugin-jsdoc": "^64.5.4", + "eslint-plugin-jsdoc": "^65.0.1", "eslint-plugin-no-async-foreach": "^0.1.1", "glob": "^13.0.6", "globals": "^17.12.0", @@ -5366,15 +5366,15 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "64.5.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-64.5.4.tgz", - "integrity": "sha512-xfRhXPSSWT612muJ6XTvxuVJ8zYHv99qNgBqPVqF28aSqoy4s4XbSkrWXnYA2hl5ejC02yEpk6fqkj3BmJ6Xbg==", + "version": "65.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-65.0.1.tgz", + "integrity": "sha512-7IvB+ZS71WCw5tGKh6f6D5k55qtXKdrGTnIpQTBKWdpyZ5IfhGHfh0i6ArWlCJ4JEtz22YRk5Bqu1MvbOlpMKQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@es-joy/jsdoccomment": "~0.98.0", "@es-joy/resolve.exports": "1.2.0", - "@typescript-eslint/utils": "^8.70.0", + "@typescript-eslint/utils": "^8.70.1", "are-docs-informative": "^0.1.1", "comment-parser": "1.4.9", "debug": "^4.4.3", diff --git a/package.json b/package.json index d1e8b1188..d9fe29c98 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeql", - "version": "4.38.3", + "version": "4.39.0", "private": true, "description": "CodeQL action", "scripts": { @@ -66,7 +66,7 @@ "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-github": "^6.1.2", "eslint-plugin-import-x": "^4.17.1", - "eslint-plugin-jsdoc": "^64.5.4", + "eslint-plugin-jsdoc": "^65.0.1", "eslint-plugin-no-async-foreach": "^0.1.1", "glob": "^13.0.6", "globals": "^17.12.0", diff --git a/pr-checks/changelog/validate.test.ts b/pr-checks/changelog/validate.test.ts index 379b5737a..77a18e8ba 100644 --- a/pr-checks/changelog/validate.test.ts +++ b/pr-checks/changelog/validate.test.ts @@ -154,26 +154,6 @@ await describe("isValidChangenoteFile", async () => { assert.equal(isValidChangenoteFile("non-existent-file.md"), false); }); - await it("rejects invalid filename", async () => { - await withTmpFile( - "fix-bug.md", - "---\ncategory: fix\n---\n- Fixed a bug\n", - (filePath) => { - assert.equal(isValidChangenoteFile(filePath), false); - }, - ); - }); - - await it("rejects missing frontmatter", async () => { - await withTmpFile( - "2026-01-01-fix-bug.md", - "- Fixed a bug\n", - (filePath) => { - assert.equal(isValidChangenoteFile(filePath), false); - }, - ); - }); - await it("rejects invalid Markdown", async () => { await withTmpFile( "2026-01-01-fix-bug.md", diff --git a/pr-checks/changelog/validate.ts b/pr-checks/changelog/validate.ts index 3c83276f3..fa0caec3e 100644 --- a/pr-checks/changelog/validate.ts +++ b/pr-checks/changelog/validate.ts @@ -1,5 +1,4 @@ import * as fs from "node:fs"; -import * as path from "node:path"; import { matter } from "lite-matter"; import type { List, ListItem } from "mdast"; @@ -95,21 +94,7 @@ export function isValidChangenoteFile(filename: string): boolean { return false; } - const { data: frontmatter, content } = matter(fileData); - - if (!isValidChangenoteFilename(path.basename(filename))) { - isValid = false; - console.error( - `${filename}: invalid filename; must match pattern YYYY-MM-DD-id.md`, - ); - } - if (!hasValidChangenoteCategory(frontmatter)) { - isValid = false; - const categories = Object.keys(VALID_CHANGE_NOTE_CATEGORIES).join(", "); - console.error( - `${filename}: invalid category; must be one of: ${categories}`, - ); - } + const { content } = matter(fileData); if (!isValidChangenoteContent(content)) { isValid = false; console.error( diff --git a/pr-checks/changenotes.ts b/pr-checks/changenotes.ts index 933d255cd..26035527b 100755 --- a/pr-checks/changenotes.ts +++ b/pr-checks/changenotes.ts @@ -28,12 +28,12 @@ interface ChangenoteFile { /** * Returns the absolute file paths of all files in - * {@link CHANGENOTES_DIR} (except ".gitkeep"). + * {@link CHANGENOTES_DIR} (except ".gitkeep" and "README.md"). * */ function listUnreleasedChangenoteDir(): string[] { return fs .readdirSync(CHANGENOTES_DIR) - .filter((name) => name !== ".gitkeep") + .filter((name) => ![".gitkeep", "README.md"].includes(name)) .map((name) => path.join(CHANGENOTES_DIR, name)); } diff --git a/pr-checks/checks/multi-language-autodetect.yml b/pr-checks/checks/multi-language-autodetect.yml index b9d80d107..f84993356 100644 --- a/pr-checks/checks/multi-language-autodetect.yml +++ b/pr-checks/checks/multi-language-autodetect.yml @@ -10,7 +10,6 @@ operatingSystems: - os: macos runner-image: macos-15-xlarge codeql-versions: - - stable-v2.19.4 - stable-v2.20.7 - stable-v2.21.4 - stable-v2.22.4 @@ -20,13 +19,14 @@ env: installGo: true installDotNet: true steps: - - name: Install Python 3.13 for older CLI versions - # We need Python 3.13 for older CLI versions because they are not compatible with Python 3.14 or newer. + - name: Install Python 3.13.15 for older CLI versions + # Older CLI versions don't work with Python 3.13.16 or newer because their Python extractor + # imports `importlib._bootstrap._ERR_MSG`, which those Python versions no longer define. # See https://github.com/github/codeql-action/pull/3212 if: matrix.version != 'nightly-latest' && matrix.version != 'linked' uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: - python-version: "3.13" + python-version: "3.13.15" - name: Use Xcode 16 # Only the older CodeQL CLI versions need Xcode 16, and these run on macOS 15. diff --git a/pr-checks/checks/rust.yml b/pr-checks/checks/rust.yml index 8589ba80e..e0b91ae9c 100644 --- a/pr-checks/checks/rust.yml +++ b/pr-checks/checks/rust.yml @@ -1,8 +1,8 @@ name: "Rust analysis" description: "Tests creation of a Rust database" versions: - # experimental rust support introduced, requires action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES` - - stable-v2.19.4 + # oldest CodeQL version supported by the Action, where Rust support is experimental and requires the Action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES` + - stable-v2.20.7 # first public preview version - stable-v2.22.1 - linked diff --git a/pr-checks/sync.ts b/pr-checks/sync.ts index 9b40c2e41..8dc1dd1d1 100755 --- a/pr-checks/sync.ts +++ b/pr-checks/sync.ts @@ -136,8 +136,6 @@ type LanguageSetups = Partial>; // The default set of CodeQL Bundle versions to use for the PR checks. const defaultTestVersions = [ // The oldest supported CodeQL version. If bumping, update `CODEQL_MINIMUM_VERSION` in `codeql.ts` - "stable-v2.19.4", - // The last CodeQL release in the 2.20 series. "stable-v2.20.7", // The last CodeQL release in the 2.21 series. "stable-v2.21.4", @@ -147,6 +145,8 @@ const defaultTestVersions = [ "stable-v2.23.9", // The last CodeQL release in the 2.24 series. "stable-v2.24.3", + // The last CodeQL release in the 2.25 series. + "stable-v2.25.6", // The default version of CodeQL for Dotcom, as determined by feature flags. "default", // The version of CodeQL shipped with the Action in `defaults.json`. During the release process diff --git a/queries/default-setup-environment-variables.ql b/queries/default-setup-environment-variables.ql index 9f677dfb9..3032cefe0 100644 --- a/queries/default-setup-environment-variables.ql +++ b/queries/default-setup-environment-variables.ql @@ -23,7 +23,8 @@ predicate isSafeForDefaultSetup(string envVar) { "GITHUB_BASE_REF", "GITHUB_EVENT_NAME", "GITHUB_JOB", "GITHUB_RUN_ATTEMPT", "GITHUB_RUN_ID", "GITHUB_SHA", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_TOKEN", "GITHUB_WORKFLOW", "GITHUB_WORKSPACE", "GOFLAGS", "ImageVersion", "JAVA_TOOL_OPTIONS", "RUNNER_ARCH", - "RUNNER_ENVIRONMENT", "RUNNER_NAME", "RUNNER_OS", "RUNNER_TEMP", "RUNNER_TOOL_CACHE" + "RUNNER_ENVIRONMENT", "RUNNER_NAME", "RUNNER_OS", "RUNNER_TEMP", "RUNNER_TOOL_CACHE", + "NODE_ENV" ] } diff --git a/src/action-common.test.ts b/src/action-common.test.ts index fc2e0a9aa..449300a8d 100644 --- a/src/action-common.test.ts +++ b/src/action-common.test.ts @@ -19,6 +19,24 @@ import { getErrorMessage } from "./util"; setupTests(test); +for (const [key, displayName] of Object.entries( + statusReport.ACTION_DISPLAY_NAMES, +)) { + test(`getDisplayActionName - '${displayName}' instead of '${key}'`, (t) => { + t.is(statusReport.getDisplayActionName(key as ActionName), displayName); + }); +} + +test("getDisplayActionName - returns action name", (t) => { + for (const actionName of Object.values(ActionName)) { + if (statusReport.ACTION_DISPLAY_NAMES[actionName]) { + continue; + } + + t.is(statusReport.getDisplayActionName(actionName), actionName); + } +}); + interface RunInActionsTestOpts { runFn?: () => Promise; expectedErrorMessage?: string; diff --git a/src/action-common.ts b/src/action-common.ts index 17d4344cc..79f1901f2 100644 --- a/src/action-common.ts +++ b/src/action-common.ts @@ -56,6 +56,29 @@ export interface FeatureState { /** Identifies a type of state an Action may have. */ export type StateFeature = keyof FeatureState; +/** + * The `Env` feature implies the availability of the `ReadOnlyEnv` feature. + * + * If `T` is `Env`, this returns `Env | ReadOnlyEnv`. + * Otherwise, it is the identity and returns T. + */ +type ImpliedFeatures = T extends "Env" + ? "Env" | "ReadOnlyEnv" + : T; + +/** + * Given an object type `Obj`, this tries to lookup a corresponding `StateFeature` + * to which the object type belongs in `FeatureState`. Resolves to `never` if there + * is no match. + */ +type FeatureNameFor = { + [K in StateFeature]: [Obj] extends [FeatureState[K]] + ? [FeatureState[K]] extends [Obj] + ? K + : never + : never; +}[StateFeature]; + /** Constructs the intersection of all state types identifies by `Fs`. */ export type FieldsOf = Fs extends [] ? Record @@ -66,8 +89,54 @@ export type FieldsOf = Fs extends [] ? FeatureState[Head] & FieldsOf : never; +/** + * Symbol used for a field in `ActionState` that carries the type array of state features. + * This is a Symbol so that it doesn't clash with any property names we might want to have. + */ +const stateFeatures = Symbol(); + /** Describes the state of an Action that has access to the state corresponding to `Fs`. */ -export type ActionState = FieldsOf; +export type ActionState = FieldsOf & { + /** + * When given a chance, TypeScript will simplify an `ActionState` type as much as possible, + * which results in a concrete object type that doesn't mention `Fs`. + * + * That causes problems for functions which accept `ActionState` values, but need to know the + * feature keys `Fs`. This property here explicitly captures `Fs` in the concrete object type + * that results from simplifying `ActionState`. + * + * This is a function rather than a field, because we want to be able to provide values of type + * `ActionState` to functions expecting `ActionState` where `As` is a subset of `Fs`. + * + * Since function types are contravariant in the types of their parameters, using a function + * type here allows that to happen. + * + * Because the field is optional, we don't have to explicitly provide a value + * for it anywhere while the type is still inferred. + * + * `Fs[number]` returns the union of all features in `Fs`. We wrap it in `ImpliedFeatures` + * so that `Env` is expanded into `Env | ReadOnlyEnv`, allowing functions that expect the + * `ReadOnlyEnv` feature to be provided with an `ActionState` that has the `Env` feature + * without requiring this to be made explicit. + */ + readonly [stateFeatures]?: (ts: ImpliedFeatures) => void; +}; + +/** Extends `state` with an `extra` feature. */ +export function extendActionState< + // In first position, so that it can be explicitly provided if `FeatureNameFor` + // should not work on `extra`. + F extends StateFeature, + Fs extends readonly StateFeature[], + E extends FeatureState[F], +>( + state: ActionState, + extra: E, +): ActionState<[...Fs, FeatureNameFor & F]> { + return { ...state, ...extra } as unknown as ActionState< + [...Fs, FeatureNameFor & F] + >; +} /** The type of an Action's main entry point. This is a function that is provided * with a basic `ActionState` object with features that are always available. diff --git a/src/actions-util.test.ts b/src/actions-util.test.ts index 3940cf755..17cf96a4a 100644 --- a/src/actions-util.test.ts +++ b/src/actions-util.test.ts @@ -7,12 +7,13 @@ import { isAnalyzingPullRequest, isDefaultSetup, isDynamicWorkflow, + printDebugLogs, } from "./actions-util"; import { computeAutomationID } from "./api-client"; import { EnvVar } from "./environment"; import { getRunnerLogger } from "./logging"; -import { setupTests } from "./testing-utils"; -import { initializeEnvironment } from "./util"; +import { RecordingLogger, setupTests } from "./testing-utils"; +import { initializeEnvironment, withTmpDir } from "./util"; setupTests(test); @@ -100,6 +101,21 @@ test("computeAutomationID()", async (t) => { ); }); +test("printDebugLogs - doesn't throw when config doesn't have needed properties", async (t) => { + const logger = new RecordingLogger(); + await t.notThrowsAsync(printDebugLogs(logger, {})); + await t.notThrowsAsync(printDebugLogs(logger, { languages: [] })); + await t.notThrowsAsync(printDebugLogs(logger, { dbLocation: "nowhere" })); +}); + +test("printDebugLogs - doesn't throw when language db doesn't exist", async (t) => + withTmpDir(async (tmpDir) => { + const logger = new RecordingLogger(); + await t.notThrowsAsync( + printDebugLogs(logger, { dbLocation: tmpDir, languages: ["javascript"] }), + ); + })); + test.serial("getPullRequestBranches() with pull request context", (t) => { withMockedContext( { diff --git a/src/actions-util.ts b/src/actions-util.ts index 6c7d6a78d..62ab42440 100644 --- a/src/actions-util.ts +++ b/src/actions-util.ts @@ -6,7 +6,7 @@ import * as toolrunner from "@actions/exec/lib/toolrunner"; import * as github from "@actions/github"; import * as io from "@actions/io"; -import type { Config } from "./config-utils"; +import { hasConfigKey, type Config } from "./config/action-config"; import { Env, EnvVar, ActionsEnvVars, ReadOnlyEnv } from "./environment"; import { Logger } from "./logging"; import { @@ -30,7 +30,6 @@ declare const __CODEQL_ACTION_VERSION__: string; export interface ActionsEnv { getRequiredInput: (name: string) => string; getOptionalInput: (name: string) => string | undefined; - exportVariable: (name: string, value: string) => void; } /** @@ -40,7 +39,6 @@ export function getActionsEnv(): ActionsEnv { return { getRequiredInput, getOptionalInput, - exportVariable: core.exportVariable, }; } @@ -133,28 +131,38 @@ export function getWorkflowEvent(env: Env = getEnv()): any { } } -export async function printDebugLogs(config: Config) { +export async function printDebugLogs(logger: Logger, config: Partial) { + if ( + !hasConfigKey(config, "languages") || + !hasConfigKey(config, "dbLocation") + ) { + logger.debug( + `Not printing debug logs, because the configuration does not include the 'languages' or 'dbLocation' fields.`, + ); + return; + } + for (const language of config.languages) { const databaseDirectory = getCodeQLDatabasePath(config, language); const logsDirectory = path.join(databaseDirectory, "log"); if (!doesDirectoryExist(logsDirectory)) { - core.info(`Directory ${logsDirectory} does not exist.`); + logger.info(`Directory ${logsDirectory} does not exist.`); continue; // Skip this language database. } const walkLogFiles = (dir: string) => { const entries = fs.readdirSync(dir, { withFileTypes: true }); if (entries.length === 0) { - core.info(`No debug logs found at directory ${logsDirectory}.`); + logger.info(`No debug logs found at directory ${logsDirectory}.`); } for (const entry of entries) { if (entry.isFile()) { const absolutePath = path.resolve(dir, entry.name); - core.startGroup( + logger.startGroup( `CodeQL Debug Logs - ${language} - ${entry.name} from file at path ${absolutePath}`, ); - process.stdout.write(fs.readFileSync(absolutePath)); - core.endGroup(); + logger.info(fs.readFileSync(absolutePath, "utf-8")); + logger.endGroup(); } else if (entry.isDirectory()) { walkLogFiles(path.resolve(dir, entry.name)); } diff --git a/src/analyze-action-post.ts b/src/analyze-action-post.ts index 3f9b2fafb..a8d6dc433 100644 --- a/src/analyze-action-post.ts +++ b/src/analyze-action-post.ts @@ -9,7 +9,6 @@ import * as core from "@actions/core"; import * as actionsUtil from "./actions-util"; import { getGitHubVersion } from "./api-client"; -import { getCodeQL } from "./codeql"; import { getConfig } from "./config-utils"; import * as debugArtifacts from "./debug-artifacts"; import { @@ -38,12 +37,9 @@ export async function runWrapper() { logger, ); if (config !== undefined) { - const codeql = await getCodeQL(logger, config.codeQLCmd); - const version = await codeql.getVersion(); await debugArtifacts.uploadCombinedSarifArtifacts( logger, config.gitHubVersion.type, - version.version, ); } } diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 7963fa52b..865564741 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -214,9 +214,10 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) { async function run({ startedAt, + env, logger, actions, -}: ActionState<["Base", "Logger", "Actions"]>) { +}: ActionState<["Base", "Env", "Logger", "Actions"]>) { // To capture errors appropriately, keep as much code within the try-catch as // possible, and only use safe functions outside. @@ -267,17 +268,6 @@ async function run({ ); } - // Unset the CODEQL_PROXY_* environment variables when using older CodeQL - // CLIs, as they are not needed and can cause issues. - if ( - process.env.CODEQL_PROXY_HOST === "" && - !(await util.codeQlVersionAtLeast(codeql, "2.20.7")) - ) { - delete process.env.CODEQL_PROXY_HOST; - delete process.env.CODEQL_PROXY_PORT; - delete process.env.CODEQL_PROXY_CA_CERTIFICATE; - } - if (actionsUtil.getOptionalInput("cleanup-level")) { logger.info( "The 'cleanup-level' input is ignored since the CodeQL Action now automatically " + @@ -287,7 +277,7 @@ async function run({ const apiDetails = getApiDetails(); const outputDir = actionsUtil.getRequiredInput("output"); - core.exportVariable(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir); + env.export(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir); const threads = util.getThreadsFlag( actionsUtil.getOptionalInput("threads") || process.env["CODEQL_THREADS"], logger, @@ -456,7 +446,7 @@ async function run({ `expect-error input was set to true but no error was thrown.`, ); } - core.exportVariable(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true"); + env.export(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true"); } catch (unwrappedError) { const error = util.wrapError(unwrappedError); if ( diff --git a/src/analyze.ts b/src/analyze.ts index d585fd6d8..4d5fd5354 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -9,6 +9,7 @@ import { getTemporaryDirectory } from "./actions-util"; import * as analyses from "./analyses"; import { setupCppAutobuild } from "./autobuild"; import { type CodeQL } from "./codeql"; +import type { ActionConfig } from "./config/action-config"; import { defaultSuites } from "./config/db-config"; import * as configUtils from "./config-utils"; import { @@ -124,7 +125,7 @@ export async function runExtraction( language === BuiltInLanguage.cpp && config.buildMode === BuildMode.Autobuild ) { - await setupCppAutobuild(codeql, logger); + await setupCppAutobuild(logger); } // The Java and C# `build-mode: none` extractors place dependencies in the @@ -171,7 +172,7 @@ async function shouldExtractLanguage( } export function dbIsFinalized( - config: configUtils.Config, + config: ActionConfig<"dbLocation">, language: Language, logger: Logger, ) { diff --git a/src/api-client.ts b/src/api-client.ts index de62f4db4..6a5e99468 100644 --- a/src/api-client.ts +++ b/src/api-client.ts @@ -17,6 +17,7 @@ import { ReadOnlyEnv, RegistryProxyVars, getEnv, + exportEnvVar, } from "./environment"; import { Logger } from "./logging"; import { getRepositoryNwo, RepositoryNwo } from "./repository"; @@ -316,7 +317,7 @@ export async function getAnalysisKey(): Promise { const jobName = getRequiredEnvParam("GITHUB_JOB"); analysisKey = `${workflowPath}:${jobName}`; - core.exportVariable(EnvVar.ANALYSIS_KEY, analysisKey); + exportEnvVar(EnvVar.ANALYSIS_KEY, analysisKey); return analysisKey; } diff --git a/src/autobuild-action.ts b/src/autobuild-action.ts index 9fa801657..18aad1185 100644 --- a/src/autobuild-action.ts +++ b/src/autobuild-action.ts @@ -68,7 +68,11 @@ async function sendCompletedStatusReport( } } -async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) { +async function run({ + startedAt, + env, + logger, +}: ActionState<["Base", "Env", "Logger"]>) { // To capture errors appropriately, keep as much code within the try-catch as // possible, and only use safe functions outside. @@ -135,7 +139,7 @@ async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) { return; } - core.exportVariable(EnvVar.AUTOBUILD_DID_COMPLETE_SUCCESSFULLY, "true"); + env.export(EnvVar.AUTOBUILD_DID_COMPLETE_SUCCESSFULLY, "true"); await sendCompletedStatusReport(config, logger, startedAt, languages ?? []); } diff --git a/src/autobuild.ts b/src/autobuild.ts index 49b790102..44f6abd0c 100644 --- a/src/autobuild.ts +++ b/src/autobuild.ts @@ -1,11 +1,9 @@ -import * as core from "@actions/core"; - import { getTemporaryDirectory, getWorkflowEventName } from "./actions-util"; import { getGitHubVersion } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; import * as configUtils from "./config-utils"; import { DocUrl } from "./doc-url"; -import { ActionsEnvVars, EnvVar } from "./environment"; +import { ActionsEnvVars, EnvVar, exportEnvVar } from "./environment"; import { Feature, featureConfig, initFeatures } from "./feature-flags"; import { BuiltInLanguage, Language } from "./languages"; import { Logger } from "./logging"; @@ -112,7 +110,7 @@ export async function determineAutobuildLanguages( return languages; } -export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) { +export async function setupCppAutobuild(logger: Logger) { const envVar = featureConfig[Feature.CppDependencyInstallation].envVar; const featureName = "C++ automatic installation of dependencies"; const gitHubVersion = await getGitHubVersion(); @@ -123,7 +121,7 @@ export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) { getTemporaryDirectory(), logger, ); - if (await features.getValue(Feature.CppDependencyInstallation, codeql)) { + if (await features.getValue(Feature.CppDependencyInstallation)) { // disable autoinstall on self-hosted runners unless explicitly requested if ( process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] === "self-hosted" && @@ -136,16 +134,16 @@ export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) { : "" }`, ); - core.exportVariable(envVar, "false"); + exportEnvVar(envVar, "false"); } else { logger.info( `Enabling ${featureName}. This can be disabled by setting the ${envVar} environment variable to 'false'. See ${DocUrl.DEFINE_ENV_VARIABLES} for more information.`, ); - core.exportVariable(envVar, "true"); + exportEnvVar(envVar, "true"); } } else { logger.info(`Disabling ${featureName}.`); - core.exportVariable(envVar, "false"); + exportEnvVar(envVar, "false"); } } @@ -157,7 +155,7 @@ export async function runAutobuild( logger.startGroup(`Attempting to automatically build ${language} code`); const codeQL = await getCodeQL(logger, config.codeQLCmd); if (language === BuiltInLanguage.cpp) { - await setupCppAutobuild(codeQL, logger); + await setupCppAutobuild(logger); } if (config.buildMode) { await codeQL.extractUsingBuildMode(config, language); @@ -165,7 +163,7 @@ export async function runAutobuild( await codeQL.runAutobuild(config, language); } if (language === BuiltInLanguage.go) { - core.exportVariable(EnvVar.DID_AUTOBUILD_GOLANG, "true"); + exportEnvVar(EnvVar.DID_AUTOBUILD_GOLANG, "true"); } logger.endGroup(); } diff --git a/src/codeql.ts b/src/codeql.ts index 4d4e4a091..68273d27b 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -15,9 +15,10 @@ import * as api from "./api-client"; import * as outputCache from "./cli/output-cache"; import type { VersionInfo } from "./cli/types"; import { CliError, wrapCliConfigurationError } from "./cli-errors"; +import type { ActionConfig } from "./config/action-config"; import { appendExtraQueryExclusions, type Config } from "./config-utils"; import { DocUrl } from "./doc-url"; -import { EnvVar, getEnv } from "./environment"; +import { EnvVar, getEnv, exportEnvVar } from "./environment"; import { CodeQLDefaultVersionInfo, Feature, @@ -197,7 +198,7 @@ export interface CodeQL { diagnosticsExport( sarifFile: string, automationDetailsId: string | undefined, - config: Config, + config: ActionConfig<"tempDir">, ): Promise; /** Get the location of an extractor for the specified language. */ resolveExtractor(language: Language): Promise; @@ -253,7 +254,7 @@ let cachedCodeQL: CodeQL | undefined = undefined; * The version flags below can be used to conditionally enable certain features * on versions newer than this. */ -const CODEQL_MINIMUM_VERSION = "2.19.4"; +const CODEQL_MINIMUM_VERSION = "2.20.7"; /** * This version will shortly become the oldest version of CodeQL that the Action will run with. @@ -913,7 +914,7 @@ async function getCodeQLForCmd( async diagnosticsExport( sarifFile: string, automationDetailsId: string | undefined, - config: Config, + config: ActionConfig<"tempDir">, ): Promise { const args = [ "diagnostics", @@ -1054,7 +1055,7 @@ async function getCodeQLForCmd( }' by 'github/codeql-action/*@v${getActionVersion()}' in your code scanning workflow to ` + "continue using this version of the CodeQL Action.", ); - core.exportVariable(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true"); + exportEnvVar(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true"); } return codeql; } @@ -1237,7 +1238,9 @@ export async function getTrapCachingExtractorConfigArgsForLang( * * This will not exist if the configuration is being parsed in the Action. */ -function getGeneratedCodeScanningConfigPath(config: Config): string { +function getGeneratedCodeScanningConfigPath( + config: ActionConfig<"tempDir">, +): string { return path.resolve(config.tempDir, "user-config.yaml"); } diff --git a/src/config-utils.ts b/src/config-utils.ts index 46640c344..e0b005db7 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -2,7 +2,6 @@ import * as fs from "fs"; import * as path from "path"; import { performance } from "perf_hooks"; -import * as core from "@actions/core"; import * as yaml from "js-yaml"; import { ActionState } from "./action-common"; @@ -22,7 +21,11 @@ import { import * as api from "./api-client"; import { getCachingKind } from "./caching-utils"; import { type CodeQL } from "./codeql"; -import { type Config } from "./config/action-config"; +import { + type AbortedInitConfig, + type ActionConfig, + type Config, +} from "./config/action-config"; import { calculateAugmentation, ExcludeQueryFilter, @@ -46,7 +49,7 @@ import { makeTelemetryDiagnostic, } from "./diagnostics"; import { prepareDiffInformedAnalysis } from "./diff-informed-analysis-utils"; -import { EnvVar } from "./environment"; +import { EnvVar, exportEnvVar } from "./environment"; import * as errorMessages from "./error-messages"; import { Feature, FeatureEnablement, FeatureWithoutCLI } from "./feature-flags"; import { @@ -72,6 +75,7 @@ import { import { OverlayDatabaseMode } from "./overlay/overlay-database-mode"; import { shouldSkipOverlayAnalysis } from "./overlay/status"; import { RepositoryNwo } from "./repository"; +import { ActionName } from "./status-report"; import { ToolsFeature } from "./tools-features"; import { downloadTrapCaches } from "./trap-caching"; import { @@ -965,10 +969,10 @@ async function setCppTrapCachingEnvironmentVariables( ); } else if (config.trapCaches[BuiltInLanguage.cpp]) { logger.info("Enabling TRAP caching for C/C++."); - core.exportVariable(envVar, "true"); + exportEnvVar(envVar, "true"); } else { logger.debug(`Disabling TRAP caching for C/C++.`); - core.exportVariable(envVar, "false"); + exportEnvVar(envVar, "false"); } } } @@ -1380,31 +1384,86 @@ export function getPathToParsedConfigFile(tempDir: string): string { return path.join(tempDir, "config"); } +function getPathToFailedConfigFile(tempDir: string): string { + return path.join(tempDir, "failed-config"); +} + /** - * Store the given config to the path returned from getPathToParsedConfigFile. + * Writes {@link config} to {@link configFilePath}. + * + * This function is not intended to be called, other than by + * {@link saveConfig} and {@link saveAbortedInitConfig} below. */ -export async function saveConfig(config: Config, logger: Logger) { +function saveConfigFile( + logger: Logger, + configFilePath: string, + config: Partial, +) { const configString = JSON.stringify(config); - const configFile = getPathToParsedConfigFile(config.tempDir); - fs.mkdirSync(path.dirname(configFile), { recursive: true }); - fs.writeFileSync(configFile, configString, "utf8"); + fs.mkdirSync(path.dirname(configFilePath), { recursive: true }); + fs.writeFileSync(configFilePath, configString, "utf8"); logger.debug("Saved config:"); logger.debug(configString); } /** - * Get the config that has been saved to the given temp dir. - * If the config could not be found then returns undefined. + * Store the given config to the path returned from getPathToParsedConfigFile. */ -export async function getConfig( - tempDir: string, +export async function saveConfig(config: Config, logger: Logger) { + const configFile = getPathToParsedConfigFile(config.tempDir); + saveConfigFile(logger, configFile, config); +} + +/** + * Store parts of {@link config} as a failed configuration file. + * + * The file will only contain parts of {@link config} that are relevant to + * the `init-post` step in the workflow. + */ +export function saveAbortedInitConfig( + action: ActionState<["Base", "Logger"]>, + config: Config, +) { + // Should only be called by init. + if (action.name !== ActionName.Init) { + throw new Error( + `Internal error: 'saveAbortedInitConfig' should only be called by '${ActionName.Init}', but was called by '${action.name}'.`, + ); + } + + // Create a copy of the input `Config` that only contains the keys we want. + const failedConfig: AbortedInitConfig = { + version: config.version, + tempDir: config.tempDir, + codeQLCmd: config.codeQLCmd, + debugMode: config.debugMode, + gitHubVersion: config.gitHubVersion, + languages: config.languages, + analysisKinds: config.analysisKinds, + }; + + action.logger.debug(`Saving config for failed init step.`); + saveConfigFile( + action.logger, + getPathToFailedConfigFile(config.tempDir), + failedConfig, + ); +} + +/** + * Attempts to read a {@link Config} from {@link configFilePath}. + * + * This function is not intended to be called, other than by + * {@link getConfig} and {@link getAbortedInitConfig} below. + */ +function readConfigFile( logger: Logger, -): Promise { - const configFile = getPathToParsedConfigFile(tempDir); - if (!fs.existsSync(configFile)) { + configFilePath: string, +): Config | undefined { + if (!fs.existsSync(configFilePath)) { return undefined; } - const configString = fs.readFileSync(configFile, "utf8"); + const configString = fs.readFileSync(configFilePath, "utf8"); logger.debug("Loaded config:"); logger.debug(configString); @@ -1429,6 +1488,38 @@ export async function getConfig( return config as Config; } +/** + * Get the config that has been saved to the given temp dir. + * If the config could not be found then returns undefined. + */ +export async function getConfig( + tempDir: string, + logger: Logger, +): Promise { + const configFile = getPathToParsedConfigFile(tempDir); + return readConfigFile(logger, configFile); +} + +/** + * Loads a {@link AbortedInitConfig} from a failed `init` step if it exists. + * + * The result will only contain parts of a {@link Config} that are relevant to + * the `init-post` step in the workflow. + */ +export function getAbortedInitConfig( + action: ActionState<["Base", "Logger"]>, + tempDir: string, +): AbortedInitConfig | undefined { + // Only intended to be called by the `init-post` action. + if (action.name !== ActionName.InitPost) { + throw new Error( + `Internal error: 'getAbortedInitConfig' should only be called by '${ActionName.InitPost}', but was called by '${action.name}'.`, + ); + } + + return readConfigFile(action.logger, getPathToFailedConfigFile(tempDir)); +} + /** * Generate a `qlconfig.yml` file from the `registries` input. * This file is used by the CodeQL CLI to list the registries to use for each @@ -1619,21 +1710,27 @@ export function appendExtraQueryExclusions( /** * Returns `true` if Code Scanning analysis is enabled, or `false` if not. */ -export function isCodeScanningEnabled(config: Config): boolean { +export function isCodeScanningEnabled( + config: ActionConfig<"analysisKinds">, +): boolean { return config.analysisKinds.includes(AnalysisKind.CodeScanning); } /** * Returns `true` if Code Quality analysis is enabled, or `false` if not. */ -export function isCodeQualityEnabled(config: Config): boolean { +export function isCodeQualityEnabled( + config: ActionConfig<"analysisKinds">, +): boolean { return config.analysisKinds.includes(AnalysisKind.CodeQuality); } /** * Returns `true` if Code Scanning Risk Assessment analysis is enabled, or `false` if not. */ -export function isRiskAssessmentEnabled(config: Config): boolean { +export function isRiskAssessmentEnabled( + config: ActionConfig<"analysisKinds">, +): boolean { return config.analysisKinds.includes(AnalysisKind.RiskAssessment); } diff --git a/src/config/action-config.ts b/src/config/action-config.ts index de6882e77..10f315028 100644 --- a/src/config/action-config.ts +++ b/src/config/action-config.ts @@ -126,3 +126,38 @@ export interface Config { */ enableFileCoverageInformation: boolean; } + +/** Properties available in `Config`. */ +export type ActionConfigProperties = keyof Config; + +/** + * The CodeQL Action configuration state that is persisted + * between steps of the CodeQL Action in a CodeQL workflow. + * + * By default, this is equivalent to `Config`. By explicitly + * providing required property names for `T` this can be restricted + * to requiring only those. For example, in `ActionConfig<"codeQLCmd">` + * all properties except `codeqlCmd` are optional. + */ +export type ActionConfig< + T extends ActionConfigProperties = ActionConfigProperties, +> = Partial & Pick; + +/** Helper function to check whether `config` has `key` to narrow the type of `config`. */ +export function hasConfigKey( + config: Partial, + key: Key, +): config is ActionConfig { + return config[key] !== undefined; +} + +/** A minimal configuration that we can make available even when `init` aborts. */ +export type AbortedInitConfig = ActionConfig< + | "version" + | "tempDir" + | "gitHubVersion" + | "debugMode" + | "languages" + | "analysisKinds" + | "codeQLCmd" +>; diff --git a/src/debug-artifacts.test.ts b/src/debug-artifacts.test.ts index 370816aef..16ecb6d5d 100644 --- a/src/debug-artifacts.test.ts +++ b/src/debug-artifacts.test.ts @@ -55,25 +55,20 @@ test("getArtifactSuffix", (t) => { } }); -// These next tests check the correctness of the logic to determine whether or not -// artifacts are uploaded in debug mode. Since it's not easy to mock the actual -// call to upload an artifact, we just check that we get an "upload-failed" result, -// instead of actually uploading the artifact. -// -// For tests where we expect artifact upload to be blocked, we check for a different -// response from the function. +// These next tests check whether `uploadArtifacts` attempts to upload an artifact. Since it's not +// easy to mock the actual call to upload an artifact, we check that we get an "upload-failed" +// result, instead of actually uploading the artifact. -test("uploadDebugArtifacts when artifacts empty should emit 'no-artifacts-to-upload'", async (t) => { +test("uploadArtifacts returns 'no-artifacts-to-upload' when there are no files to upload", async (t) => { // Test that no error is thrown if artifacts list is empty. const logger = getActionsLogger(); await t.notThrowsAsync(async () => { - const uploaded = await debugArtifacts.uploadDebugArtifacts( + const uploaded = await debugArtifacts.uploadArtifacts( logger, [], "i-dont-exist", "artifactName", GitHubVariant.DOTCOM, - undefined, ); t.is( uploaded, @@ -83,17 +78,15 @@ test("uploadDebugArtifacts when artifacts empty should emit 'no-artifacts-to-upl }); }); -test("uploadDebugArtifacts when no codeql version is used should invoke artifact upload", async (t) => { - // Test that the artifact is uploaded. +test("uploadArtifacts attempts an upload when there are files to upload", async (t) => { const logger = getActionsLogger(); await t.notThrowsAsync(async () => { - const uploaded = await debugArtifacts.uploadDebugArtifacts( + const uploaded = await debugArtifacts.uploadArtifacts( logger, ["hucairz"], "i-dont-exist", "artifactName", GitHubVariant.DOTCOM, - undefined, ); t.is( uploaded, @@ -103,44 +96,3 @@ test("uploadDebugArtifacts when no codeql version is used should invoke artifact ); }); }); - -test("uploadDebugArtifacts when new codeql version is used should invoke artifact upload", async (t) => { - // Test that the artifact is uploaded. - const logger = getActionsLogger(); - await t.notThrowsAsync(async () => { - const uploaded = await debugArtifacts.uploadDebugArtifacts( - logger, - ["hucairz"], - "i-dont-exist", - "artifactName", - GitHubVariant.DOTCOM, - "2.20.3", - ); - t.is( - uploaded, - // The failure is expected since we don't want to actually upload any artifacts in unit tests. - "upload-failed", - "Expect failure to upload artifacts since root dir does not exist", - ); - }); -}); - -test("uploadDebugArtifacts when old codeql is used should avoid trying to upload artifacts", async (t) => { - // Test that the artifact is not uploaded. - const logger = getActionsLogger(); - await t.notThrowsAsync(async () => { - const uploaded = await debugArtifacts.uploadDebugArtifacts( - logger, - ["hucairz"], - "i-dont-exist", - "artifactName", - GitHubVariant.DOTCOM, - "2.20.2", - ); - t.is( - uploaded, - "upload-not-supported", - "Expected artifact upload to be blocked because of old CodeQL version", - ); - }); -}); diff --git a/src/debug-artifacts.ts b/src/debug-artifacts.ts index 9f5f1775d..56497f14e 100644 --- a/src/debug-artifacts.ts +++ b/src/debug-artifacts.ts @@ -10,15 +10,11 @@ import { getOptionalInput, getTemporaryDirectory } from "./actions-util"; import { dbIsFinalized } from "./analyze"; import { scanArtifactsForTokens } from "./artifact-scanner"; import { type CodeQL } from "./codeql"; -import { Config } from "./config-utils"; -import { EnvVar } from "./environment"; +import type { ActionConfig } from "./config/action-config"; +import { EnvVar, exportEnvVar } from "./environment"; import * as json from "./json"; import { Language } from "./languages"; import { Logger, withGroup } from "./logging"; -import { - isSafeArtifactUpload, - SafeArtifactUploadVersion, -} from "./tools-features"; import { bundleDb, doesDirectoryExist, @@ -40,7 +36,6 @@ export function sanitizeArtifactName(name: string): string { export async function uploadCombinedSarifArtifacts( logger: Logger, gitHubVariant: GitHubVariant, - codeQlVersion: string | undefined, ) { const tempDir = getTemporaryDirectory(); @@ -70,13 +65,12 @@ export async function uploadCombinedSarifArtifacts( } try { - await uploadDebugArtifacts( + await uploadArtifacts( logger, toUpload, baseTempDir, "combined-sarif-artifacts", gitHubVariant, - codeQlVersion, ); } catch (e) { logger.warning( @@ -95,7 +89,7 @@ export async function uploadCombinedSarifArtifacts( * @return The path to that debug artifact, or undefined if an error occurs. */ function tryPrepareSarifDebugArtifact( - config: Config, + config: ActionConfig<"dbLocation">, language: Language, logger: Logger, ): string | undefined { @@ -137,7 +131,7 @@ function tryPrepareSarifDebugArtifact( */ async function tryBundleDatabase( codeql: CodeQL, - config: Config, + config: ActionConfig<"dbLocation">, language: Language, logger: Logger, ): Promise { @@ -163,6 +157,11 @@ async function tryBundleDatabase( } } +/** The minimal configuration needed for `tryUploadAllAvailableDebugArtifacts`. */ +export type UploadDebugArtifactsConfig = ActionConfig< + "languages" | "gitHubVersion" | "dbLocation" | "debugArtifactName" +>; + /** * Attempt to upload all available debug artifacts. * @@ -170,9 +169,8 @@ async function tryBundleDatabase( */ export async function tryUploadAllAvailableDebugArtifacts( codeql: CodeQL, - config: Config, + config: UploadDebugArtifactsConfig, logger: Logger, - codeQlVersion: string | undefined, ) { const filesToUpload: string[] = []; try { @@ -231,13 +229,12 @@ export async function tryUploadAllAvailableDebugArtifacts( try { await withGroup("Uploading debug artifacts", async () => - uploadDebugArtifacts( + uploadArtifacts( logger, filesToUpload, config.dbLocation, config.debugArtifactName, config.gitHubVersion.type, - codeQlVersion, ), ); } catch (e) { @@ -283,26 +280,6 @@ export type UploadArtifactsResult = | "upload-successful" | "upload-failed"; -export async function uploadDebugArtifacts( - logger: Logger, - toUpload: string[], - rootDir: string, - artifactName: string, - ghVariant: GitHubVariant, - codeQlVersion: string | undefined, -): Promise { - const uploadSupported = isSafeArtifactUpload(codeQlVersion); - - if (!uploadSupported) { - core.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"; - } - - return uploadArtifacts(logger, toUpload, rootDir, artifactName, ghVariant); -} - /** * Uploads the specified files as a single workflow artifact. * @@ -330,7 +307,7 @@ export async function uploadArtifacts( // some issues early. if (isInTestMode()) { await scanArtifactsForTokens(toUpload, logger); - core.exportVariable("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); + exportEnvVar("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); } const suffix = getArtifactSuffix(getOptionalInput("matrix")); @@ -381,7 +358,7 @@ export async function getArtifactUploaderClient( * all files in the database folder and return the path. */ async function createPartialDatabaseBundle( - config: Config, + config: ActionConfig<"dbLocation">, language: Language, ): Promise { const databasePath = getCodeQLDatabasePath(config, language); @@ -422,7 +399,7 @@ async function createPartialDatabaseBundle( */ async function createDatabaseBundleCli( codeql: CodeQL, - config: Config, + config: ActionConfig<"dbLocation">, language: Language, ): Promise { const databaseBundlePath = await bundleDb( diff --git a/src/environment.test.ts b/src/environment.test.ts new file mode 100644 index 000000000..2c8a8a8f1 --- /dev/null +++ b/src/environment.test.ts @@ -0,0 +1,12 @@ +import test from "ava"; + +import { Env, ReadOnlyEnv } from "./environment"; +import { getTestEnv, setupTests } from "./testing-utils"; + +setupTests(test); + +test("isTestingEnv() is true", (t) => { + t.true(new ReadOnlyEnv(process.env).isTestingEnv()); + t.true(new Env(process.env).isTestingEnv()); + t.true(getTestEnv().isTestingEnv()); +}); diff --git a/src/environment.ts b/src/environment.ts index bf4bb4f71..c3aad9086 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -1,3 +1,10 @@ +import * as core from "@actions/core"; + +/** + * This constant is set in `ava.setup.mjs` for tests. + */ +declare const __CODEQL_ACTION_TEST_ENV__: string | undefined; + /** * Environment variables used by Default Setup to communicate the private registry proxy configuration. */ @@ -211,8 +218,20 @@ export enum ActionsEnvVars { RUNNER_TOOL_CACHE = "RUNNER_TOOL_CACHE", } +/** Environment variables which are not specific to CodeQL. */ +export enum SystemEnvVar { + /** + * Used by Node and related tools to indicate what kind of environment we are running in. + */ + NODE_ENV = "NODE_ENV", +} + /** A type representing all known environment variables. */ -export type KnownEnvVar = EnvVar | ActionsEnvVars | RegistryProxyVars; +export type KnownEnvVar = + | EnvVar + | ActionsEnvVars + | RegistryProxyVars + | SystemEnvVar; /** * Gets an environment variable, but throws an error if it is not set. @@ -289,6 +308,26 @@ export class ReadOnlyEnv { public entries(): Array<[string, T]> { return Object.entries(this.vars); } + + /** + * Gets a value indicating whether we should skip uploads of + * all kinds (SARIF results, status reports, DBs, ...). + * + * This is not guaranteed to be set in all test environments. + */ + public isSkippingUploadsInTests(): boolean { + return this.getOptional(EnvVar.TEST_MODE) === "true"; + } + + /** + * Gets a value indicative of whether we are in a testing environment + * by testing whether the value of the `NODE_ENV` variable is "test". + * This is expected to be the case if e.g. `ava` is running the tests + * or if this instance was constructed by `getTestEnv`. + */ + public isTestingEnv(): boolean { + return __CODEQL_ACTION_TEST_ENV__ === "unit-test"; + } } /** @@ -307,6 +346,26 @@ export class Env< this.changed = true; } + /** + * Wrapper around `core.exportVariable` which does not call `core.exportVariable` + * when running unit tests. This is important, because otherwise `core.exportVariable` + * sets environment variables for other steps in a workflow when we run unit tests in CI. + * + * @param name The name of the environment variable to set and export. + * @param val The value to set and export for the environment variable. + */ + public export(name: string, val: T): void { + // Setting the environment variable for this instance is always OK, including + // in tests, since we use fresh `Env` instances whenever needed. This allows + // tests to pass that rely on that part of the `core.exportVariable` behaviour. + this.set(name, val); + + // Call `core.exportVariable` whenever we are not in a test environment. + if (!this.isTestingEnv()) { + core.exportVariable(name, val); + } + } + /** Gets a value indicating whether `set` was called at least once. */ public hasChanged(): boolean { return this.changed; @@ -317,3 +376,34 @@ export class Env< export function getEnv(env: NodeJS.ProcessEnv = process.env): Env { return new Env(env); } + +/** + * Returns whether we are in test mode. This is used by CodeQL Action PR checks. + * + * In test mode, we skip several uploads (SARIF results, status reports, DBs, ...). + * + * @deprecated + * The purpose of this function is ambiguous. Use `isSkippingUploadsInTests` on + * a `ReadOnlyEnv` instance instead for equivalent behaviour. Use `isTestingEnv` + * to determine if we are running in a unit test. + */ +export function isInTestMode(): boolean { + return getEnv().isSkippingUploadsInTests(); +} + +/** + * Wrapper around `core.exportVariable` which does not call `core.exportVariable` + * when running unit tests. This is important, because otherwise `core.exportVariable` + * sets environment variables for other steps in a workflow when we run unit tests in CI. + * + * @deprecated Use `export` on an `Env` instance instead. + */ +export function exportEnvVar(name: string, val: any): void { + const env = getEnv(); + + if (typeof val === "string") { + env.export(name, val); + } else { + env.export(name, JSON.stringify(val)); + } +} diff --git a/src/feature-flags.ts b/src/feature-flags.ts index 59b50e2df..f74d0bd25 100644 --- a/src/feature-flags.ts +++ b/src/feature-flags.ts @@ -240,7 +240,7 @@ export const featureConfig = { defaultValue: false, envVar: "CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES", legacyApi: true, - minimumVersion: "2.15.0", + minimumVersion: undefined, }, [Feature.CsharpCacheBuildModeNone]: { defaultValue: false, diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index 0e6dae13a..b6aeb5bd3 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -7,6 +7,11 @@ import * as actionsUtil from "./actions-util"; import { CodeScanning, RiskAssessment } from "./analyses"; import { getApiClient, getGitHubVersion } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; +import { + hasConfigKey, + type AbortedInitConfig, + type ActionConfig, +} from "./config/action-config"; import { Config, isCodeScanningEnabled, @@ -16,6 +21,7 @@ import { getArtifactSuffix, getArtifactUploaderClient, sanitizeArtifactName, + type UploadDebugArtifactsConfig, } from "./debug-artifacts"; import * as dependencyCaching from "./dependency-caching"; import { EnvVar, ReadOnlyEnv } from "./environment"; @@ -86,6 +92,11 @@ interface FailedSarifInfo { checkoutPath: string; } +/** The minimal Action configuration required to prepare and upload a failed SARIF. */ +export type FailedSarifConfig = ActionConfig< + "codeQLCmd" | "tempDir" | "analysisKinds" | "languages" +>; + /** * Tries to prepare a SARIF file that contains information about a failed analysis. * @@ -94,7 +105,7 @@ interface FailedSarifInfo { async function prepareFailedSarif( logger: Logger, features: FeatureEnablement, - config: Config, + config: FailedSarifConfig, ): Promise> { if (!config.codeQLCmd) { return new Failure({ @@ -160,7 +171,7 @@ async function prepareFailedSarif( async function generateFailedSarif( logger: Logger, features: FeatureEnablement, - config: Config, + config: ActionConfig<"codeQLCmd" | "tempDir">, category: string | undefined, checkoutPath: string, sarifFile?: string, @@ -192,7 +203,7 @@ async function generateFailedSarif( * category for the workflow. */ async function maybeUploadFailedSarif( - config: Config, + config: FailedSarifConfig, repositoryNwo: RepositoryNwo, features: FeatureEnablement, logger: Logger, @@ -227,7 +238,7 @@ async function maybeUploadFailedSarif( /** Uploads a failed SARIF file as workflow artifact, if it can be generated. */ async function maybeUploadFailedSarifArtifact( - config: Config, + config: FailedSarifConfig, features: FeatureEnablement, logger: Logger, ): Promise { @@ -267,7 +278,7 @@ async function maybeUploadFailedSarifArtifact( * @returns The results of uploading the SARIF file for the failure. */ export async function tryUploadSarifIfRunFailed( - config: Config, + config: FailedSarifConfig, repositoryNwo: RepositoryNwo, features: FeatureEnablement, logger: Logger, @@ -324,13 +335,12 @@ export async function tryUploadSarifIfRunFailed( export async function uploadFailureInfo( uploadAllAvailableDebugArtifacts: ( codeql: CodeQL, - config: Config, + config: UploadDebugArtifactsConfig, logger: Logger, - codeQlVersion: string, ) => Promise, - printDebugLogs: (config: Config) => Promise, + printDebugLogs: (logger: Logger, config: Partial) => Promise, codeql: CodeQL, - config: Config, + config: Config | AbortedInitConfig, repositoryNwo: RepositoryNwo, features: FeatureEnablement, jobStatus: string | undefined, @@ -377,21 +387,15 @@ export async function uploadFailureInfo( } // Upload appropriate Actions artifacts for debugging - if (config.debugMode) { + if (config.debugMode && hasConfigKey(config, "dbLocation")) { logger.info( "Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts...", ); - const version = await codeql.getVersion(); - await uploadAllAvailableDebugArtifacts( - codeql, - config, - logger, - version.version, - ); - await printDebugLogs(config); + await uploadAllAvailableDebugArtifacts(codeql, config, logger); + await printDebugLogs(logger, config); } - if (actionsUtil.isSelfHostedRunner()) { + if (actionsUtil.isSelfHostedRunner() && config.dbLocation) { try { fs.rmSync(config.dbLocation, { recursive: true, @@ -406,6 +410,10 @@ export async function uploadFailureInfo( `Failed to clean up database cluster directory ${config.dbLocation}. Details: ${e}`, ); } + } else if (config.dbLocation === undefined) { + logger.debug( + "Skipping cleanup of database cluster directory since the configuration does not include a database path.", + ); } else { logger.debug( "Skipping cleanup of database cluster directory since we are running on a GitHub-hosted " + @@ -454,7 +462,7 @@ function isConclusiveJobStatus(jobStatus: string | undefined): boolean { */ async function recordOverlayStatus( codeql: CodeQL, - config: Config, + config: Partial, features: FeatureEnablement, jobStatus: string | undefined, env: ReadOnlyEnv, @@ -466,6 +474,11 @@ async function recordOverlayStatus( !(await features.getValue(Feature.OverlayAnalysisStatusSave)) ) { return; + } else if (config.languages === undefined) { + logger.debug( + "Not recording overlay status, because the configuration contains no 'languages'.", + ); + return; } // Only record a failure when the job outcome tells us something about the analysis. A cancelled diff --git a/src/init-action-post.ts b/src/init-action-post.ts index a2bba6d7a..689cfd465 100644 --- a/src/init-action-post.ts +++ b/src/init-action-post.ts @@ -6,6 +6,7 @@ import * as core from "@actions/core"; +import { runInActions, type Action, type ActionState } from "./action-common"; import { restoreInputs, getOptionalInput, @@ -15,22 +16,25 @@ import { import { getGitHubVersion, wrapApiConfigurationError } from "./api-client"; import { CachingKind } from "./caching-utils"; import { getCodeQL } from "./codeql"; -import { type Config, getConfig } from "./config-utils"; +import { + hasConfigKey, + type AbortedInitConfig, + type Config, +} from "./config/action-config"; +import { getAbortedInitConfig, getConfig } from "./config-utils"; import * as debugArtifacts from "./debug-artifacts"; import { DependencyCachingUsageReport, getDependencyCacheUsage, } from "./dependency-caching"; -import { EnvVar, getEnv } from "./environment"; +import { EnvVar, type ReadOnlyEnv } from "./environment"; import { initFeatures } from "./feature-flags"; import * as gitUtils from "./git-utils"; import * as initActionPostHelper from "./init-action-post-helper"; -import { getActionsLogger } from "./logging"; import { getRepositoryNwo } from "./repository"; import { StatusReportBase, sendStatusReport, - sendUnhandledErrorStatusReport, createStatusReportBase, getActionsStatus, ActionName, @@ -45,16 +49,17 @@ interface InitPostStatusReport initActionPostHelper.JobStatusReport, initActionPostHelper.DependencyCachingUsageReport {} -async function run(startedAt: Date) { +async function run(action: ActionState<["Base", "Logger", "Env"]>) { // To capture errors appropriately, keep as much code within the try-catch as // possible, and only use safe functions outside. + const logger = action.logger; - const logger = getActionsLogger(); - let config: Config | undefined; + let config: Config | AbortedInitConfig | undefined; let uploadFailedSarifResult: | initActionPostHelper.UploadFailedSarifResult | undefined; let dependencyCachingUsage: DependencyCachingUsageReport | undefined; + try { // Read the job status before restoring inputs, since it is provided by the Actions runtime // environment for this step and would otherwise be overwritten by the value that the `init` @@ -64,7 +69,15 @@ async function run(startedAt: Date) { // Restore inputs from `init` Action. restoreInputs(logger); - config = await getConfig(getTemporaryDirectory(), logger); + const tmpDir = getTemporaryDirectory(); + config = await getConfig(tmpDir, logger); + + // If we weren't able to read the normal configuration file, the `init` step failed before it could write it. + // Try to load the "failed" configuration file instead which may have been written by the `init` step + // with a minimal configuration for this post-action. + if (config === undefined) { + config = getAbortedInitConfig(action, tmpDir); + } const gitHubVersion = config?.gitHubVersion ?? (await getGitHubVersion()); checkGitHubVersionInRange(gitHubVersion, logger); @@ -92,7 +105,7 @@ async function run(startedAt: Date) { repositoryNwo, features, jobStatus, - getEnv(), + action.env, logger, ); @@ -102,6 +115,7 @@ async function run(startedAt: Date) { // and where caching may not be enabled. if ( (await gitUtils.isAnalyzingDefaultBranch()) && + hasConfigKey(config, "dependencyCachingEnabled") && config.dependencyCachingEnabled !== CachingKind.None ) { dependencyCachingUsage = await getDependencyCacheUsage(logger); @@ -112,9 +126,9 @@ async function run(startedAt: Date) { core.setFailed(error.message); const statusReportBase = await createStatusReportBase( - ActionName.InitPost, + action.name, getActionsStatus(error), - startedAt, + action.startedAt, config, await checkDiskUsage(logger), logger, @@ -126,13 +140,13 @@ async function run(startedAt: Date) { } return; } - const jobStatus = getFinalJobStatus(config); + const jobStatus = getFinalJobStatus(action, config); logger.info(`CodeQL job status was ${getJobStatusDisplayName(jobStatus)}.`); const statusReportBase = await createStatusReportBase( - ActionName.InitPost, + action.name, "success", - startedAt, + action.startedAt, config, await checkDiskUsage(logger), logger, @@ -157,16 +171,21 @@ async function run(startedAt: Date) { * Otherwise, we determine the job status based on whether the analyze step * completed successfully and whether we have a valid CodeQL config. */ -function getFinalJobStatus(config: Config | undefined): JobStatus { - const existingJobStatus = getJobStatusFromEnvironment(); +function getFinalJobStatus( + action: ActionState<["Env"]>, + config: Partial | undefined, +): JobStatus { + const existingJobStatus = getJobStatusFromEnvironment(action.env); if (existingJobStatus !== undefined) { return existingJobStatus; } let jobStatus: JobStatus; - if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] === "true") { - core.exportVariable(EnvVar.JOB_STATUS, JobStatus.SuccessStatus); + if ( + action.env.getOptional(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY) === "true" + ) { + action.env.export(EnvVar.JOB_STATUS, JobStatus.SuccessStatus); jobStatus = JobStatus.SuccessStatus; } else if (config !== undefined) { // - We have computed a CodeQL config @@ -191,7 +210,7 @@ function getFinalJobStatus(config: Config | undefined): JobStatus { // This shouldn't be necessary, but in the odd case that we run more than one // `init` post step, ensure the job status is consistent between them. - core.exportVariable(EnvVar.JOB_STATUS, jobStatus); + action.env.export(EnvVar.JOB_STATUS, jobStatus); return jobStatus; } @@ -200,8 +219,8 @@ function getFinalJobStatus(config: Config | undefined): JobStatus { * * If the job status is invalid, return `UnknownStatus`. */ -function getJobStatusFromEnvironment(): JobStatus | undefined { - const jobStatusFromEnvironment = process.env[EnvVar.JOB_STATUS]; +function getJobStatusFromEnvironment(env: ReadOnlyEnv): JobStatus | undefined { + const jobStatusFromEnvironment = env.getOptional(EnvVar.JOB_STATUS); if (jobStatusFromEnvironment !== undefined) { // Validate the job status from the environment. If it is invalid, return unknown. @@ -216,18 +235,11 @@ function getJobStatusFromEnvironment(): JobStatus | undefined { return undefined; } +const initPost: Action = { + name: ActionName.InitPost, + run, +}; + export async function runWrapper() { - const startedAt = new Date(); - const logger = getActionsLogger(); - try { - await run(startedAt); - } catch (error) { - core.setFailed(`init post action failed: ${wrapError(error).message}`); - await sendUnhandledErrorStatusReport( - ActionName.InitPost, - startedAt, - error, - logger, - ); - } + return await runInActions(initPost); } diff --git a/src/init-action.ts b/src/init-action.ts index 31414bd80..5376763b5 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -5,7 +5,12 @@ import * as core from "@actions/core"; import * as io from "@actions/io"; import * as semver from "semver"; -import { Action, ActionState, runInActions } from "./action-common"; +import { + Action, + ActionState, + extendActionState, + runInActions, +} from "./action-common"; import { FileCmdNotFoundError, getActionVersion, @@ -93,7 +98,6 @@ import { checkActionVersion, getErrorMessage, BuildMode, - getOptionalEnvVar, } from "./util"; import { checkWorkflow } from "./workflow"; @@ -253,7 +257,7 @@ async function run( ); const repositoryProperties = repositoryPropertiesResult.orElse({}); - core.exportVariable(EnvVar.INIT_ACTION_HAS_RUN, "true"); + actionState.env.export(EnvVar.INIT_ACTION_HAS_RUN, "true"); // path.resolve() respects the intended semantics of source-root. If // source-root is relative, it is relative to the GITHUB_WORKSPACE. If @@ -278,7 +282,9 @@ async function run( } // Compute the value of the `config-file` input. - const actionStateWithFeatures = { ...actionState, features }; + const actionStateWithFeatures = extendActionState(actionState, { + features, + }); configFile = await getConfigFileInput( actionStateWithFeatures, repositoryProperties, @@ -349,7 +355,7 @@ async function run( // to the workflow log. No exceptions are thrown. await checkWorkflow(logger, codeql); - // Set CODEQL_ENABLE_EXPERIMENTAL_FEATURES for Rust if between 2.19.3 (included) and 2.22.1 (excluded) + // Set CODEQL_ENABLE_EXPERIMENTAL_FEATURES for Rust if the CLI is older than 2.22.1. // We need to set this environment variable before initializing the config, otherwise Rust // analysis will not be enabled (experimental language packs are only active with that environment // variable set to `true`). @@ -360,16 +366,10 @@ async function run( .getRawLanguagesNoAutodetect(getOptionalInput("languages")) .includes(BuiltInLanguage.rust) ) { - const experimental = "2.19.3"; const publicPreview = "2.22.1"; const actualVer = (await codeql.getVersion()).version; - if (semver.lt(actualVer, experimental)) { - throw new ConfigurationError( - `Rust analysis is supported by CodeQL CLI version ${experimental} or higher, but found version ${actualVer}`, - ); - } if (semver.lt(actualVer, publicPreview)) { - core.exportVariable(EnvVar.EXPERIMENTAL_FEATURES, "true"); + actionState.env.export(EnvVar.EXPERIMENTAL_FEATURES, "true"); logger.info("Experimental Rust analysis enabled"); } } @@ -457,6 +457,18 @@ async function run( await checkInstallPython311(config.languages, codeql); } catch (unwrappedError) { + // If we have initialised the Action state, then try to save a subset of it for use by the `init-post` action + // so that it can try to create and upload additional diagnostic information. + if (config !== undefined) { + try { + configUtils.saveAbortedInitConfig(actionState, config); + } catch (configSaveError) { + logger.warning( + `Unable to save configuration for '${ActionName.InitPost}' step: ${getErrorMessage(configSaveError)}`, + ); + } + } + const error = wrapError(unwrappedError); core.setFailed(error.message); const statusReportBase = await createStatusReportBase( @@ -517,9 +529,9 @@ async function run( } // Forward Go flags - const goFlags = process.env["GOFLAGS"]; + const goFlags = actionState.env.getOptional("GOFLAGS"); if (goFlags) { - core.exportVariable("GOFLAGS", goFlags); + actionState.env.export("GOFLAGS", goFlags); core.warning( "Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action.", ); @@ -565,7 +577,7 @@ async function run( // Store the original location of our wrapper script somewhere where we can // later retrieve it from and cross-check that it hasn't been changed. - core.exportVariable(EnvVar.GO_BINARY_LOCATION, goWrapperPath); + actionState.env.export(EnvVar.GO_BINARY_LOCATION, goWrapperPath); } catch (e) { logger.warning( `Analyzing Go on Linux, but failed to install wrapper script. Tracing custom builds may fail: ${e}`, @@ -574,7 +586,7 @@ async function run( } else { // Store the location of the original Go binary, so we can check that no setup tasks were performed after the // `init` Action ran. - core.exportVariable(EnvVar.GO_BINARY_LOCATION, goBinaryPath); + actionState.env.export(EnvVar.GO_BINARY_LOCATION, goBinaryPath); } } catch (e) { logger.warning( @@ -609,12 +621,12 @@ async function run( // threads it would ask extractors to use. See help text for the "--ram" and "--threads" // options at https://codeql.github.com/docs/codeql-cli/manual/database-trace-command/ // for details. - core.exportVariable( + actionState.env.export( "CODEQL_RAM", process.env["CODEQL_RAM"] || getCodeQLMemoryLimit(getOptionalInput("ram"), logger).toString(), ); - core.exportVariable( + actionState.env.export( "CODEQL_THREADS", process.env["CODEQL_THREADS"] || getThreadsFlagValue(getOptionalInput("threads"), logger).toString(), @@ -622,21 +634,15 @@ async function run( // Disable Kotlin extractor if feature flag set if (await features.getValue(Feature.DisableKotlinAnalysisEnabled)) { - core.exportVariable("CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", "true"); + actionState.env.export( + "CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", + "true", + ); } // Emergency override to force the CodeQL CLI back to the JGit-based Git backend. if (await features.getValue(Feature.ForceJGit)) { - core.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")) - ) { - core.exportVariable(kotlinLimitVar, "2.1.20"); + actionState.env.export("CODEQL_GIT_BACKEND", "jgit"); } // Restore dependency cache(s), if they exist. @@ -685,7 +691,7 @@ async function run( config.buildMode === BuildMode.None && config.languages.includes(BuiltInLanguage.java) ) { - core.exportVariable( + actionState.env.export( EnvVar.JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS, "true", ); @@ -743,7 +749,7 @@ async function run( const tracerConfig = await getCombinedTracerConfig(logger, codeql, config); if (tracerConfig !== undefined) { for (const [key, value] of Object.entries(tracerConfig.env)) { - core.exportVariable(key, value); + actionState.env.export(key, value); } } @@ -751,10 +757,10 @@ async function run( if (await features.getValue(Feature.JavaNetworkDebugging)) { // Get the existing value of `JAVA_TOOL_OPTIONS`, if any. const existingJavaToolOptions = - getOptionalEnvVar(JavaEnvVars.JAVA_TOOL_OPTIONS) || ""; + actionState.env.getOptional(JavaEnvVars.JAVA_TOOL_OPTIONS) ?? ""; // Add the network debugging options. - core.exportVariable( + actionState.env.export( JavaEnvVars.JAVA_TOOL_OPTIONS, `${existingJavaToolOptions} -Djavax.net.debug=all`, ); diff --git a/src/init.test.ts b/src/init.test.ts index 1f0d2c701..9cb169fb2 100644 --- a/src/init.test.ts +++ b/src/init.test.ts @@ -1,14 +1,13 @@ import * as fs from "fs"; import path from "path"; -import * as core from "@actions/core"; import * as github from "@actions/github"; import test, { ExecutionContext } from "ava"; import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; import { createStubCodeQL } from "./codeql"; -import { ActionsEnvVars } from "./environment"; +import * as environment from "./environment"; import { Feature } from "./feature-flags"; import { checkPacksForOverlayCompatibility, @@ -85,7 +84,7 @@ for (const { runnerEnv, ErrorConstructor, message } of [ `cleanupDatabaseClusterDirectory throws a ${ErrorConstructor.name} when cleanup fails on ${runnerEnv} runner`, async (t) => { await withTmpDir(async (tmpDir: string) => { - process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnv; + process.env[environment.ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnv; const dbLocation = path.resolve(tmpDir, "dbs"); fs.mkdirSync(dbLocation, { recursive: true }); @@ -546,7 +545,7 @@ test.serial( test.serial( "file coverage deprecation warning for org-owned repo with default setup recommends repo property", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(true); github.context.payload = { repository: { @@ -566,14 +565,14 @@ test.serial( 'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' + "`true` in the repository's settings.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); test.serial( "file coverage deprecation warning for org-owned repo with advanced setup recommends env var and repo property", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(false); github.context.payload = { repository: { @@ -594,14 +593,14 @@ test.serial( 'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' + "`true` in the repository's settings.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); test.serial( "file coverage deprecation warning for user-owned repo with default setup recommends advanced setup", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(true); github.context.payload = { repository: { @@ -620,14 +619,14 @@ test.serial( "To opt out of this change, switch to an advanced setup workflow and " + "set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); test.serial( "file coverage deprecation warning for user-owned repo with advanced setup recommends env var", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(false); github.context.payload = { repository: { @@ -645,14 +644,14 @@ test.serial( "to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" + "To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); test.serial( "file coverage deprecation warning for unknown owner type with default setup recommends advanced setup", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(true); github.context.payload = { repository: undefined }; const messages: LoggedMessage[] = []; @@ -666,14 +665,14 @@ test.serial( "To opt out of this change, switch to an advanced setup workflow and " + "set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); test.serial( "file coverage deprecation warning for unknown owner type with advanced setup recommends env var", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(false); github.context.payload = { repository: undefined }; const messages: LoggedMessage[] = []; @@ -686,7 +685,7 @@ test.serial( "to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" + "To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); @@ -695,10 +694,10 @@ test.serial( (t) => { process.env["CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION"] = "true"; - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); const messages: LoggedMessage[] = []; logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages)); t.is(messages.length, 0); - t.true(exportVariableStub.notCalled); + t.true(exportEnvVarStub.notCalled); }, ); diff --git a/src/init.ts b/src/init.ts index d757e2997..11f1eea2e 100644 --- a/src/init.ts +++ b/src/init.ts @@ -1,7 +1,6 @@ import * as fs from "fs"; import * as path from "path"; -import * as core from "@actions/core"; import * as toolrunner from "@actions/exec/lib/toolrunner"; import * as github from "@actions/github"; import * as io from "@actions/io"; @@ -17,7 +16,7 @@ import { import { GitHubApiDetails } from "./api-client"; import { CodeQL, setupCodeQL } from "./codeql"; import * as configUtils from "./config-utils"; -import { EnvVar } from "./environment"; +import { EnvVar, exportEnvVar } from "./environment"; import { CodeQLDefaultVersionInfo, Feature, @@ -411,5 +410,5 @@ export function logFileCoverageOnPrsDeprecationWarning(logger: Logger): void { } logger.warning(message); - core.exportVariable(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true"); + exportEnvVar(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true"); } diff --git a/src/overlay/caching.test.ts b/src/overlay/caching.test.ts index daf3483ed..364eeff9c 100644 --- a/src/overlay/caching.test.ts +++ b/src/overlay/caching.test.ts @@ -8,6 +8,7 @@ import * as sinon from "sinon"; import * as actionsUtil from "../actions-util"; import * as apiClient from "../api-client"; import type { ResolveDatabaseOutput } from "../codeql"; +import * as environment from "../environment"; import * as gitUtils from "../git-utils"; import { BuiltInLanguage } from "../languages"; import { getRunnerLogger } from "../logging"; @@ -82,7 +83,7 @@ const testDownloadOverlayBaseDatabaseFromCache = makeMacro({ sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/"); - sinon.stub(utils, "isInTestMode").returns(testCase.isInTestMode); + sinon.stub(environment, "isInTestMode").returns(testCase.isInTestMode); if (testCase.restoreCacheResult instanceof Error) { sinon diff --git a/src/setup-codeql-action.ts b/src/setup-codeql-action.ts index 23a9c65eb..1344b66b7 100644 --- a/src/setup-codeql-action.ts +++ b/src/setup-codeql-action.ts @@ -1,6 +1,11 @@ import * as core from "@actions/core"; -import { Action, ActionState, runInActions } from "./action-common"; +import { + Action, + ActionState, + extendActionState, + runInActions, +} from "./action-common"; import { getActionVersion, getOptionalInput, @@ -131,7 +136,9 @@ async function run( ); const repositoryProperties = repositoryPropertiesResult.orElse({}); - const actionStateWithFeatures = { ...actionState, features }; + const actionStateWithFeatures = extendActionState(actionState, { + features, + }); const statusReportBase = await createStatusReportBase( ActionName.SetupCodeQL, @@ -184,7 +191,7 @@ async function run( core.setOutput("codeql-path", codeql.getPath()); core.setOutput("codeql-version", (await codeql.getVersion()).version); - core.exportVariable(EnvVar.SETUP_CODEQL_ACTION_HAS_RUN, "true"); + actionState.env.export(EnvVar.SETUP_CODEQL_ACTION_HAS_RUN, "true"); } catch (unwrappedError) { const error = wrapError(unwrappedError); core.setFailed(error.message); diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index f2ce959a8..daaba174c 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -3,7 +3,6 @@ import { OutgoingHttpHeaders } from "http"; import * as path from "path"; import { performance } from "perf_hooks"; -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"; @@ -29,7 +28,7 @@ import { makeDiagnostic, makeTelemetryDiagnostic, } from "./diagnostics"; -import { EnvVar, getEnv } from "./environment"; +import { EnvVar, exportEnvVar, getEnv } from "./environment"; import { CODEQL_VERSION_ZSTD_BUNDLE, CodeQLDefaultVersionInfo, @@ -1071,7 +1070,7 @@ export async function setupCodeQLBundle( // 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"); + exportEnvVar(EnvVar.HAS_SET_UP_CODEQL, "true"); return { codeqlFolder, diff --git a/src/start-proxy-action.ts b/src/start-proxy-action.ts index d965a2dd6..bc3351da5 100644 --- a/src/start-proxy-action.ts +++ b/src/start-proxy-action.ts @@ -3,7 +3,12 @@ import * as path from "path"; import * as core from "@actions/core"; -import { Action, ActionState, runInActions } from "./action-common"; +import { + Action, + ActionState, + extendActionState, + runInActions, +} from "./action-common"; import * as actionsUtil from "./actions-util"; import { getGitHubVersion } from "./api-client"; import { FeatureEnablement, initFeatures } from "./feature-flags"; @@ -98,7 +103,8 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) { }; // Start the Proxy - const proxyBin = await getProxyBinaryPath({ ...action, features }); + const actionWithFeatures = extendActionState(action, { features }); + const proxyBin = await getProxyBinaryPath(actionWithFeatures); const proxyInfo = await startProxy( proxyBin, proxyConfig, diff --git a/src/status-report.ts b/src/status-report.ts index c392b5192..fc45e82d6 100644 --- a/src/status-report.ts +++ b/src/status-report.ts @@ -23,7 +23,13 @@ import type { ComputedInput, InputName } from "./config/inputs"; import { parseRegistriesWithoutCredentials } from "./config/pack-registries"; import type { DependencyCacheRestoreStatusReport } from "./dependency-caching"; import { DocUrl } from "./doc-url"; -import { EnvVar, getEnv, ReadOnlyEnv, RegistryProxyVars } from "./environment"; +import { + EnvVar, + getEnv, + ReadOnlyEnv, + RegistryProxyVars, + exportEnvVar, +} from "./environment"; import { getRef } from "./git-utils"; import * as json from "./json"; import type { Logger } from "./logging"; @@ -55,13 +61,21 @@ export enum ActionName { UploadSarif = "upload-sarif", } +/** A partial mapping from `ActionName` to names for actions whose display name is not the `ActionName` value. */ +export const ACTION_DISPLAY_NAMES: Partial> = { + [ActionName.Analyze]: "analyze", + [ActionName.InitPost]: "init post", +}; + /** - * Maps an `ActionName` to its display name. Usually that is the same, except - * for `ActionName.Analyze` where it is `"analyze"` instead of `"finish"`. + * Maps an {@link ActionName} to its display name. Usually that is the same, except + * for actions which have a different display name in {@link ACTION_DISPLAY_NAMES}. */ export function getDisplayActionName(actionName: ActionName): string { - if (actionName === ActionName.Analyze) { - return "analyze"; + const displayName = ACTION_DISPLAY_NAMES[actionName]; + + if (displayName !== undefined) { + return displayName; } return actionName; } @@ -71,9 +85,7 @@ export function getDisplayActionName(actionName: ActionName): string { * environment and returns it. * If a new UUID is generated, it is also exported as an environment variable. */ -export function getJobUUID( - action: ActionState<["Logger", "ReadOnlyEnv", "Actions"]>, -) { +export function getJobUUID(action: ActionState<["Logger", "Env", "Actions"]>) { // Check if we already have a UUID for the analysis and return it if so. const existingJobRunUuid = action.env.getOptional(EnvVar.JOB_RUN_UUID); @@ -86,7 +98,7 @@ export function getJobUUID( const jobRunUuid = uuid.v4(); action.logger.info(`Job run UUID is ${jobRunUuid}.`); - action.actions.exportVariable(EnvVar.JOB_RUN_UUID, jobRunUuid); + action.env.export(EnvVar.JOB_RUN_UUID, jobRunUuid); return jobRunUuid; } @@ -268,12 +280,12 @@ export function getJobStatusDisplayName(status: JobStatus): string { */ function setJobStatusIfUnsuccessful(actionStatus: ActionStatus) { if (actionStatus === "user-error") { - core.exportVariable( + exportEnvVar( EnvVar.JOB_STATUS, process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigErrorStatus, ); } else if (actionStatus === "failure" || actionStatus === "aborted") { - core.exportVariable( + exportEnvVar( EnvVar.JOB_STATUS, process.env[EnvVar.JOB_STATUS] ?? JobStatus.FailureStatus, ); @@ -376,7 +388,7 @@ export async function createStatusReportBase( let workflowStartedAt = process.env[EnvVar.WORKFLOW_STARTED_AT]; if (workflowStartedAt === undefined) { workflowStartedAt = actionStartedAt.toISOString(); - core.exportVariable(EnvVar.WORKFLOW_STARTED_AT, workflowStartedAt); + exportEnvVar(EnvVar.WORKFLOW_STARTED_AT, workflowStartedAt); } const runnerOs = getRequiredEnvParam("RUNNER_OS"); const codeQlCliVersion = getCachedCodeQlVersion( @@ -388,7 +400,7 @@ export async function createStatusReportBase( // re-export the testing environment variable so that it is available to subsequent steps, // even if it was only set for this step if (testingEnvironment) { - core.exportVariable(EnvVar.TESTING_ENVIRONMENT, testingEnvironment); + exportEnvVar(EnvVar.TESTING_ENVIRONMENT, testingEnvironment); } const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true"; diff --git a/src/testing-utils.ts b/src/testing-utils.ts index a5ba50554..cd6031894 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -202,10 +202,6 @@ class TestActionsEnv implements ActionsEnv { public getOptionalInput(_name: string): string | undefined { return undefined; } - - public exportVariable(name: string, value: string): void { - this.env.set(name, value); - } } /** diff --git a/src/tools-features.ts b/src/tools-features.ts index 4931be65b..35e626c88 100644 --- a/src/tools-features.ts +++ b/src/tools-features.ts @@ -1,5 +1,3 @@ -import * as semver from "semver"; - import type { VersionInfo } from "./cli/types"; export enum ToolsFeature { @@ -23,21 +21,3 @@ export function isSupportedToolsFeature( ): boolean { return !!versionInfo.features && versionInfo.features[feature]; } - -export const SafeArtifactUploadVersion = "2.20.3"; - -/** - * The first version of the CodeQL CLI where artifact upload is safe to use - * for failed runs. This is not really a feature flag, but it is easiest to - * model the behavior as a feature flag. - * - * This was not captured in a tools feature, so we need to use semver. - * - * @param codeQlVersion The version of the CodeQL CLI to check. If not provided, it is assumed to be safe. - * @returns True if artifact upload is safe to use for failed runs or false otherwise. - */ -export function isSafeArtifactUpload(codeQlVersion?: string): boolean { - return !codeQlVersion - ? true - : semver.gte(codeQlVersion, SafeArtifactUploadVersion); -} diff --git a/src/upload-lib.ts b/src/upload-lib.ts index c5b6c6efd..9792e0225 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -14,7 +14,7 @@ import { getGitHubVersion, wrapApiConfigurationError } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; import { getConfig } from "./config-utils"; import { readDiffRangesJsonFile } from "./diff-informed-analysis-utils"; -import { EnvVar } from "./environment"; +import { EnvVar, exportEnvVar } from "./environment"; import { FeatureEnablement } from "./feature-flags"; import * as fingerprints from "./fingerprints"; import * as gitUtils from "./git-utils"; @@ -126,7 +126,7 @@ async function combineSarifFilesUsingCLI( 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}`, ); - core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); + exportEnvVar("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); } // If not, use the naive method of combining the files. @@ -1032,7 +1032,7 @@ export function validateUniqueCategory( `Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})`, ); } - core.exportVariable(sentinelEnvVar, sentinelEnvVar); + exportEnvVar(sentinelEnvVar, sentinelEnvVar); } } diff --git a/src/upload-sarif-action-post.ts b/src/upload-sarif-action-post.ts index bc0e1361c..82961842e 100644 --- a/src/upload-sarif-action-post.ts +++ b/src/upload-sarif-action-post.ts @@ -34,13 +34,7 @@ export async function runWrapper() { return; } await withGroup("Uploading combined SARIF debug artifact", () => - debugArtifacts.uploadCombinedSarifArtifacts( - logger, - gitHubVersion.type, - // The codeqlVersion is not applicable for uploading non-codeql sarif. - // We can assume all versions are safe to upload. - undefined, - ), + debugArtifacts.uploadCombinedSarifArtifacts(logger, gitHubVersion.type), ); } } catch (error) { diff --git a/src/util.ts b/src/util.ts index 49a69f035..566386de6 100644 --- a/src/util.ts +++ b/src/util.ts @@ -12,15 +12,26 @@ import * as semver from "semver"; import * as apiCompatibility from "./api-compatibility.json"; import type { CodeQL } from "./codeql"; +import type { ActionConfig } from "./config/action-config"; import type { Pack } from "./config/db-config"; import type { Config } from "./config-utils"; -import { EnvVar, getRequiredEnvParam } from "./environment"; +import { + EnvVar, + getRequiredEnvParam, + isInTestMode, + exportEnvVar, +} from "./environment"; import * as json from "./json"; import { Language } from "./languages"; import { Logger } from "./logging"; // Re-export for backwards compatibility to avoid updating a lot of imports elsewhere. -export { getRequiredEnvParam, getOptionalEnvVar, getEnv } from "./environment"; +export { + getRequiredEnvParam, + getOptionalEnvVar, + getEnv, + isInTestMode, +} from "./environment"; /** * The name of the file containing the base database OIDs, as stored in the @@ -435,7 +446,10 @@ export function getThreadsFlag( /** * Get the path where the CodeQL database for the given language lives. */ -export function getCodeQLDatabasePath(config: Config, language: Language) { +export function getCodeQLDatabasePath( + config: ActionConfig<"dbLocation">, + language: Language, +) { return path.resolve(config.dbLocation, language); } @@ -542,7 +556,7 @@ export function checkGitHubVersionInRange( ); } hasBeenWarnedAboutVersion = true; - core.exportVariable(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); + exportEnvVar(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); } export enum DisallowedAPIVersionReason { @@ -586,11 +600,11 @@ export function assertNever(value: never): never { * knowing what version of CodeQL we're running. */ export function initializeEnvironment(version: string) { - core.exportVariable(EnvVar.FEATURE_MULTI_LANGUAGE, "false"); - core.exportVariable(EnvVar.FEATURE_SANDWICH, "false"); - core.exportVariable(EnvVar.FEATURE_SARIF_COMBINE, "true"); - core.exportVariable(EnvVar.FEATURE_WILL_UPLOAD, "true"); - core.exportVariable(EnvVar.VERSION, version); + exportEnvVar(EnvVar.FEATURE_MULTI_LANGUAGE, "false"); + exportEnvVar(EnvVar.FEATURE_SANDWICH, "false"); + exportEnvVar(EnvVar.FEATURE_SARIF_COMBINE, "true"); + exportEnvVar(EnvVar.FEATURE_WILL_UPLOAD, "true"); + exportEnvVar(EnvVar.VERSION, version); } export class HTTPError extends Error { @@ -629,7 +643,9 @@ export async function codeQlVersionAtLeast( return semver.gte((await codeql.getVersion()).version, requiredVersion); } -export function getBaseDatabaseOidsFilePath(config: Config): string { +export function getBaseDatabaseOidsFilePath( + config: ActionConfig<"dbLocation">, +): string { return path.join(config.dbLocation, BASE_DATABASE_OIDS_FILE_NAME); } @@ -641,7 +657,7 @@ export function getBaseDatabaseOidsFilePath(config: Config): string { * given `includeDiagnostics` value. */ export async function bundleDb( - config: Config, + config: ActionConfig<"dbLocation">, language: Language, codeql: CodeQL, dbName: string, @@ -711,15 +727,6 @@ export function isGoodVersion(versionSpec: string) { return !BROKEN_VERSIONS.includes(versionSpec); } -/** - * Returns whether we are in test mode. This is used by CodeQL Action PR checks. - * - * In test mode, we skip several uploads (SARIF results, status reports, DBs, ...). - */ -export function isInTestMode(): boolean { - return process.env[EnvVar.TEST_MODE] === "true"; -} - /** * Returns whether we specifically want to skip uploading SARIF files. */ @@ -948,7 +955,7 @@ export async function checkDiskUsage( } else { logger.debug(message); } - core.exportVariable(EnvVar.HAS_WARNED_ABOUT_DISK_SPACE, "true"); + exportEnvVar(EnvVar.HAS_WARNED_ABOUT_DISK_SPACE, "true"); } return { numAvailableBytes: diskUsage.bavail * blockSizeInBytes, @@ -997,7 +1004,7 @@ export function checkActionVersion( "https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/", ); // set LOG_VERSION_DEPRECATION env var to prevent the warning from being logged multiple times - core.exportVariable(EnvVar.LOG_VERSION_DEPRECATION, "true"); + exportEnvVar(EnvVar.LOG_VERSION_DEPRECATION, "true"); } } } diff --git a/unreleased-change-notes/README.md b/unreleased-change-notes/README.md new file mode 100644 index 000000000..60778c795 --- /dev/null +++ b/unreleased-change-notes/README.md @@ -0,0 +1,24 @@ +## Change notes + +Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a Markdown file here that describes the change. During the next release, the change-note files in `unreleased-change-notes/` will automatically be added to `CHANGELOG.md`. + +### Change-note file format + +Change-note files must follow a certain format so that they can be automatically validated and processed. Failure to follow the format will result in a failed PR check. + +You may validate your change-note file locally by running `npx tsx pr-checks/changenotes.ts validate`. This command will scan all change-note files in `unreleased-change-notes/` and report any errors. + + +#### Body + +The body of the change-note file must: + +- Be written in valid [GitHub-Flavored Markdown](https://github.github.com/gfm/). +- Be structured as a single unordered Markdown list with hyphen (`-`) bullets. Each list item should describe a single change. If there are multiple changes, use multiple list items. + +### Example change-note file + +``` +- Fixed a bug where a network error while streaming the download of the CodeQL bundle could terminate the `init` Action instead of falling back to downloading the bundle before extracting it. [#4061](https://github.com/github/codeql-action/pull/4061) +- Fix incorrect minimum required Git version for [improved incremental analysis](https://github.com/github/roadmap/issues/1158): it should have been 2.36.0, not 2.11.0. [#3781](https://github.com/github/codeql-action/pull/3781) +```