mirror of
https://github.com/github/codeql-action.git
synced 2025-12-18 05:19:18 +08:00
Compare commits
23 Commits
v4
...
copilot/up
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2c3c8e3e2 | ||
|
|
a13b404670 | ||
|
|
056581e05b | ||
|
|
9c5588d006 | ||
|
|
3765106c90 | ||
|
|
e052dbd57d | ||
|
|
32795b3c52 | ||
|
|
b88acb2f6c | ||
|
|
241948c698 | ||
|
|
1fe89fe9cb | ||
|
|
6dba00881c | ||
|
|
d4d47c0d3d | ||
|
|
6c6e810910 | ||
|
|
393c074965 | ||
|
|
c3dc529aef | ||
|
|
fc2bbb041e | ||
|
|
89753aa84b | ||
|
|
aff7998c4a | ||
|
|
7a5748cf0d | ||
|
|
db75d46248 | ||
|
|
a0fc644617 | ||
|
|
e1058e4d74 | ||
|
|
d4f39b0766 |
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs.
|
See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs.
|
||||||
|
|
||||||
|
## [UNRELEASED]
|
||||||
|
|
||||||
|
No user facing changes.
|
||||||
|
|
||||||
## 4.31.9 - 16 Dec 2025
|
## 4.31.9 - 16 Dec 2025
|
||||||
|
|
||||||
No user facing changes.
|
No user facing changes.
|
||||||
|
|||||||
42654
lib/analyze-action-post.js
generated
42654
lib/analyze-action-post.js
generated
File diff suppressed because it is too large
Load Diff
37486
lib/analyze-action.js
generated
37486
lib/analyze-action.js
generated
File diff suppressed because it is too large
Load Diff
36151
lib/autobuild-action.js
generated
36151
lib/autobuild-action.js
generated
File diff suppressed because it is too large
Load Diff
42716
lib/init-action-post.js
generated
42716
lib/init-action-post.js
generated
File diff suppressed because it is too large
Load Diff
37595
lib/init-action.js
generated
37595
lib/init-action.js
generated
File diff suppressed because it is too large
Load Diff
36149
lib/resolve-environment-action.js
generated
36149
lib/resolve-environment-action.js
generated
File diff suppressed because it is too large
Load Diff
36143
lib/setup-codeql-action.js
generated
36143
lib/setup-codeql-action.js
generated
File diff suppressed because it is too large
Load Diff
42638
lib/start-proxy-action-post.js
generated
42638
lib/start-proxy-action-post.js
generated
File diff suppressed because it is too large
Load Diff
36478
lib/start-proxy-action.js
generated
36478
lib/start-proxy-action.js
generated
File diff suppressed because it is too large
Load Diff
36187
lib/upload-lib.js
generated
36187
lib/upload-lib.js
generated
File diff suppressed because it is too large
Load Diff
42550
lib/upload-sarif-action-post.js
generated
42550
lib/upload-sarif-action-post.js
generated
File diff suppressed because it is too large
Load Diff
36161
lib/upload-sarif-action.js
generated
36161
lib/upload-sarif-action.js
generated
File diff suppressed because it is too large
Load Diff
984
package-lock.json
generated
984
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "codeql",
|
"name": "codeql",
|
||||||
"version": "4.31.9",
|
"version": "4.31.10",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "CodeQL action",
|
"description": "CodeQL action",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -24,12 +24,12 @@
|
|||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/artifact": "^4.0.0",
|
"@actions/artifact": "^5.0.1",
|
||||||
"@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2",
|
"@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2",
|
||||||
"@actions/cache": "^4.1.0",
|
"@actions/cache": "^5.0.1",
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^2.0.1",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^2.0.0",
|
||||||
"@actions/github": "^6.0.0",
|
"@actions/github": "^6.0.1",
|
||||||
"@actions/glob": "^0.5.0",
|
"@actions/glob": "^0.5.0",
|
||||||
"@actions/http-client": "^3.0.0",
|
"@actions/http-client": "^3.0.0",
|
||||||
"@actions/io": "^2.0.0",
|
"@actions/io": "^2.0.0",
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
"@ava/typescript": "6.0.0",
|
"@ava/typescript": "6.0.0",
|
||||||
"@eslint/compat": "^2.0.0",
|
"@eslint/compat": "^2.0.0",
|
||||||
"@eslint/eslintrc": "^3.3.3",
|
"@eslint/eslintrc": "^3.3.3",
|
||||||
"@eslint/js": "^9.39.1",
|
"@eslint/js": "^9.39.2",
|
||||||
"@microsoft/eslint-formatter-sarif": "^3.1.0",
|
"@microsoft/eslint-formatter-sarif": "^3.1.0",
|
||||||
"@octokit/types": "^16.0.0",
|
"@octokit/types": "^16.0.0",
|
||||||
"@types/archiver": "^7.0.0",
|
"@types/archiver": "^7.0.0",
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
"@types/node-forge": "^1.3.14",
|
"@types/node-forge": "^1.3.14",
|
||||||
"@types/semver": "^7.7.1",
|
"@types/semver": "^7.7.1",
|
||||||
"@types/sinon": "^21.0.0",
|
"@types/sinon": "^21.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
"@typescript-eslint/eslint-plugin": "^8.49.0",
|
||||||
"@typescript-eslint/parser": "^8.48.0",
|
"@typescript-eslint/parser": "^8.48.0",
|
||||||
"ava": "^6.4.1",
|
"ava": "^6.4.1",
|
||||||
"esbuild": "^0.27.1",
|
"esbuild": "^0.27.1",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import * as configUtils from "./config-utils";
|
|||||||
import * as errorMessages from "./error-messages";
|
import * as errorMessages from "./error-messages";
|
||||||
import { Feature } from "./feature-flags";
|
import { Feature } from "./feature-flags";
|
||||||
import * as gitUtils from "./git-utils";
|
import * as gitUtils from "./git-utils";
|
||||||
|
import { GitVersionInfo } from "./git-utils";
|
||||||
import { KnownLanguage, Language } from "./languages";
|
import { KnownLanguage, Language } from "./languages";
|
||||||
import { getRunnerLogger } from "./logging";
|
import { getRunnerLogger } from "./logging";
|
||||||
import {
|
import {
|
||||||
@@ -978,6 +979,7 @@ interface OverlayDatabaseModeTestSetup {
|
|||||||
languages: Language[];
|
languages: Language[];
|
||||||
codeqlVersion: string;
|
codeqlVersion: string;
|
||||||
gitRoot: string | undefined;
|
gitRoot: string | undefined;
|
||||||
|
gitVersion: GitVersionInfo | undefined;
|
||||||
codeScanningConfig: configUtils.UserConfig;
|
codeScanningConfig: configUtils.UserConfig;
|
||||||
diskUsage: DiskUsage | undefined;
|
diskUsage: DiskUsage | undefined;
|
||||||
memoryFlagValue: number;
|
memoryFlagValue: number;
|
||||||
@@ -992,6 +994,10 @@ const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = {
|
|||||||
languages: [KnownLanguage.javascript],
|
languages: [KnownLanguage.javascript],
|
||||||
codeqlVersion: CODEQL_OVERLAY_MINIMUM_VERSION,
|
codeqlVersion: CODEQL_OVERLAY_MINIMUM_VERSION,
|
||||||
gitRoot: "/some/git/root",
|
gitRoot: "/some/git/root",
|
||||||
|
gitVersion: new GitVersionInfo(
|
||||||
|
gitUtils.GIT_MINIMUM_VERSION_FOR_OVERLAY,
|
||||||
|
gitUtils.GIT_MINIMUM_VERSION_FOR_OVERLAY,
|
||||||
|
),
|
||||||
codeScanningConfig: {},
|
codeScanningConfig: {},
|
||||||
diskUsage: {
|
diskUsage: {
|
||||||
numAvailableBytes: 50_000_000_000,
|
numAvailableBytes: 50_000_000_000,
|
||||||
@@ -1070,6 +1076,7 @@ const getOverlayDatabaseModeMacro = test.macro({
|
|||||||
setup.buildMode,
|
setup.buildMode,
|
||||||
undefined,
|
undefined,
|
||||||
setup.codeScanningConfig,
|
setup.codeScanningConfig,
|
||||||
|
setup.gitVersion,
|
||||||
logger,
|
logger,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1773,6 +1780,32 @@ test(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
getOverlayDatabaseModeMacro,
|
||||||
|
"Fallback due to old git version",
|
||||||
|
{
|
||||||
|
overlayDatabaseEnvVar: "overlay",
|
||||||
|
gitVersion: new GitVersionInfo("2.30.0", "2.30.0"), // Version below required 2.38.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
overlayDatabaseMode: OverlayDatabaseMode.None,
|
||||||
|
useOverlayDatabaseCaching: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
getOverlayDatabaseModeMacro,
|
||||||
|
"Fallback when git version cannot be determined",
|
||||||
|
{
|
||||||
|
overlayDatabaseEnvVar: "overlay",
|
||||||
|
gitVersion: undefined,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
overlayDatabaseMode: OverlayDatabaseMode.None,
|
||||||
|
useOverlayDatabaseCaching: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Exercise language-specific overlay analysis features code paths
|
// Exercise language-specific overlay analysis features code paths
|
||||||
for (const language in KnownLanguage) {
|
for (const language in KnownLanguage) {
|
||||||
test(
|
test(
|
||||||
|
|||||||
@@ -22,11 +22,18 @@ import {
|
|||||||
parseUserConfig,
|
parseUserConfig,
|
||||||
UserConfig,
|
UserConfig,
|
||||||
} from "./config/db-config";
|
} from "./config/db-config";
|
||||||
|
import { addDiagnostic, makeTelemetryDiagnostic } from "./diagnostics";
|
||||||
import { shouldPerformDiffInformedAnalysis } from "./diff-informed-analysis-utils";
|
import { shouldPerformDiffInformedAnalysis } from "./diff-informed-analysis-utils";
|
||||||
import * as errorMessages from "./error-messages";
|
import * as errorMessages from "./error-messages";
|
||||||
import { Feature, FeatureEnablement } from "./feature-flags";
|
import { Feature, FeatureEnablement } from "./feature-flags";
|
||||||
import { RepositoryProperties } from "./feature-flags/properties";
|
import { RepositoryProperties } from "./feature-flags/properties";
|
||||||
import { getGitRoot, isAnalyzingDefaultBranch } from "./git-utils";
|
import {
|
||||||
|
getGitRoot,
|
||||||
|
getGitVersionOrThrow,
|
||||||
|
GIT_MINIMUM_VERSION_FOR_OVERLAY,
|
||||||
|
GitVersionInfo,
|
||||||
|
isAnalyzingDefaultBranch,
|
||||||
|
} from "./git-utils";
|
||||||
import { KnownLanguage, Language } from "./languages";
|
import { KnownLanguage, Language } from "./languages";
|
||||||
import { Logger } from "./logging";
|
import { Logger } from "./logging";
|
||||||
import {
|
import {
|
||||||
@@ -45,6 +52,7 @@ import {
|
|||||||
isDefined,
|
isDefined,
|
||||||
checkDiskUsage,
|
checkDiskUsage,
|
||||||
getCodeQLMemoryLimit,
|
getCodeQLMemoryLimit,
|
||||||
|
getErrorMessage,
|
||||||
} from "./util";
|
} from "./util";
|
||||||
|
|
||||||
export * from "./config/db-config";
|
export * from "./config/db-config";
|
||||||
@@ -709,6 +717,7 @@ export async function getOverlayDatabaseMode(
|
|||||||
buildMode: BuildMode | undefined,
|
buildMode: BuildMode | undefined,
|
||||||
ramInput: string | undefined,
|
ramInput: string | undefined,
|
||||||
codeScanningConfig: UserConfig,
|
codeScanningConfig: UserConfig,
|
||||||
|
gitVersion: GitVersionInfo | undefined,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
): Promise<{
|
): Promise<{
|
||||||
overlayDatabaseMode: OverlayDatabaseMode;
|
overlayDatabaseMode: OverlayDatabaseMode;
|
||||||
@@ -811,6 +820,22 @@ export async function getOverlayDatabaseMode(
|
|||||||
);
|
);
|
||||||
return nonOverlayAnalysis;
|
return nonOverlayAnalysis;
|
||||||
}
|
}
|
||||||
|
if (gitVersion === undefined) {
|
||||||
|
logger.warning(
|
||||||
|
`Cannot build an ${overlayDatabaseMode} database because ` +
|
||||||
|
"the Git version could not be determined. " +
|
||||||
|
"Falling back to creating a normal full database instead.",
|
||||||
|
);
|
||||||
|
return nonOverlayAnalysis;
|
||||||
|
}
|
||||||
|
if (!gitVersion.isAtLeast(GIT_MINIMUM_VERSION_FOR_OVERLAY)) {
|
||||||
|
logger.warning(
|
||||||
|
`Cannot build an ${overlayDatabaseMode} database because ` +
|
||||||
|
`the installed Git version is older than ${GIT_MINIMUM_VERSION_FOR_OVERLAY}. ` +
|
||||||
|
"Falling back to creating a normal full database instead.",
|
||||||
|
);
|
||||||
|
return nonOverlayAnalysis;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
overlayDatabaseMode,
|
overlayDatabaseMode,
|
||||||
@@ -903,6 +928,15 @@ export async function initConfig(
|
|||||||
config.computedConfig["query-filters"] = [];
|
config.computedConfig["query-filters"] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let gitVersion: GitVersionInfo | undefined = undefined;
|
||||||
|
try {
|
||||||
|
gitVersion = await getGitVersionOrThrow();
|
||||||
|
logger.info(`Using Git version ${gitVersion.fullVersion}`);
|
||||||
|
await logGitVersionTelemetry(config, gitVersion);
|
||||||
|
} catch (e) {
|
||||||
|
logger.warning(`Could not determine Git version: ${getErrorMessage(e)}`);
|
||||||
|
}
|
||||||
|
|
||||||
// The choice of overlay database mode depends on the selection of languages
|
// The choice of overlay database mode depends on the selection of languages
|
||||||
// and queries, which in turn depends on the user config and the augmentation
|
// and queries, which in turn depends on the user config and the augmentation
|
||||||
// properties. So we need to calculate the overlay database mode after the
|
// properties. So we need to calculate the overlay database mode after the
|
||||||
@@ -916,6 +950,7 @@ export async function initConfig(
|
|||||||
config.buildMode,
|
config.buildMode,
|
||||||
inputs.ramInput,
|
inputs.ramInput,
|
||||||
config.computedConfig,
|
config.computedConfig,
|
||||||
|
gitVersion,
|
||||||
logger,
|
logger,
|
||||||
);
|
);
|
||||||
logger.info(
|
logger.info(
|
||||||
@@ -1316,3 +1351,26 @@ export function getPrimaryAnalysisConfig(config: Config): AnalysisConfig {
|
|||||||
? CodeScanning
|
? CodeScanning
|
||||||
: CodeQuality;
|
: CodeQuality;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Logs the Git version as a telemetry diagnostic. */
|
||||||
|
async function logGitVersionTelemetry(
|
||||||
|
config: Config,
|
||||||
|
gitVersion: GitVersionInfo,
|
||||||
|
): Promise<void> {
|
||||||
|
if (config.languages.length > 0) {
|
||||||
|
addDiagnostic(
|
||||||
|
config,
|
||||||
|
// Arbitrarily choose the first language. We could also choose all languages, but that
|
||||||
|
// increases the risk of misinterpreting the data.
|
||||||
|
config.languages[0],
|
||||||
|
makeTelemetryDiagnostic(
|
||||||
|
"codeql-action/git-version-telemetry",
|
||||||
|
"Git version telemetry",
|
||||||
|
{
|
||||||
|
fullVersion: gitVersion.fullVersion,
|
||||||
|
truncatedVersion: gitVersion.truncatedVersion,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -185,3 +185,27 @@ export function flushDiagnostics(config: Config) {
|
|||||||
// Reset the unwritten diagnostics array.
|
// Reset the unwritten diagnostics array.
|
||||||
unwrittenDiagnostics = [];
|
unwrittenDiagnostics = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a telemetry-only diagnostic message. This is a convenience function
|
||||||
|
* for creating diagnostics that should only be sent to telemetry and not
|
||||||
|
* displayed on the status page or CLI summary table.
|
||||||
|
*
|
||||||
|
* @param id An identifier under which it makes sense to group this diagnostic message
|
||||||
|
* @param name Display name
|
||||||
|
* @param attributes Structured metadata
|
||||||
|
*/
|
||||||
|
export function makeTelemetryDiagnostic(
|
||||||
|
id: string,
|
||||||
|
name: string,
|
||||||
|
attributes: { [key: string]: any },
|
||||||
|
): DiagnosticMessage {
|
||||||
|
return makeDiagnostic(id, name, {
|
||||||
|
attributes,
|
||||||
|
visibility: {
|
||||||
|
cliSummaryTable: false,
|
||||||
|
statusPage: false,
|
||||||
|
telemetry: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -315,27 +315,23 @@ test("getFileOidsUnderPath returns correct file mapping", async (t) => {
|
|||||||
"a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96_src/git-utils.ts",
|
"a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96_src/git-utils.ts",
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
|
||||||
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
|
|
||||||
|
|
||||||
t.deepEqual(result, {
|
t.deepEqual(result, {
|
||||||
"lib/git-utils.js": "30d998ded095371488be3a729eb61d86ed721a18",
|
"lib/git-utils.js": "30d998ded095371488be3a729eb61d86ed721a18",
|
||||||
"lib/git-utils.js.map": "d89514599a9a99f22b4085766d40af7b99974827",
|
"lib/git-utils.js.map": "d89514599a9a99f22b4085766d40af7b99974827",
|
||||||
"src/git-utils.ts": "a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96",
|
"src/git-utils.ts": "a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96",
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(runGitCommandStub.firstCall.args, [
|
t.deepEqual(runGitCommandStub.firstCall.args, [
|
||||||
"/fake/path",
|
"/fake/path",
|
||||||
["ls-files", "--recurse-submodules", "--format=%(objectname)_%(path)"],
|
["ls-files", "--recurse-submodules", "--format=%(objectname)_%(path)"],
|
||||||
"Cannot list Git OIDs of tracked files.",
|
"Cannot list Git OIDs of tracked files.",
|
||||||
]);
|
]);
|
||||||
} finally {
|
|
||||||
runGitCommandStub.restore();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getFileOidsUnderPath handles quoted paths", async (t) => {
|
test("getFileOidsUnderPath handles quoted paths", async (t) => {
|
||||||
const runGitCommandStub = sinon
|
sinon
|
||||||
.stub(gitUtils as any, "runGitCommand")
|
.stub(gitUtils as any, "runGitCommand")
|
||||||
.resolves(
|
.resolves(
|
||||||
"30d998ded095371488be3a729eb61d86ed721a18_lib/normal-file.js\n" +
|
"30d998ded095371488be3a729eb61d86ed721a18_lib/normal-file.js\n" +
|
||||||
@@ -343,34 +339,24 @@ test("getFileOidsUnderPath handles quoted paths", async (t) => {
|
|||||||
'a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96_"lib/file\\twith\\ttabs.js"',
|
'a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96_"lib/file\\twith\\ttabs.js"',
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
|
||||||
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
|
|
||||||
|
|
||||||
t.deepEqual(result, {
|
t.deepEqual(result, {
|
||||||
"lib/normal-file.js": "30d998ded095371488be3a729eb61d86ed721a18",
|
"lib/normal-file.js": "30d998ded095371488be3a729eb61d86ed721a18",
|
||||||
"lib/file with spaces.js": "d89514599a9a99f22b4085766d40af7b99974827",
|
"lib/file with spaces.js": "d89514599a9a99f22b4085766d40af7b99974827",
|
||||||
"lib/file\twith\ttabs.js": "a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96",
|
"lib/file\twith\ttabs.js": "a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96",
|
||||||
});
|
});
|
||||||
} finally {
|
|
||||||
runGitCommandStub.restore();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getFileOidsUnderPath handles empty output", async (t) => {
|
test("getFileOidsUnderPath handles empty output", async (t) => {
|
||||||
const runGitCommandStub = sinon
|
sinon.stub(gitUtils as any, "runGitCommand").resolves("");
|
||||||
.stub(gitUtils as any, "runGitCommand")
|
|
||||||
.resolves("");
|
|
||||||
|
|
||||||
try {
|
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
|
||||||
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
|
t.deepEqual(result, {});
|
||||||
t.deepEqual(result, {});
|
|
||||||
} finally {
|
|
||||||
runGitCommandStub.restore();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getFileOidsUnderPath throws on unexpected output format", async (t) => {
|
test("getFileOidsUnderPath throws on unexpected output format", async (t) => {
|
||||||
const runGitCommandStub = sinon
|
sinon
|
||||||
.stub(gitUtils as any, "runGitCommand")
|
.stub(gitUtils as any, "runGitCommand")
|
||||||
.resolves(
|
.resolves(
|
||||||
"30d998ded095371488be3a729eb61d86ed721a18_lib/git-utils.js\n" +
|
"30d998ded095371488be3a729eb61d86ed721a18_lib/git-utils.js\n" +
|
||||||
@@ -378,17 +364,71 @@ test("getFileOidsUnderPath throws on unexpected output format", async (t) => {
|
|||||||
"a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96_src/git-utils.ts",
|
"a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96_src/git-utils.ts",
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
await t.throwsAsync(
|
||||||
await t.throwsAsync(
|
async () => {
|
||||||
async () => {
|
await gitUtils.getFileOidsUnderPath("/fake/path");
|
||||||
await gitUtils.getFileOidsUnderPath("/fake/path");
|
},
|
||||||
},
|
{
|
||||||
{
|
instanceOf: Error,
|
||||||
instanceOf: Error,
|
message: 'Unexpected "git ls-files" output: invalid-line-format',
|
||||||
message: 'Unexpected "git ls-files" output: invalid-line-format',
|
},
|
||||||
},
|
);
|
||||||
);
|
});
|
||||||
} finally {
|
|
||||||
runGitCommandStub.restore();
|
test("getGitVersionOrThrow returns version for valid git output", async (t) => {
|
||||||
}
|
sinon.stub(gitUtils as any, "runGitCommand").resolves("git version 2.40.0");
|
||||||
|
|
||||||
|
const version = await gitUtils.getGitVersionOrThrow();
|
||||||
|
t.is(version.truncatedVersion, "2.40.0");
|
||||||
|
t.is(version.fullVersion, "2.40.0");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("getGitVersionOrThrow throws for invalid git output", async (t) => {
|
||||||
|
sinon.stub(gitUtils as any, "runGitCommand").resolves("invalid output");
|
||||||
|
|
||||||
|
await t.throwsAsync(
|
||||||
|
async () => {
|
||||||
|
await gitUtils.getGitVersionOrThrow();
|
||||||
|
},
|
||||||
|
{
|
||||||
|
instanceOf: Error,
|
||||||
|
message: "Could not parse Git version from output: invalid output",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("getGitVersionOrThrow handles Windows-style git output", async (t) => {
|
||||||
|
sinon
|
||||||
|
.stub(gitUtils as any, "runGitCommand")
|
||||||
|
.resolves("git version 2.40.0.windows.1");
|
||||||
|
|
||||||
|
const version = await gitUtils.getGitVersionOrThrow();
|
||||||
|
// Should extract just the major.minor.patch portion
|
||||||
|
t.is(version.truncatedVersion, "2.40.0");
|
||||||
|
t.is(version.fullVersion, "2.40.0.windows.1");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("getGitVersionOrThrow throws when git command fails", async (t) => {
|
||||||
|
sinon
|
||||||
|
.stub(gitUtils as any, "runGitCommand")
|
||||||
|
.rejects(new Error("git not found"));
|
||||||
|
|
||||||
|
await t.throwsAsync(
|
||||||
|
async () => {
|
||||||
|
await gitUtils.getGitVersionOrThrow();
|
||||||
|
},
|
||||||
|
{
|
||||||
|
instanceOf: Error,
|
||||||
|
message: "git not found",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GitVersionInfo.isAtLeast correctly compares versions", async (t) => {
|
||||||
|
const version = new gitUtils.GitVersionInfo("2.40.0", "2.40.0");
|
||||||
|
|
||||||
|
t.true(version.isAtLeast("2.38.0"));
|
||||||
|
t.true(version.isAtLeast("2.40.0"));
|
||||||
|
t.false(version.isAtLeast("2.41.0"));
|
||||||
|
t.false(version.isAtLeast("3.0.0"));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import * as toolrunner from "@actions/exec/lib/toolrunner";
|
import * as toolrunner from "@actions/exec/lib/toolrunner";
|
||||||
import * as io from "@actions/io";
|
import * as io from "@actions/io";
|
||||||
|
import * as semver from "semver";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getOptionalInput,
|
getOptionalInput,
|
||||||
@@ -9,6 +10,55 @@ import {
|
|||||||
} from "./actions-util";
|
} from "./actions-util";
|
||||||
import { ConfigurationError, getRequiredEnvParam } from "./util";
|
import { ConfigurationError, getRequiredEnvParam } from "./util";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum Git version required for overlay analysis. The `git ls-files --format`
|
||||||
|
* option, which is used by `getFileOidsUnderPath`, was introduced in Git 2.38.0.
|
||||||
|
*/
|
||||||
|
export const GIT_MINIMUM_VERSION_FOR_OVERLAY = "2.38.0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Git version information
|
||||||
|
*
|
||||||
|
* The full version string as reported by `git --version` may not be
|
||||||
|
* semver-compatible (e.g., "2.40.0.windows.1"). This class captures both
|
||||||
|
* the full version string and a truncated semver-compatible version string
|
||||||
|
* (e.g., "2.40.0").
|
||||||
|
*/
|
||||||
|
export class GitVersionInfo {
|
||||||
|
constructor(
|
||||||
|
/** Truncated semver-compatible version */
|
||||||
|
public truncatedVersion: string,
|
||||||
|
/** Full version string as reported by `git --version` */
|
||||||
|
public fullVersion: string,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
isAtLeast(minVersion: string): boolean {
|
||||||
|
return semver.gte(this.truncatedVersion, minVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the version of Git installed on the system and throws an error if
|
||||||
|
* the version cannot be determined.
|
||||||
|
*
|
||||||
|
* @returns The Git version string (e.g., "2.40.0").
|
||||||
|
* @throws {Error} if the version could not be determined.
|
||||||
|
*/
|
||||||
|
export async function getGitVersionOrThrow(): Promise<GitVersionInfo> {
|
||||||
|
const stdout = await runGitCommand(
|
||||||
|
undefined,
|
||||||
|
["--version"],
|
||||||
|
"Failed to get git version.",
|
||||||
|
);
|
||||||
|
// Git version output can vary: "git version 2.40.0" or "git version 2.40.0.windows.1"
|
||||||
|
// We capture just the major.minor.patch portion to ensure semver compatibility.
|
||||||
|
const match = stdout.match(/^git version ((\d+\.\d+\.\d+).*)$/);
|
||||||
|
if (match?.[1]) {
|
||||||
|
return new GitVersionInfo(match[2], match[1]);
|
||||||
|
}
|
||||||
|
throw new Error(`Could not parse Git version from output: ${stdout.trim()}`);
|
||||||
|
}
|
||||||
|
|
||||||
export const runGitCommand = async function (
|
export const runGitCommand = async function (
|
||||||
workingDirectory: string | undefined,
|
workingDirectory: string | undefined,
|
||||||
args: string[],
|
args: string[],
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import {
|
|||||||
flushDiagnostics,
|
flushDiagnostics,
|
||||||
logUnwrittenDiagnostics,
|
logUnwrittenDiagnostics,
|
||||||
makeDiagnostic,
|
makeDiagnostic,
|
||||||
|
makeTelemetryDiagnostic,
|
||||||
} from "./diagnostics";
|
} from "./diagnostics";
|
||||||
import { EnvVar } from "./environment";
|
import { EnvVar } from "./environment";
|
||||||
import { Feature, Features } from "./feature-flags";
|
import { Feature, Features } from "./feature-flags";
|
||||||
@@ -425,17 +426,10 @@ async function run() {
|
|||||||
// Arbitrarily choose the first language. We could also choose all languages, but that
|
// Arbitrarily choose the first language. We could also choose all languages, but that
|
||||||
// increases the risk of misinterpreting the data.
|
// increases the risk of misinterpreting the data.
|
||||||
config.languages[0],
|
config.languages[0],
|
||||||
makeDiagnostic(
|
makeTelemetryDiagnostic(
|
||||||
"codeql-action/bundle-download-telemetry",
|
"codeql-action/bundle-download-telemetry",
|
||||||
"CodeQL bundle download telemetry",
|
"CodeQL bundle download telemetry",
|
||||||
{
|
toolsDownloadStatusReport,
|
||||||
attributes: toolsDownloadStatusReport,
|
|
||||||
visibility: {
|
|
||||||
cliSummaryTable: false,
|
|
||||||
statusPage: false,
|
|
||||||
telemetry: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -794,17 +788,10 @@ async function recordZstdAvailability(
|
|||||||
// Arbitrarily choose the first language. We could also choose all languages, but that
|
// Arbitrarily choose the first language. We could also choose all languages, but that
|
||||||
// increases the risk of misinterpreting the data.
|
// increases the risk of misinterpreting the data.
|
||||||
config.languages[0],
|
config.languages[0],
|
||||||
makeDiagnostic(
|
makeTelemetryDiagnostic(
|
||||||
"codeql-action/zstd-availability",
|
"codeql-action/zstd-availability",
|
||||||
"Zstandard availability",
|
"Zstandard availability",
|
||||||
{
|
zstdAvailability,
|
||||||
attributes: zstdAvailability,
|
|
||||||
visibility: {
|
|
||||||
cliSummaryTable: false,
|
|
||||||
statusPage: false,
|
|
||||||
telemetry: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user