Merge remote-tracking branch 'origin/main' into mbg/improve-json-failures

This commit is contained in:
Michael B. Gale
2026-09-24 12:06:30 +01:00
9 changed files with 136 additions and 123 deletions

View File

@@ -4,6 +4,10 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
## [UNRELEASED]
No user facing changes.
## 4.38.2 - 24 Sept 2026
- Update default CodeQL bundle version to [2.27.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.1). [#4160](https://github.com/github/codeql-action/pull/4160)
## 4.38.1 - 18 Sept 2026

62
lib/entry-points.js generated
View File

@@ -146178,7 +146178,7 @@ function getDiffRangesJsonFilePath(env = getEnv()) {
return path2.join(getTemporaryDirectory(env), PR_DIFF_RANGE_JSON_FILENAME);
}
function getActionVersion() {
return "4.38.2";
return "4.38.3";
}
function getWorkflowEventName(env = getEnv()) {
return env.getRequired("GITHUB_EVENT_NAME" /* GITHUB_EVENT_NAME */);
@@ -151224,6 +151224,20 @@ var import_fast_deep_equal = __toESM(require_fast_deep_equal());
var semver10 = __toESM(require_semver2());
// src/codeql-bundle.ts
function getCodeQLBundleName(compressionMethod, platform2, language) {
const extensions = {
gzip: ".tar.gz",
zstd: ".tar.zst"
};
const extension = extensions[compressionMethod];
if (platform2 === void 0) {
return `codeql-bundle${extension}`;
}
if (language !== void 0) {
return `codeql-bundle-${language}-${platform2}${extension}`;
}
return `codeql-bundle-${platform2}${extension}`;
}
var PER_LANGUAGE_BUNDLE_NAME = /^codeql-bundle-(.+)-(?:linux64|osx64|win64)\.tar\.(?:gz|zst)$/;
function getCodeQLBundleFromUrl(url2) {
let assetName;
@@ -151625,6 +151639,11 @@ async function getPerLanguageBundleLanguage({
}
return language;
}
function logPerLanguageBundleFallback({ logger }, language, location) {
logger.warning(
`No per-language CodeQL bundle for '${language}' was found at ${location}, so falling back to the bundle that contains all languages. This analysis will still produce correct results, but will take longer to set up.`
);
}
// src/tar.ts
var import_child_process = require("child_process");
@@ -152023,27 +152042,6 @@ var CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies";
var CODEQL_BUNDLE_VERSION_ALIAS = ["linked", "latest"];
var CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"];
var CODEQL_TOOLCACHE_INPUT = "toolcache";
function getCodeQLBundleExtension(compressionMethod) {
switch (compressionMethod) {
case "gzip":
return ".tar.gz";
case "zstd":
return ".tar.zst";
default:
assertNever(compressionMethod);
}
}
function getCodeQLBundleName(compressionMethod, language) {
const extension = getCodeQLBundleExtension(compressionMethod);
const platform2 = getBundlePlatform();
if (platform2 === void 0) {
return `codeql-bundle${extension}`;
}
if (language !== void 0) {
return `codeql-bundle-${language}-${platform2}${extension}`;
}
return `codeql-bundle-${platform2}${extension}`;
}
function getCodeQLActionRepository(logger) {
if (isRunningLocalAction()) {
logger.info(
@@ -152452,20 +152450,21 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useO
);
}
compressionMethod = cliVersion2 !== void 0 && await useZstdBundle(cliVersion2, tarSupportsZstd) ? "zstd" : "gzip";
const platform2 = getBundlePlatform();
const perLanguageBundleLanguage = await getPerLanguageBundleLanguage(
{ env: getEnv(), features, logger },
{
rawLanguages,
cliVersion: cliVersion2,
compressionMethod,
platform: getBundlePlatform(),
platform: platform2,
variant
}
);
const resolveBundleURL = (language) => getCodeQLBundleDownloadURL(
bundleTagName,
apiDetails,
getCodeQLBundleName(compressionMethod, language),
getCodeQLBundleName(compressionMethod, platform2, language),
logger
);
const combinedBundleURL = await resolveBundleURL();
@@ -152698,9 +152697,7 @@ async function downloadCodeQLBundle(action, source, apiDetails, tarVersion, temp
if (bundle.kind !== "per-language" || bundle.combinedBundleURL === void 0 || asHTTPError(e)?.status !== 404) {
throw e;
}
logger.warning(
`No per-language CodeQL bundle for '${bundle.language}' was found at ${bundle.url}, so falling back to the bundle that contains all languages. This analysis will still produce correct results, but will take longer to set up.`
);
logPerLanguageBundleFallback(action, bundle.language, bundle.url);
const result = await downloadCodeQL(
{
...source,
@@ -152737,11 +152734,12 @@ async function getLatestNightlyBundle(action, rawLanguages, variant) {
CODEQL_VERSION_ZSTD_BUNDLE,
zstdAvailability.available
) ? "zstd" : "gzip";
const platform2 = getBundlePlatform();
const language = await getPerLanguageBundleLanguage(action, {
rawLanguages,
cliVersion: void 0,
compressionMethod,
platform: getBundlePlatform(),
platform: platform2,
variant,
isLatestNightly: true
});
@@ -152758,12 +152756,16 @@ async function getLatestNightlyBundle(action, rawLanguages, variant) {
throw new Error("Could not find the latest nightly release.");
}
const assetUrl = (name) => `https://github.com/${CODEQL_NIGHTLIES_REPOSITORY_OWNER}/${CODEQL_NIGHTLIES_REPOSITORY_NAME}/releases/download/${latestRelease.tag_name}/${name}`;
const url2 = assetUrl(getCodeQLBundleName(compressionMethod, language));
const url2 = assetUrl(
getCodeQLBundleName(compressionMethod, platform2, language)
);
return language === void 0 ? { kind: "combined", url: url2 } : {
kind: "per-language",
url: url2,
language,
combinedBundleURL: assetUrl(getCodeQLBundleName(compressionMethod))
combinedBundleURL: assetUrl(
getCodeQLBundleName(compressionMethod, platform2)
)
};
} catch (e) {
throw new Error(

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "codeql",
"version": "4.38.2",
"version": "4.38.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "codeql",
"version": "4.38.2",
"version": "4.38.3",
"license": "MIT",
"workspaces": [
"pr-checks"

View File

@@ -1,6 +1,6 @@
{
"name": "codeql",
"version": "4.38.2",
"version": "4.38.3",
"private": true,
"description": "CodeQL action",
"scripts": {

View File

@@ -1,7 +1,26 @@
import test from "ava";
import { getCodeQLBundleFromUrl } from "./codeql-bundle";
import { getCodeQLBundleFromUrl, getCodeQLBundleName } from "./codeql-bundle";
import { BuiltInLanguage } from "./languages";
import { BundlePlatform } from "./platform";
test("getCodeQLBundleName returns a per-language bundle name only when a language is specified", (t) => {
t.is(
getCodeQLBundleName("zstd", BundlePlatform.Linux64, BuiltInLanguage.java),
"codeql-bundle-java-linux64.tar.zst",
);
t.is(
getCodeQLBundleName("zstd", BundlePlatform.Linux64),
"codeql-bundle-linux64.tar.zst",
);
});
test("getCodeQLBundleName names the Swift bundle for macOS", (t) => {
t.is(
getCodeQLBundleName("zstd", BundlePlatform.Osx64, BuiltInLanguage.swift),
"codeql-bundle-swift-osx64.tar.zst",
);
});
for (const [assetName, language] of [
["codeql-bundle-java-linux64.tar.zst", BuiltInLanguage.java],

View File

@@ -1,4 +1,6 @@
import { BuiltInLanguage, parseBuiltInLanguage } from "./languages";
import { BundlePlatform } from "./platform";
import type { CompressionMethod } from "./tar";
/** Describes the contents and location of a downloadable CodeQL bundle. */
export type CodeQLBundle =
@@ -11,6 +13,42 @@ export type CodeQLBundle =
combinedBundleURL?: string;
};
/** A resolved download, including its bundle identity and version. */
export interface CodeQLDownloadSource {
/** Distinguishes downloads from local archives and cached installations. */
sourceType: "download";
/** The bundle to download. */
bundle: CodeQLBundle;
/** The compression format of the bundle archive. */
compressionMethod: CompressionMethod;
/** Bundle version of the tools, if known. */
bundleVersion?: string;
/** Requested CLI version, if known. */
cliVersion?: string;
/** Resolved version for telemetry, independent of whether the bundle can be cached. */
toolsVersion: string;
}
/** Returns the exact bundle asset name for a platform and optional language. */
export function getCodeQLBundleName(
compressionMethod: CompressionMethod,
platform: BundlePlatform | undefined,
language?: BuiltInLanguage,
): string {
const extensions: Record<CompressionMethod, string> = {
gzip: ".tar.gz",
zstd: ".tar.zst",
};
const extension = extensions[compressionMethod];
if (platform === undefined) {
return `codeql-bundle${extension}`;
}
if (language !== undefined) {
return `codeql-bundle-${language}-${platform}${extension}`;
}
return `codeql-bundle-${platform}${extension}`;
}
const PER_LANGUAGE_BUNDLE_NAME =
/^codeql-bundle-(.+)-(?:linux64|osx64|win64)\.tar\.(?:gz|zst)$/;

View File

@@ -131,3 +131,16 @@ export async function getPerLanguageBundleLanguage(
return language;
}
/** Explains why an eligible per-language bundle is being replaced by a combined bundle. */
export function logPerLanguageBundleFallback(
{ logger }: ActionState<["Logger"]>,
language: BuiltInLanguage,
location: string,
): void {
logger.warning(
`No per-language CodeQL bundle for '${language}' was found at ${location}, so ` +
"falling back to the bundle that contains all languages. This analysis will still " +
"produce correct results, but will take longer to set up.",
);
}

View File

@@ -435,7 +435,7 @@ test.serial(
// Check that the `CodeQLToolsSource` object matches our expectations.
const expectedVersion = `0.0.0-${expectedDate}`;
const expectedURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}/${setupCodeql.getCodeQLBundleName("zstd")}`;
const expectedURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}/codeql-bundle-linux64.tar.zst`;
t.deepEqual(source, {
bundle: { kind: "combined", url: expectedURL },
bundleVersion: expectedDate,
@@ -505,7 +505,7 @@ test.serial(
// Check that the `CodeQLToolsSource` object matches our expectations.
const expectedVersion = `0.0.0-${expectedDate}`;
const expectedURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}/${setupCodeql.getCodeQLBundleName("zstd")}`;
const expectedURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}/codeql-bundle-linux64.tar.zst`;
t.deepEqual(source, {
bundle: { kind: "combined", url: expectedURL },
bundleVersion: expectedDate,
@@ -1143,30 +1143,6 @@ const PER_LANGUAGE_CLI_VERSION = {
],
};
test.serial(
"getCodeQLBundleName returns a per-language bundle name only when a language is specified",
(t) => {
sinon.stub(process, "platform").value("linux");
sinon.stub(process, "arch").value("x64");
t.is(
setupCodeql.getCodeQLBundleName("zstd", BuiltInLanguage.java),
"codeql-bundle-java-linux64.tar.zst",
);
t.is(
setupCodeql.getCodeQLBundleName("zstd"),
"codeql-bundle-linux64.tar.zst",
);
},
);
test.serial("getCodeQLBundleName names the Swift bundle for macOS", (t) => {
sinon.stub(process, "platform").value("darwin");
t.is(
setupCodeql.getCodeQLBundleName("zstd", BuiltInLanguage.swift),
"codeql-bundle-swift-osx64.tar.zst",
);
});
test.serial(
"getCodeQLSource downloads the per-language bundle for a single explicit language",
async (t) => {

View File

@@ -17,7 +17,12 @@ import {
isRunningLocalAction,
} from "./actions-util";
import * as api from "./api-client";
import { CodeQLBundle, getCodeQLBundleFromUrl } from "./codeql-bundle";
import {
CodeQLBundle,
CodeQLDownloadSource,
getCodeQLBundleFromUrl,
getCodeQLBundleName,
} from "./codeql-bundle";
import * as defaults from "./defaults.json";
import {
addNoLanguageDiagnostic,
@@ -35,7 +40,10 @@ import {
import { BuiltInLanguage } from "./languages";
import { Logger } from "./logging";
import { getCodeQlVersionsForOverlayBaseDatabases } from "./overlay/caching";
import { getPerLanguageBundleLanguage } from "./per-language-bundles";
import {
getPerLanguageBundleLanguage,
logPerLanguageBundleFallback,
} from "./per-language-bundles";
import { getBundlePlatform } from "./platform";
import * as tar from "./tar";
import {
@@ -49,6 +57,8 @@ import {
import * as util from "./util";
import { isGoodVersion } from "./util";
export type { CodeQLDownloadSource } from "./codeql-bundle";
export enum ToolsSource {
Unknown = "UNKNOWN",
Local = "LOCAL",
@@ -64,41 +74,6 @@ const CODEQL_BUNDLE_VERSION_ALIAS: string[] = ["linked", "latest"];
const CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"];
const CODEQL_TOOLCACHE_INPUT = "toolcache";
function getCodeQLBundleExtension(
compressionMethod: tar.CompressionMethod,
): string {
switch (compressionMethod) {
case "gzip":
return ".tar.gz";
case "zstd":
return ".tar.zst";
default:
util.assertNever(compressionMethod);
}
}
/**
* Returns the name of the CodeQL bundle asset to download.
*
* @param compressionMethod The compression method of the bundle.
* @param language Optional language for a per-language bundle. If omitted, returns a combined bundle name.
*/
export function getCodeQLBundleName(
compressionMethod: tar.CompressionMethod,
language?: BuiltInLanguage,
): string {
const extension = getCodeQLBundleExtension(compressionMethod);
const platform = getBundlePlatform();
if (platform === undefined) {
return `codeql-bundle${extension}`;
}
if (language !== undefined) {
return `codeql-bundle-${language}-${platform}${extension}`;
}
return `codeql-bundle-${platform}${extension}`;
}
export function getCodeQLActionRepository(logger: Logger): string {
if (isRunningLocalAction()) {
// This handles the case where the Action does not come from an Action repository,
@@ -223,22 +198,6 @@ export function convertToSemVer(version: string, logger: Logger): string {
return s;
}
/** A resolved download, including its bundle identity and version. */
export interface CodeQLDownloadSource {
/** Distinguishes downloads from local archives and cached installations. */
sourceType: "download";
/** The bundle to download. */
bundle: CodeQLBundle;
/** The compression format of the bundle archive. */
compressionMethod: tar.CompressionMethod;
/** Bundle version of the tools, if known. */
bundleVersion?: string;
/** Requested CLI version, if known. */
cliVersion?: string;
/** Resolved version for telemetry, independent of whether the bundle can be cached. */
toolsVersion: string;
}
export type CodeQLToolsSource =
| {
codeqlTarPath: string;
@@ -757,13 +716,14 @@ export async function getCodeQLSource(
? "zstd"
: "gzip";
const platform = getBundlePlatform();
const perLanguageBundleLanguage = await getPerLanguageBundleLanguage(
{ env: getEnv(), features, logger },
{
rawLanguages,
cliVersion,
compressionMethod,
platform: getBundlePlatform(),
platform,
variant,
},
);
@@ -773,7 +733,7 @@ export async function getCodeQLSource(
getCodeQLBundleDownloadURL(
bundleTagName,
apiDetails,
getCodeQLBundleName(compressionMethod, language),
getCodeQLBundleName(compressionMethod, platform, language),
logger,
);
@@ -1153,11 +1113,7 @@ export async function downloadCodeQLBundle(
) {
throw e;
}
logger.warning(
`No per-language CodeQL bundle for '${bundle.language}' was found at ${bundle.url}, so ` +
"falling back to the bundle that contains all languages. This analysis will still " +
"produce correct results, but will take longer to set up.",
);
logPerLanguageBundleFallback(action, bundle.language, bundle.url);
const result = await downloadCodeQL(
{
@@ -1215,11 +1171,12 @@ async function getLatestNightlyBundle(
? "zstd"
: "gzip";
const platform = getBundlePlatform();
const language = await getPerLanguageBundleLanguage(action, {
rawLanguages,
cliVersion: undefined,
compressionMethod,
platform: getBundlePlatform(),
platform,
variant,
isLatestNightly: true,
});
@@ -1241,14 +1198,18 @@ async function getLatestNightlyBundle(
}
const assetUrl = (name: string) =>
`https://github.com/${CODEQL_NIGHTLIES_REPOSITORY_OWNER}/${CODEQL_NIGHTLIES_REPOSITORY_NAME}/releases/download/${latestRelease.tag_name}/${name}`;
const url = assetUrl(getCodeQLBundleName(compressionMethod, language));
const url = assetUrl(
getCodeQLBundleName(compressionMethod, platform, language),
);
return language === undefined
? { kind: "combined", url }
: {
kind: "per-language",
url,
language,
combinedBundleURL: assetUrl(getCodeQLBundleName(compressionMethod)),
combinedBundleURL: assetUrl(
getCodeQLBundleName(compressionMethod, platform),
),
};
} catch (e) {
throw new Error(