mirror of
https://github.com/github/codeql-action.git
synced 2026-04-29 02:18:47 +00:00
Move git version logging to config utils
This commit is contained in:
@@ -4,7 +4,6 @@ import * as path from "path";
|
||||
import * as github from "@actions/github";
|
||||
import test, { ExecutionContext } from "ava";
|
||||
import * as yaml from "js-yaml";
|
||||
import * as semver from "semver";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
@@ -994,7 +993,7 @@ const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = {
|
||||
languages: [KnownLanguage.javascript],
|
||||
codeqlVersion: CODEQL_OVERLAY_MINIMUM_VERSION,
|
||||
gitRoot: "/some/git/root",
|
||||
gitVersion: "2.40.0", // Default to a version that supports overlay analysis
|
||||
gitVersion: gitUtils.GIT_MINIMUM_VERSION_FOR_OVERLAY,
|
||||
codeScanningConfig: {},
|
||||
diskUsage: {
|
||||
numAvailableBytes: 50_000_000_000,
|
||||
@@ -1060,19 +1059,6 @@ const getOverlayDatabaseModeMacro = test.macro({
|
||||
sinon.stub(gitUtils, "getGitRoot").resolves(setup.gitRoot);
|
||||
}
|
||||
|
||||
// Mock git version detection - stub gitVersionAtLeast directly
|
||||
// since internal calls to getGitVersion won't be stubbed
|
||||
if (setup.gitVersion !== undefined) {
|
||||
sinon
|
||||
.stub(gitUtils, "gitVersionAtLeast")
|
||||
.callsFake(async (requiredVersion: string) => {
|
||||
return semver.gte(setup.gitVersion!, requiredVersion);
|
||||
});
|
||||
} else {
|
||||
// When git version is undefined, gitVersionAtLeast should return false
|
||||
sinon.stub(gitUtils, "gitVersionAtLeast").resolves(false);
|
||||
}
|
||||
|
||||
// Mock default branch detection
|
||||
sinon
|
||||
.stub(gitUtils, "isAnalyzingDefaultBranch")
|
||||
@@ -1086,6 +1072,7 @@ const getOverlayDatabaseModeMacro = test.macro({
|
||||
setup.buildMode,
|
||||
undefined,
|
||||
setup.codeScanningConfig,
|
||||
setup.gitVersion,
|
||||
logger,
|
||||
);
|
||||
|
||||
|
||||
+44
-2
@@ -3,6 +3,7 @@ import * as path from "path";
|
||||
import { performance } from "perf_hooks";
|
||||
|
||||
import * as yaml from "js-yaml";
|
||||
import * as semver from "semver";
|
||||
|
||||
import { getActionVersion, isAnalyzingPullRequest } from "./actions-util";
|
||||
import {
|
||||
@@ -22,14 +23,15 @@ import {
|
||||
parseUserConfig,
|
||||
UserConfig,
|
||||
} from "./config/db-config";
|
||||
import { addDiagnostic, makeTelemetryDiagnostic } from "./diagnostics";
|
||||
import { shouldPerformDiffInformedAnalysis } from "./diff-informed-analysis-utils";
|
||||
import * as errorMessages from "./error-messages";
|
||||
import { Feature, FeatureEnablement } from "./feature-flags";
|
||||
import { RepositoryProperties } from "./feature-flags/properties";
|
||||
import {
|
||||
getGitRoot,
|
||||
getGitVersionOrThrow,
|
||||
GIT_MINIMUM_VERSION_FOR_OVERLAY,
|
||||
gitVersionAtLeast,
|
||||
isAnalyzingDefaultBranch,
|
||||
} from "./git-utils";
|
||||
import { KnownLanguage, Language } from "./languages";
|
||||
@@ -50,6 +52,7 @@ import {
|
||||
isDefined,
|
||||
checkDiskUsage,
|
||||
getCodeQLMemoryLimit,
|
||||
getErrorMessage,
|
||||
} from "./util";
|
||||
|
||||
export * from "./config/db-config";
|
||||
@@ -714,6 +717,7 @@ export async function getOverlayDatabaseMode(
|
||||
buildMode: BuildMode | undefined,
|
||||
ramInput: string | undefined,
|
||||
codeScanningConfig: UserConfig,
|
||||
gitVersion: string | undefined,
|
||||
logger: Logger,
|
||||
): Promise<{
|
||||
overlayDatabaseMode: OverlayDatabaseMode;
|
||||
@@ -816,7 +820,15 @@ export async function getOverlayDatabaseMode(
|
||||
);
|
||||
return nonOverlayAnalysis;
|
||||
}
|
||||
if (!(await gitVersionAtLeast(GIT_MINIMUM_VERSION_FOR_OVERLAY, logger))) {
|
||||
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 (!semver.gte(gitVersion, 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}. ` +
|
||||
@@ -916,6 +928,15 @@ export async function initConfig(
|
||||
config.computedConfig["query-filters"] = [];
|
||||
}
|
||||
|
||||
let gitVersion: string | undefined = undefined;
|
||||
try {
|
||||
gitVersion = await getGitVersionOrThrow();
|
||||
logger.info(`Using Git version ${gitVersion}`);
|
||||
await logGitVersionTelemetry(config, gitVersion);
|
||||
} catch (e) {
|
||||
logger.debug(`Could not determine Git version: ${getErrorMessage(e)}`);
|
||||
}
|
||||
|
||||
// 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
|
||||
// properties. So we need to calculate the overlay database mode after the
|
||||
@@ -929,6 +950,7 @@ export async function initConfig(
|
||||
config.buildMode,
|
||||
inputs.ramInput,
|
||||
config.computedConfig,
|
||||
gitVersion,
|
||||
logger,
|
||||
);
|
||||
logger.info(
|
||||
@@ -1329,3 +1351,23 @@ export function getPrimaryAnalysisConfig(config: Config): AnalysisConfig {
|
||||
? CodeScanning
|
||||
: CodeQuality;
|
||||
}
|
||||
|
||||
/** Logs the Git version as a telemetry diagnostic. */
|
||||
async function logGitVersionTelemetry(
|
||||
config: Config,
|
||||
gitVersion: string,
|
||||
): 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",
|
||||
{ gitVersion },
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-69
@@ -7,12 +7,7 @@ import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import * as gitUtils from "./git-utils";
|
||||
import {
|
||||
getRecordingLogger,
|
||||
LoggedMessage,
|
||||
setupActionsVars,
|
||||
setupTests,
|
||||
} from "./testing-utils";
|
||||
import { setupActionsVars, setupTests } from "./testing-utils";
|
||||
import { withTmpDir } from "./util";
|
||||
|
||||
setupTests(test);
|
||||
@@ -464,66 +459,3 @@ test("getGitVersionOrThrow throws when git command fails", async (t) => {
|
||||
runGitCommandStub.restore();
|
||||
}
|
||||
});
|
||||
|
||||
test("gitVersionAtLeast returns true for version meeting requirement", async (t) => {
|
||||
const runGitCommandStub = sinon
|
||||
.stub(gitUtils as any, "runGitCommand")
|
||||
.resolves("git version 2.40.0\n");
|
||||
|
||||
const messages: LoggedMessage[] = [];
|
||||
const logger = getRecordingLogger(messages);
|
||||
|
||||
try {
|
||||
const result = await gitUtils.gitVersionAtLeast("2.38.0", logger);
|
||||
t.true(result);
|
||||
t.true(
|
||||
messages.some(
|
||||
(m) =>
|
||||
m.type === "debug" &&
|
||||
m.message === "Installed Git version is 2.40.0.",
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
runGitCommandStub.restore();
|
||||
}
|
||||
});
|
||||
|
||||
test("gitVersionAtLeast returns false for version not meeting requirement", async (t) => {
|
||||
const runGitCommandStub = sinon
|
||||
.stub(gitUtils as any, "runGitCommand")
|
||||
.resolves("git version 2.30.0\n");
|
||||
|
||||
const messages: LoggedMessage[] = [];
|
||||
const logger = getRecordingLogger(messages);
|
||||
|
||||
try {
|
||||
const result = await gitUtils.gitVersionAtLeast("2.38.0", logger);
|
||||
t.false(result);
|
||||
} finally {
|
||||
runGitCommandStub.restore();
|
||||
}
|
||||
});
|
||||
|
||||
test("gitVersionAtLeast returns false when version cannot be determined", async (t) => {
|
||||
const runGitCommandStub = sinon
|
||||
.stub(gitUtils as any, "runGitCommand")
|
||||
.rejects(new Error("git not found"));
|
||||
|
||||
const messages: LoggedMessage[] = [];
|
||||
const logger = getRecordingLogger(messages);
|
||||
|
||||
try {
|
||||
const result = await gitUtils.gitVersionAtLeast("2.38.0", logger);
|
||||
t.false(result);
|
||||
t.true(
|
||||
messages.some(
|
||||
(m) =>
|
||||
m.type === "debug" &&
|
||||
typeof m.message === "string" &&
|
||||
m.message.includes("Could not determine Git version"),
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
runGitCommandStub.restore();
|
||||
}
|
||||
});
|
||||
|
||||
+1
-62
@@ -1,21 +1,13 @@
|
||||
import * as core from "@actions/core";
|
||||
import * as toolrunner from "@actions/exec/lib/toolrunner";
|
||||
import * as io from "@actions/io";
|
||||
import * as semver from "semver";
|
||||
|
||||
import {
|
||||
getOptionalInput,
|
||||
getWorkflowEvent,
|
||||
getWorkflowEventName,
|
||||
} from "./actions-util";
|
||||
import type { Config } from "./config-utils";
|
||||
import { addDiagnostic, makeTelemetryDiagnostic } from "./diagnostics";
|
||||
import { Logger } from "./logging";
|
||||
import {
|
||||
ConfigurationError,
|
||||
getErrorMessage,
|
||||
getRequiredEnvParam,
|
||||
} from "./util";
|
||||
import { ConfigurationError, getRequiredEnvParam } from "./util";
|
||||
|
||||
/**
|
||||
* Minimum Git version required for overlay analysis. The `git ls-files --format`
|
||||
@@ -45,59 +37,6 @@ export async function getGitVersionOrThrow(): Promise<string> {
|
||||
throw new Error(`Could not parse Git version from output: ${stdout.trim()}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the Git version as a telemetry diagnostic. Should be called once during
|
||||
* initialization after the config is available.
|
||||
*
|
||||
* @param config The configuration that tells us where to store the diagnostic.
|
||||
* @param logger A logger to use for logging errors.
|
||||
*/
|
||||
export async function logGitVersionTelemetry(
|
||||
config: Config,
|
||||
logger: Logger,
|
||||
): Promise<void> {
|
||||
try {
|
||||
const version = await getGitVersionOrThrow();
|
||||
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",
|
||||
{ gitVersion: version },
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.debug(`Could not determine Git version: ${getErrorMessage(e)}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the installed Git version is at least the given required version.
|
||||
*
|
||||
* @param requiredVersion The minimum required Git version.
|
||||
* @param logger A logger to use for logging.
|
||||
* @returns `true` if the installed Git version is at least the required version,
|
||||
* `false` otherwise.
|
||||
*/
|
||||
export async function gitVersionAtLeast(
|
||||
requiredVersion: string,
|
||||
logger: Logger,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
const version = await getGitVersionOrThrow();
|
||||
logger.debug(`Installed Git version is ${version}.`);
|
||||
return semver.gte(version, requiredVersion);
|
||||
} catch (e) {
|
||||
logger.debug(`Could not determine Git version: ${getErrorMessage(e)}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export const runGitCommand = async function (
|
||||
workingDirectory: string | undefined,
|
||||
args: string[],
|
||||
|
||||
@@ -38,7 +38,6 @@ import {
|
||||
import { EnvVar } from "./environment";
|
||||
import { Feature, Features } from "./feature-flags";
|
||||
import { loadPropertiesFromApi } from "./feature-flags/properties";
|
||||
import { logGitVersionTelemetry } from "./git-utils";
|
||||
import {
|
||||
checkInstallPython311,
|
||||
checkPacksForOverlayCompatibility,
|
||||
@@ -435,9 +434,6 @@ async function run() {
|
||||
);
|
||||
}
|
||||
|
||||
// Log Git version telemetry
|
||||
await logGitVersionTelemetry(config, logger);
|
||||
|
||||
// Forward Go flags
|
||||
const goFlags = process.env["GOFLAGS"];
|
||||
if (goFlags) {
|
||||
|
||||
Reference in New Issue
Block a user