mirror of
https://github.com/github/codeql-action.git
synced 2026-10-03 09:14:58 +00:00
Select the default bundle from the first compatible release
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
138
lib/entry-points.js
generated
138
lib/entry-points.js
generated
@@ -27216,8 +27216,8 @@ var require_gte = __commonJS({
|
|||||||
"node_modules/semver/functions/gte.js"(exports2, module2) {
|
"node_modules/semver/functions/gte.js"(exports2, module2) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var compare3 = require_compare();
|
var compare3 = require_compare();
|
||||||
var gte9 = (a, b, loose) => compare3(a, b, loose) >= 0;
|
var gte8 = (a, b, loose) => compare3(a, b, loose) >= 0;
|
||||||
module2.exports = gte9;
|
module2.exports = gte8;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -27238,7 +27238,7 @@ var require_cmp = __commonJS({
|
|||||||
var eq = require_eq();
|
var eq = require_eq();
|
||||||
var neq = require_neq();
|
var neq = require_neq();
|
||||||
var gt = require_gt();
|
var gt = require_gt();
|
||||||
var gte9 = require_gte();
|
var gte8 = require_gte();
|
||||||
var lt2 = require_lt();
|
var lt2 = require_lt();
|
||||||
var lte2 = require_lte();
|
var lte2 = require_lte();
|
||||||
var cmp = (a, op, b, loose) => {
|
var cmp = (a, op, b, loose) => {
|
||||||
@@ -27268,7 +27268,7 @@ var require_cmp = __commonJS({
|
|||||||
case ">":
|
case ">":
|
||||||
return gt(a, b, loose);
|
return gt(a, b, loose);
|
||||||
case ">=":
|
case ">=":
|
||||||
return gte9(a, b, loose);
|
return gte8(a, b, loose);
|
||||||
case "<":
|
case "<":
|
||||||
return lt2(a, b, loose);
|
return lt2(a, b, loose);
|
||||||
case "<=":
|
case "<=":
|
||||||
@@ -28076,7 +28076,7 @@ var require_outside = __commonJS({
|
|||||||
var gt = require_gt();
|
var gt = require_gt();
|
||||||
var lt2 = require_lt();
|
var lt2 = require_lt();
|
||||||
var lte2 = require_lte();
|
var lte2 = require_lte();
|
||||||
var gte9 = require_gte();
|
var gte8 = require_gte();
|
||||||
var outside = (version, range2, hilo, options) => {
|
var outside = (version, range2, hilo, options) => {
|
||||||
version = new SemVer(version, options);
|
version = new SemVer(version, options);
|
||||||
range2 = new Range2(range2, options);
|
range2 = new Range2(range2, options);
|
||||||
@@ -28091,7 +28091,7 @@ var require_outside = __commonJS({
|
|||||||
break;
|
break;
|
||||||
case "<":
|
case "<":
|
||||||
gtfn = lt2;
|
gtfn = lt2;
|
||||||
ltefn = gte9;
|
ltefn = gte8;
|
||||||
ltfn = gt;
|
ltfn = gt;
|
||||||
comp = "<";
|
comp = "<";
|
||||||
ecomp = "<=";
|
ecomp = "<=";
|
||||||
@@ -28406,7 +28406,7 @@ var require_semver2 = __commonJS({
|
|||||||
var lt2 = require_lt();
|
var lt2 = require_lt();
|
||||||
var eq = require_eq();
|
var eq = require_eq();
|
||||||
var neq = require_neq();
|
var neq = require_neq();
|
||||||
var gte9 = require_gte();
|
var gte8 = require_gte();
|
||||||
var lte2 = require_lte();
|
var lte2 = require_lte();
|
||||||
var cmp = require_cmp();
|
var cmp = require_cmp();
|
||||||
var coerce3 = require_coerce();
|
var coerce3 = require_coerce();
|
||||||
@@ -28445,7 +28445,7 @@ var require_semver2 = __commonJS({
|
|||||||
lt: lt2,
|
lt: lt2,
|
||||||
eq,
|
eq,
|
||||||
neq,
|
neq,
|
||||||
gte: gte9,
|
gte: gte8,
|
||||||
lte: lte2,
|
lte: lte2,
|
||||||
cmp,
|
cmp,
|
||||||
coerce: coerce3,
|
coerce: coerce3,
|
||||||
@@ -31721,7 +31721,7 @@ var require_brace_expansion = __commonJS({
|
|||||||
function lte2(i, y) {
|
function lte2(i, y) {
|
||||||
return i <= y;
|
return i <= y;
|
||||||
}
|
}
|
||||||
function gte9(i, y) {
|
function gte8(i, y) {
|
||||||
return i >= y;
|
return i >= y;
|
||||||
}
|
}
|
||||||
function combine2(acc, base, pre, values, max, maxLength, dropEmpties, outBase) {
|
function combine2(acc, base, pre, values, max, maxLength, dropEmpties, outBase) {
|
||||||
@@ -31754,7 +31754,7 @@ var require_brace_expansion = __commonJS({
|
|||||||
var reverse = y < x;
|
var reverse = y < x;
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
incr *= -1;
|
incr *= -1;
|
||||||
test = gte9;
|
test = gte8;
|
||||||
}
|
}
|
||||||
var pad = n.some(isPadded2);
|
var pad = n.some(isPadded2);
|
||||||
var length = 0;
|
var length = 0;
|
||||||
@@ -33901,8 +33901,8 @@ var require_semver3 = __commonJS({
|
|||||||
function neq(a, b, loose) {
|
function neq(a, b, loose) {
|
||||||
return compare3(a, b, loose) !== 0;
|
return compare3(a, b, loose) !== 0;
|
||||||
}
|
}
|
||||||
exports2.gte = gte9;
|
exports2.gte = gte8;
|
||||||
function gte9(a, b, loose) {
|
function gte8(a, b, loose) {
|
||||||
return compare3(a, b, loose) >= 0;
|
return compare3(a, b, loose) >= 0;
|
||||||
}
|
}
|
||||||
exports2.lte = lte2;
|
exports2.lte = lte2;
|
||||||
@@ -33933,7 +33933,7 @@ var require_semver3 = __commonJS({
|
|||||||
case ">":
|
case ">":
|
||||||
return gt(a, b, loose);
|
return gt(a, b, loose);
|
||||||
case ">=":
|
case ">=":
|
||||||
return gte9(a, b, loose);
|
return gte8(a, b, loose);
|
||||||
case "<":
|
case "<":
|
||||||
return lt2(a, b, loose);
|
return lt2(a, b, loose);
|
||||||
case "<=":
|
case "<=":
|
||||||
@@ -34478,7 +34478,7 @@ var require_semver3 = __commonJS({
|
|||||||
break;
|
break;
|
||||||
case "<":
|
case "<":
|
||||||
gtfn = lt2;
|
gtfn = lt2;
|
||||||
ltefn = gte9;
|
ltefn = gte8;
|
||||||
ltfn = gt;
|
ltfn = gt;
|
||||||
comp = "<";
|
comp = "<";
|
||||||
ecomp = "<=";
|
ecomp = "<=";
|
||||||
@@ -89595,7 +89595,7 @@ var require_brace_expansion2 = __commonJS({
|
|||||||
function lte2(i, y) {
|
function lte2(i, y) {
|
||||||
return i <= y;
|
return i <= y;
|
||||||
}
|
}
|
||||||
function gte9(i, y) {
|
function gte8(i, y) {
|
||||||
return i >= y;
|
return i >= y;
|
||||||
}
|
}
|
||||||
function combine2(acc, pre, values, max, maxLength, dropEmpties) {
|
function combine2(acc, pre, values, max, maxLength, dropEmpties) {
|
||||||
@@ -89627,7 +89627,7 @@ var require_brace_expansion2 = __commonJS({
|
|||||||
var reverse = y < x;
|
var reverse = y < x;
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
incr *= -1;
|
incr *= -1;
|
||||||
test = gte9;
|
test = gte8;
|
||||||
}
|
}
|
||||||
var pad = n.some(isPadded2);
|
var pad = n.some(isPadded2);
|
||||||
var length = 0;
|
var length = 0;
|
||||||
@@ -151359,6 +151359,18 @@ function getReleasePageURL(reference) {
|
|||||||
const { serverURL, owner, repo, tagName } = reference;
|
const { serverURL, owner, repo, tagName } = reference;
|
||||||
return `${serverURL}/${owner}/${repo}/releases/tag/${encodeTag(tagName)}`;
|
return `${serverURL}/${owner}/${repo}/releases/tag/${encodeTag(tagName)}`;
|
||||||
}
|
}
|
||||||
|
async function getRelease({ apiClient }, reference) {
|
||||||
|
const { owner, repo, tagName } = reference;
|
||||||
|
const { data: release2 } = await apiClient.rest.repos.getReleaseByTag({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
tag: tagName
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
url: getReleasePageURL(reference),
|
||||||
|
getAssetURL: (name) => release2.assets.find((asset) => asset.name === name)?.url
|
||||||
|
};
|
||||||
|
}
|
||||||
function getPublicRelease(reference) {
|
function getPublicRelease(reference) {
|
||||||
const { serverURL, owner, repo, tagName } = reference;
|
const { serverURL, owner, repo, tagName } = reference;
|
||||||
return {
|
return {
|
||||||
@@ -152133,7 +152145,8 @@ function getCodeQLActionRepository(logger) {
|
|||||||
}
|
}
|
||||||
return getRequiredEnvParam("GITHUB_ACTION_REPOSITORY");
|
return getRequiredEnvParam("GITHUB_ACTION_REPOSITORY");
|
||||||
}
|
}
|
||||||
async function getCodeQLBundleDownloadURL(tagName, apiDetails, codeQLBundleName, logger) {
|
async function selectDefaultBundle(action, tagName, apiDetails, options) {
|
||||||
|
const { logger } = action;
|
||||||
const codeQLActionRepository = getCodeQLActionRepository(logger);
|
const codeQLActionRepository = getCodeQLActionRepository(logger);
|
||||||
const potentialDownloadSources = [
|
const potentialDownloadSources = [
|
||||||
// This GitHub instance, and this Action.
|
// This GitHub instance, and this Action.
|
||||||
@@ -152148,33 +152161,34 @@ async function getCodeQLBundleDownloadURL(tagName, apiDetails, codeQLBundleName,
|
|||||||
return !self2.slice(0, index2).some((other) => (0, import_fast_deep_equal.default)(source, other));
|
return !self2.slice(0, index2).some((other) => (0, import_fast_deep_equal.default)(source, other));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
for (const downloadSource of uniqueDownloadSources) {
|
for (const [serverURL, repository] of uniqueDownloadSources) {
|
||||||
const [apiURL, repository] = downloadSource;
|
if (serverURL === GITHUB_DOTCOM_URL && repository === CODEQL_DEFAULT_ACTION_REPOSITORY) {
|
||||||
if (apiURL === GITHUB_DOTCOM_URL && repository === CODEQL_DEFAULT_ACTION_REPOSITORY) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const [repositoryOwner, repositoryName] = repository.split("/");
|
const [owner2, repo2] = repository.split("/");
|
||||||
try {
|
try {
|
||||||
const release2 = await getApiClient().rest.repos.getReleaseByTag({
|
const release2 = await getRelease(
|
||||||
owner: repositoryOwner,
|
{ apiClient: getApiClient() },
|
||||||
repo: repositoryName,
|
{ serverURL, owner: owner2, repo: repo2, tagName }
|
||||||
tag: tagName
|
);
|
||||||
});
|
return await selectBundle(action, release2, options);
|
||||||
for (const asset of release2.data.assets) {
|
|
||||||
if (asset.name === codeQLBundleName) {
|
|
||||||
logger.info(
|
|
||||||
`Found CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} with URL ${asset.url}.`
|
|
||||||
);
|
|
||||||
return asset.url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Looked for CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} but got error ${e}.`
|
`Looked for CodeQL bundles in release ${tagName} of ${repository} on ${serverURL} but got error ${e}.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`;
|
const [owner, repo] = CODEQL_DEFAULT_ACTION_REPOSITORY.split("/");
|
||||||
|
return selectBundle(
|
||||||
|
action,
|
||||||
|
getPublicRelease({
|
||||||
|
serverURL: GITHUB_DOTCOM_URL,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
tagName
|
||||||
|
}),
|
||||||
|
options
|
||||||
|
);
|
||||||
}
|
}
|
||||||
function tryGetBundleVersionFromTagName(tagName, logger) {
|
function tryGetBundleVersionFromTagName(tagName, logger) {
|
||||||
const match2 = tagName.match(/^codeql-bundle-(.+)$/);
|
const match2 = tagName.match(/^codeql-bundle-(.+)$/);
|
||||||
@@ -152525,47 +152539,26 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let compressionMethod;
|
let compressionMethod;
|
||||||
|
let perLanguageBundleFallback;
|
||||||
if (!url2) {
|
if (!url2) {
|
||||||
const bundleTagName = tagName;
|
if (tagName === void 0) {
|
||||||
if (bundleTagName === void 0) {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Could not determine a release tag for the requested CodeQL bundle."
|
"Could not determine a release tag for the requested CodeQL bundle."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
compressionMethod = cliVersion2 !== void 0 && await useZstdBundle(cliVersion2, tarSupportsZstd) ? "zstd" : "gzip";
|
({ bundle, compressionMethod, perLanguageBundleFallback } = await selectDefaultBundle(
|
||||||
const platform2 = getBundlePlatform();
|
|
||||||
const perLanguageBundleLanguage = await getPerLanguageBundleLanguage(
|
|
||||||
{ env: getEnv(), features, logger },
|
{ env: getEnv(), features, logger },
|
||||||
|
tagName,
|
||||||
|
apiDetails,
|
||||||
{
|
{
|
||||||
rawLanguages,
|
rawLanguages,
|
||||||
cliVersion: cliVersion2,
|
cliVersion: cliVersion2,
|
||||||
compressionMethod,
|
platform: getBundlePlatform(),
|
||||||
platform: platform2,
|
variant,
|
||||||
variant
|
tarSupportsZstd
|
||||||
}
|
}
|
||||||
);
|
));
|
||||||
const resolveBundleURL = (language) => getCodeQLBundleDownloadURL(
|
url2 = bundle.url;
|
||||||
bundleTagName,
|
|
||||||
apiDetails,
|
|
||||||
getCodeQLBundleName(compressionMethod, platform2, language),
|
|
||||||
logger
|
|
||||||
);
|
|
||||||
const combinedBundleURL = await resolveBundleURL();
|
|
||||||
if (perLanguageBundleLanguage !== void 0) {
|
|
||||||
logger.info(
|
|
||||||
`Selected the per-language CodeQL bundle for '${perLanguageBundleLanguage}'.`
|
|
||||||
);
|
|
||||||
url2 = await resolveBundleURL(perLanguageBundleLanguage);
|
|
||||||
bundle = {
|
|
||||||
kind: "per-language",
|
|
||||||
url: url2,
|
|
||||||
language: perLanguageBundleLanguage,
|
|
||||||
combinedBundleURL
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
url2 = combinedBundleURL;
|
|
||||||
bundle = { kind: "combined", url: url2 };
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const method = inferCompressionMethod(url2);
|
const method = inferCompressionMethod(url2);
|
||||||
if (method === void 0) {
|
if (method === void 0) {
|
||||||
@@ -152591,6 +152584,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useO
|
|||||||
bundleVersion: bundleVersion2,
|
bundleVersion: bundleVersion2,
|
||||||
cliVersion: cliVersion2,
|
cliVersion: cliVersion2,
|
||||||
compressionMethod,
|
compressionMethod,
|
||||||
|
...perLanguageBundleFallback ? { perLanguageBundleFallback } : {},
|
||||||
sourceType: "download",
|
sourceType: "download",
|
||||||
toolsVersion: resolvedVersion ?? "unknown"
|
toolsVersion: resolvedVersion ?? "unknown"
|
||||||
};
|
};
|
||||||
@@ -152804,12 +152798,6 @@ 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 && semver11.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
function getTempExtractionDir(tempDir) {
|
function getTempExtractionDir(tempDir) {
|
||||||
return path13.join(tempDir, v4_default());
|
return path13.join(tempDir, v4_default());
|
||||||
}
|
}
|
||||||
@@ -157064,7 +157052,7 @@ function isPadded(el) {
|
|||||||
function lte(i, y) {
|
function lte(i, y) {
|
||||||
return i <= y;
|
return i <= y;
|
||||||
}
|
}
|
||||||
function gte8(i, y) {
|
function gte7(i, y) {
|
||||||
return i >= y;
|
return i >= y;
|
||||||
}
|
}
|
||||||
function combine(acc, pre, values, max, maxLength, dropEmpties) {
|
function combine(acc, pre, values, max, maxLength, dropEmpties) {
|
||||||
@@ -157099,7 +157087,7 @@ function expandSequence(body, isAlphaSequence, max, maxLength) {
|
|||||||
const reverse = y < x;
|
const reverse = y < x;
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
incr *= -1;
|
incr *= -1;
|
||||||
test = gte8;
|
test = gte7;
|
||||||
}
|
}
|
||||||
const pad = n.some(isPadded);
|
const pad = n.some(isPadded);
|
||||||
let length = 0;
|
let length = 0;
|
||||||
|
|||||||
@@ -1272,9 +1272,14 @@ for (const status of [200, 404]) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const fallback of [false, true]) {
|
for (const scenario of ["per-language", "fallback", "missing"] as const) {
|
||||||
|
const suffix = {
|
||||||
|
"per-language": "",
|
||||||
|
fallback: " with fallback",
|
||||||
|
missing: " when the release lacks the per-language bundle",
|
||||||
|
}[scenario];
|
||||||
test.serial(
|
test.serial(
|
||||||
`setupCodeQLBundle retains the selected release identity for an opaque asset URL${fallback ? " with fallback" : ""}`,
|
`setupCodeQLBundle retains the selected release identity for an opaque asset URL${suffix}`,
|
||||||
async (t) => {
|
async (t) => {
|
||||||
sinon.stub(process, "platform").value("linux");
|
sinon.stub(process, "platform").value("linux");
|
||||||
sinon.stub(process, "arch").value("x64");
|
sinon.stub(process, "arch").value("x64");
|
||||||
@@ -1288,22 +1293,22 @@ for (const fallback of [false, true]) {
|
|||||||
const assetURL =
|
const assetURL =
|
||||||
"https://api.github.com/repos/codeql-testing/action-fork/releases/assets/123";
|
"https://api.github.com/repos/codeql-testing/action-fork/releases/assets/123";
|
||||||
const combinedURL = `${assetURL}4`;
|
const combinedURL = `${assetURL}4`;
|
||||||
|
const assets = [
|
||||||
|
{ name: "codeql-bundle-linux64.tar.zst", url: combinedURL },
|
||||||
|
];
|
||||||
|
if (scenario !== "missing") {
|
||||||
|
assets.push({
|
||||||
|
name: "codeql-bundle-java-linux64.tar.zst",
|
||||||
|
url: assetURL,
|
||||||
|
});
|
||||||
|
}
|
||||||
const fetchRelease = sinon
|
const fetchRelease = sinon
|
||||||
.stub<Parameters<typeof fetch>, ReturnType<typeof fetch>>()
|
.stub<Parameters<typeof fetch>, ReturnType<typeof fetch>>()
|
||||||
.callsFake(
|
.callsFake(
|
||||||
async () =>
|
async () =>
|
||||||
new Response(
|
new Response(JSON.stringify({ assets }), {
|
||||||
JSON.stringify({
|
headers: { "content-type": "application/json" },
|
||||||
assets: [
|
}),
|
||||||
{ name: "codeql-bundle-java-linux64.tar.zst", url: assetURL },
|
|
||||||
{
|
|
||||||
name: "codeql-bundle-linux64.tar.zst",
|
|
||||||
url: combinedURL,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
{ headers: { "content-type": "application/json" } },
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
const client = github.getOctokit("123", {
|
const client = github.getOctokit("123", {
|
||||||
request: { fetch: fetchRelease },
|
request: { fetch: fetchRelease },
|
||||||
@@ -1311,7 +1316,7 @@ for (const fallback of [false, true]) {
|
|||||||
sinon.stub(api, "getApiClient").value(() => client);
|
sinon.stub(api, "getApiClient").value(() => client);
|
||||||
const authorizationSpy = sinon.spy(api, "getAuthorizationHeaderFor");
|
const authorizationSpy = sinon.spy(api, "getAuthorizationHeaderFor");
|
||||||
const extractStub = stubDownloadAndExtract();
|
const extractStub = stubDownloadAndExtract();
|
||||||
if (fallback) {
|
if (scenario === "fallback") {
|
||||||
extractStub.onFirstCall().rejects(new HTTPError("Not Found", 404));
|
extractStub.onFirstCall().rejects(new HTTPError("Not Found", 404));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1331,41 +1336,46 @@ for (const fallback of [false, true]) {
|
|||||||
getRunnerLogger(true),
|
getRunnerLogger(true),
|
||||||
);
|
);
|
||||||
|
|
||||||
t.true(fetchRelease.calledTwice);
|
const usesPerLanguageBundle = scenario === "per-language";
|
||||||
|
t.true(fetchRelease.calledOnce);
|
||||||
t.is(
|
t.is(
|
||||||
fetchRelease.firstCall.args[0],
|
fetchRelease.firstCall.args[0],
|
||||||
`https://api.github.com/repos/codeql-testing/action-fork/releases/tags/${tag}`,
|
`https://api.github.com/repos/codeql-testing/action-fork/releases/tags/${tag}`,
|
||||||
);
|
);
|
||||||
t.is(extractStub.callCount, fallback ? 2 : 1);
|
t.is(extractStub.callCount, scenario === "fallback" ? 2 : 1);
|
||||||
t.is(extractStub.firstCall.args[0], assetURL);
|
|
||||||
t.is(extractStub.lastCall.args[0], fallback ? combinedURL : assetURL);
|
|
||||||
t.is(authorizationSpy.callCount, extractStub.callCount);
|
|
||||||
t.is(authorizationSpy.firstCall.args[2], assetURL);
|
|
||||||
t.is(
|
t.is(
|
||||||
authorizationSpy.lastCall.args[2],
|
extractStub.firstCall.args[0],
|
||||||
fallback ? combinedURL : assetURL,
|
scenario === "missing" ? combinedURL : assetURL,
|
||||||
|
);
|
||||||
|
t.is(
|
||||||
|
extractStub.lastCall.args[0],
|
||||||
|
usesPerLanguageBundle ? assetURL : combinedURL,
|
||||||
|
);
|
||||||
|
t.deepEqual(
|
||||||
|
authorizationSpy.getCalls().map((call) => call.args[2]),
|
||||||
|
extractStub.getCalls().map((call) => call.args[0]),
|
||||||
);
|
);
|
||||||
t.is(extractStub.lastCall.args[3], "token token");
|
t.is(extractStub.lastCall.args[3], "token token");
|
||||||
t.is(result.toolsVersion, MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION);
|
t.is(result.toolsVersion, MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION);
|
||||||
t.is(
|
t.is(
|
||||||
result.toolsDownloadStatusReport?.perLanguage?.tools_bundle_language,
|
result.toolsDownloadStatusReport?.perLanguage?.tools_bundle_language,
|
||||||
fallback ? undefined : BuiltInLanguage.java,
|
usesPerLanguageBundle ? BuiltInLanguage.java : undefined,
|
||||||
);
|
);
|
||||||
t.is(
|
t.is(
|
||||||
result.toolsDownloadStatusReport?.perLanguage
|
result.toolsDownloadStatusReport?.perLanguage
|
||||||
?.tools_per_language_bundle_fallback,
|
?.tools_per_language_bundle_fallback,
|
||||||
fallback ? true : undefined,
|
usesPerLanguageBundle ? undefined : true,
|
||||||
);
|
);
|
||||||
if (fallback) {
|
if (usesPerLanguageBundle) {
|
||||||
|
t.is(path.dirname(result.codeqlFolder), tmpDir);
|
||||||
|
t.deepEqual(toolcache.findAllVersions("CodeQL"), []);
|
||||||
|
t.false(fs.existsSync(`${result.codeqlFolder}.complete`));
|
||||||
|
} else {
|
||||||
t.is(
|
t.is(
|
||||||
result.codeqlFolder,
|
result.codeqlFolder,
|
||||||
toolcache.find("CodeQL", MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION),
|
toolcache.find("CodeQL", MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION),
|
||||||
);
|
);
|
||||||
t.true(fs.existsSync(`${result.codeqlFolder}.complete`));
|
t.true(fs.existsSync(`${result.codeqlFolder}.complete`));
|
||||||
} else {
|
|
||||||
t.is(path.dirname(result.codeqlFolder), tmpDir);
|
|
||||||
t.deepEqual(toolcache.findAllVersions("CodeQL"), []);
|
|
||||||
t.false(fs.existsSync(`${result.codeqlFolder}.complete`));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,9 +21,14 @@ import {
|
|||||||
CodeQLBundle,
|
CodeQLBundle,
|
||||||
CodeQLDownloadSource,
|
CodeQLDownloadSource,
|
||||||
getCodeQLBundleFromUrl,
|
getCodeQLBundleFromUrl,
|
||||||
getCodeQLBundleName,
|
|
||||||
} from "./codeql-bundle";
|
} from "./codeql-bundle";
|
||||||
import { getPublicRelease, selectBundle } from "./codeql-release";
|
import {
|
||||||
|
BundleSelection,
|
||||||
|
BundleSelectionOptions,
|
||||||
|
getPublicRelease,
|
||||||
|
getRelease,
|
||||||
|
selectBundle,
|
||||||
|
} from "./codeql-release";
|
||||||
import * as defaults from "./defaults.json";
|
import * as defaults from "./defaults.json";
|
||||||
import {
|
import {
|
||||||
addNoLanguageDiagnostic,
|
addNoLanguageDiagnostic,
|
||||||
@@ -32,19 +37,14 @@ import {
|
|||||||
} from "./diagnostics";
|
} from "./diagnostics";
|
||||||
import { EnvVar, getEnv } from "./environment";
|
import { EnvVar, getEnv } from "./environment";
|
||||||
import {
|
import {
|
||||||
CODEQL_VERSION_ZSTD_BUNDLE,
|
|
||||||
CodeQLDefaultVersionInfo,
|
CodeQLDefaultVersionInfo,
|
||||||
CodeQLVersionInfo,
|
CodeQLVersionInfo,
|
||||||
Feature,
|
Feature,
|
||||||
FeatureEnablement,
|
FeatureEnablement,
|
||||||
} from "./feature-flags";
|
} from "./feature-flags";
|
||||||
import { BuiltInLanguage } from "./languages";
|
|
||||||
import { Logger } from "./logging";
|
import { Logger } from "./logging";
|
||||||
import { getCodeQlVersionsForOverlayBaseDatabases } from "./overlay/caching";
|
import { getCodeQlVersionsForOverlayBaseDatabases } from "./overlay/caching";
|
||||||
import {
|
import { logMissingPerLanguageBundle } from "./per-language-bundles";
|
||||||
getPerLanguageBundleLanguage,
|
|
||||||
logMissingPerLanguageBundle,
|
|
||||||
} from "./per-language-bundles";
|
|
||||||
import { getBundlePlatform } from "./platform";
|
import { getBundlePlatform } from "./platform";
|
||||||
import * as tar from "./tar";
|
import * as tar from "./tar";
|
||||||
import {
|
import {
|
||||||
@@ -89,12 +89,19 @@ export function getCodeQLActionRepository(logger: Logger): string {
|
|||||||
return util.getRequiredEnvParam("GITHUB_ACTION_REPOSITORY");
|
return util.getRequiredEnvParam("GITHUB_ACTION_REPOSITORY");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getCodeQLBundleDownloadURL(
|
/**
|
||||||
|
* Selects a bundle from the first release tagged `tagName` that has a compatible bundle, trying the
|
||||||
|
* Action repositories on this GitHub instance before the canonical Action on GitHub.com. If we
|
||||||
|
* can't look up a release, or it has no compatible bundle, we move on to the next repository. We
|
||||||
|
* assume that the public release on GitHub.com has every bundle.
|
||||||
|
*/
|
||||||
|
async function selectDefaultBundle(
|
||||||
|
action: ActionState<["Logger", "ReadOnlyEnv", "FeatureFlags"]>,
|
||||||
tagName: string,
|
tagName: string,
|
||||||
apiDetails: api.GitHubApiDetails,
|
apiDetails: api.GitHubApiDetails,
|
||||||
codeQLBundleName: string,
|
options: BundleSelectionOptions,
|
||||||
logger: Logger,
|
): Promise<BundleSelection> {
|
||||||
): Promise<string> {
|
const { logger } = action;
|
||||||
const codeQLActionRepository = getCodeQLActionRepository(logger);
|
const codeQLActionRepository = getCodeQLActionRepository(logger);
|
||||||
const potentialDownloadSources = [
|
const potentialDownloadSources = [
|
||||||
// This GitHub instance, and this Action.
|
// This GitHub instance, and this Action.
|
||||||
@@ -111,37 +118,38 @@ async function getCodeQLBundleDownloadURL(
|
|||||||
return !self.slice(0, index).some((other) => deepEqual(source, other));
|
return !self.slice(0, index).some((other) => deepEqual(source, other));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
for (const downloadSource of uniqueDownloadSources) {
|
for (const [serverURL, repository] of uniqueDownloadSources) {
|
||||||
const [apiURL, repository] = downloadSource;
|
|
||||||
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
|
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
|
||||||
if (
|
if (
|
||||||
apiURL === util.GITHUB_DOTCOM_URL &&
|
serverURL === util.GITHUB_DOTCOM_URL &&
|
||||||
repository === CODEQL_DEFAULT_ACTION_REPOSITORY
|
repository === CODEQL_DEFAULT_ACTION_REPOSITORY
|
||||||
) {
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const [repositoryOwner, repositoryName] = repository.split("/");
|
const [owner, repo] = repository.split("/");
|
||||||
try {
|
try {
|
||||||
const release = await api.getApiClient().rest.repos.getReleaseByTag({
|
const release = await getRelease(
|
||||||
owner: repositoryOwner,
|
{ apiClient: api.getApiClient() },
|
||||||
repo: repositoryName,
|
{ serverURL, owner, repo, tagName },
|
||||||
tag: tagName,
|
);
|
||||||
});
|
return await selectBundle(action, release, options);
|
||||||
for (const asset of release.data.assets) {
|
|
||||||
if (asset.name === codeQLBundleName) {
|
|
||||||
logger.info(
|
|
||||||
`Found CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} with URL ${asset.url}.`,
|
|
||||||
);
|
|
||||||
return asset.url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Looked for CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} but got error ${e}.`,
|
`Looked for CodeQL bundles in release ${tagName} of ${repository} on ${serverURL} but got error ${e}.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`;
|
const [owner, repo] = CODEQL_DEFAULT_ACTION_REPOSITORY.split("/");
|
||||||
|
return selectBundle(
|
||||||
|
action,
|
||||||
|
getPublicRelease({
|
||||||
|
serverURL: util.GITHUB_DOTCOM_URL,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
tagName,
|
||||||
|
}),
|
||||||
|
options,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryGetBundleVersionFromTagName(
|
function tryGetBundleVersionFromTagName(
|
||||||
@@ -719,58 +727,28 @@ export async function getCodeQLSource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let compressionMethod: tar.CompressionMethod;
|
let compressionMethod: tar.CompressionMethod;
|
||||||
|
let perLanguageBundleFallback: true | undefined;
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
const bundleTagName = tagName;
|
if (tagName === undefined) {
|
||||||
if (bundleTagName === undefined) {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Could not determine a release tag for the requested CodeQL bundle.",
|
"Could not determine a release tag for the requested CodeQL bundle.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
({ bundle, compressionMethod, perLanguageBundleFallback } =
|
||||||
compressionMethod =
|
await selectDefaultBundle(
|
||||||
cliVersion !== undefined &&
|
{ env: getEnv(), features, logger },
|
||||||
(await useZstdBundle(cliVersion, tarSupportsZstd))
|
tagName,
|
||||||
? "zstd"
|
|
||||||
: "gzip";
|
|
||||||
|
|
||||||
const platform = getBundlePlatform();
|
|
||||||
const perLanguageBundleLanguage = await getPerLanguageBundleLanguage(
|
|
||||||
{ env: getEnv(), features, logger },
|
|
||||||
{
|
|
||||||
rawLanguages,
|
|
||||||
cliVersion,
|
|
||||||
compressionMethod,
|
|
||||||
platform,
|
|
||||||
variant,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Resolves the combined or per-language bundle URL for the requested release.
|
|
||||||
const resolveBundleURL = (language?: BuiltInLanguage) =>
|
|
||||||
getCodeQLBundleDownloadURL(
|
|
||||||
bundleTagName,
|
|
||||||
apiDetails,
|
apiDetails,
|
||||||
getCodeQLBundleName(compressionMethod, platform, language),
|
{
|
||||||
logger,
|
rawLanguages,
|
||||||
);
|
cliVersion,
|
||||||
|
platform: getBundlePlatform(),
|
||||||
const combinedBundleURL = await resolveBundleURL();
|
variant,
|
||||||
if (perLanguageBundleLanguage !== undefined) {
|
tarSupportsZstd,
|
||||||
logger.info(
|
},
|
||||||
`Selected the per-language CodeQL bundle for '${perLanguageBundleLanguage}'.`,
|
));
|
||||||
);
|
url = bundle.url;
|
||||||
url = await resolveBundleURL(perLanguageBundleLanguage);
|
|
||||||
bundle = {
|
|
||||||
kind: "per-language",
|
|
||||||
url,
|
|
||||||
language: perLanguageBundleLanguage,
|
|
||||||
combinedBundleURL,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
url = combinedBundleURL;
|
|
||||||
bundle = { kind: "combined", url };
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const method = tar.inferCompressionMethod(url);
|
const method = tar.inferCompressionMethod(url);
|
||||||
if (method === undefined) {
|
if (method === undefined) {
|
||||||
@@ -801,6 +779,7 @@ export async function getCodeQLSource(
|
|||||||
bundleVersion,
|
bundleVersion,
|
||||||
cliVersion,
|
cliVersion,
|
||||||
compressionMethod,
|
compressionMethod,
|
||||||
|
...(perLanguageBundleFallback ? { perLanguageBundleFallback } : {}),
|
||||||
sourceType: "download",
|
sourceType: "download",
|
||||||
toolsVersion: resolvedVersion ?? "unknown",
|
toolsVersion: resolvedVersion ?? "unknown",
|
||||||
};
|
};
|
||||||
@@ -1161,18 +1140,6 @@ export async function downloadCodeQLBundle(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function useZstdBundle(
|
|
||||||
cliVersion: string,
|
|
||||||
tarSupportsZstd: boolean,
|
|
||||||
): Promise<boolean> {
|
|
||||||
return (
|
|
||||||
// In testing, gzip performs better than zstd on Windows.
|
|
||||||
process.platform !== "win32" &&
|
|
||||||
tarSupportsZstd &&
|
|
||||||
semver.gte(cliVersion, CODEQL_VERSION_ZSTD_BUNDLE)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTempExtractionDir(tempDir: string) {
|
function getTempExtractionDir(tempDir: string) {
|
||||||
return path.join(tempDir, uuidV4());
|
return path.join(tempDir, uuidV4());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user