Compare commits

...

8 Commits

Author SHA1 Message Date
Michael B. Gale
5378192d25 Update changelog for v3.28.21 2025-07-28 16:10:50 +01:00
github-actions[bot]
23aee9a3fc Update supported GitHub Enterprise Server versions 2025-07-28 16:08:39 +01:00
Koen Vlaswinkel
07bb2b932c Update changelog and version for v3.28.20 2025-07-21 11:24:11 +02:00
Koen Vlaswinkel
f6c7f63bda Ignore pre-release parts when comparing GHES versions 2025-07-21 11:19:24 +02:00
Koen Vlaswinkel
6370c01206 Move comment to JSDoc 2025-07-21 11:19:07 +02:00
Koen Vlaswinkel
dd627a9af6 Fix parsing of GHES pre-release versions 2025-07-21 11:19:02 +02:00
Koen Vlaswinkel
bcdb4ecb96 Unconditionally disable combining SARIF files for GHES 3.18 2025-07-21 11:18:49 +02:00
Koen Vlaswinkel
c0809df981 Remove support for combining SARIF runs with non-unique categories 2025-07-21 11:18:34 +02:00
18 changed files with 441 additions and 18 deletions

View File

@@ -2,6 +2,14 @@
See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs. See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs.
## 3.28.21 - 28 July 2025
No user facing changes.
## 3.28.20 - 21 July 2025
- Remove support for combining SARIF files from a single upload for GHES 3.18, see [the changelog post](https://github.blog/changelog/2024-05-06-code-scanning-will-stop-combining-runs-from-a-single-upload/). [#2959](https://github.com/github/codeql-action/pull/2959)
## 3.28.18 - 16 May 2025 ## 3.28.18 - 16 May 2025
- Update default CodeQL bundle version to 2.21.3. [#2893](https://github.com/github/codeql-action/pull/2893) - Update default CodeQL bundle version to 2.21.3. [#2893](https://github.com/github/codeql-action/pull/2893)

View File

@@ -1 +1 @@
{ "maximumVersion": "3.17", "minimumVersion": "3.13" } { "maximumVersion": "3.18", "minimumVersion": "3.13" }

6
lib/feature-flags.js generated
View File

@@ -61,6 +61,7 @@ var Feature;
Feature["CppBuildModeNone"] = "cpp_build_mode_none"; Feature["CppBuildModeNone"] = "cpp_build_mode_none";
Feature["CppDependencyInstallation"] = "cpp_dependency_installation_enabled"; Feature["CppDependencyInstallation"] = "cpp_dependency_installation_enabled";
Feature["DiffInformedQueries"] = "diff_informed_queries"; Feature["DiffInformedQueries"] = "diff_informed_queries";
Feature["DisableCombineSarifFiles"] = "disable_combine_sarif_files";
Feature["DisableCsharpBuildless"] = "disable_csharp_buildless"; Feature["DisableCsharpBuildless"] = "disable_csharp_buildless";
Feature["DisableJavaBuildlessEnabled"] = "disable_java_buildless_enabled"; Feature["DisableJavaBuildlessEnabled"] = "disable_java_buildless_enabled";
Feature["DisableKotlinAnalysisEnabled"] = "disable_kotlin_analysis_enabled"; Feature["DisableKotlinAnalysisEnabled"] = "disable_kotlin_analysis_enabled";
@@ -98,6 +99,11 @@ exports.featureConfig = {
envVar: "CODEQL_ACTION_DIFF_INFORMED_QUERIES", envVar: "CODEQL_ACTION_DIFF_INFORMED_QUERIES",
minimumVersion: "2.21.0", minimumVersion: "2.21.0",
}, },
[Feature.DisableCombineSarifFiles]: {
defaultValue: false,
envVar: "CODEQL_ACTION_DISABLE_COMBINE_SARIF_FILES",
minimumVersion: undefined,
},
[Feature.DisableCsharpBuildless]: { [Feature.DisableCsharpBuildless]: {
defaultValue: false, defaultValue: false,
envVar: "CODEQL_ACTION_DISABLE_CSHARP_BUILDLESS", envVar: "CODEQL_ACTION_DISABLE_CSHARP_BUILDLESS",

File diff suppressed because one or more lines are too long

39
lib/upload-lib.js generated
View File

@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.InvalidSarifUploadError = void 0; exports.InvalidSarifUploadError = void 0;
exports.shouldShowCombineSarifFilesDeprecationWarning = shouldShowCombineSarifFilesDeprecationWarning; exports.shouldShowCombineSarifFilesDeprecationWarning = shouldShowCombineSarifFilesDeprecationWarning;
exports.throwIfCombineSarifFilesDisabled = throwIfCombineSarifFilesDisabled;
exports.populateRunAutomationDetails = populateRunAutomationDetails; exports.populateRunAutomationDetails = populateRunAutomationDetails;
exports.findSarifFilesInDir = findSarifFilesInDir; exports.findSarifFilesInDir = findSarifFilesInDir;
exports.readSarifFile = readSarifFile; exports.readSarifFile = readSarifFile;
@@ -54,7 +55,6 @@ const zlib_1 = __importDefault(require("zlib"));
const core = __importStar(require("@actions/core")); const core = __importStar(require("@actions/core"));
const file_url_1 = __importDefault(require("file-url")); const file_url_1 = __importDefault(require("file-url"));
const jsonschema = __importStar(require("jsonschema")); const jsonschema = __importStar(require("jsonschema"));
const semver = __importStar(require("semver"));
const actionsUtil = __importStar(require("./actions-util")); const actionsUtil = __importStar(require("./actions-util"));
const actions_util_1 = require("./actions-util"); const actions_util_1 = require("./actions-util");
const api = __importStar(require("./api-client")); const api = __importStar(require("./api-client"));
@@ -63,6 +63,7 @@ const codeql_1 = require("./codeql");
const config_utils_1 = require("./config-utils"); const config_utils_1 = require("./config-utils");
const diff_informed_analysis_utils_1 = require("./diff-informed-analysis-utils"); const diff_informed_analysis_utils_1 = require("./diff-informed-analysis-utils");
const environment_1 = require("./environment"); const environment_1 = require("./environment");
const feature_flags_1 = require("./feature-flags");
const fingerprints = __importStar(require("./fingerprints")); const fingerprints = __importStar(require("./fingerprints"));
const gitUtils = __importStar(require("./git-utils")); const gitUtils = __importStar(require("./git-utils"));
const init_1 = require("./init"); const init_1 = require("./init");
@@ -136,7 +137,7 @@ function areAllRunsUnique(sarifObjects) {
async function shouldShowCombineSarifFilesDeprecationWarning(sarifObjects, githubVersion) { async function shouldShowCombineSarifFilesDeprecationWarning(sarifObjects, githubVersion) {
// Do not show this warning on GHES versions before 3.14.0 // Do not show this warning on GHES versions before 3.14.0
if (githubVersion.type === util_1.GitHubVariant.GHES && if (githubVersion.type === util_1.GitHubVariant.GHES &&
semver.lt(githubVersion.version, "3.14.0")) { (0, util_1.satisfiesGHESVersion)(githubVersion.version, "<3.14", true)) {
return false; return false;
} }
// Only give a deprecation warning when not all runs are unique and // Only give a deprecation warning when not all runs are unique and
@@ -144,6 +145,36 @@ async function shouldShowCombineSarifFilesDeprecationWarning(sarifObjects, githu
return (!areAllRunsUnique(sarifObjects) && return (!areAllRunsUnique(sarifObjects) &&
!process.env.CODEQL_MERGE_SARIF_DEPRECATION_WARNING); !process.env.CODEQL_MERGE_SARIF_DEPRECATION_WARNING);
} }
async function throwIfCombineSarifFilesDisabled(sarifObjects, features, githubVersion) {
if (!(await shouldDisableCombineSarifFiles(sarifObjects, features, githubVersion))) {
return;
}
// TODO: Update this changelog URL to the correct one when it's published.
const deprecationMoreInformationMessage = "For more information, see https://github.blog/changelog/2024-05-06-code-scanning-will-stop-combining-runs-from-a-single-upload";
throw new util_1.ConfigurationError(`The CodeQL Action does not support uploading multiple SARIF runs with the same category. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}`);
}
// Checks whether combining SARIF files should be disabled.
async function shouldDisableCombineSarifFiles(sarifObjects, features, githubVersion) {
if (githubVersion.type === util_1.GitHubVariant.GHES) {
// Never block on GHES versions before 3.18.
if ((0, util_1.satisfiesGHESVersion)(githubVersion.version, "<3.18", true)) {
return false;
}
}
else {
// Never block when the feature flag is disabled.
if (!(await features.getValue(feature_flags_1.Feature.DisableCombineSarifFiles))) {
return false;
}
}
if (areAllRunsUnique(sarifObjects)) {
// If all runs are unique, we can safely combine them.
return false;
}
// Combining SARIF files is not supported and Code Scanning will return an
// error if multiple runs with the same category are uploaded.
return true;
}
// Takes a list of paths to sarif files and combines them together using the // Takes a list of paths to sarif files and combines them together using the
// CLI `github merge-results` command when all SARIF files are produced by // CLI `github merge-results` command when all SARIF files are produced by
// CodeQL. Otherwise, it will fall back to combining the files in the action. // CodeQL. Otherwise, it will fall back to combining the files in the action.
@@ -158,9 +189,10 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
}); });
const deprecationWarningMessage = gitHubVersion.type === util_1.GitHubVariant.GHES const deprecationWarningMessage = gitHubVersion.type === util_1.GitHubVariant.GHES
? "and will be removed in GitHub Enterprise Server 3.18" ? "and will be removed in GitHub Enterprise Server 3.18"
: "and will be removed on June 4, 2025"; : "and will be removed in July 2025";
const deprecationMoreInformationMessage = "For more information, see https://github.blog/changelog/2024-05-06-code-scanning-will-stop-combining-runs-from-a-single-upload"; const deprecationMoreInformationMessage = "For more information, see https://github.blog/changelog/2024-05-06-code-scanning-will-stop-combining-runs-from-a-single-upload";
if (!areAllRunsProducedByCodeQL(sarifObjects)) { if (!areAllRunsProducedByCodeQL(sarifObjects)) {
await throwIfCombineSarifFilesDisabled(sarifObjects, features, gitHubVersion);
logger.debug("Not all SARIF files were produced by CodeQL. Merging files in the action."); logger.debug("Not all SARIF files were produced by CodeQL. Merging files in the action.");
if (await shouldShowCombineSarifFilesDeprecationWarning(sarifObjects, gitHubVersion)) { if (await shouldShowCombineSarifFilesDeprecationWarning(sarifObjects, gitHubVersion)) {
logger.warning(`Uploading multiple SARIF runs with the same category is deprecated ${deprecationWarningMessage}. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}`); logger.warning(`Uploading multiple SARIF runs with the same category is deprecated ${deprecationWarningMessage}. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}`);
@@ -192,6 +224,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
codeQL = initCodeQLResult.codeql; codeQL = initCodeQLResult.codeql;
} }
if (!(await codeQL.supportsFeature(tools_features_1.ToolsFeature.SarifMergeRunsFromEqualCategory))) { if (!(await codeQL.supportsFeature(tools_features_1.ToolsFeature.SarifMergeRunsFromEqualCategory))) {
await throwIfCombineSarifFilesDisabled(sarifObjects, features, gitHubVersion);
logger.warning("The CodeQL CLI does not support merging SARIF files. Merging files in the action."); logger.warning("The CodeQL CLI does not support merging SARIF files. Merging files in the action.");
if (await shouldShowCombineSarifFilesDeprecationWarning(sarifObjects, gitHubVersion)) { if (await shouldShowCombineSarifFilesDeprecationWarning(sarifObjects, gitHubVersion)) {
logger.warning(`Uploading multiple CodeQL runs with the same category is deprecated ${deprecationWarningMessage} for CodeQL CLI 2.16.6 and earlier. Please update your CodeQL CLI version or update your workflow to set a distinct category for each CodeQL run. ${deprecationMoreInformationMessage}`); logger.warning(`Uploading multiple CodeQL runs with the same category is deprecated ${deprecationWarningMessage} for CodeQL CLI 2.16.6 and earlier. Please update your CodeQL CLI version or update your workflow to set a distinct category for each CodeQL run. ${deprecationMoreInformationMessage}`);

File diff suppressed because one or more lines are too long

82
lib/upload-lib.test.js generated
View File

@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs")); const fs = __importStar(require("fs"));
const path = __importStar(require("path")); const path = __importStar(require("path"));
const ava_1 = __importDefault(require("ava")); const ava_1 = __importDefault(require("ava"));
const feature_flags_1 = require("./feature-flags");
const logging_1 = require("./logging"); const logging_1 = require("./logging");
const testing_utils_1 = require("./testing-utils"); const testing_utils_1 = require("./testing-utils");
const uploadLib = __importStar(require("./upload-lib")); const uploadLib = __importStar(require("./upload-lib"));
@@ -223,6 +224,12 @@ ava_1.default.beforeEach(() => {
version: "3.14.0", version: "3.14.0",
})); }));
}); });
(0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning when on GHES 3.16 pre", async (t) => {
t.true(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "def"), createMockSarif("abc", "def")], {
type: util_1.GitHubVariant.GHES,
version: "3.16.0.pre1",
}));
});
(0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning with only 1 run", async (t) => { (0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning with only 1 run", async (t) => {
t.false(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "def")], { t.false(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "def")], {
type: util_1.GitHubVariant.DOTCOM, type: util_1.GitHubVariant.DOTCOM,
@@ -244,6 +251,81 @@ ava_1.default.beforeEach(() => {
type: util_1.GitHubVariant.DOTCOM, type: util_1.GitHubVariant.DOTCOM,
})); }));
}); });
(0, ava_1.default)("throwIfCombineSarifFilesDisabled when on dotcom with feature flag", async (t) => {
await t.throwsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.DisableCombineSarifFiles]), {
type: util_1.GitHubVariant.DOTCOM,
}), {
message: /The CodeQL Action does not support uploading multiple SARIF runs with the same category/,
});
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled when on dotcom without feature flag", async (t) => {
await t.notThrowsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([]), {
type: util_1.GitHubVariant.DOTCOM,
}));
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled when on GHES 3.13", async (t) => {
await t.notThrowsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([]), {
type: util_1.GitHubVariant.GHES,
version: "3.13.2",
}));
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled when on GHES 3.14", async (t) => {
await t.notThrowsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([]), {
type: util_1.GitHubVariant.GHES,
version: "3.14.0",
}));
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled when on GHES 3.17", async (t) => {
await t.notThrowsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([]), {
type: util_1.GitHubVariant.GHES,
version: "3.17.0",
}));
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled when on GHES 3.18 pre", async (t) => {
await t.throwsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([]), {
type: util_1.GitHubVariant.GHES,
version: "3.18.0.pre1",
}), {
message: /The CodeQL Action does not support uploading multiple SARIF runs with the same category/,
});
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled when on GHES 3.18 alpha", async (t) => {
await t.throwsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([]), {
type: util_1.GitHubVariant.GHES,
version: "3.18.0-alpha.1",
}), {
message: /The CodeQL Action does not support uploading multiple SARIF runs with the same category/,
});
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled when on GHES 3.18", async (t) => {
await t.throwsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([]), {
type: util_1.GitHubVariant.GHES,
version: "3.18.0",
}), {
message: /The CodeQL Action does not support uploading multiple SARIF runs with the same category/,
});
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled with an invalid GHES version", async (t) => {
await t.notThrowsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([]), {
type: util_1.GitHubVariant.GHES,
version: "foobar",
}));
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled with only 1 run", async (t) => {
await t.notThrowsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.DisableCombineSarifFiles]), {
type: util_1.GitHubVariant.DOTCOM,
}));
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled with distinct categories", async (t) => {
await t.notThrowsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "def"), createMockSarif("def", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.DisableCombineSarifFiles]), {
type: util_1.GitHubVariant.DOTCOM,
}));
});
(0, ava_1.default)("throwIfCombineSarifFilesDisabled with distinct tools", async (t) => {
await t.notThrowsAsync(uploadLib.throwIfCombineSarifFilesDisabled([createMockSarif("abc", "abc"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.DisableCombineSarifFiles]), {
type: util_1.GitHubVariant.DOTCOM,
}));
});
(0, ava_1.default)("shouldConsiderConfigurationError correctly detects configuration errors", (t) => { (0, ava_1.default)("shouldConsiderConfigurationError correctly detects configuration errors", (t) => {
const error1 = [ const error1 = [
"CodeQL analyses from advanced configurations cannot be processed when the default setup is enabled", "CodeQL analyses from advanced configurations cannot be processed when the default setup is enabled",

File diff suppressed because one or more lines are too long

19
lib/util.js generated
View File

@@ -77,6 +77,7 @@ exports.getErrorMessage = getErrorMessage;
exports.prettyPrintPack = prettyPrintPack; exports.prettyPrintPack = prettyPrintPack;
exports.checkDiskUsage = checkDiskUsage; exports.checkDiskUsage = checkDiskUsage;
exports.checkActionVersion = checkActionVersion; exports.checkActionVersion = checkActionVersion;
exports.satisfiesGHESVersion = satisfiesGHESVersion;
exports.cloneObject = cloneObject; exports.cloneObject = cloneObject;
exports.checkSipEnablement = checkSipEnablement; exports.checkSipEnablement = checkSipEnablement;
exports.cleanUpGlob = cleanUpGlob; exports.cleanUpGlob = cleanUpGlob;
@@ -887,6 +888,24 @@ function checkActionVersion(version, githubVersion) {
} }
} }
} }
/**
* This will check whether the given GitHub version satisfies the given range,
* taking into account that a range like >=3.18 will also match the GHES 3.18
* pre-release/RC versions.
*
* When the given `githubVersion` is not a GHES version, or if the version
* is invalid, this will return `defaultIfInvalid`.
*/
function satisfiesGHESVersion(ghesVersion, range, defaultIfInvalid) {
const semverVersion = semver.coerce(ghesVersion);
if (semverVersion === null) {
return defaultIfInvalid;
}
// We always drop the pre-release part of the version, since anything that
// applies to GHES 3.18.0 should also apply to GHES 3.18.0.pre1.
semverVersion.prerelease = [];
return semver.satisfies(semverVersion, range);
}
/** /**
* Supported build modes. * Supported build modes.
* *

File diff suppressed because one or more lines are too long

2
node_modules/.package-lock.json generated vendored
View File

@@ -1,6 +1,6 @@
{ {
"name": "codeql", "name": "codeql",
"version": "3.28.18", "version": "3.28.20",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "codeql", "name": "codeql",
"version": "3.28.18", "version": "3.28.20",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "codeql", "name": "codeql",
"version": "3.28.18", "version": "3.28.20",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/artifact": "^2.3.1", "@actions/artifact": "^2.3.1",

View File

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

View File

@@ -1 +1 @@
{"maximumVersion": "3.17", "minimumVersion": "3.13"} {"maximumVersion": "3.18", "minimumVersion": "3.13"}

View File

@@ -46,6 +46,7 @@ export enum Feature {
CppBuildModeNone = "cpp_build_mode_none", CppBuildModeNone = "cpp_build_mode_none",
CppDependencyInstallation = "cpp_dependency_installation_enabled", CppDependencyInstallation = "cpp_dependency_installation_enabled",
DiffInformedQueries = "diff_informed_queries", DiffInformedQueries = "diff_informed_queries",
DisableCombineSarifFiles = "disable_combine_sarif_files",
DisableCsharpBuildless = "disable_csharp_buildless", DisableCsharpBuildless = "disable_csharp_buildless",
DisableJavaBuildlessEnabled = "disable_java_buildless_enabled", DisableJavaBuildlessEnabled = "disable_java_buildless_enabled",
DisableKotlinAnalysisEnabled = "disable_kotlin_analysis_enabled", DisableKotlinAnalysisEnabled = "disable_kotlin_analysis_enabled",
@@ -114,6 +115,11 @@ export const featureConfig: Record<
envVar: "CODEQL_ACTION_DIFF_INFORMED_QUERIES", envVar: "CODEQL_ACTION_DIFF_INFORMED_QUERIES",
minimumVersion: "2.21.0", minimumVersion: "2.21.0",
}, },
[Feature.DisableCombineSarifFiles]: {
defaultValue: false,
envVar: "CODEQL_ACTION_DISABLE_COMBINE_SARIF_FILES",
minimumVersion: undefined,
},
[Feature.DisableCsharpBuildless]: { [Feature.DisableCsharpBuildless]: {
defaultValue: false, defaultValue: false,
envVar: "CODEQL_ACTION_DISABLE_CSHARP_BUILDLESS", envVar: "CODEQL_ACTION_DISABLE_CSHARP_BUILDLESS",

View File

@@ -3,8 +3,9 @@ import * as path from "path";
import test from "ava"; import test from "ava";
import { Feature } from "./feature-flags";
import { getRunnerLogger, Logger } from "./logging"; import { getRunnerLogger, Logger } from "./logging";
import { setupTests } from "./testing-utils"; import { createFeatures, setupTests } from "./testing-utils";
import * as uploadLib from "./upload-lib"; import * as uploadLib from "./upload-lib";
import { GitHubVariant, initializeEnvironment, withTmpDir } from "./util"; import { GitHubVariant, initializeEnvironment, withTmpDir } from "./util";
@@ -371,6 +372,18 @@ test("shouldShowCombineSarifFilesDeprecationWarning when on GHES 3.14", async (t
); );
}); });
test("shouldShowCombineSarifFilesDeprecationWarning when on GHES 3.16 pre", async (t) => {
t.true(
await uploadLib.shouldShowCombineSarifFilesDeprecationWarning(
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
{
type: GitHubVariant.GHES,
version: "3.16.0.pre1",
},
),
);
});
test("shouldShowCombineSarifFilesDeprecationWarning with only 1 run", async (t) => { test("shouldShowCombineSarifFilesDeprecationWarning with only 1 run", async (t) => {
t.false( t.false(
await uploadLib.shouldShowCombineSarifFilesDeprecationWarning( await uploadLib.shouldShowCombineSarifFilesDeprecationWarning(
@@ -417,6 +430,173 @@ test("shouldShowCombineSarifFilesDeprecationWarning when environment variable is
); );
}); });
test("throwIfCombineSarifFilesDisabled when on dotcom with feature flag", async (t) => {
await t.throwsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
createFeatures([Feature.DisableCombineSarifFiles]),
{
type: GitHubVariant.DOTCOM,
},
),
{
message:
/The CodeQL Action does not support uploading multiple SARIF runs with the same category/,
},
);
});
test("throwIfCombineSarifFilesDisabled when on dotcom without feature flag", async (t) => {
await t.notThrowsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
createFeatures([]),
{
type: GitHubVariant.DOTCOM,
},
),
);
});
test("throwIfCombineSarifFilesDisabled when on GHES 3.13", async (t) => {
await t.notThrowsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
createFeatures([]),
{
type: GitHubVariant.GHES,
version: "3.13.2",
},
),
);
});
test("throwIfCombineSarifFilesDisabled when on GHES 3.14", async (t) => {
await t.notThrowsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
createFeatures([]),
{
type: GitHubVariant.GHES,
version: "3.14.0",
},
),
);
});
test("throwIfCombineSarifFilesDisabled when on GHES 3.17", async (t) => {
await t.notThrowsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
createFeatures([]),
{
type: GitHubVariant.GHES,
version: "3.17.0",
},
),
);
});
test("throwIfCombineSarifFilesDisabled when on GHES 3.18 pre", async (t) => {
await t.throwsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
createFeatures([]),
{
type: GitHubVariant.GHES,
version: "3.18.0.pre1",
},
),
{
message:
/The CodeQL Action does not support uploading multiple SARIF runs with the same category/,
},
);
});
test("throwIfCombineSarifFilesDisabled when on GHES 3.18 alpha", async (t) => {
await t.throwsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
createFeatures([]),
{
type: GitHubVariant.GHES,
version: "3.18.0-alpha.1",
},
),
{
message:
/The CodeQL Action does not support uploading multiple SARIF runs with the same category/,
},
);
});
test("throwIfCombineSarifFilesDisabled when on GHES 3.18", async (t) => {
await t.throwsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
createFeatures([]),
{
type: GitHubVariant.GHES,
version: "3.18.0",
},
),
{
message:
/The CodeQL Action does not support uploading multiple SARIF runs with the same category/,
},
);
});
test("throwIfCombineSarifFilesDisabled with an invalid GHES version", async (t) => {
await t.notThrowsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
createFeatures([]),
{
type: GitHubVariant.GHES,
version: "foobar",
},
),
);
});
test("throwIfCombineSarifFilesDisabled with only 1 run", async (t) => {
await t.notThrowsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def")],
createFeatures([Feature.DisableCombineSarifFiles]),
{
type: GitHubVariant.DOTCOM,
},
),
);
});
test("throwIfCombineSarifFilesDisabled with distinct categories", async (t) => {
await t.notThrowsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "def"), createMockSarif("def", "def")],
createFeatures([Feature.DisableCombineSarifFiles]),
{
type: GitHubVariant.DOTCOM,
},
),
);
});
test("throwIfCombineSarifFilesDisabled with distinct tools", async (t) => {
await t.notThrowsAsync(
uploadLib.throwIfCombineSarifFilesDisabled(
[createMockSarif("abc", "abc"), createMockSarif("abc", "def")],
createFeatures([Feature.DisableCombineSarifFiles]),
{
type: GitHubVariant.DOTCOM,
},
),
);
});
test("shouldConsiderConfigurationError correctly detects configuration errors", (t) => { test("shouldConsiderConfigurationError correctly detects configuration errors", (t) => {
const error1 = [ const error1 = [
"CodeQL analyses from advanced configurations cannot be processed when the default setup is enabled", "CodeQL analyses from advanced configurations cannot be processed when the default setup is enabled",

View File

@@ -6,7 +6,6 @@ import * as core from "@actions/core";
import { OctokitResponse } from "@octokit/types"; import { OctokitResponse } from "@octokit/types";
import fileUrl from "file-url"; import fileUrl from "file-url";
import * as jsonschema from "jsonschema"; import * as jsonschema from "jsonschema";
import * as semver from "semver";
import * as actionsUtil from "./actions-util"; import * as actionsUtil from "./actions-util";
import { getOptionalInput, getRequiredInput } from "./actions-util"; import { getOptionalInput, getRequiredInput } from "./actions-util";
@@ -16,7 +15,7 @@ import { CodeQL, getCodeQL } from "./codeql";
import { getConfig } from "./config-utils"; import { getConfig } from "./config-utils";
import { readDiffRangesJsonFile } from "./diff-informed-analysis-utils"; import { readDiffRangesJsonFile } from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment"; import { EnvVar } from "./environment";
import { FeatureEnablement } from "./feature-flags"; import { Feature, FeatureEnablement } from "./feature-flags";
import * as fingerprints from "./fingerprints"; import * as fingerprints from "./fingerprints";
import * as gitUtils from "./git-utils"; import * as gitUtils from "./git-utils";
import { initCodeQL } from "./init"; import { initCodeQL } from "./init";
@@ -30,6 +29,7 @@ import {
getRequiredEnvParam, getRequiredEnvParam,
GitHubVariant, GitHubVariant,
GitHubVersion, GitHubVersion,
satisfiesGHESVersion,
SarifFile, SarifFile,
SarifRun, SarifRun,
} from "./util"; } from "./util";
@@ -132,7 +132,7 @@ export async function shouldShowCombineSarifFilesDeprecationWarning(
// Do not show this warning on GHES versions before 3.14.0 // Do not show this warning on GHES versions before 3.14.0
if ( if (
githubVersion.type === GitHubVariant.GHES && githubVersion.type === GitHubVariant.GHES &&
semver.lt(githubVersion.version, "3.14.0") satisfiesGHESVersion(githubVersion.version, "<3.14", true)
) { ) {
return false; return false;
} }
@@ -145,6 +145,58 @@ export async function shouldShowCombineSarifFilesDeprecationWarning(
); );
} }
export async function throwIfCombineSarifFilesDisabled(
sarifObjects: util.SarifFile[],
features: FeatureEnablement,
githubVersion: GitHubVersion,
) {
if (
!(await shouldDisableCombineSarifFiles(
sarifObjects,
features,
githubVersion,
))
) {
return;
}
// TODO: Update this changelog URL to the correct one when it's published.
const deprecationMoreInformationMessage =
"For more information, see https://github.blog/changelog/2024-05-06-code-scanning-will-stop-combining-runs-from-a-single-upload";
throw new ConfigurationError(
`The CodeQL Action does not support uploading multiple SARIF runs with the same category. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}`,
);
}
// Checks whether combining SARIF files should be disabled.
async function shouldDisableCombineSarifFiles(
sarifObjects: util.SarifFile[],
features: FeatureEnablement,
githubVersion: GitHubVersion,
) {
if (githubVersion.type === GitHubVariant.GHES) {
// Never block on GHES versions before 3.18.
if (satisfiesGHESVersion(githubVersion.version, "<3.18", true)) {
return false;
}
} else {
// Never block when the feature flag is disabled.
if (!(await features.getValue(Feature.DisableCombineSarifFiles))) {
return false;
}
}
if (areAllRunsUnique(sarifObjects)) {
// If all runs are unique, we can safely combine them.
return false;
}
// Combining SARIF files is not supported and Code Scanning will return an
// error if multiple runs with the same category are uploaded.
return true;
}
// Takes a list of paths to sarif files and combines them together using the // Takes a list of paths to sarif files and combines them together using the
// CLI `github merge-results` command when all SARIF files are produced by // CLI `github merge-results` command when all SARIF files are produced by
// CodeQL. Otherwise, it will fall back to combining the files in the action. // CodeQL. Otherwise, it will fall back to combining the files in the action.
@@ -167,11 +219,17 @@ async function combineSarifFilesUsingCLI(
const deprecationWarningMessage = const deprecationWarningMessage =
gitHubVersion.type === GitHubVariant.GHES gitHubVersion.type === GitHubVariant.GHES
? "and will be removed in GitHub Enterprise Server 3.18" ? "and will be removed in GitHub Enterprise Server 3.18"
: "and will be removed on June 4, 2025"; : "and will be removed in July 2025";
const deprecationMoreInformationMessage = const deprecationMoreInformationMessage =
"For more information, see https://github.blog/changelog/2024-05-06-code-scanning-will-stop-combining-runs-from-a-single-upload"; "For more information, see https://github.blog/changelog/2024-05-06-code-scanning-will-stop-combining-runs-from-a-single-upload";
if (!areAllRunsProducedByCodeQL(sarifObjects)) { if (!areAllRunsProducedByCodeQL(sarifObjects)) {
await throwIfCombineSarifFilesDisabled(
sarifObjects,
features,
gitHubVersion,
);
logger.debug( logger.debug(
"Not all SARIF files were produced by CodeQL. Merging files in the action.", "Not all SARIF files were produced by CodeQL. Merging files in the action.",
); );
@@ -235,6 +293,12 @@ async function combineSarifFilesUsingCLI(
ToolsFeature.SarifMergeRunsFromEqualCategory, ToolsFeature.SarifMergeRunsFromEqualCategory,
)) ))
) { ) {
await throwIfCombineSarifFilesDisabled(
sarifObjects,
features,
gitHubVersion,
);
logger.warning( logger.warning(
"The CodeQL CLI does not support merging SARIF files. Merging files in the action.", "The CodeQL CLI does not support merging SARIF files. Merging files in the action.",
); );

View File

@@ -1132,6 +1132,31 @@ export function checkActionVersion(
} }
} }
/**
* This will check whether the given GitHub version satisfies the given range,
* taking into account that a range like >=3.18 will also match the GHES 3.18
* pre-release/RC versions.
*
* When the given `githubVersion` is not a GHES version, or if the version
* is invalid, this will return `defaultIfInvalid`.
*/
export function satisfiesGHESVersion(
ghesVersion: string,
range: string,
defaultIfInvalid: boolean,
): boolean {
const semverVersion = semver.coerce(ghesVersion);
if (semverVersion === null) {
return defaultIfInvalid;
}
// We always drop the pre-release part of the version, since anything that
// applies to GHES 3.18.0 should also apply to GHES 3.18.0.pre1.
semverVersion.prerelease = [];
return semver.satisfies(semverVersion, range);
}
/** /**
* Supported build modes. * Supported build modes.
* *