Compare commits

..

6 Commits

Author SHA1 Message Date
Alex Eyers-Taylor 5a8e345008 Fix linitng issues. 2025-10-10 14:26:40 +01:00
Alex Eyers-Taylor f030ca35d0 Pass changed files in code ratehr than by file-system. 2025-10-09 21:05:00 +01:00
Alex Eyers-Taylor 6a32dd9374 Include diff-edidted files in overlay changes. 2025-10-09 20:47:37 +01:00
Alex Eyers-Taylor 4c0acfe29e Consume precomputed diff ranges in analyze and avoid getting them from the API. 2025-10-09 20:47:04 +01:00
Alex Eyers-Taylor 9bb8375aed Persist PR diff ranges early during init
We don't use them yet and will re-save them during analysis.
2025-10-09 20:46:30 +01:00
Alex Eyers-Taylor 56b69c76aa Extract diff range computation into utils for reuse 2025-10-09 20:46:16 +01:00
36 changed files with 1632 additions and 1843 deletions
+2 -8
View File
@@ -16,12 +16,9 @@ updates:
- dependency-name: "eslint-plugin-import"
versions: [">=2.30.0"]
groups:
npm-minor:
npm:
patterns:
- "*"
update-types:
- "minor"
- "patch"
- package-ecosystem: github-actions
directories:
- "/.github/workflows"
@@ -31,9 +28,6 @@ updates:
labels:
- Rebuild
groups:
actions-minor:
actions:
patterns:
- "*"
update-types:
- "minor"
- "patch"
+4 -4
View File
@@ -371,10 +371,10 @@ def main():
# releases.
run_git('revert', vOlder_update_commits[0], '--no-edit')
# Also revert the "Rebuild" commit created by Actions.
rebuild_commit = run_git('log', '--grep', '^Rebuild$', '--format=%H').split()[0]
print(f' Reverting {rebuild_commit}')
run_git('revert', rebuild_commit, '--no-edit')
# Also revert the "Update checked-in dependencies" commit created by Actions.
update_dependencies_commit = run_git('log', '--grep', '^Update checked-in dependencies', '--format=%H').split()[0]
print(f' Reverting {update_dependencies_commit}')
run_git('revert', update_dependencies_commit, '--no-edit')
else:
print(' Nothing to revert.')
+1 -1
View File
@@ -56,7 +56,7 @@ jobs:
use-all-platform-bundle: 'false'
setup-kotlin: 'true'
- name: Set up Ruby
uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a # v1.263.0
with:
ruby-version: 2.6
- name: Install Code Scanning integration
@@ -146,7 +146,6 @@ jobs:
private-key: ${{ secrets.AUTOMATION_PRIVATE_KEY }}
- name: Create the GitHub release
if: steps.check.outputs.exists != 'true'
env:
PARTIAL_CHANGELOG: "${{ runner.temp }}/partial_changelog.md"
VERSION: "${{ steps.getVersion.outputs.version }}"
+1 -1
View File
@@ -73,7 +73,7 @@ jobs:
run: npm run lint-ci
- name: Upload sarif
uses: github/codeql-action/upload-sarif@v4
uses: github/codeql-action/upload-sarif@v3
if: matrix.os == 'ubuntu-latest' && matrix.node-version == 24
with:
sarif_file: eslint.sarif
-4
View File
@@ -6,10 +6,6 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
No user facing changes.
## 4.30.8 - 10 Oct 2025
No user facing changes.
## 4.30.7 - 06 Oct 2025
- [v4+ only] The CodeQL Action now runs on Node.js v24. [#3169](https://github.com/github/codeql-action/pull/3169)
+37 -34
View File
@@ -24680,9 +24680,6 @@ var require_identifiers = __commonJS({
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
@@ -24789,25 +24786,7 @@ var require_semver = __commonJS({
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
@@ -25568,7 +25547,6 @@ var require_range = __commonJS({
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug2("comp", comp, options);
comp = replaceCarets(comp, options);
debug2("caret", comp);
@@ -26460,7 +26438,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.30.9",
version: "4.30.8",
private: true,
description: "CodeQL action",
scripts: {
@@ -26509,7 +26487,7 @@ var require_package = __commonJS({
long: "^5.3.2",
"node-forge": "^1.3.1",
octokit: "^5.0.3",
semver: "^7.7.3",
semver: "^7.7.2",
uuid: "^13.0.0"
},
devDependencies: {
@@ -26527,7 +26505,7 @@ var require_package = __commonJS({
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
ava: "^6.4.1",
esbuild: "^0.25.10",
@@ -117783,12 +117761,41 @@ async function readBaseDatabaseOidsFile(config, logger) {
function getBaseDatabaseOidsFilePath(config) {
return path2.join(config.dbLocation, "base-database-oids.json");
}
async function writeOverlayChangesFile(config, sourceRoot, logger) {
async function writeOverlayChangesFile(config, sourceRoot, prDiffChangedFiles, logger) {
const baseFileOids = await readBaseDatabaseOidsFile(config, logger);
const overlayFileOids = await getFileOidsUnderPath(sourceRoot);
const changedFiles = computeChangedFiles(baseFileOids, overlayFileOids);
const originalCount = changedFiles.length;
let extraAddedCount = 0;
try {
if (prDiffChangedFiles && prDiffChangedFiles.size > 0) {
const existing = new Set(changedFiles);
for (const f of prDiffChangedFiles) {
if (!existing.has(f)) {
if (overlayFileOids[f] !== void 0 || fs2.existsSync(path2.join(sourceRoot, f))) {
existing.add(f);
changedFiles.push(f);
extraAddedCount++;
}
}
}
if (extraAddedCount > 0) {
logger.debug(
`Added ${extraAddedCount} file(s) from PR diff ranges into overlay: ${changedFiles.slice(-extraAddedCount).join(", ")}`
);
} else {
logger.debug(
"All diff range files were already present in the diff from the base database."
);
}
}
} catch (e) {
logger.debug(
`Failed while attempting to add diff range files in overlay: ${e.message || e}`
);
}
logger.info(
`Found ${changedFiles.length} changed file(s) under ${sourceRoot}.`
`Found ${originalCount} natural changed file(s); added from diff ${extraAddedCount}; total ${changedFiles.length} under ${sourceRoot}.`
);
const changedFilesJson = JSON.stringify({ changes: changedFiles });
const overlayChangesFile = path2.join(
@@ -117828,11 +117835,6 @@ function isSafeArtifactUpload(codeQlVersion) {
// src/feature-flags.ts
var featureConfig = {
["allow_toolcache_input" /* AllowToolcacheInput */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: void 0
},
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
@@ -118162,7 +118164,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
async isScannedLanguage(language) {
return !await this.isTracedLanguage(language);
},
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, logger) {
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, prDiffChangedFiles, logger) {
const extraArgs = config.languages.map(
(language) => `--language=${language}`
);
@@ -118197,6 +118199,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
const overlayChangesFile = await writeOverlayChangesFile(
config,
sourceRoot,
prDiffChangedFiles,
logger
);
extraArgs.push(`--overlay-changes=${overlayChangesFile}`);
+69 -227
View File
@@ -30529,9 +30529,6 @@ var require_identifiers = __commonJS({
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
@@ -30638,25 +30635,7 @@ var require_semver = __commonJS({
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
@@ -31417,7 +31396,6 @@ var require_range = __commonJS({
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug3("comp", comp, options);
comp = replaceCarets(comp, options);
debug3("caret", comp);
@@ -32309,7 +32287,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.30.9",
version: "4.30.8",
private: true,
description: "CodeQL action",
scripts: {
@@ -32358,7 +32336,7 @@ var require_package = __commonJS({
long: "^5.3.2",
"node-forge": "^1.3.1",
octokit: "^5.0.3",
semver: "^7.7.3",
semver: "^7.7.2",
uuid: "^13.0.0"
},
devDependencies: {
@@ -32376,7 +32354,7 @@ var require_package = __commonJS({
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
ava: "^6.4.1",
esbuild: "^0.25.10",
@@ -90134,29 +90112,6 @@ var persistInputs = function() {
);
core4.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables));
};
function getPullRequestBranches() {
const pullRequest = github.context.payload.pull_request;
if (pullRequest) {
return {
base: pullRequest.base.ref,
// We use the head label instead of the head ref here, because the head
// ref lacks owner information and by itself does not uniquely identify
// the head branch (which may be in a forked repository).
head: pullRequest.head.label
};
}
const codeScanningRef = process.env.CODE_SCANNING_REF;
const codeScanningBaseBranch = process.env.CODE_SCANNING_BASE_BRANCH;
if (codeScanningRef && codeScanningBaseBranch) {
return {
base: codeScanningBaseBranch,
// PR analysis under Default Setup analyzes the PR head commit instead of
// the merge commit, so we can use the provided ref directly.
head: codeScanningRef
};
}
return void 0;
}
var qualityCategoryMapping = {
"c#": "csharp",
cpp: "c-cpp",
@@ -90215,6 +90170,9 @@ var path16 = __toESM(require("path"));
var import_perf_hooks2 = require("perf_hooks");
var io5 = __toESM(require_io());
// src/autobuild.ts
var core11 = __toESM(require_core());
// src/api-client.ts
var core5 = __toESM(require_core());
var githubUtils = __toESM(require_utils4());
@@ -90384,9 +90342,6 @@ function wrapApiConfigurationError(e) {
return e;
}
// src/autobuild.ts
var core11 = __toESM(require_core());
// src/codeql.ts
var fs14 = __toESM(require("fs"));
var path14 = __toESM(require("path"));
@@ -90963,12 +90918,41 @@ async function readBaseDatabaseOidsFile(config, logger) {
function getBaseDatabaseOidsFilePath(config) {
return path7.join(config.dbLocation, "base-database-oids.json");
}
async function writeOverlayChangesFile(config, sourceRoot, logger) {
async function writeOverlayChangesFile(config, sourceRoot, prDiffChangedFiles, logger) {
const baseFileOids = await readBaseDatabaseOidsFile(config, logger);
const overlayFileOids = await getFileOidsUnderPath(sourceRoot);
const changedFiles = computeChangedFiles(baseFileOids, overlayFileOids);
const originalCount = changedFiles.length;
let extraAddedCount = 0;
try {
if (prDiffChangedFiles && prDiffChangedFiles.size > 0) {
const existing = new Set(changedFiles);
for (const f of prDiffChangedFiles) {
if (!existing.has(f)) {
if (overlayFileOids[f] !== void 0 || fs6.existsSync(path7.join(sourceRoot, f))) {
existing.add(f);
changedFiles.push(f);
extraAddedCount++;
}
}
}
if (extraAddedCount > 0) {
logger.debug(
`Added ${extraAddedCount} file(s) from PR diff ranges into overlay: ${changedFiles.slice(-extraAddedCount).join(", ")}`
);
} else {
logger.debug(
"All diff range files were already present in the diff from the base database."
);
}
}
} catch (e) {
logger.debug(
`Failed while attempting to add diff range files in overlay: ${e.message || e}`
);
}
logger.info(
`Found ${changedFiles.length} changed file(s) under ${sourceRoot}.`
`Found ${originalCount} natural changed file(s); added from diff ${extraAddedCount}; total ${changedFiles.length} under ${sourceRoot}.`
);
const changedFilesJson = JSON.stringify({ changes: changedFiles });
const overlayChangesFile = path7.join(
@@ -91117,11 +91101,6 @@ var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_";
var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled";
var CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0";
var featureConfig = {
["allow_toolcache_input" /* AllowToolcacheInput */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: void 0
},
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
@@ -91561,34 +91540,9 @@ var GitHubFeatureFlags = class {
};
// src/diff-informed-analysis-utils.ts
async function getDiffInformedAnalysisBranches(codeql, features, logger) {
if (!await features.getValue("diff_informed_queries" /* DiffInformedQueries */, codeql)) {
return void 0;
}
const gitHubVersion = await getGitHubVersion();
if (gitHubVersion.type === 1 /* GHES */ && satisfiesGHESVersion(gitHubVersion.version, "<3.19", true)) {
return void 0;
}
const branches = getPullRequestBranches();
if (!branches) {
logger.info(
"Not performing diff-informed analysis because we are not analyzing a pull request."
);
}
return branches;
}
function getDiffRangesJsonFilePath() {
return path9.join(getTemporaryDirectory(), "pr-diff-range.json");
}
function writeDiffRangesJsonFile(logger, ranges) {
const jsonContents = JSON.stringify(ranges, null, 2);
const jsonFilePath = getDiffRangesJsonFilePath();
fs8.writeFileSync(jsonFilePath, jsonContents);
logger.debug(
`Wrote pr-diff-range JSON file to ${jsonFilePath}:
${jsonContents}`
);
}
function readDiffRangesJsonFile(logger) {
const jsonFilePath = getDiffRangesJsonFilePath();
if (!fs8.existsSync(jsonFilePath)) {
@@ -92326,7 +92280,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) {
}
return void 0;
}
async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) {
async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, logger) {
if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) {
logger.info(`Using CodeQL CLI from local path ${toolsInput}`);
const compressionMethod2 = inferCompressionMethod(toolsInput);
@@ -92365,10 +92319,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian
}
} else if (toolsInput !== void 0 && toolsInput === CODEQL_TOOLCACHE_INPUT) {
let latestToolcacheVersion;
const allowToolcacheValueFF = await features.getValue(
"allow_toolcache_input" /* AllowToolcacheInput */
);
const allowToolcacheValue = allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode());
const allowToolcacheValue = isDynamicWorkflow() || isInTestMode();
if (allowToolcacheValue) {
logger.info(
`Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.`
@@ -92384,15 +92335,9 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian
`Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...`
);
} else {
if (allowToolcacheValueFF) {
logger.warning(
`Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`
);
} else {
logger.info(
`Ignoring 'tools: ${toolsInput}' because the feature is not enabled.`
);
}
logger.warning(
`Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`
);
}
cliVersion2 = defaultCliVersion.cliVersion;
tagName = defaultCliVersion.tagName;
@@ -92605,7 +92550,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) {
}
return cliVersion2;
}
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) {
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
if (!await isBinaryAccessible("tar", logger)) {
throw new ConfigurationError(
"Could not find tar in PATH, so unable to extract CodeQL bundle."
@@ -92618,7 +92563,6 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau
apiDetails,
variant,
zstdAvailability.available,
features,
logger
);
let codeqlFolder;
@@ -92776,7 +92720,7 @@ var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13";
var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19";
var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
var CODEQL_VERSION_CACHE_CLEANUP = "2.17.1";
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) {
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger, checkVersion) {
try {
const {
codeqlFolder,
@@ -92790,7 +92734,6 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV
tempDir,
variant,
defaultCliVersion,
features,
logger
);
logger.debug(
@@ -92870,7 +92813,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
async isScannedLanguage(language) {
return !await this.isTracedLanguage(language);
},
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, logger) {
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, prDiffChangedFiles, logger) {
const extraArgs = config.languages.map(
(language) => `--language=${language}`
);
@@ -92905,6 +92848,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
const overlayChangesFile = await writeOverlayChangesFile(
config,
sourceRoot,
prDiffChangedFiles,
logger
);
extraArgs.push(`--overlay-changes=${overlayChangesFile}`);
@@ -93674,14 +93618,31 @@ async function finalizeDatabaseCreation(codeql, config, threadsFlag, memoryFlag,
trap_import_duration_ms: Math.round(trapImportTime)
};
}
async function setupDiffInformedQueryRun(branches, logger) {
async function setupDiffInformedQueryRun(logger) {
return await withGroupAsync(
"Generating diff range extension pack",
async () => {
let diffRanges;
try {
diffRanges = readDiffRangesJsonFile(logger);
} catch (e) {
logger.debug(
`Failed to read precomputed diff ranges: ${getErrorMessage(e)}`
);
diffRanges = void 0;
}
if (diffRanges === void 0) {
logger.info(
"No precomputed diff ranges found; skipping diff-informed analysis stage."
);
return void 0;
}
const fileCount = new Set(
diffRanges.filter((r) => r.path).map((r) => r.path)
).size;
logger.info(
`Calculating diff ranges for ${branches.base}...${branches.head}`
`Using precomputed diff ranges (${diffRanges.length} ranges across ${fileCount} files).`
);
const diffRanges = await getPullRequestEditedDiffRanges(branches, logger);
const packDir = writeDiffRangeDataExtensionPack(logger, diffRanges);
if (packDir === void 0) {
logger.warning(
@@ -93696,117 +93657,6 @@ async function setupDiffInformedQueryRun(branches, logger) {
}
);
}
async function getPullRequestEditedDiffRanges(branches, logger) {
const fileDiffs = await getFileDiffsWithBasehead(branches, logger);
if (fileDiffs === void 0) {
return void 0;
}
if (fileDiffs.length >= 300) {
logger.warning(
`Cannot retrieve the full diff because there are too many (${fileDiffs.length}) changed files in the pull request.`
);
return void 0;
}
const results = [];
for (const filediff of fileDiffs) {
const diffRanges = getDiffRanges(filediff, logger);
if (diffRanges === void 0) {
return void 0;
}
results.push(...diffRanges);
}
return results;
}
async function getFileDiffsWithBasehead(branches, logger) {
const repositoryNwo = getRepositoryNwoFromEnv(
"CODE_SCANNING_REPOSITORY",
"GITHUB_REPOSITORY"
);
const basehead = `${branches.base}...${branches.head}`;
try {
const response = await getApiClient().rest.repos.compareCommitsWithBasehead(
{
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
basehead,
per_page: 1
}
);
logger.debug(
`Response from compareCommitsWithBasehead(${basehead}):
${JSON.stringify(response, null, 2)}`
);
return response.data.files;
} catch (error2) {
if (error2.status) {
logger.warning(`Error retrieving diff ${basehead}: ${error2.message}`);
logger.debug(
`Error running compareCommitsWithBasehead(${basehead}):
Request: ${JSON.stringify(error2.request, null, 2)}
Error Response: ${JSON.stringify(error2.response, null, 2)}`
);
return void 0;
} else {
throw error2;
}
}
}
function getDiffRanges(fileDiff, logger) {
const filename = path16.join(getRequiredInput("checkout_path"), fileDiff.filename).replaceAll(path16.sep, "/");
if (fileDiff.patch === void 0) {
if (fileDiff.changes === 0) {
return [];
}
return [
{
path: filename,
startLine: 0,
endLine: 0
}
];
}
let currentLine = 0;
let additionRangeStartLine = void 0;
const diffRanges = [];
const diffLines = fileDiff.patch.split("\n");
diffLines.push(" ");
for (const diffLine of diffLines) {
if (diffLine.startsWith("-")) {
continue;
}
if (diffLine.startsWith("+")) {
if (additionRangeStartLine === void 0) {
additionRangeStartLine = currentLine;
}
currentLine++;
continue;
}
if (additionRangeStartLine !== void 0) {
diffRanges.push({
path: filename,
startLine: additionRangeStartLine,
endLine: currentLine - 1
});
additionRangeStartLine = void 0;
}
if (diffLine.startsWith("@@ ")) {
const match = diffLine.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
if (match === null) {
logger.warning(
`Cannot parse diff hunk header for ${fileDiff.filename}: ${diffLine}`
);
return void 0;
}
currentLine = parseInt(match[1], 10);
continue;
}
if (diffLine.startsWith(" ")) {
currentLine++;
continue;
}
}
return diffRanges;
}
function writeDiffRangeDataExtensionPack(logger, ranges) {
if (ranges === void 0) {
return void 0;
@@ -93855,7 +93705,6 @@ extensions:
`Wrote pr-diff-range extension pack to ${extensionFilePath}:
${extensionContents}`
);
writeDiffRangesJsonFile(logger, ranges);
return diffRangeDir;
}
var defaultSuites = /* @__PURE__ */ new Set([
@@ -95442,7 +95291,7 @@ async function addFingerprints(sarif, sourceRoot, logger) {
// src/init.ts
var toolrunner4 = __toESM(require_toolrunner());
var io6 = __toESM(require_io());
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) {
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
logger.startGroup("Setup CodeQL tools");
const {
codeql,
@@ -95456,7 +95305,6 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe
tempDir,
variant,
defaultCliVersion,
features,
logger,
true
);
@@ -95603,7 +95451,6 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
tempDir,
gitHubVersion.type,
codeQLDefaultVersionInfo,
features,
logger
);
codeQL = initCodeQLResult.codeql;
@@ -96246,12 +96093,7 @@ async function run() {
getOptionalInput("ram") || process.env["CODEQL_RAM"],
logger
);
const branches = await getDiffInformedAnalysisBranches(
codeql,
features,
logger
);
const diffRangePackDir = branches ? await setupDiffInformedQueryRun(branches, logger) : void 0;
const diffRangePackDir = await setupDiffInformedQueryRun(logger);
await warnIfGoInstalledAfterInit(config, logger);
await runAutobuildIfLegacyGoWorkflow(config, logger);
dbCreationTimings = await runFinalize(
+37 -34
View File
@@ -24680,9 +24680,6 @@ var require_identifiers = __commonJS({
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
@@ -24789,25 +24786,7 @@ var require_semver = __commonJS({
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
@@ -25568,7 +25547,6 @@ var require_range = __commonJS({
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug3("comp", comp, options);
comp = replaceCarets(comp, options);
debug3("caret", comp);
@@ -26460,7 +26438,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.30.9",
version: "4.30.8",
private: true,
description: "CodeQL action",
scripts: {
@@ -26509,7 +26487,7 @@ var require_package = __commonJS({
long: "^5.3.2",
"node-forge": "^1.3.1",
octokit: "^5.0.3",
semver: "^7.7.3",
semver: "^7.7.2",
uuid: "^13.0.0"
},
devDependencies: {
@@ -26527,7 +26505,7 @@ var require_package = __commonJS({
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
ava: "^6.4.1",
esbuild: "^0.25.10",
@@ -78523,12 +78501,41 @@ async function readBaseDatabaseOidsFile(config, logger) {
function getBaseDatabaseOidsFilePath(config) {
return path2.join(config.dbLocation, "base-database-oids.json");
}
async function writeOverlayChangesFile(config, sourceRoot, logger) {
async function writeOverlayChangesFile(config, sourceRoot, prDiffChangedFiles, logger) {
const baseFileOids = await readBaseDatabaseOidsFile(config, logger);
const overlayFileOids = await getFileOidsUnderPath(sourceRoot);
const changedFiles = computeChangedFiles(baseFileOids, overlayFileOids);
const originalCount = changedFiles.length;
let extraAddedCount = 0;
try {
if (prDiffChangedFiles && prDiffChangedFiles.size > 0) {
const existing = new Set(changedFiles);
for (const f of prDiffChangedFiles) {
if (!existing.has(f)) {
if (overlayFileOids[f] !== void 0 || fs2.existsSync(path2.join(sourceRoot, f))) {
existing.add(f);
changedFiles.push(f);
extraAddedCount++;
}
}
}
if (extraAddedCount > 0) {
logger.debug(
`Added ${extraAddedCount} file(s) from PR diff ranges into overlay: ${changedFiles.slice(-extraAddedCount).join(", ")}`
);
} else {
logger.debug(
"All diff range files were already present in the diff from the base database."
);
}
}
} catch (e) {
logger.debug(
`Failed while attempting to add diff range files in overlay: ${e.message || e}`
);
}
logger.info(
`Found ${changedFiles.length} changed file(s) under ${sourceRoot}.`
`Found ${originalCount} natural changed file(s); added from diff ${extraAddedCount}; total ${changedFiles.length} under ${sourceRoot}.`
);
const changedFilesJson = JSON.stringify({ changes: changedFiles });
const overlayChangesFile = path2.join(
@@ -78566,11 +78573,6 @@ function isSupportedToolsFeature(versionInfo, feature) {
var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_";
var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled";
var featureConfig = {
["allow_toolcache_input" /* AllowToolcacheInput */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: void 0
},
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
@@ -79197,7 +79199,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
async isScannedLanguage(language) {
return !await this.isTracedLanguage(language);
},
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, logger) {
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, prDiffChangedFiles, logger) {
const extraArgs = config.languages.map(
(language) => `--language=${language}`
);
@@ -79232,6 +79234,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
const overlayChangesFile = await writeOverlayChangesFile(
config,
sourceRoot,
prDiffChangedFiles,
logger
);
extraArgs.push(`--overlay-changes=${overlayChangesFile}`);
+45 -55
View File
@@ -30529,9 +30529,6 @@ var require_identifiers = __commonJS({
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
@@ -30638,25 +30635,7 @@ var require_semver = __commonJS({
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
@@ -31417,7 +31396,6 @@ var require_range = __commonJS({
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug3("comp", comp, options);
comp = replaceCarets(comp, options);
debug3("caret", comp);
@@ -32309,7 +32287,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.30.9",
version: "4.30.8",
private: true,
description: "CodeQL action",
scripts: {
@@ -32358,7 +32336,7 @@ var require_package = __commonJS({
long: "^5.3.2",
"node-forge": "^1.3.1",
octokit: "^5.0.3",
semver: "^7.7.3",
semver: "^7.7.2",
uuid: "^13.0.0"
},
devDependencies: {
@@ -32376,7 +32354,7 @@ var require_package = __commonJS({
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
ava: "^6.4.1",
esbuild: "^0.25.10",
@@ -129207,12 +129185,41 @@ async function readBaseDatabaseOidsFile(config, logger) {
function getBaseDatabaseOidsFilePath(config) {
return path7.join(config.dbLocation, "base-database-oids.json");
}
async function writeOverlayChangesFile(config, sourceRoot, logger) {
async function writeOverlayChangesFile(config, sourceRoot, prDiffChangedFiles, logger) {
const baseFileOids = await readBaseDatabaseOidsFile(config, logger);
const overlayFileOids = await getFileOidsUnderPath(sourceRoot);
const changedFiles = computeChangedFiles(baseFileOids, overlayFileOids);
const originalCount = changedFiles.length;
let extraAddedCount = 0;
try {
if (prDiffChangedFiles && prDiffChangedFiles.size > 0) {
const existing = new Set(changedFiles);
for (const f of prDiffChangedFiles) {
if (!existing.has(f)) {
if (overlayFileOids[f] !== void 0 || fs6.existsSync(path7.join(sourceRoot, f))) {
existing.add(f);
changedFiles.push(f);
extraAddedCount++;
}
}
}
if (extraAddedCount > 0) {
logger.debug(
`Added ${extraAddedCount} file(s) from PR diff ranges into overlay: ${changedFiles.slice(-extraAddedCount).join(", ")}`
);
} else {
logger.debug(
"All diff range files were already present in the diff from the base database."
);
}
}
} catch (e) {
logger.debug(
`Failed while attempting to add diff range files in overlay: ${e.message || e}`
);
}
logger.info(
`Found ${changedFiles.length} changed file(s) under ${sourceRoot}.`
`Found ${originalCount} natural changed file(s); added from diff ${extraAddedCount}; total ${changedFiles.length} under ${sourceRoot}.`
);
const changedFilesJson = JSON.stringify({ changes: changedFiles });
const overlayChangesFile = path7.join(
@@ -129255,11 +129262,6 @@ var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_";
var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled";
var CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0";
var featureConfig = {
["allow_toolcache_input" /* AllowToolcacheInput */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: void 0
},
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
@@ -130308,7 +130310,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) {
}
return void 0;
}
async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) {
async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, logger) {
if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) {
logger.info(`Using CodeQL CLI from local path ${toolsInput}`);
const compressionMethod2 = inferCompressionMethod(toolsInput);
@@ -130347,10 +130349,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian
}
} else if (toolsInput !== void 0 && toolsInput === CODEQL_TOOLCACHE_INPUT) {
let latestToolcacheVersion;
const allowToolcacheValueFF = await features.getValue(
"allow_toolcache_input" /* AllowToolcacheInput */
);
const allowToolcacheValue = allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode());
const allowToolcacheValue = isDynamicWorkflow() || isInTestMode();
if (allowToolcacheValue) {
logger.info(
`Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.`
@@ -130366,15 +130365,9 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian
`Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...`
);
} else {
if (allowToolcacheValueFF) {
logger.warning(
`Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`
);
} else {
logger.info(
`Ignoring 'tools: ${toolsInput}' because the feature is not enabled.`
);
}
logger.warning(
`Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`
);
}
cliVersion2 = defaultCliVersion.cliVersion;
tagName = defaultCliVersion.tagName;
@@ -130587,7 +130580,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) {
}
return cliVersion2;
}
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) {
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
if (!await isBinaryAccessible("tar", logger)) {
throw new ConfigurationError(
"Could not find tar in PATH, so unable to extract CodeQL bundle."
@@ -130600,7 +130593,6 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau
apiDetails,
variant,
zstdAvailability.available,
features,
logger
);
let codeqlFolder;
@@ -130725,7 +130717,7 @@ var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13";
var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19";
var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
var CODEQL_VERSION_CACHE_CLEANUP = "2.17.1";
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) {
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger, checkVersion) {
try {
const {
codeqlFolder,
@@ -130739,7 +130731,6 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV
tempDir,
variant,
defaultCliVersion,
features,
logger
);
logger.debug(
@@ -130819,7 +130810,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
async isScannedLanguage(language) {
return !await this.isTracedLanguage(language);
},
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, logger) {
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, prDiffChangedFiles, logger) {
const extraArgs = config.languages.map(
(language) => `--language=${language}`
);
@@ -130854,6 +130845,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
const overlayChangesFile = await writeOverlayChangesFile(
config,
sourceRoot,
prDiffChangedFiles,
logger
);
extraArgs.push(`--overlay-changes=${overlayChangesFile}`);
@@ -132918,7 +132910,7 @@ async function addFingerprints(sarif, sourceRoot, logger) {
// src/init.ts
var toolrunner4 = __toESM(require_toolrunner());
var io6 = __toESM(require_io());
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) {
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
logger.startGroup("Setup CodeQL tools");
const {
codeql,
@@ -132932,7 +132924,6 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe
tempDir,
variant,
defaultCliVersion,
features,
logger,
true
);
@@ -133079,7 +133070,6 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
tempDir,
gitHubVersion.type,
codeQLDefaultVersionInfo,
features,
logger
);
codeQL = initCodeQLResult.codeql;
+605 -450
View File
File diff suppressed because it is too large Load Diff
+37 -34
View File
@@ -24680,9 +24680,6 @@ var require_identifiers = __commonJS({
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
@@ -24789,25 +24786,7 @@ var require_semver = __commonJS({
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
@@ -25568,7 +25547,6 @@ var require_range = __commonJS({
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug3("comp", comp, options);
comp = replaceCarets(comp, options);
debug3("caret", comp);
@@ -26460,7 +26438,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.30.9",
version: "4.30.8",
private: true,
description: "CodeQL action",
scripts: {
@@ -26509,7 +26487,7 @@ var require_package = __commonJS({
long: "^5.3.2",
"node-forge": "^1.3.1",
octokit: "^5.0.3",
semver: "^7.7.3",
semver: "^7.7.2",
uuid: "^13.0.0"
},
devDependencies: {
@@ -26527,7 +26505,7 @@ var require_package = __commonJS({
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
ava: "^6.4.1",
esbuild: "^0.25.10",
@@ -78516,12 +78494,41 @@ async function readBaseDatabaseOidsFile(config, logger) {
function getBaseDatabaseOidsFilePath(config) {
return path2.join(config.dbLocation, "base-database-oids.json");
}
async function writeOverlayChangesFile(config, sourceRoot, logger) {
async function writeOverlayChangesFile(config, sourceRoot, prDiffChangedFiles, logger) {
const baseFileOids = await readBaseDatabaseOidsFile(config, logger);
const overlayFileOids = await getFileOidsUnderPath(sourceRoot);
const changedFiles = computeChangedFiles(baseFileOids, overlayFileOids);
const originalCount = changedFiles.length;
let extraAddedCount = 0;
try {
if (prDiffChangedFiles && prDiffChangedFiles.size > 0) {
const existing = new Set(changedFiles);
for (const f of prDiffChangedFiles) {
if (!existing.has(f)) {
if (overlayFileOids[f] !== void 0 || fs2.existsSync(path2.join(sourceRoot, f))) {
existing.add(f);
changedFiles.push(f);
extraAddedCount++;
}
}
}
if (extraAddedCount > 0) {
logger.debug(
`Added ${extraAddedCount} file(s) from PR diff ranges into overlay: ${changedFiles.slice(-extraAddedCount).join(", ")}`
);
} else {
logger.debug(
"All diff range files were already present in the diff from the base database."
);
}
}
} catch (e) {
logger.debug(
`Failed while attempting to add diff range files in overlay: ${e.message || e}`
);
}
logger.info(
`Found ${changedFiles.length} changed file(s) under ${sourceRoot}.`
`Found ${originalCount} natural changed file(s); added from diff ${extraAddedCount}; total ${changedFiles.length} under ${sourceRoot}.`
);
const changedFilesJson = JSON.stringify({ changes: changedFiles });
const overlayChangesFile = path2.join(
@@ -78557,11 +78564,6 @@ function isSupportedToolsFeature(versionInfo, feature) {
// src/feature-flags.ts
var featureConfig = {
["allow_toolcache_input" /* AllowToolcacheInput */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: void 0
},
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
@@ -78897,7 +78899,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
async isScannedLanguage(language) {
return !await this.isTracedLanguage(language);
},
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, logger) {
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, prDiffChangedFiles, logger) {
const extraArgs = config.languages.map(
(language) => `--language=${language}`
);
@@ -78932,6 +78934,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
const overlayChangesFile = await writeOverlayChangesFile(
config,
sourceRoot,
prDiffChangedFiles,
logger
);
extraArgs.push(`--overlay-changes=${overlayChangesFile}`);
+4 -31
View File
@@ -24680,9 +24680,6 @@ var require_identifiers = __commonJS({
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
@@ -24789,25 +24786,7 @@ var require_semver = __commonJS({
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
@@ -25568,7 +25547,6 @@ var require_range = __commonJS({
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug2("comp", comp, options);
comp = replaceCarets(comp, options);
debug2("caret", comp);
@@ -26460,7 +26438,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.30.9",
version: "4.30.8",
private: true,
description: "CodeQL action",
scripts: {
@@ -26509,7 +26487,7 @@ var require_package = __commonJS({
long: "^5.3.2",
"node-forge": "^1.3.1",
octokit: "^5.0.3",
semver: "^7.7.3",
semver: "^7.7.2",
uuid: "^13.0.0"
},
devDependencies: {
@@ -26527,7 +26505,7 @@ var require_package = __commonJS({
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
ava: "^6.4.1",
esbuild: "^0.25.10",
@@ -117237,11 +117215,6 @@ var semver3 = __toESM(require_semver2());
// src/feature-flags.ts
var featureConfig = {
["allow_toolcache_input" /* AllowToolcacheInput */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: void 0
},
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
+4 -31
View File
@@ -19971,9 +19971,6 @@ var require_identifiers = __commonJS({
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
@@ -20080,25 +20077,7 @@ var require_semver = __commonJS({
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
@@ -20859,7 +20838,6 @@ var require_range = __commonJS({
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug3("comp", comp, options);
comp = replaceCarets(comp, options);
debug3("caret", comp);
@@ -44996,7 +44974,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.30.9",
version: "4.30.8",
private: true,
description: "CodeQL action",
scripts: {
@@ -45045,7 +45023,7 @@ var require_package = __commonJS({
long: "^5.3.2",
"node-forge": "^1.3.1",
octokit: "^5.0.3",
semver: "^7.7.3",
semver: "^7.7.2",
uuid: "^13.0.0"
},
devDependencies: {
@@ -45063,7 +45041,7 @@ var require_package = __commonJS({
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
ava: "^6.4.1",
esbuild: "^0.25.10",
@@ -95351,11 +95329,6 @@ var semver3 = __toESM(require_semver2());
// src/feature-flags.ts
var featureConfig = {
["allow_toolcache_input" /* AllowToolcacheInput */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: void 0
},
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
+45 -57
View File
@@ -31826,9 +31826,6 @@ var require_identifiers = __commonJS({
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
@@ -31935,25 +31932,7 @@ var require_semver = __commonJS({
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
@@ -32714,7 +32693,6 @@ var require_range = __commonJS({
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug2("comp", comp, options);
comp = replaceCarets(comp, options);
debug2("caret", comp);
@@ -33606,7 +33584,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.30.9",
version: "4.30.8",
private: true,
description: "CodeQL action",
scripts: {
@@ -33655,7 +33633,7 @@ var require_package = __commonJS({
long: "^5.3.2",
"node-forge": "^1.3.1",
octokit: "^5.0.3",
semver: "^7.7.3",
semver: "^7.7.2",
uuid: "^13.0.0"
},
devDependencies: {
@@ -33673,7 +33651,7 @@ var require_package = __commonJS({
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
ava: "^6.4.1",
esbuild: "^0.25.10",
@@ -84853,7 +84831,6 @@ __export(upload_lib_exports, {
shouldShowCombineSarifFilesDeprecationWarning: () => shouldShowCombineSarifFilesDeprecationWarning,
throwIfCombineSarifFilesDisabled: () => throwIfCombineSarifFilesDisabled,
uploadFiles: () => uploadFiles,
uploadPayload: () => uploadPayload,
uploadSpecifiedFiles: () => uploadSpecifiedFiles,
validateSarifFileSchema: () => validateSarifFileSchema,
validateUniqueCategory: () => validateUniqueCategory,
@@ -89312,12 +89289,41 @@ async function readBaseDatabaseOidsFile(config, logger) {
function getBaseDatabaseOidsFilePath(config) {
return path7.join(config.dbLocation, "base-database-oids.json");
}
async function writeOverlayChangesFile(config, sourceRoot, logger) {
async function writeOverlayChangesFile(config, sourceRoot, prDiffChangedFiles, logger) {
const baseFileOids = await readBaseDatabaseOidsFile(config, logger);
const overlayFileOids = await getFileOidsUnderPath(sourceRoot);
const changedFiles = computeChangedFiles(baseFileOids, overlayFileOids);
const originalCount = changedFiles.length;
let extraAddedCount = 0;
try {
if (prDiffChangedFiles && prDiffChangedFiles.size > 0) {
const existing = new Set(changedFiles);
for (const f of prDiffChangedFiles) {
if (!existing.has(f)) {
if (overlayFileOids[f] !== void 0 || fs5.existsSync(path7.join(sourceRoot, f))) {
existing.add(f);
changedFiles.push(f);
extraAddedCount++;
}
}
}
if (extraAddedCount > 0) {
logger.debug(
`Added ${extraAddedCount} file(s) from PR diff ranges into overlay: ${changedFiles.slice(-extraAddedCount).join(", ")}`
);
} else {
logger.debug(
"All diff range files were already present in the diff from the base database."
);
}
}
} catch (e) {
logger.debug(
`Failed while attempting to add diff range files in overlay: ${e.message || e}`
);
}
logger.info(
`Found ${changedFiles.length} changed file(s) under ${sourceRoot}.`
`Found ${originalCount} natural changed file(s); added from diff ${extraAddedCount}; total ${changedFiles.length} under ${sourceRoot}.`
);
const changedFilesJson = JSON.stringify({ changes: changedFiles });
const overlayChangesFile = path7.join(
@@ -89354,11 +89360,6 @@ function isSupportedToolsFeature(versionInfo, feature) {
// src/feature-flags.ts
var CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0";
var featureConfig = {
["allow_toolcache_input" /* AllowToolcacheInput */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: void 0
},
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
@@ -90143,7 +90144,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) {
}
return void 0;
}
async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) {
async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, logger) {
if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) {
logger.info(`Using CodeQL CLI from local path ${toolsInput}`);
const compressionMethod2 = inferCompressionMethod(toolsInput);
@@ -90182,10 +90183,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian
}
} else if (toolsInput !== void 0 && toolsInput === CODEQL_TOOLCACHE_INPUT) {
let latestToolcacheVersion;
const allowToolcacheValueFF = await features.getValue(
"allow_toolcache_input" /* AllowToolcacheInput */
);
const allowToolcacheValue = allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode());
const allowToolcacheValue = isDynamicWorkflow() || isInTestMode();
if (allowToolcacheValue) {
logger.info(
`Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.`
@@ -90201,15 +90199,9 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian
`Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...`
);
} else {
if (allowToolcacheValueFF) {
logger.warning(
`Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`
);
} else {
logger.info(
`Ignoring 'tools: ${toolsInput}' because the feature is not enabled.`
);
}
logger.warning(
`Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`
);
}
cliVersion2 = defaultCliVersion.cliVersion;
tagName = defaultCliVersion.tagName;
@@ -90422,7 +90414,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) {
}
return cliVersion2;
}
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) {
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
if (!await isBinaryAccessible("tar", logger)) {
throw new ConfigurationError(
"Could not find tar in PATH, so unable to extract CodeQL bundle."
@@ -90435,7 +90427,6 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau
apiDetails,
variant,
zstdAvailability.available,
features,
logger
);
let codeqlFolder;
@@ -90560,7 +90551,7 @@ var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13";
var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19";
var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
var CODEQL_VERSION_CACHE_CLEANUP = "2.17.1";
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) {
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger, checkVersion) {
try {
const {
codeqlFolder,
@@ -90574,7 +90565,6 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV
tempDir,
variant,
defaultCliVersion,
features,
logger
);
logger.debug(
@@ -90654,7 +90644,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
async isScannedLanguage(language) {
return !await this.isTracedLanguage(language);
},
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, logger) {
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, prDiffChangedFiles, logger) {
const extraArgs = config.languages.map(
(language) => `--language=${language}`
);
@@ -90689,6 +90679,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
const overlayChangesFile = await writeOverlayChangesFile(
config,
sourceRoot,
prDiffChangedFiles,
logger
);
extraArgs.push(`--overlay-changes=${overlayChangesFile}`);
@@ -92278,7 +92269,7 @@ async function addFingerprints(sarif, sourceRoot, logger) {
// src/init.ts
var toolrunner4 = __toESM(require_toolrunner());
var io5 = __toESM(require_io());
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) {
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
logger.startGroup("Setup CodeQL tools");
const {
codeql,
@@ -92292,7 +92283,6 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe
tempDir,
variant,
defaultCliVersion,
features,
logger,
true
);
@@ -92439,7 +92429,6 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
tempDir,
gitHubVersion.type,
codeQLDefaultVersionInfo,
features,
logger
);
codeQL = initCodeQLResult.codeql;
@@ -92985,7 +92974,6 @@ function filterAlertsByDiffRange(logger, sarif) {
shouldShowCombineSarifFilesDeprecationWarning,
throwIfCombineSarifFilesDisabled,
uploadFiles,
uploadPayload,
uploadSpecifiedFiles,
validateSarifFileSchema,
validateUniqueCategory,
+4 -31
View File
@@ -24680,9 +24680,6 @@ var require_identifiers = __commonJS({
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
@@ -24789,25 +24786,7 @@ var require_semver = __commonJS({
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
@@ -25568,7 +25547,6 @@ var require_range = __commonJS({
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug2("comp", comp, options);
comp = replaceCarets(comp, options);
debug2("caret", comp);
@@ -26460,7 +26438,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.30.9",
version: "4.30.8",
private: true,
description: "CodeQL action",
scripts: {
@@ -26509,7 +26487,7 @@ var require_package = __commonJS({
long: "^5.3.2",
"node-forge": "^1.3.1",
octokit: "^5.0.3",
semver: "^7.7.3",
semver: "^7.7.2",
uuid: "^13.0.0"
},
devDependencies: {
@@ -26527,7 +26505,7 @@ var require_package = __commonJS({
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
ava: "^6.4.1",
esbuild: "^0.25.10",
@@ -117400,11 +117378,6 @@ function isSafeArtifactUpload(codeQlVersion) {
// src/feature-flags.ts
var featureConfig = {
["allow_toolcache_input" /* AllowToolcacheInput */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: void 0
},
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
+45 -55
View File
@@ -30529,9 +30529,6 @@ var require_identifiers = __commonJS({
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
@@ -30638,25 +30635,7 @@ var require_semver = __commonJS({
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
@@ -31417,7 +31396,6 @@ var require_range = __commonJS({
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug4("comp", comp, options);
comp = replaceCarets(comp, options);
debug4("caret", comp);
@@ -32309,7 +32287,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.30.9",
version: "4.30.8",
private: true,
description: "CodeQL action",
scripts: {
@@ -32358,7 +32336,7 @@ var require_package = __commonJS({
long: "^5.3.2",
"node-forge": "^1.3.1",
octokit: "^5.0.3",
semver: "^7.7.3",
semver: "^7.7.2",
uuid: "^13.0.0"
},
devDependencies: {
@@ -32376,7 +32354,7 @@ var require_package = __commonJS({
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
ava: "^6.4.1",
esbuild: "^0.25.10",
@@ -89226,12 +89204,41 @@ async function readBaseDatabaseOidsFile(config, logger) {
function getBaseDatabaseOidsFilePath(config) {
return path7.join(config.dbLocation, "base-database-oids.json");
}
async function writeOverlayChangesFile(config, sourceRoot, logger) {
async function writeOverlayChangesFile(config, sourceRoot, prDiffChangedFiles, logger) {
const baseFileOids = await readBaseDatabaseOidsFile(config, logger);
const overlayFileOids = await getFileOidsUnderPath(sourceRoot);
const changedFiles = computeChangedFiles(baseFileOids, overlayFileOids);
const originalCount = changedFiles.length;
let extraAddedCount = 0;
try {
if (prDiffChangedFiles && prDiffChangedFiles.size > 0) {
const existing = new Set(changedFiles);
for (const f of prDiffChangedFiles) {
if (!existing.has(f)) {
if (overlayFileOids[f] !== void 0 || fs5.existsSync(path7.join(sourceRoot, f))) {
existing.add(f);
changedFiles.push(f);
extraAddedCount++;
}
}
}
if (extraAddedCount > 0) {
logger.debug(
`Added ${extraAddedCount} file(s) from PR diff ranges into overlay: ${changedFiles.slice(-extraAddedCount).join(", ")}`
);
} else {
logger.debug(
"All diff range files were already present in the diff from the base database."
);
}
}
} catch (e) {
logger.debug(
`Failed while attempting to add diff range files in overlay: ${e.message || e}`
);
}
logger.info(
`Found ${changedFiles.length} changed file(s) under ${sourceRoot}.`
`Found ${originalCount} natural changed file(s); added from diff ${extraAddedCount}; total ${changedFiles.length} under ${sourceRoot}.`
);
const changedFilesJson = JSON.stringify({ changes: changedFiles });
const overlayChangesFile = path7.join(
@@ -89270,11 +89277,6 @@ var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_";
var DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled";
var CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0";
var featureConfig = {
["allow_toolcache_input" /* AllowToolcacheInput */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: void 0
},
["cleanup_trap_caches" /* CleanupTrapCaches */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
@@ -90814,7 +90816,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) {
}
return void 0;
}
async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) {
async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, logger) {
if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) {
logger.info(`Using CodeQL CLI from local path ${toolsInput}`);
const compressionMethod2 = inferCompressionMethod(toolsInput);
@@ -90853,10 +90855,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian
}
} else if (toolsInput !== void 0 && toolsInput === CODEQL_TOOLCACHE_INPUT) {
let latestToolcacheVersion;
const allowToolcacheValueFF = await features.getValue(
"allow_toolcache_input" /* AllowToolcacheInput */
);
const allowToolcacheValue = allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode());
const allowToolcacheValue = isDynamicWorkflow() || isInTestMode();
if (allowToolcacheValue) {
logger.info(
`Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.`
@@ -90872,15 +90871,9 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian
`Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...`
);
} else {
if (allowToolcacheValueFF) {
logger.warning(
`Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`
);
} else {
logger.info(
`Ignoring 'tools: ${toolsInput}' because the feature is not enabled.`
);
}
logger.warning(
`Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`
);
}
cliVersion2 = defaultCliVersion.cliVersion;
tagName = defaultCliVersion.tagName;
@@ -91093,7 +91086,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) {
}
return cliVersion2;
}
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) {
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
if (!await isBinaryAccessible("tar", logger)) {
throw new ConfigurationError(
"Could not find tar in PATH, so unable to extract CodeQL bundle."
@@ -91106,7 +91099,6 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau
apiDetails,
variant,
zstdAvailability.available,
features,
logger
);
let codeqlFolder;
@@ -91231,7 +91223,7 @@ var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13";
var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19";
var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
var CODEQL_VERSION_CACHE_CLEANUP = "2.17.1";
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) {
async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger, checkVersion) {
try {
const {
codeqlFolder,
@@ -91245,7 +91237,6 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV
tempDir,
variant,
defaultCliVersion,
features,
logger
);
logger.debug(
@@ -91325,7 +91316,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
async isScannedLanguage(language) {
return !await this.isTracedLanguage(language);
},
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, logger) {
async databaseInitCluster(config, sourceRoot, processName, qlconfigFile, prDiffChangedFiles, logger) {
const extraArgs = config.languages.map(
(language) => `--language=${language}`
);
@@ -91360,6 +91351,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
const overlayChangesFile = await writeOverlayChangesFile(
config,
sourceRoot,
prDiffChangedFiles,
logger
);
extraArgs.push(`--overlay-changes=${overlayChangesFile}`);
@@ -92949,7 +92941,7 @@ async function addFingerprints(sarif, sourceRoot, logger) {
// src/init.ts
var toolrunner4 = __toESM(require_toolrunner());
var io5 = __toESM(require_io());
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) {
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
logger.startGroup("Setup CodeQL tools");
const {
codeql,
@@ -92963,7 +92955,6 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe
tempDir,
variant,
defaultCliVersion,
features,
logger,
true
);
@@ -93110,7 +93101,6 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
tempDir,
gitHubVersion.type,
codeQLDefaultVersionInfo,
features,
logger
);
codeQL = initCodeQLResult.codeql;
+108 -109
View File
@@ -1,12 +1,12 @@
{
"name": "codeql",
"version": "4.30.9",
"version": "4.30.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "codeql",
"version": "4.30.9",
"version": "4.30.8",
"license": "MIT",
"dependencies": {
"@actions/artifact": "^2.3.1",
@@ -34,7 +34,7 @@
"long": "^5.3.2",
"node-forge": "^1.3.1",
"octokit": "^5.0.3",
"semver": "^7.7.3",
"semver": "^7.7.2",
"uuid": "^13.0.0"
},
"devDependencies": {
@@ -52,7 +52,7 @@
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
"ava": "^6.4.1",
"esbuild": "^0.25.10",
@@ -2697,17 +2697,17 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.0.tgz",
"integrity": "sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.45.0.tgz",
"integrity": "sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.46.0",
"@typescript-eslint/type-utils": "8.46.0",
"@typescript-eslint/utils": "8.46.0",
"@typescript-eslint/visitor-keys": "8.46.0",
"@typescript-eslint/scope-manager": "8.45.0",
"@typescript-eslint/type-utils": "8.45.0",
"@typescript-eslint/utils": "8.45.0",
"@typescript-eslint/visitor-keys": "8.45.0",
"graphemer": "^1.4.0",
"ignore": "^7.0.0",
"natural-compare": "^1.4.0",
@@ -2721,20 +2721,20 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.46.0",
"@typescript-eslint/parser": "^8.45.0",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.0.tgz",
"integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz",
"integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/visitor-keys": "8.46.0"
"@typescript-eslint/types": "8.45.0",
"@typescript-eslint/visitor-keys": "8.45.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2745,9 +2745,9 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.0.tgz",
"integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz",
"integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2759,16 +2759,16 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.0.tgz",
"integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz",
"integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.46.0",
"@typescript-eslint/tsconfig-utils": "8.46.0",
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/visitor-keys": "8.46.0",
"@typescript-eslint/project-service": "8.45.0",
"@typescript-eslint/tsconfig-utils": "8.45.0",
"@typescript-eslint/types": "8.45.0",
"@typescript-eslint/visitor-keys": "8.45.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -2788,16 +2788,16 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.0.tgz",
"integrity": "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz",
"integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.46.0",
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/typescript-estree": "8.46.0"
"@typescript-eslint/scope-manager": "8.45.0",
"@typescript-eslint/types": "8.45.0",
"@typescript-eslint/typescript-estree": "8.45.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2812,13 +2812,13 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.0.tgz",
"integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz",
"integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/types": "8.45.0",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
@@ -2891,16 +2891,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.0.tgz",
"integrity": "sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.45.0.tgz",
"integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.46.0",
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/typescript-estree": "8.46.0",
"@typescript-eslint/visitor-keys": "8.46.0",
"@typescript-eslint/scope-manager": "8.45.0",
"@typescript-eslint/types": "8.45.0",
"@typescript-eslint/typescript-estree": "8.45.0",
"@typescript-eslint/visitor-keys": "8.45.0",
"debug": "^4.3.4"
},
"engines": {
@@ -2916,14 +2916,14 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.0.tgz",
"integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz",
"integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/visitor-keys": "8.46.0"
"@typescript-eslint/types": "8.45.0",
"@typescript-eslint/visitor-keys": "8.45.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2934,9 +2934,9 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.0.tgz",
"integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz",
"integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2948,16 +2948,16 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.0.tgz",
"integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz",
"integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.46.0",
"@typescript-eslint/tsconfig-utils": "8.46.0",
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/visitor-keys": "8.46.0",
"@typescript-eslint/project-service": "8.45.0",
"@typescript-eslint/tsconfig-utils": "8.45.0",
"@typescript-eslint/types": "8.45.0",
"@typescript-eslint/visitor-keys": "8.45.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -2977,13 +2977,13 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.0.tgz",
"integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz",
"integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/types": "8.45.0",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
@@ -3047,14 +3047,14 @@
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.0.tgz",
"integrity": "sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.45.0.tgz",
"integrity": "sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.46.0",
"@typescript-eslint/types": "^8.46.0",
"@typescript-eslint/tsconfig-utils": "^8.45.0",
"@typescript-eslint/types": "^8.45.0",
"debug": "^4.3.4"
},
"engines": {
@@ -3069,9 +3069,9 @@
}
},
"node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.0.tgz",
"integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz",
"integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3101,9 +3101,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.0.tgz",
"integrity": "sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.45.0.tgz",
"integrity": "sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3118,15 +3118,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.0.tgz",
"integrity": "sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.45.0.tgz",
"integrity": "sha512-bpjepLlHceKgyMEPglAeULX1vixJDgaKocp0RVJ5u4wLJIMNuKtUXIczpJCPcn2waII0yuvks/5m5/h3ZQKs0A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/typescript-estree": "8.46.0",
"@typescript-eslint/utils": "8.46.0",
"@typescript-eslint/types": "8.45.0",
"@typescript-eslint/typescript-estree": "8.45.0",
"@typescript-eslint/utils": "8.45.0",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
},
@@ -3143,14 +3143,14 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.0.tgz",
"integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz",
"integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/visitor-keys": "8.46.0"
"@typescript-eslint/types": "8.45.0",
"@typescript-eslint/visitor-keys": "8.45.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3161,9 +3161,9 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.0.tgz",
"integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz",
"integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3175,16 +3175,16 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.0.tgz",
"integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz",
"integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.46.0",
"@typescript-eslint/tsconfig-utils": "8.46.0",
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/visitor-keys": "8.46.0",
"@typescript-eslint/project-service": "8.45.0",
"@typescript-eslint/tsconfig-utils": "8.45.0",
"@typescript-eslint/types": "8.45.0",
"@typescript-eslint/visitor-keys": "8.45.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -3204,16 +3204,16 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.0.tgz",
"integrity": "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz",
"integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.46.0",
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/typescript-estree": "8.46.0"
"@typescript-eslint/scope-manager": "8.45.0",
"@typescript-eslint/types": "8.45.0",
"@typescript-eslint/typescript-estree": "8.45.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3228,13 +3228,13 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
"version": "8.46.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.0.tgz",
"integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==",
"version": "8.45.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz",
"integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.46.0",
"@typescript-eslint/types": "8.45.0",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
@@ -8210,10 +8210,9 @@
"license": "ISC"
},
"node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
"license": "ISC",
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"bin": {
"semver": "bin/semver.js"
},
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "codeql",
"version": "4.30.9",
"version": "4.30.8",
"private": true,
"description": "CodeQL action",
"scripts": {
@@ -49,7 +49,7 @@
"long": "^5.3.2",
"node-forge": "^1.3.1",
"octokit": "^5.0.3",
"semver": "^7.7.3",
"semver": "^7.7.2",
"uuid": "^13.0.0"
},
"devDependencies": {
@@ -67,7 +67,7 @@
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.41.0",
"ava": "^6.4.1",
"esbuild": "^0.25.10",
+1 -1
View File
@@ -4,7 +4,7 @@ description: "Tests using RuboCop to analyze a multi-language repository and the
versions: ["default"]
steps:
- name: Set up Ruby
uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a # v1.263.0
with:
ruby-version: 2.6
- name: Install Code Scanning integration
+2 -9
View File
@@ -30,7 +30,6 @@ import {
DependencyCacheUploadStatusReport,
uploadDependencyCaches,
} from "./dependency-caching";
import { getDiffInformedAnalysisBranches } from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment";
import { Feature, Features } from "./feature-flags";
import { KnownLanguage } from "./languages";
@@ -299,14 +298,8 @@ async function run() {
logger,
);
const branches = await getDiffInformedAnalysisBranches(
codeql,
features,
logger,
);
const diffRangePackDir = branches
? await setupDiffInformedQueryRun(branches, logger)
: undefined;
// Setup diff informed analysis if needed (based on whether init created the file)
const diffRangePackDir = await setupDiffInformedQueryRun(logger);
await warnIfGoInstalledAfterInit(config, logger);
await runAutobuildIfLegacyGoWorkflow(config, logger);
-200
View File
@@ -4,10 +4,8 @@ import * as path from "path";
import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import { CodeQuality, CodeScanning } from "./analyses";
import {
exportedForTesting,
runQueries,
defaultSuites,
resolveQuerySuiteAlias,
@@ -131,204 +129,6 @@ test("status report fields", async (t) => {
});
});
function runGetDiffRanges(changes: number, patch: string[] | undefined): any {
sinon
.stub(actionsUtil, "getRequiredInput")
.withArgs("checkout_path")
.returns("/checkout/path");
return exportedForTesting.getDiffRanges(
{
filename: "test.txt",
changes,
patch: patch?.join("\n"),
},
getRunnerLogger(true),
);
}
test("getDiffRanges: file unchanged", async (t) => {
const diffRanges = runGetDiffRanges(0, undefined);
t.deepEqual(diffRanges, []);
});
test("getDiffRanges: file diff too large", async (t) => {
const diffRanges = runGetDiffRanges(1000000, undefined);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 0,
endLine: 0,
},
]);
});
test("getDiffRanges: diff thunk with single addition range", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,6 +50,8 @@",
" a",
" b",
" c",
"+1",
"+2",
" d",
" e",
" f",
]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 53,
endLine: 54,
},
]);
});
test("getDiffRanges: diff thunk with single deletion range", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,8 +50,6 @@",
" a",
" b",
" c",
"-1",
"-2",
" d",
" e",
" f",
]);
t.deepEqual(diffRanges, []);
});
test("getDiffRanges: diff thunk with single update range", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,7 +50,7 @@",
" a",
" b",
" c",
"-1",
"+2",
" d",
" e",
" f",
]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 53,
endLine: 53,
},
]);
});
test("getDiffRanges: diff thunk with addition ranges", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,7 +50,9 @@",
" a",
" b",
" c",
"+1",
" c",
"+2",
" d",
" e",
" f",
]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 53,
endLine: 53,
},
{
path: "/checkout/path/test.txt",
startLine: 55,
endLine: 55,
},
]);
});
test("getDiffRanges: diff thunk with mixed ranges", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,7 +50,7 @@",
" a",
" b",
" c",
"-1",
" d",
"-2",
"+3",
" e",
" f",
"+4",
"+5",
" g",
" h",
" i",
]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 54,
endLine: 54,
},
{
path: "/checkout/path/test.txt",
startLine: 57,
endLine: 58,
},
]);
});
test("getDiffRanges: multiple diff thunks", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,6 +50,8 @@",
" a",
" b",
" c",
"+1",
"+2",
" d",
" e",
" f",
"@@ -130,6 +150,8 @@",
" a",
" b",
" c",
"+1",
"+2",
" d",
" e",
" f",
]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 53,
endLine: 54,
},
{
path: "/checkout/path/test.txt",
startLine: 153,
endLine: 154,
},
]);
});
test("getDiffRanges: no diff context lines", async (t) => {
const diffRanges = runGetDiffRanges(2, ["@@ -30 +50,2 @@", "+1", "+2"]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 50,
endLine: 51,
},
]);
});
test("getDiffRanges: malformed thunk header", async (t) => {
const diffRanges = runGetDiffRanges(2, ["@@ 30 +50,2 @@", "+1", "+2"]);
t.deepEqual(diffRanges, undefined);
});
test("resolveQuerySuiteAlias", (t) => {
// default query suite names should resolve to something language-specific ending in `.qls`.
for (const suite of defaultSuites) {
+28 -197
View File
@@ -6,13 +6,9 @@ import * as io from "@actions/io";
import * as del from "del";
import * as yaml from "js-yaml";
import {
getRequiredInput,
getTemporaryDirectory,
PullRequestBranches,
} from "./actions-util";
import { getTemporaryDirectory } from "./actions-util";
import * as analyses from "./analyses";
import { getApiClient } from "./api-client";
// (getApiClient import removed; no longer needed after diff refactor)
import { setupCppAutobuild } from "./autobuild";
import { type CodeQL } from "./codeql";
import * as configUtils from "./config-utils";
@@ -20,14 +16,14 @@ import { getJavaTempDependencyDir } from "./dependency-caching";
import { addDiagnostic, makeDiagnostic } from "./diagnostics";
import {
DiffThunkRange,
writeDiffRangesJsonFile,
readDiffRangesJsonFile,
} from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment";
import { FeatureEnablement, Feature } from "./feature-flags";
import { KnownLanguage, Language } from "./languages";
import { Logger, withGroupAsync } from "./logging";
import { OverlayDatabaseMode } from "./overlay-database-utils";
import { getRepositoryNwoFromEnv } from "./repository";
// getRepositoryNwoFromEnv no longer needed after extracting diff logic
import { DatabaseCreationTimings, EventReport } from "./status-report";
import { endTracingForCluster } from "./tracer-config";
import * as util from "./util";
@@ -287,16 +283,36 @@ async function finalizeDatabaseCreation(
* the diff range information, or `undefined` if the feature is disabled.
*/
export async function setupDiffInformedQueryRun(
branches: PullRequestBranches,
logger: Logger,
): Promise<string | undefined> {
return await withGroupAsync(
"Generating diff range extension pack",
async () => {
// Only use precomputed diff ranges; never recompute here.
let diffRanges: DiffThunkRange[] | undefined;
try {
diffRanges = readDiffRangesJsonFile(logger);
} catch (e) {
logger.debug(
`Failed to read precomputed diff ranges: ${util.getErrorMessage(e)}`,
);
diffRanges = undefined;
}
if (diffRanges === undefined) {
logger.info(
"No precomputed diff ranges found; skipping diff-informed analysis stage.",
);
return undefined;
}
const fileCount = new Set(
diffRanges.filter((r) => r.path).map((r) => r.path),
).size;
logger.info(
`Calculating diff ranges for ${branches.base}...${branches.head}`,
`Using precomputed diff ranges (${diffRanges.length} ranges across ${fileCount} files).`,
);
const diffRanges = await getPullRequestEditedDiffRanges(branches, logger);
const packDir = writeDiffRangeDataExtensionPack(logger, diffRanges);
if (packDir === undefined) {
logger.warning(
@@ -313,185 +329,6 @@ export async function setupDiffInformedQueryRun(
);
}
/**
* Return the file line ranges that were added or modified in the pull request.
*
* @param branches The base and head branches of the pull request.
* @param logger
* @returns An array of tuples, where each tuple contains the absolute path of a
* file, the start line and the end line (both 1-based and inclusive) of an
* added or modified range in that file. Returns `undefined` if the action was
* not triggered by a pull request or if there was an error.
*/
async function getPullRequestEditedDiffRanges(
branches: PullRequestBranches,
logger: Logger,
): Promise<DiffThunkRange[] | undefined> {
const fileDiffs = await getFileDiffsWithBasehead(branches, logger);
if (fileDiffs === undefined) {
return undefined;
}
if (fileDiffs.length >= 300) {
// The "compare two commits" API returns a maximum of 300 changed files. If
// we see that many changed files, it is possible that there could be more,
// with the rest being truncated. In this case, we should not attempt to
// compute the diff ranges, as the result would be incomplete.
logger.warning(
`Cannot retrieve the full diff because there are too many ` +
`(${fileDiffs.length}) changed files in the pull request.`,
);
return undefined;
}
const results: DiffThunkRange[] = [];
for (const filediff of fileDiffs) {
const diffRanges = getDiffRanges(filediff, logger);
if (diffRanges === undefined) {
return undefined;
}
results.push(...diffRanges);
}
return results;
}
/**
* This interface is an abbreviated version of the file diff object returned by
* the GitHub API.
*/
interface FileDiff {
filename: string;
changes: number;
// A patch may be absent if the file is binary, if the file diff is too large,
// or if the file is unchanged.
patch?: string | undefined;
}
async function getFileDiffsWithBasehead(
branches: PullRequestBranches,
logger: Logger,
): Promise<FileDiff[] | undefined> {
// Check CODE_SCANNING_REPOSITORY first. If it is empty or not set, fall back
// to GITHUB_REPOSITORY.
const repositoryNwo = getRepositoryNwoFromEnv(
"CODE_SCANNING_REPOSITORY",
"GITHUB_REPOSITORY",
);
const basehead = `${branches.base}...${branches.head}`;
try {
const response = await getApiClient().rest.repos.compareCommitsWithBasehead(
{
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
basehead,
per_page: 1,
},
);
logger.debug(
`Response from compareCommitsWithBasehead(${basehead}):` +
`\n${JSON.stringify(response, null, 2)}`,
);
return response.data.files;
} catch (error: any) {
if (error.status) {
logger.warning(`Error retrieving diff ${basehead}: ${error.message}`);
logger.debug(
`Error running compareCommitsWithBasehead(${basehead}):` +
`\nRequest: ${JSON.stringify(error.request, null, 2)}` +
`\nError Response: ${JSON.stringify(error.response, null, 2)}`,
);
return undefined;
} else {
throw error;
}
}
}
function getDiffRanges(
fileDiff: FileDiff,
logger: Logger,
): DiffThunkRange[] | undefined {
// Diff-informed queries expect the file path to be absolute. CodeQL always
// uses forward slashes as the path separator, so on Windows we need to
// replace any backslashes with forward slashes.
const filename = path
.join(getRequiredInput("checkout_path"), fileDiff.filename)
.replaceAll(path.sep, "/");
if (fileDiff.patch === undefined) {
if (fileDiff.changes === 0) {
// There are situations where a changed file legitimately has no diff.
// For example, the file may be a binary file, or that the file may have
// been renamed with no changes to its contents. In these cases, the
// file would be reported as having 0 changes, and we can return an empty
// array to indicate no diff range in this file.
return [];
}
// If a file is reported to have nonzero changes but no patch, that may be
// due to the file diff being too large. In this case, we should fall back
// to a special diff range that covers the entire file.
return [
{
path: filename,
startLine: 0,
endLine: 0,
},
];
}
// The 1-based file line number of the current line
let currentLine = 0;
// The 1-based file line number that starts the current range of added lines
let additionRangeStartLine: number | undefined = undefined;
const diffRanges: DiffThunkRange[] = [];
const diffLines = fileDiff.patch.split("\n");
// Adding a fake context line at the end ensures that the following loop will
// always terminate the last range of added lines.
diffLines.push(" ");
for (const diffLine of diffLines) {
if (diffLine.startsWith("-")) {
// Ignore deletions completely -- we do not even want to consider them when
// calculating consecutive ranges of added lines.
continue;
}
if (diffLine.startsWith("+")) {
if (additionRangeStartLine === undefined) {
additionRangeStartLine = currentLine;
}
currentLine++;
continue;
}
if (additionRangeStartLine !== undefined) {
// Any line that does not start with a "+" or "-" terminates the current
// range of added lines.
diffRanges.push({
path: filename,
startLine: additionRangeStartLine,
endLine: currentLine - 1,
});
additionRangeStartLine = undefined;
}
if (diffLine.startsWith("@@ ")) {
// A new hunk header line resets the current line number.
const match = diffLine.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
if (match === null) {
logger.warning(
`Cannot parse diff hunk header for ${fileDiff.filename}: ${diffLine}`,
);
return undefined;
}
currentLine = parseInt(match[1], 10);
continue;
}
if (diffLine.startsWith(" ")) {
// An unchanged context line advances the current line number.
currentLine++;
continue;
}
}
return diffRanges;
}
/**
* Create an extension pack in the temporary directory that contains the file
* line ranges that were added or modified in the pull request.
@@ -572,10 +409,6 @@ extensions:
`Wrote pr-diff-range extension pack to ${extensionFilePath}:\n${extensionContents}`,
);
// Write the diff ranges to a JSON file, for action-side alert filtering by the
// upload-lib module.
writeDiffRangesJsonFile(logger, ranges);
return diffRangeDir;
}
@@ -923,6 +756,4 @@ export async function warnIfGoInstalledAfterInit(
}
}
export const exportedForTesting = {
getDiffRanges,
};
export const exportedForTesting = {};
+4 -28
View File
@@ -74,7 +74,6 @@ async function installIntoToolcache({
cliVersion !== undefined
? { cliVersion, tagName }
: SAMPLE_DEFAULT_CLI_VERSION,
createFeatures([]),
getRunnerLogger(true),
false,
);
@@ -123,8 +122,6 @@ async function stubCodeql(): Promise<codeql.CodeQL> {
}
test("downloads and caches explicitly requested bundles that aren't in the toolcache", async (t) => {
const features = createFeatures([]);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -143,7 +140,6 @@ test("downloads and caches explicitly requested bundles that aren't in the toolc
tmpDir,
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
features,
getRunnerLogger(true),
false,
);
@@ -158,8 +154,6 @@ test("downloads and caches explicitly requested bundles that aren't in the toolc
});
test("caches semantically versioned bundles using their semantic version number", async (t) => {
const features = createFeatures([]);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const url = mockBundleDownloadApi({
@@ -172,7 +166,6 @@ test("caches semantically versioned bundles using their semantic version number"
tmpDir,
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
features,
getRunnerLogger(true),
false,
);
@@ -188,8 +181,6 @@ test("caches semantically versioned bundles using their semantic version number"
});
test("downloads an explicitly requested bundle even if a different version is cached", async (t) => {
const features = createFeatures([]);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -208,7 +199,6 @@ test("downloads an explicitly requested bundle even if a different version is ca
tmpDir,
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
features,
getRunnerLogger(true),
false,
);
@@ -237,8 +227,6 @@ for (const {
expectedToolcacheVersion,
} of EXPLICITLY_REQUESTED_BUNDLE_TEST_CASES) {
test(`caches explicitly requested bundle ${tagName} as ${expectedToolcacheVersion}`, async (t) => {
const features = createFeatures([]);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -255,7 +243,6 @@ for (const {
tmpDir,
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
features,
getRunnerLogger(true),
false,
);
@@ -279,8 +266,6 @@ for (const toolcacheVersion of [
`uses tools from toolcache when ${SAMPLE_DEFAULT_CLI_VERSION.cliVersion} is requested and ` +
`${toolcacheVersion} is installed`,
async (t) => {
const features = createFeatures([]);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -296,7 +281,6 @@ for (const toolcacheVersion of [
tmpDir,
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
features,
getRunnerLogger(true),
false,
);
@@ -311,8 +295,6 @@ for (const toolcacheVersion of [
}
test(`uses a cached bundle when no tools input is given on GHES`, async (t) => {
const features = createFeatures([]);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -331,7 +313,6 @@ test(`uses a cached bundle when no tools input is given on GHES`, async (t) => {
cliVersion: defaults.cliVersion,
tagName: defaults.bundleVersion,
},
features,
getRunnerLogger(true),
false,
);
@@ -347,8 +328,6 @@ test(`uses a cached bundle when no tools input is given on GHES`, async (t) => {
});
test(`downloads bundle if only an unpinned version is cached on GHES`, async (t) => {
const features = createFeatures([]);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -370,7 +349,6 @@ test(`downloads bundle if only an unpinned version is cached on GHES`, async (t)
cliVersion: defaults.cliVersion,
tagName: defaults.bundleVersion,
},
features,
getRunnerLogger(true),
false,
);
@@ -386,8 +364,6 @@ test(`downloads bundle if only an unpinned version is cached on GHES`, async (t)
});
test('downloads bundle if "latest" tools specified but not cached', async (t) => {
const features = createFeatures([]);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -406,7 +382,6 @@ test('downloads bundle if "latest" tools specified but not cached', async (t) =>
tmpDir,
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
features,
getRunnerLogger(true),
false,
);
@@ -422,8 +397,6 @@ test('downloads bundle if "latest" tools specified but not cached', async (t) =>
});
test("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t) => {
const features = createFeatures([]);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -444,7 +417,6 @@ test("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t)
tmpDir,
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
features,
getRunnerLogger(true),
false,
);
@@ -545,6 +517,7 @@ const injectedConfigMacro = test.macro({
"",
undefined,
undefined,
undefined,
getRunnerLogger(true),
);
@@ -831,6 +804,7 @@ test("passes a code scanning config AND qlconfig to the CLI", async (t: Executio
"",
undefined,
"/path/to/qlconfig.yml",
undefined,
getRunnerLogger(true),
);
@@ -859,6 +833,7 @@ test("does not pass a qlconfig to the CLI when it is undefined", async (t: Execu
"",
undefined,
undefined, // undefined qlconfigFile
undefined,
getRunnerLogger(true),
);
@@ -1108,6 +1083,7 @@ test("Avoids duplicating --overwrite flag if specified in CODEQL_ACTION_EXTRA_OP
"sourceRoot",
undefined,
undefined,
undefined,
getRunnerLogger(false),
);
+3 -3
View File
@@ -96,6 +96,7 @@ export interface CodeQL {
sourceRoot: string,
processName: string | undefined,
qlconfigFile: string | undefined,
prDiffChangedFiles: Set<string> | undefined,
logger: Logger,
): Promise<void>;
/**
@@ -309,7 +310,6 @@ const CODEQL_VERSION_CACHE_CLEANUP = "2.17.1";
* @param tempDir
* @param variant
* @param defaultCliVersion
* @param features Information about the features that are enabled.
* @param logger
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
* version requirement. Must be set to true outside tests.
@@ -321,7 +321,6 @@ export async function setupCodeQL(
tempDir: string,
variant: util.GitHubVariant,
defaultCliVersion: CodeQLDefaultVersionInfo,
features: FeatureEnablement,
logger: Logger,
checkVersion: boolean,
): Promise<{
@@ -344,7 +343,6 @@ export async function setupCodeQL(
tempDir,
variant,
defaultCliVersion,
features,
logger,
);
@@ -563,6 +561,7 @@ export async function getCodeQLForCmd(
sourceRoot: string,
processName: string | undefined,
qlconfigFile: string | undefined,
prDiffChangedFiles: Set<string> | undefined,
logger: Logger,
) {
const extraArgs = config.languages.map(
@@ -605,6 +604,7 @@ export async function getCodeQLForCmd(
const overlayChangesFile = await writeOverlayChangesFile(
config,
sourceRoot,
prDiffChangedFiles,
logger,
);
extraArgs.push(`--overlay-changes=${overlayChangesFile}`);
+205 -1
View File
@@ -4,7 +4,10 @@ import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import type { PullRequestBranches } from "./actions-util";
import * as apiClient from "./api-client";
import { shouldPerformDiffInformedAnalysis } from "./diff-informed-analysis-utils";
import {
shouldPerformDiffInformedAnalysis,
exportedForTesting as diffExportedForTesting,
} from "./diff-informed-analysis-utils";
import { Feature, Features } from "./feature-flags";
import { getRunnerLogger } from "./logging";
import { parseRepositoryNwo } from "./repository";
@@ -183,3 +186,204 @@ test(
},
false,
);
// ---------------------------------------------------------------------------
// Tests for getDiffRanges (moved from analyze.test.ts after extraction)
// ---------------------------------------------------------------------------
function runGetDiffRanges(changes: number, patch: string[] | undefined): any {
sinon
.stub(actionsUtil, "getRequiredInput")
.withArgs("checkout_path")
.returns("/checkout/path");
return diffExportedForTesting.getDiffRanges(
{
filename: "test.txt",
changes,
patch: patch?.join("\n"),
},
getRunnerLogger(true),
);
}
test("getDiffRanges: file unchanged", async (t) => {
const diffRanges = runGetDiffRanges(0, undefined);
t.deepEqual(diffRanges, []);
});
test("getDiffRanges: file diff too large", async (t) => {
const diffRanges = runGetDiffRanges(1000000, undefined);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 0,
endLine: 0,
},
]);
});
test("getDiffRanges: diff thunk with single addition range", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,6 +50,8 @@",
" a",
" b",
" c",
"+1",
"+2",
" d",
" e",
" f",
]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 53,
endLine: 54,
},
]);
});
test("getDiffRanges: diff thunk with single deletion range", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,8 +50,6 @@",
" a",
" b",
" c",
"-1",
"-2",
" d",
" e",
" f",
]);
t.deepEqual(diffRanges, []);
});
test("getDiffRanges: diff thunk with single update range", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,7 +50,7 @@",
" a",
" b",
" c",
"-1",
"+2",
" d",
" e",
" f",
]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 53,
endLine: 53,
},
]);
});
test("getDiffRanges: diff thunk with addition ranges", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,7 +50,9 @@",
" a",
" b",
" c",
"+1",
" c",
"+2",
" d",
" e",
" f",
]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 53,
endLine: 53,
},
{
path: "/checkout/path/test.txt",
startLine: 55,
endLine: 55,
},
]);
});
test("getDiffRanges: diff thunk with mixed ranges", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,7 +50,7 @@",
" a",
" b",
" c",
"-1",
" d",
"-2",
"+3",
" e",
" f",
"+4",
"+5",
" g",
" h",
" i",
]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 54,
endLine: 54,
},
{
path: "/checkout/path/test.txt",
startLine: 57,
endLine: 58,
},
]);
});
test("getDiffRanges: multiple diff thunks", async (t) => {
const diffRanges = runGetDiffRanges(2, [
"@@ -30,6 +50,8 @@",
" a",
" b",
" c",
"+1",
"+2",
" d",
" e",
" f",
"@@ -130,6 +150,8 @@",
" a",
" b",
" c",
"+1",
"+2",
" d",
" e",
" f",
]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 53,
endLine: 54,
},
{
path: "/checkout/path/test.txt",
startLine: 153,
endLine: 154,
},
]);
});
test("getDiffRanges: no diff context lines", async (t) => {
const diffRanges = runGetDiffRanges(2, ["@@ -30 +50,2 @@", "+1", "+2"]);
t.deepEqual(diffRanges, [
{
path: "/checkout/path/test.txt",
startLine: 50,
endLine: 51,
},
]);
});
test("getDiffRanges: malformed thunk header", async (t) => {
const diffRanges = runGetDiffRanges(2, ["@@ 30 +50,2 @@", "+1", "+2"]);
t.deepEqual(diffRanges, undefined);
});
+189 -2
View File
@@ -1,14 +1,28 @@
import * as fs from "fs";
import * as path from "path";
import * as actionsUtil from "./actions-util";
import type { PullRequestBranches } from "./actions-util";
import { getGitHubVersion } from "./api-client";
import * as actionsUtil from "./actions-util";
import { getRequiredInput } from "./actions-util";
import { getGitHubVersion, getApiClient } from "./api-client";
import type { CodeQL } from "./codeql";
import { Feature, FeatureEnablement } from "./feature-flags";
import { Logger } from "./logging";
import { getRepositoryNwoFromEnv } from "./repository";
import { GitHubVariant, satisfiesGHESVersion } from "./util";
/**
* This interface is an abbreviated version of the file diff object returned by
* the GitHub API. (Kept internal to this module.)
*/
interface FileDiff {
filename: string;
changes: number;
// A patch may be absent if the file is binary, if the file diff is too large,
// or if the file is unchanged.
patch?: string | undefined;
}
/**
* Check if the action should perform diff-informed analysis.
*/
@@ -93,3 +107,176 @@ export function readDiffRangesJsonFile(
);
return JSON.parse(jsonContents) as DiffThunkRange[];
}
/**
* Return the file line ranges that were added or modified in the pull request.
*
* @param branches The base and head branches of the pull request.
* @param logger
* @returns An array of objects, where each object contains the absolute path of a
* file, the start line and the end line (both 1-based and inclusive) of an
* added or modified range in that file. Returns `undefined` if the action was
* not triggered by a pull request or if there was an error (including API
* truncation conditions).
*/
export async function getPullRequestEditedDiffRanges(
branches: PullRequestBranches,
logger: Logger,
): Promise<DiffThunkRange[] | undefined> {
const fileDiffs = await getFileDiffsWithBasehead(branches, logger);
if (fileDiffs === undefined) {
return undefined;
}
if (fileDiffs.length >= 300) {
// The "compare two commits" API returns a maximum of 300 changed files. If
// we see that many changed files, it is possible that there could be more,
// with the rest being truncated. In this case, we should not attempt to
// compute the diff ranges, as the result would be incomplete.
logger.warning(
`Cannot retrieve the full diff because there are too many ` +
`(${fileDiffs.length}) changed files in the pull request.`,
);
return undefined;
}
const results: DiffThunkRange[] = [];
for (const filediff of fileDiffs) {
const diffRanges = getDiffRanges(filediff, logger);
if (diffRanges === undefined) {
return undefined;
}
results.push(...diffRanges);
}
return results;
}
async function getFileDiffsWithBasehead(
branches: PullRequestBranches,
logger: Logger,
): Promise<FileDiff[] | undefined> {
// Check CODE_SCANNING_REPOSITORY first. If it is empty or not set, fall back
// to GITHUB_REPOSITORY.
const repositoryNwo = getRepositoryNwoFromEnv(
"CODE_SCANNING_REPOSITORY",
"GITHUB_REPOSITORY",
);
const basehead = `${branches.base}...${branches.head}`;
try {
const response = await getApiClient().rest.repos.compareCommitsWithBasehead(
{
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
basehead,
per_page: 1,
},
);
logger.debug(
`Response from compareCommitsWithBasehead(${basehead}):` +
`\n${JSON.stringify(response, null, 2)}`,
);
return response.data.files;
} catch (error: any) {
if (error.status) {
logger.warning(`Error retrieving diff ${basehead}: ${error.message}`);
logger.debug(
`Error running compareCommitsWithBasehead(${basehead}):` +
`\nRequest: ${JSON.stringify(error.request, null, 2)}` +
`\nError Response: ${JSON.stringify(error.response, null, 2)}`,
);
return undefined;
} else {
throw error;
}
}
}
function getDiffRanges(
fileDiff: FileDiff,
logger: Logger,
): DiffThunkRange[] | undefined {
// Diff-informed queries expect the file path to be absolute. CodeQL always
// uses forward slashes as the path separator, so on Windows we need to
// replace any backslashes with forward slashes.
const filename = path
.join(getRequiredInput("checkout_path"), fileDiff.filename)
.replaceAll(path.sep, "/");
if (fileDiff.patch === undefined) {
if (fileDiff.changes === 0) {
// There are situations where a changed file legitimately has no diff.
// For example, the file may be a binary file, or that the file may have
// been renamed with no changes to its contents. In these cases, the
// file would be reported as having 0 changes, and we can return an empty
// array to indicate no diff range in this file.
return [];
}
// If a file is reported to have nonzero changes but no patch, that may be
// due to the file diff being too large. In this case, we should fall back
// to a special diff range that covers the entire file.
return [
{
path: filename,
startLine: 0,
endLine: 0,
},
];
}
// The 1-based file line number of the current line
let currentLine = 0;
// The 1-based file line number that starts the current range of added lines
let additionRangeStartLine: number | undefined = undefined;
const diffRanges: DiffThunkRange[] = [];
const diffLines = fileDiff.patch.split("\n");
// Adding a fake context line at the end ensures that the following loop will
// always terminate the last range of added lines.
diffLines.push(" ");
for (const diffLine of diffLines) {
if (diffLine.startsWith("-")) {
// Ignore deletions completely -- we do not even want to consider them when
// calculating consecutive ranges of added lines.
continue;
}
if (diffLine.startsWith("+")) {
if (additionRangeStartLine === undefined) {
additionRangeStartLine = currentLine;
}
currentLine++;
continue;
}
if (additionRangeStartLine !== undefined) {
// Any line that does not start with a "+" or "-" terminates the current
// range of added lines.
diffRanges.push({
path: filename,
startLine: additionRangeStartLine,
endLine: currentLine - 1,
});
additionRangeStartLine = undefined;
}
if (diffLine.startsWith("@@ ")) {
// A new hunk header line resets the current line number.
const match = diffLine.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
if (match === null) {
logger.warning(
`Cannot parse diff hunk header for ${fileDiff.filename}: ${diffLine}`,
);
return undefined;
}
currentLine = parseInt(match[1], 10);
continue;
}
if (diffLine.startsWith(" ")) {
// An unchanged context line advances the current line number.
currentLine++;
continue;
}
}
return diffRanges;
}
// Export internal helpers for unit testing only (kept stable for existing tests)
export const exportedForTesting = {
getDiffRanges,
};
+1 -7
View File
@@ -43,7 +43,6 @@ export interface FeatureEnablement {
* Legacy features should end with `_enabled`.
*/
export enum Feature {
AllowToolcacheInput = "allow_toolcache_input",
CleanupTrapCaches = "cleanup_trap_caches",
CppDependencyInstallation = "cpp_dependency_installation_enabled",
DiffInformedQueries = "diff_informed_queries",
@@ -74,9 +73,9 @@ export enum Feature {
OverlayAnalysisRust = "overlay_analysis_rust",
OverlayAnalysisSwift = "overlay_analysis_swift",
PythonDefaultIsToNotExtractStdlib = "python_default_is_to_not_extract_stdlib",
UseRepositoryProperties = "use_repository_properties",
QaTelemetryEnabled = "qa_telemetry_enabled",
ResolveSupportedLanguagesUsingCli = "resolve_supported_languages_using_cli",
UseRepositoryProperties = "use_repository_properties",
}
export const featureConfig: Record<
@@ -110,11 +109,6 @@ export const featureConfig: Record<
toolsFeature?: ToolsFeature;
}
> = {
[Feature.AllowToolcacheInput]: {
defaultValue: false,
envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT",
minimumVersion: undefined,
},
[Feature.CleanupTrapCaches]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
+54 -2
View File
@@ -33,6 +33,11 @@ import {
logUnwrittenDiagnostics,
makeDiagnostic,
} from "./diagnostics";
import {
getPullRequestEditedDiffRanges,
writeDiffRangesJsonFile,
getDiffInformedAnalysisBranches,
} from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment";
import { Feature, Features } from "./feature-flags";
import { loadPropertiesFromApi } from "./feature-flags/properties";
@@ -45,7 +50,7 @@ import {
runDatabaseInitCluster,
} from "./init";
import { KnownLanguage } from "./languages";
import { getActionsLogger, Logger } from "./logging";
import { getActionsLogger, Logger, withGroupAsync } from "./logging";
import {
downloadOverlayBaseDatabaseFromCache,
OverlayBaseDatabaseDownloadStats,
@@ -175,6 +180,7 @@ async function run() {
persistInputs();
let config: configUtils.Config | undefined;
let prDiffChangedFiles: Set<string> | undefined;
let codeql: CodeQL;
let toolsDownloadStatusReport: ToolsDownloadStatusReport | undefined;
let toolsFeatureFlagsValid: boolean | undefined;
@@ -248,7 +254,6 @@ async function run() {
getTemporaryDirectory(),
gitHubVersion.type,
codeQLDefaultVersionInfo,
features,
logger,
);
codeql = initCodeQLResult.codeql;
@@ -337,6 +342,12 @@ async function run() {
});
await checkInstallPython311(config.languages, codeql);
prDiffChangedFiles = await computeAndPersistDiffRanges(
codeql,
features,
logger,
);
} catch (unwrappedError) {
const error = wrapError(unwrappedError);
core.setFailed(error.message);
@@ -663,6 +674,7 @@ async function run() {
sourceRoot,
"Runner.Worker.exe",
qlconfigFile,
prDiffChangedFiles,
logger,
);
@@ -692,6 +704,7 @@ async function run() {
sourceRoot,
"Runner.Worker.exe",
qlconfigFile,
prDiffChangedFiles,
logger,
);
}
@@ -749,6 +762,45 @@ async function run() {
);
}
/**
* Compute and persist diff ranges early during init when diff-informed analysis
* is enabled (feature flag + PR context). This writes the standard pr-diff-range.json
* file for later reuse in the analyze step. Failures are logged but non-fatal.
*/
async function computeAndPersistDiffRanges(
codeql: CodeQL,
features: Features,
logger: Logger,
): Promise<Set<string> | undefined> {
try {
return await withGroupAsync("Compute PR diff ranges", async () => {
const branches = await getDiffInformedAnalysisBranches(
codeql,
features,
logger,
);
if (!branches) {
return undefined;
}
const ranges = await getPullRequestEditedDiffRanges(branches, logger);
if (ranges === undefined) {
return undefined;
}
writeDiffRangesJsonFile(logger, ranges);
const distinctFiles = new Set(ranges.map((r) => r.path));
logger.info(
`Persisted ${ranges.length} diff range(s) across ${distinctFiles.size} file(s) for reuse during analyze step.`,
);
return distinctFiles;
});
} catch (e) {
logger.warning(
`Failed to compute and persist PR diff ranges early: ${getErrorMessage(e)}`,
);
return undefined;
}
}
function getTrapCachingEnabled(): boolean {
// If the workflow specified something always respect that
const trapCaching = getOptionalInput("trap-caching");
+3 -3
View File
@@ -9,7 +9,7 @@ import { getOptionalInput, isSelfHostedRunner } from "./actions-util";
import { GitHubApiDetails } from "./api-client";
import { CodeQL, setupCodeQL } from "./codeql";
import * as configUtils from "./config-utils";
import { CodeQLDefaultVersionInfo, FeatureEnablement } from "./feature-flags";
import { CodeQLDefaultVersionInfo } from "./feature-flags";
import { KnownLanguage, Language } from "./languages";
import { Logger, withGroupAsync } from "./logging";
import { ToolsSource } from "./setup-codeql";
@@ -23,7 +23,6 @@ export async function initCodeQL(
tempDir: string,
variant: util.GitHubVariant,
defaultCliVersion: CodeQLDefaultVersionInfo,
features: FeatureEnablement,
logger: Logger,
): Promise<{
codeql: CodeQL;
@@ -45,7 +44,6 @@ export async function initCodeQL(
tempDir,
variant,
defaultCliVersion,
features,
logger,
true,
);
@@ -75,6 +73,7 @@ export async function runDatabaseInitCluster(
sourceRoot: string,
processName: string | undefined,
qlconfigFile: string | undefined,
prDiffChangedFiles: Set<string> | undefined,
logger: Logger,
): Promise<void> {
fs.mkdirSync(config.dbLocation, { recursive: true });
@@ -86,6 +85,7 @@ export async function runDatabaseInitCluster(
sourceRoot,
processName,
qlconfigFile,
prDiffChangedFiles,
logger,
),
);
+1
View File
@@ -69,6 +69,7 @@ test("writeOverlayChangesFile generates correct changes file", async (t) => {
const changesFilePath = await writeOverlayChangesFile(
config,
sourceRoot,
new Set([]), // The PR didn't touch any files
logger,
);
getFileOidsStubForOverlay.restore();
+39 -1
View File
@@ -116,13 +116,51 @@ function getBaseDatabaseOidsFilePath(config: Config): string {
export async function writeOverlayChangesFile(
config: Config,
sourceRoot: string,
prDiffChangedFiles: Set<string> | undefined,
logger: Logger,
): Promise<string> {
const baseFileOids = await readBaseDatabaseOidsFile(config, logger);
const overlayFileOids = await getFileOidsUnderPath(sourceRoot);
const changedFiles = computeChangedFiles(baseFileOids, overlayFileOids);
// Augment changed files with any files that appear in the precomputed PR diff ranges.
// This ensures overlay analysis always includes every file with at least one edited range.
const originalCount = changedFiles.length;
let extraAddedCount = 0;
try {
if (prDiffChangedFiles && prDiffChangedFiles.size > 0) {
const existing = new Set(changedFiles);
for (const f of prDiffChangedFiles) {
if (!existing.has(f)) {
// Only include if file still exists (added/modified) — skip deleted files that might appear in diff.
if (
overlayFileOids[f] !== undefined ||
fs.existsSync(path.join(sourceRoot, f))
) {
existing.add(f);
changedFiles.push(f);
extraAddedCount++;
}
}
}
if (extraAddedCount > 0) {
logger.debug(
`Added ${extraAddedCount} file(s) from PR diff ranges into overlay: ${changedFiles.slice(-extraAddedCount).join(", ")}`,
);
} else {
logger.debug(
"All diff range files were already present in the diff from the base database.",
);
}
}
} catch (e) {
logger.debug(
`Failed while attempting to add diff range files in overlay: ${(e as any).message || e}`,
);
}
logger.info(
`Found ${changedFiles.length} changed file(s) under ${sourceRoot}.`,
`Found ${originalCount} natural changed file(s); added from diff ${extraAddedCount}; total ${changedFiles.length} under ${sourceRoot}.`,
);
const changedFilesJson = JSON.stringify({ changes: changedFiles });
+44 -100
View File
@@ -1,7 +1,7 @@
import * as path from "path";
import * as toolcache from "@actions/tool-cache";
import test, { ExecutionContext } from "ava";
import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
@@ -13,7 +13,6 @@ import {
LoggedMessage,
SAMPLE_DEFAULT_CLI_VERSION,
SAMPLE_DOTCOM_API_DETAILS,
createFeatures,
getRecordingLogger,
initializeFeatures,
mockBundleDownloadApi,
@@ -92,8 +91,6 @@ test("getCodeQLActionRepository", (t) => {
});
test("getCodeQLSource sets CLI version for a semver tagged bundle", async (t) => {
const features = createFeatures([]);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const tagName = "codeql-bundle-v1.2.3";
@@ -104,7 +101,6 @@ test("getCodeQLSource sets CLI version for a semver tagged bundle", async (t) =>
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
features,
getRunnerLogger(true),
);
@@ -114,8 +110,6 @@ test("getCodeQLSource sets CLI version for a semver tagged bundle", async (t) =>
});
test("getCodeQLSource correctly returns bundled CLI version when tools == linked", async (t) => {
const features = createFeatures([]);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const source = await setupCodeql.getCodeQLSource(
@@ -124,7 +118,6 @@ test("getCodeQLSource correctly returns bundled CLI version when tools == linked
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
features,
getRunnerLogger(true),
);
@@ -136,7 +129,6 @@ test("getCodeQLSource correctly returns bundled CLI version when tools == linked
test("getCodeQLSource correctly returns bundled CLI version when tools == latest", async (t) => {
const loggedMessages: LoggedMessage[] = [];
const logger = getRecordingLogger(loggedMessages);
const features = createFeatures([]);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -146,7 +138,6 @@ test("getCodeQLSource correctly returns bundled CLI version when tools == latest
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
features,
logger,
);
@@ -171,7 +162,6 @@ test("getCodeQLSource correctly returns bundled CLI version when tools == latest
test("setupCodeQLBundle logs the CodeQL CLI version being used when asked to use linked tools", async (t) => {
const loggedMessages: LoggedMessage[] = [];
const logger = getRecordingLogger(loggedMessages);
const features = createFeatures([]);
// Stub the downloadCodeQL function to prevent downloading artefacts
// during testing from being called.
@@ -196,7 +186,6 @@ test("setupCodeQLBundle logs the CodeQL CLI version being used when asked to use
"tmp/codeql_action_test/",
GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
features,
logger,
);
@@ -219,7 +208,6 @@ test("setupCodeQLBundle logs the CodeQL CLI version being used when asked to use
test("setupCodeQLBundle logs the CodeQL CLI version being used when asked to download a non-default bundle", async (t) => {
const loggedMessages: LoggedMessage[] = [];
const logger = getRecordingLogger(loggedMessages);
const features = createFeatures([]);
const bundleUrl =
"https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.16.0/codeql-bundle-linux64.tar.gz";
@@ -248,7 +236,6 @@ test("setupCodeQLBundle logs the CodeQL CLI version being used when asked to dow
"tmp/codeql_action_test/",
GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
features,
logger,
);
@@ -271,7 +258,6 @@ test("setupCodeQLBundle logs the CodeQL CLI version being used when asked to dow
test("getCodeQLSource correctly returns latest version from toolcache when tools == toolcache", async (t) => {
const loggedMessages: LoggedMessage[] = [];
const logger = getRecordingLogger(loggedMessages);
const features = createFeatures([Feature.AllowToolcacheInput]);
process.env["GITHUB_EVENT_NAME"] = "dynamic";
@@ -294,7 +280,6 @@ test("getCodeQLSource correctly returns latest version from toolcache when tools
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
features,
logger,
);
@@ -325,103 +310,62 @@ test("getCodeQLSource correctly returns latest version from toolcache when tools
typeof msg.message === "string" &&
msg.message.includes(expectedMessage),
),
`Expected '${expectedMessage}' in the logger output, but didn't find it in:\n ${loggedMessages.map((m) => ` - '${m.message}'`).join("\n")}`,
`Expected '${expectedMessage}' in the logger output, but didn't find it.`,
);
}
});
});
const toolcacheInputFallbackMacro = test.macro({
exec: async (
t: ExecutionContext<unknown>,
featureList: Feature[],
environment: Record<string, string>,
testVersions: string[],
expectedMessages: string[],
) => {
const loggedMessages: LoggedMessage[] = [];
const logger = getRecordingLogger(loggedMessages);
const features = createFeatures(featureList);
test("getCodeQLSource falls back to downloading the CLI if the toolcache doesn't have a CodeQL CLI when tools == toolcache", async (t) => {
const loggedMessages: LoggedMessage[] = [];
const logger = getRecordingLogger(loggedMessages);
for (const [k, v] of Object.entries(environment)) {
process.env[k] = v;
}
process.env["GITHUB_EVENT_NAME"] = "dynamic";
const findAllVersionsStub = sinon
.stub(toolcache, "findAllVersions")
.returns(testVersions);
const testVersions = [];
const findAllVersionsStub = sinon
.stub(toolcache, "findAllVersions")
.returns(testVersions);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const source = await setupCodeql.getCodeQLSource(
"toolcache",
SAMPLE_DEFAULT_CLI_VERSION,
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
features,
logger,
);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const source = await setupCodeql.getCodeQLSource(
"toolcache",
SAMPLE_DEFAULT_CLI_VERSION,
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
logger,
);
// Check that the toolcache functions were called with the expected arguments
// Check that the toolcache functions were called with the expected arguments
t.assert(
findAllVersionsStub.calledWith("CodeQL"),
`toolcache.findAllVersions("CodeQL") wasn't called`,
);
// Check that `sourceType` and `toolsVersion` match expectations.
t.is(source.sourceType, "download");
t.is(source.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion);
// Check that key messages we would expect to find in the log are present.
const expectedMessages: string[] = [
`Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: toolcache'.`,
`Found no CodeQL CLI in the toolcache, ignoring 'tools: toolcache'...`,
];
for (const expectedMessage of expectedMessages) {
t.assert(
findAllVersionsStub.calledWith("CodeQL"),
`toolcache.findAllVersions("CodeQL") wasn't called`,
loggedMessages.some(
(msg) =>
typeof msg.message === "string" &&
msg.message.includes(expectedMessage),
),
`Expected '${expectedMessage}' in the logger output, but didn't find it.`,
);
// Check that `sourceType` and `toolsVersion` match expectations.
t.is(source.sourceType, "download");
t.is(source.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion);
// Check that key messages we would expect to find in the log are present.
for (const expectedMessage of expectedMessages) {
t.assert(
loggedMessages.some(
(msg) =>
typeof msg.message === "string" &&
msg.message.includes(expectedMessage),
),
`Expected '${expectedMessage}' in the logger output, but didn't find it in:\n ${loggedMessages.map((m) => ` - '${m.message}'`).join("\n")}`,
);
}
});
},
title: (providedTitle = "") =>
`getCodeQLSource falls back to downloading the CLI if ${providedTitle}`,
}
});
});
test(
"the toolcache doesn't have a CodeQL CLI when tools == toolcache",
toolcacheInputFallbackMacro,
[Feature.AllowToolcacheInput],
{ GITHUB_EVENT_NAME: "dynamic" },
[],
[
`Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: toolcache'.`,
`Found no CodeQL CLI in the toolcache, ignoring 'tools: toolcache'...`,
],
);
test(
"the workflow trigger is not `dynamic`",
toolcacheInputFallbackMacro,
[Feature.AllowToolcacheInput],
{ GITHUB_EVENT_NAME: "pull_request" },
[],
[
`Ignoring 'tools: toolcache' because the workflow was not triggered dynamically.`,
],
);
test(
"the feature flag is not enabled",
toolcacheInputFallbackMacro,
[],
{ GITHUB_EVENT_NAME: "dynamic" },
[],
[`Ignoring 'tools: toolcache' because the feature is not enabled.`],
);
test('tryGetTagNameFromUrl extracts the right tag name for a repo name containing "codeql-bundle"', (t) => {
t.is(
setupCodeql.tryGetTagNameFromUrl(
+4 -19
View File
@@ -13,8 +13,6 @@ import * as defaults from "./defaults.json";
import {
CODEQL_VERSION_ZSTD_BUNDLE,
CodeQLDefaultVersionInfo,
Feature,
FeatureEnablement,
} from "./feature-flags";
import { Logger } from "./logging";
import * as tar from "./tar";
@@ -278,7 +276,6 @@ export async function getCodeQLSource(
apiDetails: api.GitHubApiDetails,
variant: util.GitHubVariant,
tarSupportsZstd: boolean,
features: FeatureEnablement,
logger: Logger,
): Promise<CodeQLToolsSource> {
if (
@@ -359,11 +356,7 @@ export async function getCodeQLSource(
// We only allow `toolsInput === "toolcache"` for `dynamic` events. In general, using `toolsInput === "toolcache"`
// can lead to alert wobble and so it shouldn't be used for an analysis where results are intended to be uploaded.
// We also allow this in test mode.
const allowToolcacheValueFF = await features.getValue(
Feature.AllowToolcacheInput,
);
const allowToolcacheValue =
allowToolcacheValueFF && (isDynamicWorkflow() || util.isInTestMode());
const allowToolcacheValue = isDynamicWorkflow() || util.isInTestMode();
if (allowToolcacheValue) {
// If `toolsInput === "toolcache"`, try to find the latest version of the CLI that's available in the toolcache
// and use that. We perform this check here since we can set `cliVersion` directly and don't want to default to
@@ -384,15 +377,9 @@ export async function getCodeQLSource(
`Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...`,
);
} else {
if (allowToolcacheValueFF) {
logger.warning(
`Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`,
);
} else {
logger.info(
`Ignoring 'tools: ${toolsInput}' because the feature is not enabled.`,
);
}
logger.warning(
`Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`,
);
}
cliVersion = defaultCliVersion.cliVersion;
@@ -748,7 +735,6 @@ export async function setupCodeQLBundle(
tempDir: string,
variant: util.GitHubVariant,
defaultCliVersion: CodeQLDefaultVersionInfo,
features: FeatureEnablement,
logger: Logger,
) {
if (!(await util.isBinaryAccessible("tar", logger))) {
@@ -764,7 +750,6 @@ export async function setupCodeQLBundle(
apiDetails,
variant,
zstdAvailability.available,
features,
logger,
);
-93
View File
@@ -1,14 +1,9 @@
import * as fs from "fs";
import * as path from "path";
import * as github from "@actions/github";
import { HTTPError } from "@actions/tool-cache";
import test from "ava";
import * as sinon from "sinon";
import * as analyses from "./analyses";
import { AnalysisKind, CodeQuality, CodeScanning } from "./analyses";
import * as api from "./api-client";
import { getRunnerLogger, Logger } from "./logging";
import { setupTests } from "./testing-utils";
import * as uploadLib from "./upload-lib";
@@ -872,91 +867,3 @@ function createMockSarif(id?: string, tool?: string) {
],
};
}
function uploadPayloadFixtures(analysis: analyses.AnalysisConfig) {
const mockData = {
payload: { sarif: "base64data", commit_sha: "abc123" },
owner: "test-owner",
repo: "test-repo",
response: {
status: 200,
data: { id: "uploaded-sarif-id" },
headers: {},
url: analysis.target,
},
};
const client = github.getOctokit("123");
sinon.stub(api, "getApiClient").value(() => client);
const requestStub = sinon.stub(client, "request");
const upload = async () =>
uploadLib.uploadPayload(
mockData.payload,
{
owner: mockData.owner,
repo: mockData.repo,
},
getRunnerLogger(true),
analysis,
);
return {
upload,
requestStub,
mockData,
};
}
for (const analysis of [CodeScanning, CodeQuality]) {
test(`uploadPayload on ${analysis.name} uploads successfully`, async (t) => {
const { upload, requestStub, mockData } = uploadPayloadFixtures(analysis);
requestStub
.withArgs(analysis.target, {
owner: mockData.owner,
repo: mockData.repo,
data: mockData.payload,
})
.onFirstCall()
.returns(Promise.resolve(mockData.response));
const result = await upload();
t.is(result, mockData.response.data.id);
t.true(requestStub.calledOnce);
});
for (const envVar of [
"CODEQL_ACTION_SKIP_SARIF_UPLOAD",
"CODEQL_ACTION_TEST_MODE",
]) {
test(`uploadPayload on ${analysis.name} skips upload when ${envVar} is set`, async (t) => {
const { upload, requestStub, mockData } = uploadPayloadFixtures(analysis);
await withTmpDir(async (tmpDir) => {
process.env.RUNNER_TEMP = tmpDir;
process.env[envVar] = "true";
const result = await upload();
t.is(result, "dummy-sarif-id");
t.false(requestStub.called);
const payloadFile = path.join(tmpDir, `payload-${analysis.kind}.json`);
t.true(fs.existsSync(payloadFile));
const savedPayload = JSON.parse(fs.readFileSync(payloadFile, "utf8"));
t.deepEqual(savedPayload, mockData.payload);
});
});
}
test(`uploadPayload on ${analysis.name} wraps request errors using wrapApiConfigurationError`, async (t) => {
const { upload, requestStub } = uploadPayloadFixtures(analysis);
const wrapApiConfigurationErrorStub = sinon.stub(
api,
"wrapApiConfigurationError",
);
const originalError = new HTTPError(404);
const wrappedError = new Error("Wrapped error message");
requestStub.rejects(originalError);
wrapApiConfigurationErrorStub.withArgs(originalError).returns(wrappedError);
await t.throwsAsync(upload, {
is: wrappedError,
});
});
}
+3 -7
View File
@@ -262,7 +262,6 @@ async function combineSarifFilesUsingCLI(
tempDir,
gitHubVersion.type,
codeQLDefaultVersionInfo,
features,
logger,
);
@@ -347,12 +346,9 @@ function getAutomationID(
return api.computeAutomationID(analysis_key, environment);
}
/**
* Upload the given payload.
* If the request fails then this will retry a small number of times.
* This is exported for testing purposes only.
*/
export async function uploadPayload(
// Upload the given payload.
// If the request fails then this will retry a small number of times.
async function uploadPayload(
payload: any,
repositoryNwo: RepositoryNwo,
logger: Logger,