mirror of
https://github.com/github/codeql-action.git
synced 2026-01-03 21:20:09 +08:00
Compare commits
25 Commits
codeql-bun
...
v3.25.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccf74c9479 | ||
|
|
4fdf4ac628 | ||
|
|
4b812a5dff | ||
|
|
1e21373a75 | ||
|
|
4673d41da1 | ||
|
|
65297ef0b0 | ||
|
|
84d6ead480 | ||
|
|
b20bf5914d | ||
|
|
93b8232a39 | ||
|
|
ee63da2847 | ||
|
|
e62cc70a8b | ||
|
|
5d274be858 | ||
|
|
3a471a06fa | ||
|
|
725ed4139d | ||
|
|
1de9b371a1 | ||
|
|
757fcd3d21 | ||
|
|
40f70f96b1 | ||
|
|
41857bab35 | ||
|
|
b3225af51b | ||
|
|
905f9b0083 | ||
|
|
80394dcc32 | ||
|
|
7c29971135 | ||
|
|
a5e49d1544 | ||
|
|
24acd7711e | ||
|
|
8b0dfa84c7 |
20
.github/update-release-branch.py
vendored
20
.github/update-release-branch.py
vendored
@@ -1,5 +1,6 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import datetime
|
import datetime
|
||||||
|
import fileinput
|
||||||
import re
|
import re
|
||||||
from github import Github
|
from github import Github
|
||||||
import json
|
import json
|
||||||
@@ -171,6 +172,19 @@ def get_current_version():
|
|||||||
with open('package.json', 'r') as f:
|
with open('package.json', 'r') as f:
|
||||||
return json.load(f)['version']
|
return json.load(f)['version']
|
||||||
|
|
||||||
|
# `npm version` doesn't always work because of merge conflicts, so we
|
||||||
|
# replace the version in package.json textually.
|
||||||
|
def replace_version_package_json(prev_version, new_version):
|
||||||
|
prev_line_is_codeql = False
|
||||||
|
for line in fileinput.input('package.json', inplace = True, encoding='utf-8'):
|
||||||
|
if prev_line_is_codeql and f'\"version\": \"{prev_version}\"' in line:
|
||||||
|
print(line.replace(prev_version, new_version), end='')
|
||||||
|
else:
|
||||||
|
prev_line_is_codeql = False
|
||||||
|
print(line, end='')
|
||||||
|
if '\"name\": \"codeql\",' in line:
|
||||||
|
prev_line_is_codeql = True
|
||||||
|
|
||||||
def get_today_string():
|
def get_today_string():
|
||||||
today = datetime.datetime.today()
|
today = datetime.datetime.today()
|
||||||
return '{:%d %b %Y}'.format(today)
|
return '{:%d %b %Y}'.format(today)
|
||||||
@@ -374,9 +388,9 @@ def main():
|
|||||||
run_git('commit', '--no-edit')
|
run_git('commit', '--no-edit')
|
||||||
|
|
||||||
# Migrate the package version number from a vLatest version number to a vOlder version number
|
# Migrate the package version number from a vLatest version number to a vOlder version number
|
||||||
print(f'Setting version number to {version}')
|
print(f'Setting version number to {version} in package.json')
|
||||||
subprocess.check_output(['npm', 'version', version, '--no-git-tag-version'])
|
replace_version_package_json(get_current_version(), version) # We rely on the `Update dependencies` workflow to update package-lock.json
|
||||||
run_git('add', 'package.json', 'package-lock.json')
|
run_git('add', 'package.json')
|
||||||
|
|
||||||
# Migrate the changelog notes from vLatest version numbers to vOlder version numbers
|
# Migrate the changelog notes from vLatest version numbers to vOlder version numbers
|
||||||
print(f'Migrating changelog notes from v{source_branch_major_version} to v{target_branch_major_version}')
|
print(f'Migrating changelog notes from v{source_branch_major_version} to v{target_branch_major_version}')
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
|
|||||||
|
|
||||||
Note that the only difference between `v2` and `v3` of the CodeQL Action is the node version they support, with `v3` running on node 20 while we continue to release `v2` to support running on node 16. For example `3.22.11` was the first `v3` release and is functionally identical to `2.22.11`. This approach ensures an easy way to track exactly which features are included in different versions, indicated by the minor and patch version numbers.
|
Note that the only difference between `v2` and `v3` of the CodeQL Action is the node version they support, with `v3` running on node 20 while we continue to release `v2` to support running on node 16. For example `3.22.11` was the first `v3` release and is functionally identical to `2.22.11`. This approach ensures an easy way to track exactly which features are included in different versions, indicated by the minor and patch version numbers.
|
||||||
|
|
||||||
## [UNRELEASED]
|
## 3.25.4 - 08 May 2024
|
||||||
|
|
||||||
No user facing changes.
|
- Update default CodeQL bundle version to 2.17.2. [#2270](https://github.com/github/codeql-action/pull/2270)
|
||||||
|
|
||||||
## 3.25.3 - 25 Apr 2024
|
## 3.25.3 - 25 Apr 2024
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"bundleVersion": "codeql-bundle-v2.17.1",
|
"bundleVersion": "codeql-bundle-v2.17.2",
|
||||||
"cliVersion": "2.17.1",
|
"cliVersion": "2.17.2",
|
||||||
"priorBundleVersion": "codeql-bundle-v2.17.0",
|
"priorBundleVersion": "codeql-bundle-v2.17.1",
|
||||||
"priorCliVersion": "2.17.0"
|
"priorCliVersion": "2.17.1"
|
||||||
}
|
}
|
||||||
|
|||||||
8
lib/feature-flags.js
generated
8
lib/feature-flags.js
generated
@@ -50,7 +50,7 @@ exports.CODEQL_VERSION_FINE_GRAINED_PARALLELISM = "2.15.1";
|
|||||||
var Feature;
|
var Feature;
|
||||||
(function (Feature) {
|
(function (Feature) {
|
||||||
Feature["AutobuildDirectTracingEnabled"] = "autobuild_direct_tracing_enabled";
|
Feature["AutobuildDirectTracingEnabled"] = "autobuild_direct_tracing_enabled";
|
||||||
Feature["CliSarifMerge"] = "cli_sarif_merge_enabled";
|
Feature["CombineSarifFilesDeprecationWarning"] = "combine_sarif_files_deprecation_warning_enabled";
|
||||||
Feature["CppDependencyInstallation"] = "cpp_dependency_installation_enabled";
|
Feature["CppDependencyInstallation"] = "cpp_dependency_installation_enabled";
|
||||||
Feature["CppTrapCachingEnabled"] = "cpp_trap_caching_enabled";
|
Feature["CppTrapCachingEnabled"] = "cpp_trap_caching_enabled";
|
||||||
Feature["DisableJavaBuildlessEnabled"] = "disable_java_buildless_enabled";
|
Feature["DisableJavaBuildlessEnabled"] = "disable_java_buildless_enabled";
|
||||||
@@ -65,9 +65,9 @@ exports.featureConfig = {
|
|||||||
toolsFeature: tools_features_1.ToolsFeature.TraceCommandUseBuildMode,
|
toolsFeature: tools_features_1.ToolsFeature.TraceCommandUseBuildMode,
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
},
|
},
|
||||||
[Feature.CliSarifMerge]: {
|
[Feature.CombineSarifFilesDeprecationWarning]: {
|
||||||
envVar: "CODEQL_ACTION_CLI_SARIF_MERGE",
|
envVar: "CODEQL_ACTION_COMBINE_SARIF_FILES_DEPRECATION_WARNING",
|
||||||
// This is guarded by a `supportsFeature` check rather than by a version check.
|
// Independent of the CLI version.
|
||||||
minimumVersion: undefined,
|
minimumVersion: undefined,
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
76
lib/upload-lib.js
generated
76
lib/upload-lib.js
generated
@@ -26,13 +26,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.InvalidSarifUploadError = exports.validateUniqueCategory = exports.waitForProcessing = exports.buildPayload = exports.validateSarifFileSchema = exports.uploadFromActions = exports.findSarifFilesInDir = exports.populateRunAutomationDetails = void 0;
|
exports.InvalidSarifUploadError = exports.validateUniqueCategory = exports.waitForProcessing = exports.buildPayload = exports.validateSarifFileSchema = exports.uploadFromActions = exports.findSarifFilesInDir = exports.populateRunAutomationDetails = exports.shouldShowCombineSarifFilesDeprecationWarning = void 0;
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const zlib_1 = __importDefault(require("zlib"));
|
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"));
|
||||||
@@ -73,14 +74,58 @@ function combineSarifFiles(sarifFiles, logger) {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks whether all the runs in the given SARIF files were produced by CodeQL.
|
* Checks whether all the runs in the given SARIF files were produced by CodeQL.
|
||||||
* @param sarifFiles The list of SARIF files to check.
|
* @param sarifObjects The list of SARIF objects to check.
|
||||||
*/
|
*/
|
||||||
function areAllRunsProducedByCodeQL(sarifFiles) {
|
function areAllRunsProducedByCodeQL(sarifObjects) {
|
||||||
return sarifFiles.every((sarifFile) => {
|
return sarifObjects.every((sarifObject) => {
|
||||||
const sarifObject = JSON.parse(fs.readFileSync(sarifFile, "utf8"));
|
|
||||||
return sarifObject.runs?.every((run) => run.tool?.driver?.name === "CodeQL");
|
return sarifObject.runs?.every((run) => run.tool?.driver?.name === "CodeQL");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function createRunKey(run) {
|
||||||
|
return {
|
||||||
|
name: run.tool?.driver?.name,
|
||||||
|
fullName: run.tool?.driver?.fullName,
|
||||||
|
version: run.tool?.driver?.version,
|
||||||
|
semanticVersion: run.tool?.driver?.semanticVersion,
|
||||||
|
guid: run.tool?.driver?.guid,
|
||||||
|
automationId: run.automationDetails?.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Checks whether all runs in the given SARIF files are unique (based on the
|
||||||
|
* criteria used by Code Scanning to determine analysis categories).
|
||||||
|
* @param sarifObjects The list of SARIF objects to check.
|
||||||
|
*/
|
||||||
|
function areAllRunsUnique(sarifObjects) {
|
||||||
|
const keys = new Set();
|
||||||
|
for (const sarifObject of sarifObjects) {
|
||||||
|
for (const run of sarifObject.runs) {
|
||||||
|
const key = JSON.stringify(createRunKey(run));
|
||||||
|
// If the key already exists, the runs are not unique.
|
||||||
|
if (keys.has(key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
keys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Checks whether the deprecation warning for combining SARIF files should be shown.
|
||||||
|
async function shouldShowCombineSarifFilesDeprecationWarning(sarifObjects, features, githubVersion) {
|
||||||
|
if (!(await features.getValue(feature_flags_1.Feature.CombineSarifFilesDeprecationWarning))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Do not show this warning on GHES versions before 3.14.0
|
||||||
|
if (githubVersion.type === util_1.GitHubVariant.GHES &&
|
||||||
|
semver.lt(githubVersion.version, "3.14.0")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Only give a deprecation warning when not all runs are unique and
|
||||||
|
// we haven't already shown the warning.
|
||||||
|
return (!areAllRunsUnique(sarifObjects) &&
|
||||||
|
!process.env.CODEQL_MERGE_SARIF_DEPRECATION_WARNING);
|
||||||
|
}
|
||||||
|
exports.shouldShowCombineSarifFilesDeprecationWarning = shouldShowCombineSarifFilesDeprecationWarning;
|
||||||
// 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.
|
||||||
@@ -90,8 +135,19 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
|
|||||||
if (sarifFiles.length === 1) {
|
if (sarifFiles.length === 1) {
|
||||||
return JSON.parse(fs.readFileSync(sarifFiles[0], "utf8"));
|
return JSON.parse(fs.readFileSync(sarifFiles[0], "utf8"));
|
||||||
}
|
}
|
||||||
if (!areAllRunsProducedByCodeQL(sarifFiles)) {
|
const sarifObjects = sarifFiles.map((sarifFile) => {
|
||||||
|
return JSON.parse(fs.readFileSync(sarifFile, "utf8"));
|
||||||
|
});
|
||||||
|
const deprecationWarningMessage = gitHubVersion.type === util_1.GitHubVariant.GHES
|
||||||
|
? "and will be removed in GitHub Enterprise Server 3.18"
|
||||||
|
: "and will be removed on June 4, 2025";
|
||||||
|
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)) {
|
||||||
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, features, 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}`);
|
||||||
|
core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
|
||||||
|
}
|
||||||
// If not, use the naive method of combining the files.
|
// If not, use the naive method of combining the files.
|
||||||
return combineSarifFiles(sarifFiles, logger);
|
return combineSarifFiles(sarifFiles, logger);
|
||||||
}
|
}
|
||||||
@@ -119,6 +175,10 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
|
|||||||
}
|
}
|
||||||
if (!(await codeQL.supportsFeature(tools_features_1.ToolsFeature.SarifMergeRunsFromEqualCategory))) {
|
if (!(await codeQL.supportsFeature(tools_features_1.ToolsFeature.SarifMergeRunsFromEqualCategory))) {
|
||||||
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, features, 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}`);
|
||||||
|
core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
|
||||||
|
}
|
||||||
return combineSarifFiles(sarifFiles, logger);
|
return combineSarifFiles(sarifFiles, logger);
|
||||||
}
|
}
|
||||||
const baseTempDir = path.resolve(tempDir, "combined-sarif");
|
const baseTempDir = path.resolve(tempDir, "combined-sarif");
|
||||||
@@ -341,9 +401,7 @@ async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKe
|
|||||||
for (const file of sarifFiles) {
|
for (const file of sarifFiles) {
|
||||||
validateSarifFileSchema(file, logger);
|
validateSarifFileSchema(file, logger);
|
||||||
}
|
}
|
||||||
let sarif = (await features.getValue(feature_flags_1.Feature.CliSarifMerge))
|
let sarif = await combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, logger);
|
||||||
? await combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, logger)
|
|
||||||
: combineSarifFiles(sarifFiles, logger);
|
|
||||||
sarif = await fingerprints.addFingerprints(sarif, sourceRoot, logger);
|
sarif = await fingerprints.addFingerprints(sarif, sourceRoot, logger);
|
||||||
sarif = populateRunAutomationDetails(sarif, category, analysisKey, environment);
|
sarif = populateRunAutomationDetails(sarif, category, analysisKey, environment);
|
||||||
const toolNames = util.getToolNames(sarif);
|
const toolNames = util.getToolNames(sarif);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
44
lib/upload-lib.test.js
generated
44
lib/upload-lib.test.js
generated
@@ -29,6 +29,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"));
|
||||||
@@ -195,6 +196,49 @@ ava_1.default.beforeEach(() => {
|
|||||||
t.deepEqual(loggedMessages.length, 2);
|
t.deepEqual(loggedMessages.length, 2);
|
||||||
t.deepEqual(loggedMessages[1], "Warning: 'not a valid URI' is not a valid URI in 'instance.runs[0].results[0].locations[0].physicalLocation.artifactLocation.uri'.");
|
t.deepEqual(loggedMessages[1], "Warning: 'not a valid URI' is not a valid URI in 'instance.runs[0].results[0].locations[0].physicalLocation.artifactLocation.uri'.");
|
||||||
});
|
});
|
||||||
|
(0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning when on dotcom with feature flag", async (t) => {
|
||||||
|
t.true(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.CombineSarifFilesDeprecationWarning]), {
|
||||||
|
type: util_1.GitHubVariant.DOTCOM,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning without feature flag", async (t) => {
|
||||||
|
t.false(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([]), {
|
||||||
|
type: util_1.GitHubVariant.DOTCOM,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning when on GHES 3.13", async (t) => {
|
||||||
|
t.false(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.CombineSarifFilesDeprecationWarning]), {
|
||||||
|
type: util_1.GitHubVariant.GHES,
|
||||||
|
version: "3.13.2",
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning when on GHES 3.14", async (t) => {
|
||||||
|
t.true(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.CombineSarifFilesDeprecationWarning]), {
|
||||||
|
type: util_1.GitHubVariant.GHES,
|
||||||
|
version: "3.14.0",
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning with only 1 run", async (t) => {
|
||||||
|
t.false(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.CombineSarifFilesDeprecationWarning]), {
|
||||||
|
type: util_1.GitHubVariant.DOTCOM,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning with distinct categories", async (t) => {
|
||||||
|
t.false(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "def"), createMockSarif("def", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.CombineSarifFilesDeprecationWarning]), {
|
||||||
|
type: util_1.GitHubVariant.DOTCOM,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning with distinct tools", async (t) => {
|
||||||
|
t.false(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "abc"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.CombineSarifFilesDeprecationWarning]), {
|
||||||
|
type: util_1.GitHubVariant.DOTCOM,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("shouldShowCombineSarifFilesDeprecationWarning when environment variable is already set", async (t) => {
|
||||||
|
process.env["CODEQL_MERGE_SARIF_DEPRECATION_WARNING"] = "true";
|
||||||
|
t.false(await uploadLib.shouldShowCombineSarifFilesDeprecationWarning([createMockSarif("abc", "def"), createMockSarif("abc", "def")], (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.CombineSarifFilesDeprecationWarning]), {
|
||||||
|
type: util_1.GitHubVariant.DOTCOM,
|
||||||
|
}));
|
||||||
|
});
|
||||||
function createMockSarif(id, tool) {
|
function createMockSarif(id, tool) {
|
||||||
return {
|
return {
|
||||||
runs: [
|
runs: [
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"bundleVersion": "codeql-bundle-v2.17.1",
|
"bundleVersion": "codeql-bundle-v2.17.2",
|
||||||
"cliVersion": "2.17.1",
|
"cliVersion": "2.17.2",
|
||||||
"priorBundleVersion": "codeql-bundle-v2.17.0",
|
"priorBundleVersion": "codeql-bundle-v2.17.1",
|
||||||
"priorCliVersion": "2.17.0"
|
"priorCliVersion": "2.17.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export interface FeatureEnablement {
|
|||||||
*/
|
*/
|
||||||
export enum Feature {
|
export enum Feature {
|
||||||
AutobuildDirectTracingEnabled = "autobuild_direct_tracing_enabled",
|
AutobuildDirectTracingEnabled = "autobuild_direct_tracing_enabled",
|
||||||
CliSarifMerge = "cli_sarif_merge_enabled",
|
CombineSarifFilesDeprecationWarning = "combine_sarif_files_deprecation_warning_enabled",
|
||||||
CppDependencyInstallation = "cpp_dependency_installation_enabled",
|
CppDependencyInstallation = "cpp_dependency_installation_enabled",
|
||||||
CppTrapCachingEnabled = "cpp_trap_caching_enabled",
|
CppTrapCachingEnabled = "cpp_trap_caching_enabled",
|
||||||
DisableJavaBuildlessEnabled = "disable_java_buildless_enabled",
|
DisableJavaBuildlessEnabled = "disable_java_buildless_enabled",
|
||||||
@@ -85,9 +85,9 @@ export const featureConfig: Record<
|
|||||||
toolsFeature: ToolsFeature.TraceCommandUseBuildMode,
|
toolsFeature: ToolsFeature.TraceCommandUseBuildMode,
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
},
|
},
|
||||||
[Feature.CliSarifMerge]: {
|
[Feature.CombineSarifFilesDeprecationWarning]: {
|
||||||
envVar: "CODEQL_ACTION_CLI_SARIF_MERGE",
|
envVar: "CODEQL_ACTION_COMBINE_SARIF_FILES_DEPRECATION_WARNING",
|
||||||
// This is guarded by a `supportsFeature` check rather than by a version check.
|
// Independent of the CLI version.
|
||||||
minimumVersion: undefined,
|
minimumVersion: undefined,
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ 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 { initializeEnvironment, withTmpDir } from "./util";
|
import { GitHubVariant, initializeEnvironment, withTmpDir } from "./util";
|
||||||
|
|
||||||
setupTests(test);
|
setupTests(test);
|
||||||
|
|
||||||
@@ -324,6 +325,106 @@ test("accept results with invalid artifactLocation.uri value", (t) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("shouldShowCombineSarifFilesDeprecationWarning when on dotcom with feature flag", async (t) => {
|
||||||
|
t.true(
|
||||||
|
await uploadLib.shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
|
||||||
|
createFeatures([Feature.CombineSarifFilesDeprecationWarning]),
|
||||||
|
{
|
||||||
|
type: GitHubVariant.DOTCOM,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("shouldShowCombineSarifFilesDeprecationWarning without feature flag", async (t) => {
|
||||||
|
t.false(
|
||||||
|
await uploadLib.shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
|
||||||
|
createFeatures([]),
|
||||||
|
{
|
||||||
|
type: GitHubVariant.DOTCOM,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("shouldShowCombineSarifFilesDeprecationWarning when on GHES 3.13", async (t) => {
|
||||||
|
t.false(
|
||||||
|
await uploadLib.shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
|
||||||
|
createFeatures([Feature.CombineSarifFilesDeprecationWarning]),
|
||||||
|
{
|
||||||
|
type: GitHubVariant.GHES,
|
||||||
|
version: "3.13.2",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("shouldShowCombineSarifFilesDeprecationWarning when on GHES 3.14", async (t) => {
|
||||||
|
t.true(
|
||||||
|
await uploadLib.shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
|
||||||
|
createFeatures([Feature.CombineSarifFilesDeprecationWarning]),
|
||||||
|
{
|
||||||
|
type: GitHubVariant.GHES,
|
||||||
|
version: "3.14.0",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("shouldShowCombineSarifFilesDeprecationWarning with only 1 run", async (t) => {
|
||||||
|
t.false(
|
||||||
|
await uploadLib.shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
[createMockSarif("abc", "def")],
|
||||||
|
createFeatures([Feature.CombineSarifFilesDeprecationWarning]),
|
||||||
|
{
|
||||||
|
type: GitHubVariant.DOTCOM,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("shouldShowCombineSarifFilesDeprecationWarning with distinct categories", async (t) => {
|
||||||
|
t.false(
|
||||||
|
await uploadLib.shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
[createMockSarif("abc", "def"), createMockSarif("def", "def")],
|
||||||
|
createFeatures([Feature.CombineSarifFilesDeprecationWarning]),
|
||||||
|
{
|
||||||
|
type: GitHubVariant.DOTCOM,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("shouldShowCombineSarifFilesDeprecationWarning with distinct tools", async (t) => {
|
||||||
|
t.false(
|
||||||
|
await uploadLib.shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
[createMockSarif("abc", "abc"), createMockSarif("abc", "def")],
|
||||||
|
createFeatures([Feature.CombineSarifFilesDeprecationWarning]),
|
||||||
|
{
|
||||||
|
type: GitHubVariant.DOTCOM,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("shouldShowCombineSarifFilesDeprecationWarning when environment variable is already set", async (t) => {
|
||||||
|
process.env["CODEQL_MERGE_SARIF_DEPRECATION_WARNING"] = "true";
|
||||||
|
|
||||||
|
t.false(
|
||||||
|
await uploadLib.shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
[createMockSarif("abc", "def"), createMockSarif("abc", "def")],
|
||||||
|
createFeatures([Feature.CombineSarifFilesDeprecationWarning]),
|
||||||
|
{
|
||||||
|
type: GitHubVariant.DOTCOM,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
function createMockSarif(id?: string, tool?: string) {
|
function createMockSarif(id?: string, tool?: string) {
|
||||||
return {
|
return {
|
||||||
runs: [
|
runs: [
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ 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";
|
||||||
@@ -14,7 +15,7 @@ import { getGitHubVersion, wrapApiConfigurationError } from "./api-client";
|
|||||||
import { CodeQL, getCodeQL } from "./codeql";
|
import { CodeQL, getCodeQL } from "./codeql";
|
||||||
import { getConfig } from "./config-utils";
|
import { getConfig } from "./config-utils";
|
||||||
import { EnvVar } from "./environment";
|
import { EnvVar } from "./environment";
|
||||||
import { Feature, Features } from "./feature-flags";
|
import { Feature, FeatureEnablement, Features } from "./feature-flags";
|
||||||
import * as fingerprints from "./fingerprints";
|
import * as fingerprints from "./fingerprints";
|
||||||
import { initCodeQL } from "./init";
|
import { initCodeQL } from "./init";
|
||||||
import { Logger } from "./logging";
|
import { Logger } from "./logging";
|
||||||
@@ -24,8 +25,10 @@ import * as util from "./util";
|
|||||||
import {
|
import {
|
||||||
ConfigurationError,
|
ConfigurationError,
|
||||||
getRequiredEnvParam,
|
getRequiredEnvParam,
|
||||||
|
GitHubVariant,
|
||||||
GitHubVersion,
|
GitHubVersion,
|
||||||
SarifFile,
|
SarifFile,
|
||||||
|
SarifRun,
|
||||||
wrapError,
|
wrapError,
|
||||||
} from "./util";
|
} from "./util";
|
||||||
|
|
||||||
@@ -65,20 +68,86 @@ function combineSarifFiles(sarifFiles: string[], logger: Logger): SarifFile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether all the runs in the given SARIF files were produced by CodeQL.
|
* Checks whether all the runs in the given SARIF files were produced by CodeQL.
|
||||||
* @param sarifFiles The list of SARIF files to check.
|
* @param sarifObjects The list of SARIF objects to check.
|
||||||
*/
|
*/
|
||||||
function areAllRunsProducedByCodeQL(sarifFiles: string[]): boolean {
|
function areAllRunsProducedByCodeQL(sarifObjects: SarifFile[]): boolean {
|
||||||
return sarifFiles.every((sarifFile) => {
|
return sarifObjects.every((sarifObject) => {
|
||||||
const sarifObject = JSON.parse(
|
|
||||||
fs.readFileSync(sarifFile, "utf8"),
|
|
||||||
) as SarifFile;
|
|
||||||
|
|
||||||
return sarifObject.runs?.every(
|
return sarifObject.runs?.every(
|
||||||
(run) => run.tool?.driver?.name === "CodeQL",
|
(run) => run.tool?.driver?.name === "CodeQL",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SarifRunKey = {
|
||||||
|
name: string | undefined;
|
||||||
|
fullName: string | undefined;
|
||||||
|
version: string | undefined;
|
||||||
|
semanticVersion: string | undefined;
|
||||||
|
guid: string | undefined;
|
||||||
|
automationId: string | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
function createRunKey(run: SarifRun): SarifRunKey {
|
||||||
|
return {
|
||||||
|
name: run.tool?.driver?.name,
|
||||||
|
fullName: run.tool?.driver?.fullName,
|
||||||
|
version: run.tool?.driver?.version,
|
||||||
|
semanticVersion: run.tool?.driver?.semanticVersion,
|
||||||
|
guid: run.tool?.driver?.guid,
|
||||||
|
automationId: run.automationDetails?.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether all runs in the given SARIF files are unique (based on the
|
||||||
|
* criteria used by Code Scanning to determine analysis categories).
|
||||||
|
* @param sarifObjects The list of SARIF objects to check.
|
||||||
|
*/
|
||||||
|
function areAllRunsUnique(sarifObjects: SarifFile[]): boolean {
|
||||||
|
const keys = new Set<string>();
|
||||||
|
|
||||||
|
for (const sarifObject of sarifObjects) {
|
||||||
|
for (const run of sarifObject.runs) {
|
||||||
|
const key = JSON.stringify(createRunKey(run));
|
||||||
|
|
||||||
|
// If the key already exists, the runs are not unique.
|
||||||
|
if (keys.has(key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
keys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks whether the deprecation warning for combining SARIF files should be shown.
|
||||||
|
export async function shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
sarifObjects: util.SarifFile[],
|
||||||
|
features: FeatureEnablement,
|
||||||
|
githubVersion: GitHubVersion,
|
||||||
|
) {
|
||||||
|
if (!(await features.getValue(Feature.CombineSarifFilesDeprecationWarning))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not show this warning on GHES versions before 3.14.0
|
||||||
|
if (
|
||||||
|
githubVersion.type === GitHubVariant.GHES &&
|
||||||
|
semver.lt(githubVersion.version, "3.14.0")
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only give a deprecation warning when not all runs are unique and
|
||||||
|
// we haven't already shown the warning.
|
||||||
|
return (
|
||||||
|
!areAllRunsUnique(sarifObjects) &&
|
||||||
|
!process.env.CODEQL_MERGE_SARIF_DEPRECATION_WARNING
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -86,7 +155,7 @@ function areAllRunsProducedByCodeQL(sarifFiles: string[]): boolean {
|
|||||||
async function combineSarifFilesUsingCLI(
|
async function combineSarifFilesUsingCLI(
|
||||||
sarifFiles: string[],
|
sarifFiles: string[],
|
||||||
gitHubVersion: GitHubVersion,
|
gitHubVersion: GitHubVersion,
|
||||||
features: Features,
|
features: FeatureEnablement,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
): Promise<SarifFile> {
|
): Promise<SarifFile> {
|
||||||
logger.info("Combining SARIF files using the CodeQL CLI");
|
logger.info("Combining SARIF files using the CodeQL CLI");
|
||||||
@@ -94,11 +163,35 @@ async function combineSarifFilesUsingCLI(
|
|||||||
return JSON.parse(fs.readFileSync(sarifFiles[0], "utf8")) as SarifFile;
|
return JSON.parse(fs.readFileSync(sarifFiles[0], "utf8")) as SarifFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!areAllRunsProducedByCodeQL(sarifFiles)) {
|
const sarifObjects = sarifFiles.map((sarifFile): SarifFile => {
|
||||||
|
return JSON.parse(fs.readFileSync(sarifFile, "utf8")) as SarifFile;
|
||||||
|
});
|
||||||
|
|
||||||
|
const deprecationWarningMessage =
|
||||||
|
gitHubVersion.type === GitHubVariant.GHES
|
||||||
|
? "and will be removed in GitHub Enterprise Server 3.18"
|
||||||
|
: "and will be removed on June 4, 2025";
|
||||||
|
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)) {
|
||||||
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.",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
await shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
sarifObjects,
|
||||||
|
features,
|
||||||
|
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}`,
|
||||||
|
);
|
||||||
|
core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
|
||||||
|
}
|
||||||
|
|
||||||
// If not, use the naive method of combining the files.
|
// If not, use the naive method of combining the files.
|
||||||
return combineSarifFiles(sarifFiles, logger);
|
return combineSarifFiles(sarifFiles, logger);
|
||||||
}
|
}
|
||||||
@@ -149,6 +242,19 @@ async function combineSarifFilesUsingCLI(
|
|||||||
"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.",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
await shouldShowCombineSarifFilesDeprecationWarning(
|
||||||
|
sarifObjects,
|
||||||
|
features,
|
||||||
|
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}`,
|
||||||
|
);
|
||||||
|
core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
|
||||||
|
}
|
||||||
|
|
||||||
return combineSarifFiles(sarifFiles, logger);
|
return combineSarifFiles(sarifFiles, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,14 +602,12 @@ async function uploadFiles(
|
|||||||
validateSarifFileSchema(file, logger);
|
validateSarifFileSchema(file, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
let sarif = (await features.getValue(Feature.CliSarifMerge))
|
let sarif = await combineSarifFilesUsingCLI(
|
||||||
? await combineSarifFilesUsingCLI(
|
|
||||||
sarifFiles,
|
sarifFiles,
|
||||||
gitHubVersion,
|
gitHubVersion,
|
||||||
features,
|
features,
|
||||||
logger,
|
logger,
|
||||||
)
|
);
|
||||||
: combineSarifFiles(sarifFiles, logger);
|
|
||||||
sarif = await fingerprints.addFingerprints(sarif, sourceRoot, logger);
|
sarif = await fingerprints.addFingerprints(sarif, sourceRoot, logger);
|
||||||
|
|
||||||
sarif = populateRunAutomationDetails(
|
sarif = populateRunAutomationDetails(
|
||||||
|
|||||||
@@ -56,8 +56,11 @@ export interface SarifFile {
|
|||||||
export interface SarifRun {
|
export interface SarifRun {
|
||||||
tool?: {
|
tool?: {
|
||||||
driver?: {
|
driver?: {
|
||||||
|
guid?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
fullName?: string;
|
||||||
semanticVersion?: string;
|
semanticVersion?: string;
|
||||||
|
version?: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
automationDetails?: {
|
automationDetails?: {
|
||||||
|
|||||||
Reference in New Issue
Block a user