mirror of
https://github.com/github/codeql-action.git
synced 2026-10-03 09:14:58 +00:00
Reuse the toolcache for stable releases in the CodeQL Action repositories
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
15
lib/entry-points.js
generated
15
lib/entry-points.js
generated
@@ -152243,6 +152243,15 @@ function getDefaultBundleSources(apiDetails, logger) {
|
||||
return !self2.slice(0, index2).some((other) => (0, import_fast_deep_equal.default)(source, other));
|
||||
});
|
||||
}
|
||||
function isCacheableRelease(reference, cliVersion2, apiDetails, logger) {
|
||||
if (cliVersion2 === void 0 || !/^\d+\.\d+\.\d+$/.test(cliVersion2) || reference.tagName !== `codeql-bundle-v${cliVersion2}`) {
|
||||
return false;
|
||||
}
|
||||
const repository = `${reference.owner}/${reference.repo}`.toLowerCase();
|
||||
return getDefaultBundleSources(apiDetails, logger).some(
|
||||
([serverURL, sourceRepository]) => new URL(serverURL).origin === new URL(reference.serverURL).origin && sourceRepository.toLowerCase() === repository
|
||||
);
|
||||
}
|
||||
async function selectDefaultBundle(action, tagName, apiDetails, options) {
|
||||
const { logger } = action;
|
||||
for (const [serverURL, repository] of getDefaultBundleSources(
|
||||
@@ -152534,7 +152543,9 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useO
|
||||
release2.assetNames ?? [],
|
||||
logger
|
||||
);
|
||||
customReleaseURL = release2.url;
|
||||
if (!isCacheableRelease(requestedRelease, cliVersion2, apiDetails, logger)) {
|
||||
customReleaseURL = release2.url;
|
||||
}
|
||||
} else if (toolsInput !== void 0) {
|
||||
tagName = tryGetTagNameFromUrl(toolsInput, logger);
|
||||
url2 = toolsInput;
|
||||
@@ -152776,7 +152787,7 @@ var downloadCodeQL = async function(source, apiDetails, tarVersion, tempDir, log
|
||||
function getToolcacheDestination({ logger }, source) {
|
||||
if (source.customReleaseURL !== void 0) {
|
||||
return new Failure(
|
||||
`Not caching the CodeQL tools from ${source.customReleaseURL}, since we don't cache releases requested by URL.`
|
||||
`Not caching the CodeQL tools from ${source.customReleaseURL}, since we only cache stable releases in the CodeQL Action repositories.`
|
||||
);
|
||||
}
|
||||
if (source.bundle.kind !== "combined") {
|
||||
|
||||
@@ -1519,15 +1519,88 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
for (const [apiDetails, variant] of [
|
||||
[SAMPLE_DOTCOM_API_DETAILS, GitHubVariant.DOTCOM],
|
||||
[GHES_API_DETAILS, GitHubVariant.GHES],
|
||||
] as const) {
|
||||
test.serial(
|
||||
`setupCodeQLBundle caches a stable release in the CodeQL Action repository on ${variant}`,
|
||||
async (t) => {
|
||||
const fixture = stubRequestedRelease({
|
||||
apiDetails,
|
||||
repository: "github/codeql-action",
|
||||
});
|
||||
const extract = stubDownloadAndExtract();
|
||||
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
const setup = () =>
|
||||
setupCodeql.setupCodeQLBundle(
|
||||
fixture.releaseURL,
|
||||
apiDetails,
|
||||
tmpDir,
|
||||
variant,
|
||||
PER_LANGUAGE_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([]),
|
||||
getRunnerLogger(true),
|
||||
);
|
||||
|
||||
const downloaded = await setup();
|
||||
t.deepEqual(fixture.requests, [
|
||||
`${apiDetails.apiURL}/repos/github/codeql-action/releases/tags/codeql-bundle-v${MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION}`,
|
||||
]);
|
||||
t.is(downloaded.toolsSource, setupCodeql.ToolsSource.Download);
|
||||
t.is(extract.firstCall.args[0], fixture.assets[0].url);
|
||||
t.is(extract.firstCall.args[3], `token ${apiDetails.auth}`);
|
||||
t.is(
|
||||
downloaded.codeqlFolder,
|
||||
toolcache.find("CodeQL", MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION),
|
||||
);
|
||||
|
||||
const cached = await setup();
|
||||
t.is(cached.toolsSource, setupCodeql.ToolsSource.Toolcache);
|
||||
t.is(cached.codeqlFolder, downloaded.codeqlFolder);
|
||||
t.true(extract.calledOnce);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
for (const { repository, tagName, markers } of [
|
||||
{
|
||||
repository: "github/codeql-action",
|
||||
tagName: "codeql-bundle-v2.27.1-rc.1",
|
||||
markers: [],
|
||||
},
|
||||
{
|
||||
repository: "github/codeql-action",
|
||||
tagName: "codeql-bundle-v2.27.1",
|
||||
markers: ["2.27.1+202609241200"],
|
||||
},
|
||||
{
|
||||
repository: "github/codeql-action",
|
||||
tagName: "codeql-bundle-20260924",
|
||||
markers: ["2.27.1+202609241200"],
|
||||
},
|
||||
{
|
||||
repository: "github/codeql-action",
|
||||
tagName: "codeql-bundle-acme-2.27.1",
|
||||
markers: ["2.27.1"],
|
||||
},
|
||||
{
|
||||
repository: "octo/tools",
|
||||
tagName: "codeql-bundle-feature_branch",
|
||||
markers: [],
|
||||
},
|
||||
]) {
|
||||
const description =
|
||||
markers.length === 0
|
||||
? tagName
|
||||
: `${tagName} with marker ${markers.join(", ")}`;
|
||||
test.serial(
|
||||
`setupCodeQLBundle doesn't share the toolcache with ${tagName} in ${repository}`,
|
||||
`setupCodeQLBundle doesn't share the toolcache with ${description} in ${repository}`,
|
||||
async (t) => {
|
||||
const fixture = stubRequestedRelease({ repository, tagName, markers });
|
||||
const extract = stubDownloadAndExtract();
|
||||
@@ -1590,7 +1663,10 @@ for (const repository of ["github/codeql-action", "octo/tools"]) {
|
||||
`https://github.com/${repository}/releases/download/codeql-bundle-v${MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION}/codeql-bundle-linux64.tar.zst`,
|
||||
);
|
||||
t.is(extract.firstCall.args[3], undefined);
|
||||
t.false(fs.existsSync(`${result.codeqlFolder}.complete`));
|
||||
t.is(
|
||||
fs.existsSync(`${result.codeqlFolder}.complete`),
|
||||
repository === "github/codeql-action",
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
BundleSelection,
|
||||
BundleSelectionOptions,
|
||||
CodeQLRelease,
|
||||
CodeQLReleaseReference,
|
||||
getPublicRelease,
|
||||
getRelease,
|
||||
getReleaseCliVersion,
|
||||
@@ -114,6 +115,32 @@ function getDefaultBundleSources(
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a release requested by URL contains the same build as the toolcache entry for its CLI
|
||||
* version. The toolcache is keyed by version alone, so we only assume this for stable releases
|
||||
* tagged `codeql-bundle-v<version>` in the repositories we download the default bundles from.
|
||||
*/
|
||||
function isCacheableRelease(
|
||||
reference: CodeQLReleaseReference,
|
||||
cliVersion: string | undefined,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
logger: Logger,
|
||||
): boolean {
|
||||
if (
|
||||
cliVersion === undefined ||
|
||||
!/^\d+\.\d+\.\d+$/.test(cliVersion) ||
|
||||
reference.tagName !== `codeql-bundle-v${cliVersion}`
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
const repository = `${reference.owner}/${reference.repo}`.toLowerCase();
|
||||
return getDefaultBundleSources(apiDetails, logger).some(
|
||||
([serverURL, sourceRepository]) =>
|
||||
new URL(serverURL).origin === new URL(reference.serverURL).origin &&
|
||||
sourceRepository.toLowerCase() === repository,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -405,9 +432,10 @@ async function resolveDefaultCliVersion(
|
||||
*
|
||||
* - A local path is extracted without using the toolcache.
|
||||
* - A release URL selects a bundle from that release, and takes precedence over the `force_nightly`
|
||||
* feature flag. We don't use the toolcache, since a release may contain a different build than
|
||||
* the cached bundle for its version. Bundle URLs keep using the toolcache for the version in
|
||||
* their tag, for compatibility.
|
||||
* feature flag. Only stable releases in the repositories we download the default bundles from use
|
||||
* the toolcache, since other releases may contain a different build than the cached bundle for
|
||||
* their version. Bundle URLs keep using the toolcache for the version in their tag, for
|
||||
* compatibility.
|
||||
* - `nightly` or `nightly-latest`, or the `force_nightly` feature flag in a dynamic workflow,
|
||||
* selects a bundle from the latest nightly release. We then continue with that bundle's URL.
|
||||
* - `linked`, or its old name `latest`, selects the version shipped with the Action.
|
||||
@@ -625,7 +653,9 @@ export async function getCodeQLSource(
|
||||
release.assetNames ?? [],
|
||||
logger,
|
||||
);
|
||||
customReleaseURL = release.url;
|
||||
if (!isCacheableRelease(requestedRelease, cliVersion, apiDetails, logger)) {
|
||||
customReleaseURL = release.url;
|
||||
}
|
||||
} else if (toolsInput !== undefined) {
|
||||
// Any other value is a bundle URL, including one we selected from the latest nightly above.
|
||||
// We use the version in its tag, if any, for the toolcache, so we assume that bundles with the
|
||||
@@ -971,8 +1001,8 @@ function getToolcacheDestination(
|
||||
): util.Result<string, string> {
|
||||
if (source.customReleaseURL !== undefined) {
|
||||
return new util.Failure(
|
||||
`Not caching the CodeQL tools from ${source.customReleaseURL}, since we don't cache ` +
|
||||
"releases requested by URL.",
|
||||
`Not caching the CodeQL tools from ${source.customReleaseURL}, since we only cache stable ` +
|
||||
"releases in the CodeQL Action repositories.",
|
||||
);
|
||||
}
|
||||
if (source.bundle.kind !== "combined") {
|
||||
|
||||
Reference in New Issue
Block a user