Share CodeQL bundle platform definitions

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Henry Mercer
2026-09-16 17:28:00 +01:00
parent 2d47caf123
commit dfb9bf52c9
7 changed files with 124 additions and 100 deletions

View File

@@ -0,0 +1,18 @@
import test from "ava";
import { BundlePlatform, getBundlePlatform } from "./bundle-platform";
for (const [platform, arch, expected] of [
["linux", "x64", BundlePlatform.Linux64],
["linux", "arm64", BundlePlatform.LinuxArm64],
["linux", "ia32", BundlePlatform.Linux64],
["darwin", "x64", BundlePlatform.Osx64],
["darwin", "arm64", BundlePlatform.Osx64],
["win32", "x64", BundlePlatform.Win64],
["win32", "arm64", BundlePlatform.Win64],
["freebsd", "x64", undefined],
] as const) {
test(`getBundlePlatform maps ${platform}/${arch} to ${expected ?? "an all-platform bundle"}`, (t) => {
t.is(getBundlePlatform(platform, arch), expected);
});
}

26
src/bundle-platform.ts Normal file
View File

@@ -0,0 +1,26 @@
/** Platform identifiers used in CodeQL bundle asset names. */
export enum BundlePlatform {
Linux64 = "linux64",
LinuxArm64 = "linux-arm64",
Osx64 = "osx64",
Win64 = "win64",
}
/** Returns the bundle platform, or undefined when an all-platform bundle is required. */
export function getBundlePlatform(
platform: NodeJS.Platform = process.platform,
arch: NodeJS.Architecture = process.arch,
): BundlePlatform | undefined {
switch (platform) {
case "win32":
return BundlePlatform.Win64;
case "linux":
return arch === "arm64"
? BundlePlatform.LinuxArm64
: BundlePlatform.Linux64;
case "darwin":
return BundlePlatform.Osx64;
default:
return undefined;
}
}

View File

