mirror of
https://github.com/github/codeql-action.git
synced 2026-10-03 17:41:28 +00:00
Clarify resolved bundle handling
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
27
lib/entry-points.js
generated
27
lib/entry-points.js
generated
@@ -151967,7 +151967,7 @@ async function getCodeQLBundleDownloadURL(tagName, apiDetails, compressionMethod
|
|||||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`;
|
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`;
|
||||||
}
|
}
|
||||||
function tryGetBundleVersionFromTagName(tagName, logger) {
|
function tryGetBundleVersionFromTagName(tagName, logger) {
|
||||||
const match2 = tagName.match(/^codeql-bundle-(.*)$/);
|
const match2 = tagName.match(/^codeql-bundle-(.+)$/);
|
||||||
if (match2 === null || match2.length < 2) {
|
if (match2 === null || match2.length < 2) {
|
||||||
logger.debug(`Could not determine bundle version from tag ${tagName}.`);
|
logger.debug(`Could not determine bundle version from tag ${tagName}.`);
|
||||||
return void 0;
|
return void 0;
|
||||||
@@ -152207,7 +152207,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useO
|
|||||||
url2 = toolsInput;
|
url2 = toolsInput;
|
||||||
if (tagName) {
|
if (tagName) {
|
||||||
const bundleVersion3 = tryGetBundleVersionFromTagName(tagName, logger);
|
const bundleVersion3 = tryGetBundleVersionFromTagName(tagName, logger);
|
||||||
if (bundleVersion3 && semver9.valid(bundleVersion3)) {
|
if (bundleVersion3 !== void 0 && semver9.valid(bundleVersion3)) {
|
||||||
cliVersion2 = convertToSemVer(bundleVersion3, logger);
|
cliVersion2 = convertToSemVer(bundleVersion3, logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152222,8 +152222,8 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useO
|
|||||||
cliVersion2 = version.cliVersion;
|
cliVersion2 = version.cliVersion;
|
||||||
tagName = version.tagName;
|
tagName = version.tagName;
|
||||||
}
|
}
|
||||||
const bundleVersion2 = tagName && tryGetBundleVersionFromTagName(tagName, logger);
|
const bundleVersion2 = tagName !== void 0 ? tryGetBundleVersionFromTagName(tagName, logger) : void 0;
|
||||||
const resolvedVersion = cliVersion2 ?? (bundleVersion2 ? convertToSemVer(bundleVersion2, logger) : void 0);
|
const resolvedVersion = cliVersion2 ?? (bundleVersion2 !== void 0 ? convertToSemVer(bundleVersion2, logger) : void 0);
|
||||||
const humanReadableVersion = resolvedVersion ?? tagName ?? url2 ?? "unknown";
|
const humanReadableVersion = resolvedVersion ?? tagName ?? url2 ?? "unknown";
|
||||||
logger.debug(
|
logger.debug(
|
||||||
`Attempting to obtain CodeQL tools. CLI version: ${cliVersion2 ?? "unknown"}, bundle tag name: ${tagName ?? "unknown"}, URL: ${url2 ?? "unspecified"}.`
|
`Attempting to obtain CodeQL tools. CLI version: ${cliVersion2 ?? "unknown"}, bundle tag name: ${tagName ?? "unknown"}, URL: ${url2 ?? "unspecified"}.`
|
||||||
@@ -152341,7 +152341,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useO
|
|||||||
}
|
}
|
||||||
async function tryGetFallbackToolcacheVersion(cliVersion2, tagName, logger) {
|
async function tryGetFallbackToolcacheVersion(cliVersion2, tagName, logger) {
|
||||||
const bundleVersion2 = tryGetBundleVersionFromTagName(tagName, logger);
|
const bundleVersion2 = tryGetBundleVersionFromTagName(tagName, logger);
|
||||||
if (!bundleVersion2) {
|
if (bundleVersion2 === void 0) {
|
||||||
return void 0;
|
return void 0;
|
||||||
}
|
}
|
||||||
const fallbackVersion = convertToSemVer(bundleVersion2, logger);
|
const fallbackVersion = convertToSemVer(bundleVersion2, logger);
|
||||||
@@ -152473,12 +152473,11 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau
|
|||||||
break;
|
break;
|
||||||
case "download": {
|
case "download": {
|
||||||
const result = await downloadCodeQLBundle(
|
const result = await downloadCodeQLBundle(
|
||||||
|
{ env: getEnv(), features, logger },
|
||||||
source,
|
source,
|
||||||
apiDetails,
|
apiDetails,
|
||||||
zstdAvailability.version,
|
zstdAvailability.version,
|
||||||
tempDir,
|
tempDir
|
||||||
features,
|
|
||||||
logger
|
|
||||||
);
|
);
|
||||||
codeqlFolder = result.codeqlFolder;
|
codeqlFolder = result.codeqlFolder;
|
||||||
toolsDownloadStatusReport = result.statusReport;
|
toolsDownloadStatusReport = result.statusReport;
|
||||||
@@ -152496,9 +152495,15 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau
|
|||||||
toolsVersion: source.toolsVersion
|
toolsVersion: source.toolsVersion
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
async function downloadCodeQLBundle(source, apiDetails, tarVersion, tempDir, features, logger) {
|
async function downloadCodeQLBundle(action, source, apiDetails, tarVersion, tempDir) {
|
||||||
await tryDeleteToolcacheBundles({ env: getEnv(), features, logger });
|
await tryDeleteToolcacheBundles(action);
|
||||||
return await downloadCodeQL(source, apiDetails, tarVersion, tempDir, logger);
|
return await downloadCodeQL(
|
||||||
|
source,
|
||||||
|
apiDetails,
|
||||||
|
tarVersion,
|
||||||
|
tempDir,
|
||||||
|
action.logger
|
||||||
|
);
|
||||||
}
|
}
|
||||||
async function useZstdBundle(cliVersion2, tarSupportsZstd) {
|
async function useZstdBundle(cliVersion2, tarSupportsZstd) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import * as sinon from "sinon";
|
|||||||
import * as actionsUtil from "./actions-util";
|
import * as actionsUtil from "./actions-util";
|
||||||
import * as api from "./api-client";
|
import * as api from "./api-client";
|
||||||
import * as diagnostics from "./diagnostics";
|
import * as diagnostics from "./diagnostics";
|
||||||
import { ActionsEnvVars, EnvVar, ReadOnlyEnv } from "./environment";
|
import { ActionsEnvVars, EnvVar, getEnv, ReadOnlyEnv } from "./environment";
|
||||||
import { Feature } from "./feature-flags";
|
import { Feature } from "./feature-flags";
|
||||||
import { getRunnerLogger } from "./logging";
|
import { getRunnerLogger } from "./logging";
|
||||||
import { getCacheRestoreKeyPrefix } from "./overlay/caching";
|
import { getCacheRestoreKeyPrefix } from "./overlay/caching";
|
||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
createFeatures,
|
createFeatures,
|
||||||
createTestConfig,
|
createTestConfig,
|
||||||
getRecordingLogger,
|
getRecordingLogger,
|
||||||
|
getTestEnv,
|
||||||
makeMacro,
|
makeMacro,
|
||||||
mockBundleDownloadApi,
|
mockBundleDownloadApi,
|
||||||
setupActionsVars,
|
setupActionsVars,
|
||||||
@@ -537,6 +538,7 @@ for (const bundlePath of [
|
|||||||
|
|
||||||
t.true(extractStub.calledOnce);
|
t.true(extractStub.calledOnce);
|
||||||
t.is(extractStub.firstCall.args[0], url);
|
t.is(extractStub.firstCall.args[0], url);
|
||||||
|
t.is(downloadSpy.firstCall.args[0].bundleVersion, undefined);
|
||||||
t.is(downloadSpy.firstCall.args[0].toolsVersion, "unknown");
|
t.is(downloadSpy.firstCall.args[0].toolsVersion, "unknown");
|
||||||
t.is(result.toolsVersion, "unknown");
|
t.is(result.toolsVersion, "unknown");
|
||||||
t.is(result.toolsSource, setupCodeql.ToolsSource.Download);
|
t.is(result.toolsSource, setupCodeql.ToolsSource.Download);
|
||||||
@@ -1094,6 +1096,7 @@ async function runDownloadCodeQL(
|
|||||||
toolcacheRoot: string,
|
toolcacheRoot: string,
|
||||||
features: Feature[],
|
features: Feature[],
|
||||||
bundleVersion: string | undefined,
|
bundleVersion: string | undefined,
|
||||||
|
env: ReadOnlyEnv = getEnv(),
|
||||||
): Promise<{
|
): Promise<{
|
||||||
codeqlFolder: string;
|
codeqlFolder: string;
|
||||||
cleanupDiagnostic: toolsDownload.ToolcacheCleanupResult | undefined;
|
cleanupDiagnostic: toolsDownload.ToolcacheCleanupResult | undefined;
|
||||||
@@ -1102,6 +1105,11 @@ async function runDownloadCodeQL(
|
|||||||
const addDiagnostic = sinon.stub(diagnostics, "addNoLanguageDiagnostic");
|
const addDiagnostic = sinon.stub(diagnostics, "addNoLanguageDiagnostic");
|
||||||
|
|
||||||
const { codeqlFolder } = await setupCodeql.downloadCodeQLBundle(
|
const { codeqlFolder } = await setupCodeql.downloadCodeQLBundle(
|
||||||
|
{
|
||||||
|
env,
|
||||||
|
features: createFeatures(features),
|
||||||
|
logger: getRunnerLogger(true),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
bundle: {
|
bundle: {
|
||||||
kind: "combined",
|
kind: "combined",
|
||||||
@@ -1116,8 +1124,6 @@ async function runDownloadCodeQL(
|
|||||||
SAMPLE_DOTCOM_API_DETAILS,
|
SAMPLE_DOTCOM_API_DETAILS,
|
||||||
undefined, // tarVersion
|
undefined, // tarVersion
|
||||||
toolcacheRoot, // tempDir
|
toolcacheRoot, // tempDir
|
||||||
createFeatures(features),
|
|
||||||
getRunnerLogger(true),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const diagnostic = addDiagnostic
|
const diagnostic = addDiagnostic
|
||||||
@@ -1484,6 +1490,33 @@ test.serial(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test.serial(
|
||||||
|
"downloadCodeQLBundle checks the supplied environment before cleaning the toolcache",
|
||||||
|
async (t) => {
|
||||||
|
await withTmpDir(async (tmpDir) => {
|
||||||
|
setupActionsVars(tmpDir, tmpDir);
|
||||||
|
process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = "github-hosted";
|
||||||
|
delete process.env[EnvVar.HAS_SET_UP_CODEQL];
|
||||||
|
|
||||||
|
const staleDirectory = createToolcacheEntry(
|
||||||
|
tmpDir,
|
||||||
|
"CodeQL",
|
||||||
|
CLEANUP_STALE_VERSION,
|
||||||
|
);
|
||||||
|
const { codeqlFolder, cleanupDiagnostic } = await runDownloadCodeQL(
|
||||||
|
tmpDir,
|
||||||
|
[Feature.CleanupToolcacheBundles],
|
||||||
|
CLEANUP_BUNDLE_VERSION,
|
||||||
|
getTestEnv({ [EnvVar.HAS_SET_UP_CODEQL]: "true" }),
|
||||||
|
);
|
||||||
|
|
||||||
|
t.true(fs.existsSync(staleDirectory));
|
||||||
|
t.true(fs.existsSync(`${codeqlFolder}.complete`));
|
||||||
|
t.is(cleanupDiagnostic, undefined);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
test.serial(
|
test.serial(
|
||||||
"setupCodeQLBundle records that this job has set up CodeQL",
|
"setupCodeQLBundle records that this job has set up CodeQL",
|
||||||
async (t) => {
|
async (t) => {
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ function tryGetBundleVersionFromTagName(
|
|||||||
tagName: string,
|
tagName: string,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
const match = tagName.match(/^codeql-bundle-(.*)$/);
|
const match = tagName.match(/^codeql-bundle-(.+)$/);
|
||||||
if (match === null || match.length < 2) {
|
if (match === null || match.length < 2) {
|
||||||
logger.debug(`Could not determine bundle version from tag ${tagName}.`);
|
logger.debug(`Could not determine bundle version from tag ${tagName}.`);
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -215,12 +215,16 @@ export function convertToSemVer(version: string, logger: Logger): string {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Describes the contents and location of a downloadable CodeQL bundle. */
|
||||||
type CodeQLBundle = { kind: "combined"; url: string };
|
type CodeQLBundle = { kind: "combined"; url: string };
|
||||||
|
|
||||||
/** A resolved download, including its bundle identity and version. */
|
/** A resolved download, including its bundle identity and version. */
|
||||||
export interface CodeQLDownloadSource {
|
export interface CodeQLDownloadSource {
|
||||||
|
/** Distinguishes downloads from local archives and cached installations. */
|
||||||
sourceType: "download";
|
sourceType: "download";
|
||||||
|
/** The bundle to download. */
|
||||||
bundle: CodeQLBundle;
|
bundle: CodeQLBundle;
|
||||||
|
/** The compression format of the bundle archive. */
|
||||||
compressionMethod: tar.CompressionMethod;
|
compressionMethod: tar.CompressionMethod;
|
||||||
/** Bundle version of the tools, if known. */
|
/** Bundle version of the tools, if known. */
|
||||||
bundleVersion?: string;
|
bundleVersion?: string;
|
||||||
@@ -588,7 +592,7 @@ export async function getCodeQLSource(
|
|||||||
if (tagName) {
|
if (tagName) {
|
||||||
const bundleVersion = tryGetBundleVersionFromTagName(tagName, logger);
|
const bundleVersion = tryGetBundleVersionFromTagName(tagName, logger);
|
||||||
// If the bundle version is a semantic version, it is a CLI version number.
|
// If the bundle version is a semantic version, it is a CLI version number.
|
||||||
if (bundleVersion && semver.valid(bundleVersion)) {
|
if (bundleVersion !== undefined && semver.valid(bundleVersion)) {
|
||||||
cliVersion = convertToSemVer(bundleVersion, logger);
|
cliVersion = convertToSemVer(bundleVersion, logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -605,10 +609,14 @@ export async function getCodeQLSource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bundleVersion =
|
const bundleVersion =
|
||||||
tagName && tryGetBundleVersionFromTagName(tagName, logger);
|
tagName !== undefined
|
||||||
|
? tryGetBundleVersionFromTagName(tagName, logger)
|
||||||
|
: undefined;
|
||||||
const resolvedVersion =
|
const resolvedVersion =
|
||||||
cliVersion ??
|
cliVersion ??
|
||||||
(bundleVersion ? convertToSemVer(bundleVersion, logger) : undefined);
|
(bundleVersion !== undefined
|
||||||
|
? convertToSemVer(bundleVersion, logger)
|
||||||
|
: undefined);
|
||||||
const humanReadableVersion = resolvedVersion ?? tagName ?? url ?? "unknown";
|
const humanReadableVersion = resolvedVersion ?? tagName ?? url ?? "unknown";
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
@@ -772,7 +780,7 @@ async function tryGetFallbackToolcacheVersion(
|
|||||||
logger: Logger,
|
logger: Logger,
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
const bundleVersion = tryGetBundleVersionFromTagName(tagName, logger);
|
const bundleVersion = tryGetBundleVersionFromTagName(tagName, logger);
|
||||||
if (!bundleVersion) {
|
if (bundleVersion === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const fallbackVersion = convertToSemVer(bundleVersion, logger);
|
const fallbackVersion = convertToSemVer(bundleVersion, logger);
|
||||||
@@ -844,6 +852,10 @@ export const downloadCodeQL = async function (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the canonical toolcache directory for a resolved download, or `undefined` if its bundle
|
||||||
|
* version is unknown.
|
||||||
|
*/
|
||||||
function getToolcacheDestination(
|
function getToolcacheDestination(
|
||||||
source: CodeQLDownloadSource,
|
source: CodeQLDownloadSource,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
@@ -1004,12 +1016,11 @@ export async function setupCodeQLBundle(
|
|||||||
break;
|
break;
|
||||||
case "download": {
|
case "download": {
|
||||||
const result = await downloadCodeQLBundle(
|
const result = await downloadCodeQLBundle(
|
||||||
|
{ env: getEnv(), features, logger },
|
||||||
source,
|
source,
|
||||||
apiDetails,
|
apiDetails,
|
||||||
zstdAvailability.version,
|
zstdAvailability.version,
|
||||||
tempDir,
|
tempDir,
|
||||||
features,
|
|
||||||
logger,
|
|
||||||
);
|
);
|
||||||
codeqlFolder = result.codeqlFolder;
|
codeqlFolder = result.codeqlFolder;
|
||||||
toolsDownloadStatusReport = result.statusReport;
|
toolsDownloadStatusReport = result.statusReport;
|
||||||
@@ -1032,19 +1043,29 @@ export async function setupCodeQLBundle(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs eligible toolcache cleanup once, then downloads and extracts the resolved bundle.
|
||||||
|
*
|
||||||
|
* @returns The extraction directory and download timings.
|
||||||
|
*/
|
||||||
export async function downloadCodeQLBundle(
|
export async function downloadCodeQLBundle(
|
||||||
|
action: ActionState<["Logger", "ReadOnlyEnv", "FeatureFlags"]>,
|
||||||
source: CodeQLDownloadSource,
|
source: CodeQLDownloadSource,
|
||||||
apiDetails: api.GitHubApiDetails,
|
apiDetails: api.GitHubApiDetails,
|
||||||
tarVersion: tar.TarVersion | undefined,
|
tarVersion: tar.TarVersion | undefined,
|
||||||
tempDir: string,
|
tempDir: string,
|
||||||
features: FeatureEnablement,
|
|
||||||
logger: Logger,
|
|
||||||
): Promise<{
|
): Promise<{
|
||||||
codeqlFolder: string;
|
codeqlFolder: string;
|
||||||
statusReport: ToolsDownloadStatusReport;
|
statusReport: ToolsDownloadStatusReport;
|
||||||
}> {
|
}> {
|
||||||
await tryDeleteToolcacheBundles({ env: getEnv(), features, logger });
|
await tryDeleteToolcacheBundles(action);
|
||||||
return await downloadCodeQL(source, apiDetails, tarVersion, tempDir, logger);
|
return await downloadCodeQL(
|
||||||
|
source,
|
||||||
|
apiDetails,
|
||||||
|
tarVersion,
|
||||||
|
tempDir,
|
||||||
|
action.logger,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function useZstdBundle(
|
async function useZstdBundle(
|
||||||
|
|||||||
Reference in New Issue
Block a user