Use direct tracing when autobuild build mode specified

Behind a flag, for now
This commit is contained in:
Henry Mercer 2024-04-11 20:31:01 +01:00
parent 5b74166227
commit e37d0f3e7c
24 changed files with 100 additions and 58 deletions

View file

@ -211,6 +211,8 @@ async function run() {
);
}
const codeql = await getCodeQL(config.codeQLCmd);
if (hasBadExpectErrorInput()) {
throw new util.ConfigurationError(
"`expect-error` input parameter is for internal use only. It should only be set by codeql-action or a fork.",
@ -251,7 +253,9 @@ async function run() {
outputDir,
threads,
memory,
codeql,
config,
features,
logger,
);
@ -300,7 +304,6 @@ async function run() {
// Possibly upload the TRAP caches for later re-use
const trapCacheUploadStartTime = performance.now();
const codeql = await getCodeQL(config.codeQLCmd);
didUploadTrapCaches = await uploadTrapCaches(codeql, config, logger);
trapCacheUploadTime = performance.now() - trapCacheUploadStartTime;

View file

@ -218,13 +218,12 @@ export function dbIsFinalized(
}
async function finalizeDatabaseCreation(
codeql: CodeQL,
config: configUtils.Config,
threadsFlag: string,
memoryFlag: string,
logger: Logger,
): Promise<DatabaseCreationTimings> {
const codeql = await getCodeQL(config.codeQLCmd);
const extractionStart = performance.now();
await runExtraction(codeql, config, logger);
const extractionTime = performance.now() - extractionStart;
@ -400,7 +399,9 @@ export async function runFinalize(
outputDir: string,
threadsFlag: string,
memoryFlag: string,
codeql: CodeQL,
config: configUtils.Config,
features: FeatureEnablement,
logger: Logger,
): Promise<DatabaseCreationTimings> {
try {
@ -413,6 +414,7 @@ export async function runFinalize(
await fs.promises.mkdir(outputDir, { recursive: true });
const timings = await finalizeDatabaseCreation(
codeql,
config,
threadsFlag,
memoryFlag,
@ -425,7 +427,7 @@ export async function runFinalize(
// However, it will stop tracing for all steps past the codeql-action/analyze
// step.
// Delete variables as specified by the end-tracing script
await endTracingForCluster(config);
await endTracingForCluster(codeql, config, features);
return timings;
}

View file

@ -482,6 +482,7 @@ const injectedConfigMacro = test.macro({
"",
undefined,
undefined,
createFeatures([]),
getRunnerLogger(true),
);
@ -695,6 +696,7 @@ test("passes a code scanning config AND qlconfig to the CLI", async (t: Executio
"",
undefined,
"/path/to/qlconfig.yml",
createFeatures([]),
getRunnerLogger(true),
);
@ -724,6 +726,7 @@ test("does not pass a qlconfig to the CLI when it is undefined", async (t: Execu
"",
undefined,
undefined, // undefined qlconfigFile
createFeatures([]),
getRunnerLogger(true),
);

View file

@ -16,7 +16,7 @@ import {
CommandInvocationError,
wrapCliConfigurationError,
} from "./cli-errors";
import type { Config } from "./config-utils";
import { type Config } from "./config-utils";
import { EnvVar } from "./environment";
import {
CODEQL_VERSION_FINE_GRAINED_PARALLELISM,
@ -24,10 +24,11 @@ import {
Feature,
FeatureEnablement,
} from "./feature-flags";
import { isTracedLanguage, Language } from "./languages";
import { Language } from "./languages";
import { Logger } from "./logging";
import * as setupCodeql from "./setup-codeql";
import { ToolsFeature, isSupportedToolsFeature } from "./tools-features";
import { shouldEnableIndirectTracing } from "./tracer-config";
import * as util from "./util";
import { wrapError } from "./util";
@ -81,6 +82,7 @@ export interface CodeQL {
sourceRoot: string,
processName: string | undefined,
qlconfigFile: string | undefined,
features: FeatureEnablement,
logger: Logger,
): Promise<void>;
/**
@ -556,12 +558,13 @@ export async function getCodeQLForCmd(
sourceRoot: string,
processName: string | undefined,
qlconfigFile: string | undefined,
features: FeatureEnablement,
logger: Logger,
) {
const extraArgs = config.languages.map(
(language) => `--language=${language}`,
);
if (config.languages.filter((l) => isTracedLanguage(l)).length > 0) {
if (await shouldEnableIndirectTracing(codeql, config, features)) {
extraArgs.push("--begin-tracing");
extraArgs.push(...(await getTrapCachingExtractorConfigArgs(config)));
extraArgs.push(`--trace-process-name=${processName}`);

View file

@ -491,6 +491,7 @@ async function run() {
"Runner.Worker.exe",
getOptionalInput("registries"),
apiDetails,
features,
logger,
);
if (tracerConfig !== undefined) {

View file

@ -7,7 +7,7 @@ import * as safeWhich from "@chrisgavin/safe-which";
import { GitHubApiCombinedDetails, GitHubApiDetails } from "./api-client";
import { CodeQL, setupCodeQL } from "./codeql";
import * as configUtils from "./config-utils";
import { CodeQLDefaultVersionInfo } from "./feature-flags";
import { CodeQLDefaultVersionInfo, FeatureEnablement } from "./feature-flags";
import { Language, isScannedLanguage } from "./languages";
import { Logger } from "./logging";
import { ToolsSource } from "./setup-codeql";
@ -69,6 +69,7 @@ export async function runInit(
processName: string | undefined,
registriesInput: string | undefined,
apiDetails: GitHubApiCombinedDetails,
features: FeatureEnablement,
logger: Logger,
): Promise<TracerConfig | undefined> {
fs.mkdirSync(config.dbLocation, { recursive: true });
@ -92,10 +93,11 @@ export async function runInit(
sourceRoot,
processName,
qlconfigFile,
features,
logger,
),
);
return await getCombinedTracerConfig(codeql, config);
return await getCombinedTracerConfig(codeql, config, features);
}
export function printPathFiltersWarning(

View file

@ -6,6 +6,7 @@ import test from "ava";
import * as configUtils from "./config-utils";
import { Language } from "./languages";
import {
createFeatures,
createTestConfig,
mockCodeQLVersion,
setupTests,
@ -29,7 +30,11 @@ test("getCombinedTracerConfig - return undefined when no languages are traced la
// No traced languages
config.languages = [Language.javascript, Language.python];
t.deepEqual(
await getCombinedTracerConfig(mockCodeQLVersion("1.0.0"), config),
await getCombinedTracerConfig(
mockCodeQLVersion("1.0.0"),
config,
createFeatures([]),
),
undefined,
);
});
@ -67,6 +72,7 @@ test("getCombinedTracerConfig - with start-tracing.json environment file", async
const result = await getCombinedTracerConfig(
mockCodeQLVersion("1.0.0"),
config,
createFeatures([]),
);
t.notDeepEqual(result, undefined);
@ -127,6 +133,7 @@ test("getCombinedTracerConfig - with SetsCodeqlRunnerEnvVar feature enabled in C
const result = await getCombinedTracerConfig(
mockCodeQLVersion("1.0.0", { setsCodeqlRunnerEnvVar: true }),
config,
createFeatures([]),
);
t.notDeepEqual(result, undefined);

View file

@ -1,20 +1,39 @@
import * as fs from "fs";
import * as path from "path";
import { CodeQL } from "./codeql";
import * as configUtils from "./config-utils";
import { type CodeQL } from "./codeql";
import { type Config } from "./config-utils";
import { Feature, FeatureEnablement } from "./feature-flags";
import { isTracedLanguage } from "./languages";
import { ToolsFeature } from "./tools-features";
import { BuildMode } from "./util";
export type TracerConfig = {
env: { [key: string]: string };
};
export async function shouldEnableIndirectTracing(
codeql: CodeQL,
config: Config,
features: FeatureEnablement,
): Promise<boolean> {
return (
(!config.buildMode ||
config.buildMode === BuildMode.Manual ||
!(await features.getValue(
Feature.AutobuildDirectTracingEnabled,
codeql,
))) &&
config.languages.some((l) => isTracedLanguage(l))
);
}
export async function endTracingForCluster(
config: configUtils.Config,
codeql: CodeQL,
config: Config,
features: FeatureEnablement,
): Promise<void> {
// If there are no traced languages, we don't need to do anything.
if (!config.languages.some((l) => isTracedLanguage(l))) return;
if (!(await shouldEnableIndirectTracing(codeql, config, features))) return;
const envVariablesFile = path.resolve(
config.dbLocation,
@ -44,7 +63,7 @@ export async function endTracingForCluster(
}
export async function getTracerConfigForCluster(
config: configUtils.Config,
config: Config,
): Promise<TracerConfig> {
const tracingEnvVariables = JSON.parse(
fs.readFileSync(
@ -62,13 +81,11 @@ export async function getTracerConfigForCluster(
export async function getCombinedTracerConfig(
codeql: CodeQL,
config: configUtils.Config,
config: Config,
features: FeatureEnablement,
): Promise<TracerConfig | undefined> {
// Abort if there are no traced languages as there's nothing to do
const tracedLanguages = config.languages.filter((l) => isTracedLanguage(l));
if (tracedLanguages.length === 0) {
if (!(await shouldEnableIndirectTracing(codeql, config, features)))
return undefined;
}
const mainTracerConfig = await getTracerConfigForCluster(config);