@@ -1,5 +1,6 @@
import test from "ava";
import { BundlePlatform } from "./bundle-platform";
import { ActionsEnvVars, ReadOnlyEnv } from "./environment";
import { Feature } from "./feature-flags";
import { BuiltInLanguage } from "./languages";
@@ -23,7 +24,7 @@ const ELIGIBLE_OPTIONS: PerLanguageBundleOptions = {
// Any version at least as new as the minimum will do.
cliVersion: MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION,
compressionMethod: "zstd",
platform: "linux64",
platform: BundlePlatform.Linux64,
variant: GitHubVariant.DOTCOM,
};
@@ -44,14 +45,21 @@ async function checkEligibility(
);
}
test("getPerLanguageBundleLanguage selects Linux bundles for non-Swift languages", async (t) => {
for (const language of Object.values(BuiltInLanguage)) {
if (language === BuiltInLanguage.swift) {
continue;
for (const platform of Object.values(BundlePlatform)) {
test(`getPerLanguageBundleLanguage selects only supported languages on ${platform}`, async (t) => {
for (const language of Object.values(BuiltInLanguage)) {
const supported =
language === BuiltInLanguage.swift
? platform === BundlePlatform.Osx64
: platform === BundlePlatform.Linux64;
t.is(
await checkEligibility({ rawLanguages: [language], platform }),
supported ? language : undefined,
language,
);
}
t.is(await checkEligibility({ rawLanguages: [language] }), language);
}
});
});
}
test("getPerLanguageBundleLanguage normalizes aliases before selecting a bundle", async (t) => {
t.is(
@@ -60,23 +68,7 @@ test("getPerLanguageBundleLanguage normalizes aliases before selecting a bundle"
);
});
test("getPerLanguageBundleLanguage selects the macOS bundle for Swift", async (t) => {
t.is(
await checkEligibility({ rawLanguages: ["swift"], platform: "osx64" }),
BuiltInLanguage.swift,
);
// Swift is only published for macOS.
t.is(
await checkEligibility({ rawLanguages: ["swift"], platform: "linux64" }),
undefined,
);
});
test("getPerLanguageBundleLanguage rejects unsupported platforms", async (t) => {
t.is(await checkEligibility({ platform: "osx64" }), undefined);
t.is(await checkEligibility({ platform: "win64" }), undefined);
// We do not publish per-language bundles for Linux Arm64 either.
t.is(await checkEligibility({ platform: "linux-arm64" }), undefined);
test("getPerLanguageBundleLanguage rejects unknown platforms", async (t) => {
t.is(await checkEligibility({ platform: undefined }), undefined);
});
@@ -164,7 +156,7 @@ test("getPerLanguageBundleLanguage skips only the release version check for nigh
{ rawLanguages: undefined },
{ rawLanguages: ["java", "python"] },
{ compressionMethod: "gzip" as const },
{ platform: "osx64" },
{ platform: BundlePlatform.Osx64 },
{ variant: GitHubVariant.GHES },
{ variant: GitHubVariant.GHEC_DR },
]) {

View File

@@ -2,6 +2,7 @@ import * as semver from "semver";
import { ActionState } from "./action-common";
import { isGitHubHostedRunner } from "./actions-util";
import { BundlePlatform } from "./bundle-platform";
import { Feature } from "./feature-flags";
import { BuiltInLanguage, parseBuiltInLanguage } from "./languages";
import * as tar from "./tar";
@@ -30,20 +31,24 @@ export function tryGetBundleLanguageFromUrl(
return match ? parseBuiltInLanguage(match[1]) : undefined;
}
/** Published platform for each language; absent entries are ineligible. */
const PER_LANGUAGE_BUNDLE_PLATFORMS: Readonly<
Partial<Record<BuiltInLanguage, string>>
/** Languages with per-language bundles published for each platform. */
const PER_LANGUAGE_BUNDLE_LANGUAGES: Readonly<
Record<BundlePlatform, ReadonlySet<BuiltInLanguage>>
> = {
[BuiltInLanguage.actions]: "linux64",
[BuiltInLanguage.cpp]: "linux64",
[BuiltInLanguage.csharp]: "linux64",
[BuiltInLanguage.go]: "linux64",
[BuiltInLanguage.java]: "linux64",
[BuiltInLanguage.javascript]: "linux64",
[BuiltInLanguage.python]: "linux64",
[BuiltInLanguage.ruby]: "linux64",
[BuiltInLanguage.rust]: "linux64",
[BuiltInLanguage.swift]: "osx64",
[BundlePlatform.Linux64]: new Set([
BuiltInLanguage.actions,
BuiltInLanguage.cpp,
BuiltInLanguage.csharp,
BuiltInLanguage.go,
BuiltInLanguage.java,
BuiltInLanguage.javascript,
BuiltInLanguage.python,
BuiltInLanguage.ruby,
BuiltInLanguage.rust,
]),
[BundlePlatform.LinuxArm64]: new Set(),
[BundlePlatform.Osx64]: new Set([BuiltInLanguage.swift]),
[BundlePlatform.Win64]: new Set(),
};
/** Inputs that determine whether we may download a per-language bundle. */
@@ -53,8 +58,8 @@ export interface PerLanguageBundleOptions {
/** CLI version, if known. Ignored for nightly bundles. */
cliVersion: string | undefined;
compressionMethod: tar.CompressionMethod;
/** Bundle platform identifier, such as linux64. */
platform: string | undefined;
/** Platform for which the bundle is requested. */
platform: BundlePlatform | undefined;
variant: GitHubVariant;
isNightly?: boolean;
}
@@ -130,14 +135,13 @@ export async function getPerLanguageBundleLanguage(
}
}
const supportedPlatform = PER_LANGUAGE_BUNDLE_PLATFORMS[language];
if (supportedPlatform === undefined) {
return explain(`no per-language bundle is published for ${language}`);
}
if (supportedPlatform !== platform) {
const supportedLanguages =
platform === undefined
? undefined
: PER_LANGUAGE_BUNDLE_LANGUAGES[platform];
if (!supportedLanguages?.has(language)) {
return explain(
`the ${language} bundle is only published for ${supportedPlatform}, but this job is ` +
`running on ${platform ?? "an unknown platform"}`,
`no per-language bundle is published for ${language} on ${platform ?? "an unknown platform"}`,
);
}

View File

@@ -17,6 +17,7 @@ import {
isRunningLocalAction,
} from "./actions-util";
import * as api from "./api-client";
import { getBundlePlatform } from "./bundle-platform";
import * as defaults from "./defaults.json";
import {
addNoLanguageDiagnostic,
@@ -78,20 +79,6 @@ function getCodeQLBundleExtension(
}
}
/** Returns the platform component of the CodeQL bundle name for the current platform. */
export function getBundlePlatform(): string | undefined {
switch (process.platform) {
case "win32":
return "win64";
case "linux":
return process.arch === "arm64" ? "linux-arm64" : "linux64";
case "darwin":
return "osx64";
default:
return undefined;
}
}
/**
* Returns the name of the CodeQL bundle asset to download.
*

View File

@@ -17,6 +17,7 @@ import { ActionsEnv, getActionVersion } from "./actions-util";
import { AnalysisKind } from "./analyses";
import * as apiClient from "./api-client";
import { GitHubApiDetails } from "./api-client";
import { getBundlePlatform } from "./bundle-platform";
import { CachingKind } from "./caching-utils";
import { resetCachedCodeQlVersion } from "./cli/output-cache";
import type { VersionInfo } from "./cli/types";
@@ -933,21 +934,14 @@ export function mockBundleDownloadApi({
platformSpecific?: boolean;
tagName: string;
}): string {
const platform =
process.platform === "win32"
? "win64"
: process.platform === "linux"
? process.arch === "arm64"
? "linux-arm64"
: "linux64"
: "osx64";
const platform = platformSpecific ? getBundlePlatform() : undefined;
const baseUrl = apiDetails?.url ?? "https://example.com";
const bundleUrls = ["tar.gz", "tar.zst"].map((extension) => {
const relativeUrl = apiDetails
? `/${repo}/releases/download/${tagName}/codeql-bundle${
platformSpecific ? `-${platform}` : ""
platform !== undefined ? `-${platform}` : ""
}.${extension}`
: `/download/${tagName}/codeql-bundle.${extension}`;