Remove CliConfigFileEnabled feature flag

This commit is contained in:
Henry Mercer 2024-01-04 14:39:36 +00:00
parent 216127f34a
commit fa98ec0c7a
30 changed files with 104 additions and 887 deletions

View file

@ -2,7 +2,6 @@ import * as fs from "fs";
import * as path from "path";
import test, { ExecutionContext } from "ava";
import * as yaml from "js-yaml";
import * as sinon from "sinon";
import {
@ -13,7 +12,7 @@ import {
QueriesStatusReport,
} from "./analyze";
import { CodeQL, setCodeQL } from "./codeql";
import { Config, QueriesWithSearchPath } from "./config-utils";
import { Config } from "./config-utils";
import { Feature } from "./feature-flags";
import { Language } from "./languages";
import { getRunnerLogger } from "./logging";
@ -134,10 +133,6 @@ test("status report fields and search path setting", async (t) => {
recursive: true,
});
config.queries[language] = {
builtin: ["foo.ql"],
custom: [],
};
const builtinStatusReport = await runQueries(
tmpDir,
memoryFlag,
@ -148,116 +143,18 @@ test("status report fields and search path setting", async (t) => {
getRunnerLogger(true),
createFeatures([Feature.QaTelemetryEnabled]),
);
const hasPacks = language in packs;
const statusReportKeys = Object.keys(builtinStatusReport).sort();
if (hasPacks) {
t.deepEqual(statusReportKeys.length, 4, statusReportKeys.toString());
t.deepEqual(
statusReportKeys[0],
`analyze_builtin_queries_${language}_duration_ms`,
);
t.deepEqual(
statusReportKeys[1],
`analyze_custom_queries_${language}_duration_ms`,
);
t.deepEqual(statusReportKeys[2], "event_reports");
t.deepEqual(
statusReportKeys[3],
`interpret_results_${language}_duration_ms`,
);
} else {
t.deepEqual(
statusReportKeys[0],
`analyze_builtin_queries_${language}_duration_ms`,
);
t.deepEqual(statusReportKeys[1], "event_reports");
t.deepEqual(
statusReportKeys[2],
`interpret_results_${language}_duration_ms`,
);
}
if (builtinStatusReport.event_reports) {
for (const eventReport of builtinStatusReport.event_reports) {
t.deepEqual(eventReport.event, "codeql database interpret-results");
t.true("properties" in eventReport);
t.true("alertCounts" in eventReport.properties!);
}
}
config.queries[language] = {
builtin: [],
custom: [
{
queries: ["foo.ql"],
searchPath: "/1",
},
{
queries: ["bar.ql"],
searchPath: "/2",
},
],
};
const customStatusReport = await runQueries(
tmpDir,
memoryFlag,
addSnippetsFlag,
threadsFlag,
undefined,
config,
getRunnerLogger(true),
createFeatures([Feature.QaTelemetryEnabled]),
);
t.deepEqual(Object.keys(customStatusReport).length, 3);
t.true(
`analyze_custom_queries_${language}_duration_ms` in customStatusReport,
);
const expectedSearchPathsUsed = hasPacks
? [undefined, undefined, "/1", "/2", undefined]
: [undefined, "/1", "/2"];
t.deepEqual(searchPathsUsed, expectedSearchPathsUsed);
t.true(`interpret_results_${language}_duration_ms` in customStatusReport);
t.true("event_reports" in customStatusReport);
if (customStatusReport.event_reports) {
for (const eventReport of customStatusReport.event_reports) {
t.deepEqual(eventReport.event, "codeql database interpret-results");
t.true("properties" in eventReport);
t.true("alertCounts" in eventReport.properties!);
}
t.deepEqual(Object.keys(builtinStatusReport).sort(), [
`analyze_builtin_queries_${language}_duration_ms`,
"event_reports",
`interpret_results_${language}_duration_ms`,
]);
for (const eventReport of builtinStatusReport.event_reports!) {
t.deepEqual(eventReport.event, "codeql database interpret-results");
t.true("properties" in eventReport);
t.true("alertCounts" in eventReport.properties!);
}
}
verifyQuerySuites(tmpDir);
});
function verifyQuerySuites(tmpDir: string) {
const qlsContent = [
{
query: "foo.ql",
},
];
const qlsContent2 = [
{
query: "bar.ql",
},
];
for (const lang of Object.values(Language)) {
t.deepEqual(readContents(`${lang}-queries-builtin.qls`), qlsContent);
t.deepEqual(readContents(`${lang}-queries-custom-0.qls`), qlsContent);
t.deepEqual(readContents(`${lang}-queries-custom-1.qls`), qlsContent2);
}
function readContents(name: string) {
const x = fs.readFileSync(
path.join(tmpDir, "codeql_databases", name),
"utf8",
);
console.log(x);
return yaml.load(
fs.readFileSync(path.join(tmpDir, "codeql_databases", name), "utf8"),
);
}
}
});
function mockCodeQL(): Partial<CodeQL> {
@ -295,16 +192,6 @@ function createBaseConfig(tmpDir: string): Config {
};
}
function createQueryConfig(
builtin: string[],
custom: string[],
): { builtin: string[]; custom: QueriesWithSearchPath[] } {
return {
builtin,
custom: custom.map((c) => ({ searchPath: "/search", queries: [c] })),
};
}
async function runQueriesWithConfig(
config: Config,
features: Feature[],
@ -336,7 +223,6 @@ test("optimizeForLastQueryRun for one language", async (t) => {
setCodeQL(codeql);
const config: Config = createBaseConfig(tmpDir);
config.languages = [Language.cpp];
config.queries.cpp = createQueryConfig(["foo.ql"], []);
await runQueriesWithConfig(config, []);
t.deepEqual(
@ -352,8 +238,6 @@ test("optimizeForLastQueryRun for two languages", async (t) => {
setCodeQL(codeql);
const config: Config = createBaseConfig(tmpDir);
config.languages = [Language.cpp, Language.java];
config.queries.cpp = createQueryConfig(["foo.ql"], []);
config.queries.java = createQueryConfig(["bar.ql"], []);
await runQueriesWithConfig(config, []);
t.deepEqual(
@ -363,71 +247,6 @@ test("optimizeForLastQueryRun for two languages", async (t) => {
});
});
test("optimizeForLastQueryRun for two languages, with custom queries", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const codeql = mockCodeQL();
setCodeQL(codeql);
const config: Config = createBaseConfig(tmpDir);
config.languages = [Language.cpp, Language.java];
config.queries.cpp = createQueryConfig(["foo.ql"], ["c1.ql", "c2.ql"]);
config.queries.java = createQueryConfig(["bar.ql"], ["c3.ql"]);
await runQueriesWithConfig(config, []);
t.deepEqual(
getDatabaseRunQueriesCalls(codeql).map((c) => c.args[4]),
[false, false, true, false, true],
);
});
});
test("optimizeForLastQueryRun for two languages, with custom queries and packs", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const codeql = mockCodeQL();
setCodeQL(codeql);
const config: Config = createBaseConfig(tmpDir);
config.languages = [Language.cpp, Language.java];
config.queries.cpp = createQueryConfig(["foo.ql"], ["c1.ql", "c2.ql"]);
config.queries.java = createQueryConfig(["bar.ql"], ["c3.ql"]);
config.packs.cpp = ["a/cpp-pack1@0.1.0"];
config.packs.java = ["b/java-pack1@0.2.0", "b/java-pack2@0.3.3"];
await runQueriesWithConfig(config, []);
t.deepEqual(
getDatabaseRunQueriesCalls(codeql).map((c) => c.args[4]),
[false, false, false, true, false, false, true],
);
});
});
test("optimizeForLastQueryRun for one language, CliConfigFileEnabled", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const codeql = mockCodeQL();
setCodeQL(codeql);
const config: Config = createBaseConfig(tmpDir);
config.languages = [Language.cpp];
await runQueriesWithConfig(config, [Feature.CliConfigFileEnabled]);
t.deepEqual(
getDatabaseRunQueriesCalls(codeql).map((c) => c.args[4]),
[true],
);
});
});
test("optimizeForLastQueryRun for two languages, CliConfigFileEnabled", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const codeql = mockCodeQL();
setCodeQL(codeql);
const config: Config = createBaseConfig(tmpDir);
config.languages = [Language.cpp, Language.java];
await runQueriesWithConfig(config, [Feature.CliConfigFileEnabled]);
t.deepEqual(
getDatabaseRunQueriesCalls(codeql).map((c) => c.args[4]),
[true, true],
);
});
});
test("validateQueryFilters", (t) => {
t.notThrows(() => validateQueryFilters([]));
t.notThrows(() => validateQueryFilters(undefined));

View file

@ -13,12 +13,7 @@ import {
getCodeQL,
} from "./codeql";
import * as configUtils from "./config-utils";
import {
FeatureEnablement,
Feature,
logCodeScanningConfigInCli,
useCodeScanningConfigInCli,
} from "./feature-flags";
import { FeatureEnablement, Feature } from "./feature-flags";
import { isScannedLanguage, Language } from "./languages";
import { Logger } from "./logging";
import { DatabaseCreationTimings, EventReport } from "./status-report";
@ -245,8 +240,6 @@ export async function runQueries(
const codeql = await getCodeQL(config.codeQLCmd);
const queryFlags = [memoryFlag, threadsFlag];
await logCodeScanningConfigInCli(codeql, features, logger);
for (const language of config.languages) {
const queries = config.queries[language];
const queryFilters = validateQueryFilters(
@ -258,7 +251,9 @@ export async function runQueries(
const sarifFile = path.join(sarifFolder, `${language}.sarif`);
let startTimeInterpretResults: Date;
let endTimeInterpretResults: Date;
if (await useCodeScanningConfigInCli(codeql, features)) {
// TODO: will clean up in a future commit
// eslint-disable-next-line no-constant-condition
if (true) {
// If we are using the code scanning config in the CLI,
// much of the work needed to generate the query suites
// is done in the CLI. We just need to make a single

View file

@ -16,7 +16,6 @@ import { GitHubApiDetails } from "./api-client";
import * as codeql from "./codeql";
import { AugmentationProperties, Config } from "./config-utils";
import * as defaults from "./defaults.json";
import { Feature, featureConfig } from "./feature-flags";
import { Language } from "./languages";
import { getRunnerLogger } from "./logging";
import { ToolsSource } from "./setup-codeql";
@ -560,41 +559,6 @@ test("getExtraOptions throws for bad content", (t) => {
);
});
test("databaseInitCluster() without injected codescanning config", async (t) => {
await util.withTmpDir(async (tempDir) => {
const runnerConstructorStub = stubToolRunnerConstructor();
const codeqlObject = await codeql.getCodeQLForTesting();
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.10.5"));
// safeWhich throws because of the test CodeQL object.
sinon.stub(safeWhich, "safeWhich").resolves("");
const thisStubConfig: Config = {
...stubConfig,
tempDir,
augmentationProperties: {
queriesInputCombines: false,
packsInputCombines: false,
},
};
await codeqlObject.databaseInitCluster(
thisStubConfig,
"",
undefined,
createFeatures([]),
"/path/to/qlconfig.yml",
getRunnerLogger(true),
);
const args = runnerConstructorStub.firstCall.args[1];
// should NOT have used an config file
const configArg = args.find((arg: string) =>
arg.startsWith("--codescanning-config="),
);
t.falsy(configArg, "Should NOT have injected a codescanning config");
});
});
// Test macro for ensuring different variants of injected augmented configurations
const injectedConfigMacro = test.macro({
exec: async (
@ -606,14 +570,7 @@ const injectedConfigMacro = test.macro({
await util.withTmpDir(async (tempDir) => {
const runnerConstructorStub = stubToolRunnerConstructor();
const codeqlObject = await codeql.getCodeQLForTesting();
sinon
.stub(codeqlObject, "getVersion")
.resolves(
makeVersionInfo(
featureConfig[Feature.CliConfigFileEnabled].minimumVersion ||
"1.0.0",
),
);
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("1.0.0"));
const thisStubConfig: Config = {
...stubConfig,
@ -626,7 +583,6 @@ const injectedConfigMacro = test.macro({
thisStubConfig,
"",
undefined,
createFeatures([Feature.CliConfigFileEnabled]),
undefined,
getRunnerLogger(true),
);
@ -830,38 +786,7 @@ test(
{},
);
test("does not pass a code scanning config or qlconfig file to the CLI when CLI config passing is disabled", async (t: ExecutionContext<unknown>) => {
await util.withTmpDir(async (tempDir) => {
const runnerConstructorStub = stubToolRunnerConstructor();
const codeqlObject = await codeql.getCodeQLForTesting();
// stubbed version doesn't matter. It just needs to be valid semver.
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("0.0.0"));
await codeqlObject.databaseInitCluster(
{ ...stubConfig, tempDir },
"",
undefined,
createFeatures([]),
"/path/to/qlconfig.yml",
getRunnerLogger(true),
);
const args = runnerConstructorStub.firstCall.args[1];
// should not have used a config file
const hasConfigArg = args.some((arg: string) =>
arg.startsWith("--codescanning-config="),
);
t.false(hasConfigArg, "Should NOT have injected a codescanning config");
// should not have passed a qlconfig file
const hasQlconfigArg = args.some((arg: string) =>
arg.startsWith("--qlconfig-file="),
);
t.false(hasQlconfigArg, "Should NOT have passed a qlconfig file");
});
});
test("passes a code scanning config AND qlconfig to the CLI when CLI config passing is enabled", async (t: ExecutionContext<unknown>) => {
test("passes a code scanning config AND qlconfig to the CLI", async (t: ExecutionContext<unknown>) => {
await util.withTmpDir(async (tempDir) => {
const runnerConstructorStub = stubToolRunnerConstructor();
const codeqlObject = await codeql.getCodeQLForTesting();
@ -873,7 +798,6 @@ test("passes a code scanning config AND qlconfig to the CLI when CLI config pass
{ ...stubConfig, tempDir },
"",
undefined,
createFeatures([Feature.CliConfigFileEnabled]),
"/path/to/qlconfig.yml",
getRunnerLogger(true),
);
@ -893,7 +817,7 @@ test("passes a code scanning config AND qlconfig to the CLI when CLI config pass
});
});
test("passes a code scanning config BUT NOT a qlconfig to the CLI when CLI config passing is enabled", async (t: ExecutionContext<unknown>) => {
test("passes a code scanning config BUT NOT a qlconfig to the CLI for CodeQL v2.12.2", async (t: ExecutionContext<unknown>) => {
await util.withTmpDir(async (tempDir) => {
const runnerConstructorStub = stubToolRunnerConstructor();
const codeqlObject = await codeql.getCodeQLForTesting();
@ -903,7 +827,6 @@ test("passes a code scanning config BUT NOT a qlconfig to the CLI when CLI confi
{ ...stubConfig, tempDir },
"",
undefined,
createFeatures([Feature.CliConfigFileEnabled]),
"/path/to/qlconfig.yml",
getRunnerLogger(true),
);
@ -938,7 +861,6 @@ test("does not pass a qlconfig to the CLI when it is undefined", async (t: Execu
{ ...stubConfig, tempDir },
"",
undefined,
createFeatures([Feature.CliConfigFileEnabled]),
undefined, // undefined qlconfigFile
getRunnerLogger(true),
);

View file

@ -19,7 +19,6 @@ import {
CodeQLDefaultVersionInfo,
Feature,
FeatureEnablement,
useCodeScanningConfigInCli,
} from "./feature-flags";
import { isTracedLanguage, Language } from "./languages";
import { Logger } from "./logging";
@ -98,7 +97,6 @@ export interface CodeQL {
config: Config,
sourceRoot: string,
processName: string | undefined,
features: FeatureEnablement,
qlconfigFile: string | undefined,
logger: Logger,
): Promise<void>;
@ -576,7 +574,6 @@ export async function getCodeQLForCmd(
config: Config,
sourceRoot: string,
processName: string | undefined,
features: FeatureEnablement,
qlconfigFile: string | undefined,
logger: Logger,
) {
@ -589,21 +586,16 @@ export async function getCodeQLForCmd(
extraArgs.push(`--trace-process-name=${processName}`);
}
// A code scanning config file is only generated if the CliConfigFileEnabled feature flag is enabled.
const codeScanningConfigFile = await generateCodeScanningConfig(
codeql,
config,
features,
logger,
);
// Only pass external repository token if a config file is going to be parsed by the CLI.
let externalRepositoryToken: string | undefined;
if (codeScanningConfigFile) {
externalRepositoryToken = getOptionalInput("external-repository-token");
extraArgs.push(`--codescanning-config=${codeScanningConfigFile}`);
if (externalRepositoryToken) {
extraArgs.push("--external-repository-token-stdin");
}
const externalRepositoryToken = getOptionalInput(
"external-repository-token",
);
extraArgs.push(`--codescanning-config=${codeScanningConfigFile}`);
if (externalRepositoryToken) {
extraArgs.push("--external-repository-token-stdin");
}
if (
@ -1325,22 +1317,16 @@ function ensureEndsInPeriod(text: string): string {
}
/**
* If appropriate, generates a code scanning configuration that is to be used for a scan.
* If the configuration is not to be generated, returns undefined.
* Generates a code scanning configuration that is to be used for a scan.
*
* @param codeql The CodeQL object to use.
* @param config The configuration to use.
* @returns the path to the generated user configuration file.
*/
async function generateCodeScanningConfig(
codeql: CodeQL,
config: Config,
features: FeatureEnablement,
logger: Logger,
): Promise<string | undefined> {
if (!(await useCodeScanningConfigInCli(codeql, features))) {
return;
}
): Promise<string> {
const codeScanningConfigFile = getGeneratedCodeScanningConfigPath(config);
// make a copy so we can modify it

View file

@ -1101,62 +1101,6 @@ test("Using config input and file together, config input should be used.", async
});
});
test("Invalid queries in workflow file handled correctly", async (t) => {
return await withTmpDir(async (tmpDir) => {
const queries = "foo/bar@v1@v3";
const languages = "javascript";
// This function just needs to be type-correct; it doesn't need to do anything,
// since we're deliberately passing in invalid data
const codeQL = setCodeQL({
async resolveQueries() {
return {
byLanguage: {
javascript: {},
},
noDeclaredLanguage: {},
multipleDeclaredLanguages: {},
};
},
async packDownload(): Promise<PackDownloadOutput> {
return { packs: [] };
},
});
try {
await configUtils.initConfig(
languages,
queries,
undefined,
undefined,
undefined,
undefined,
undefined,
false,
false,
"",
"",
{ owner: "github", repo: "example" },
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
sampleApiDetails,
createFeatures([]),
getRunnerLogger(true),
);
t.fail("initConfig did not throw error");
} catch (err) {
t.deepEqual(
err,
new UserError(
configUtils.getQueryUsesInvalid(undefined, "foo/bar@v1@v3"),
),
);
}
});
});
test("API client used when reading remote config", async (t) => {
return await withTmpDir(async (tmpDir) => {
const codeQL = setCodeQL({
@ -1643,18 +1587,6 @@ function doInvalidQueryUsesTest(
doInvalidQueryUsesTest("''", (c) =>
configUtils.getQueryUsesInvalid(c, undefined),
);
doInvalidQueryUsesTest("foo/bar", (c) =>
configUtils.getQueryUsesInvalid(c, "foo/bar"),
);
doInvalidQueryUsesTest("foo/bar@v1@v2", (c) =>
configUtils.getQueryUsesInvalid(c, "foo/bar@v1@v2"),
);
doInvalidQueryUsesTest("foo@master", (c) =>
configUtils.getQueryUsesInvalid(c, "foo@master"),
);
doInvalidQueryUsesTest("https://github.com/foo/bar@master", (c) =>
configUtils.getQueryUsesInvalid(c, "https://github.com/foo/bar@master"),
);
doInvalidQueryUsesTest("./foo", (c) =>
configUtils.getLocalPathDoesNotExist(c, "foo"),
);

View file

@ -12,12 +12,7 @@ import {
CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE,
ResolveQueriesOutput,
} from "./codeql";
import * as externalQueries from "./external-queries";
import {
FeatureEnablement,
logCodeScanningConfigInCli,
useCodeScanningConfigInCli,
} from "./feature-flags";
import { FeatureEnablement } from "./feature-flags";
import { Language, parseLanguage } from "./languages";
import { Logger } from "./logging";
import { RepositoryNwo } from "./repository";
@ -454,55 +449,6 @@ async function addLocalQueries(
);
}
/**
* Retrieve the set of queries at the referenced remote repo and add them to resultMap.
*/
async function addRemoteQueries(
codeQL: CodeQL,
resultMap: Queries,
queryUses: string,
tempDir: string,
apiDetails: api.GitHubApiExternalRepoDetails,
logger: Logger,
configFile?: string,
) {
let tok = queryUses.split("@");
if (tok.length !== 2) {
throw new UserError(getQueryUsesInvalid(configFile, queryUses));
}
const ref = tok[1];
tok = tok[0].split("/");
// The first token is the owner
// The second token is the repo
// The rest is a path, if there is more than one token combine them to form the full path
if (tok.length < 2) {
throw new UserError(getQueryUsesInvalid(configFile, queryUses));
}
// Check none of the parts of the repository name are empty
if (tok[0].trim() === "" || tok[1].trim() === "") {
throw new UserError(getQueryUsesInvalid(configFile, queryUses));
}
const nwo = `${tok[0]}/${tok[1]}`;
// Checkout the external repository
const checkoutPath = await externalQueries.checkoutExternalRepository(
nwo,
ref,
apiDetails,
tempDir,
logger,
);
const queryPath =
tok.length > 2
? path.join(checkoutPath, tok.slice(2).join("/"))
: checkoutPath;
await runResolveQueries(codeQL, resultMap, [queryPath], checkoutPath);
}
/**
* Parse a query 'uses' field to a discrete set of query files and update resultMap.
*
@ -516,11 +462,12 @@ async function parseQueryUses(
codeQL: CodeQL,
resultMap: Queries,
queryUses: string,
tempDir: string,
// TODO: will clean this up in a future commit
_tempDir: string,
workspacePath: string,
apiDetails: api.GitHubApiExternalRepoDetails,
features: FeatureEnablement,
logger: Logger,
_apiDetails: api.GitHubApiExternalRepoDetails,
_features: FeatureEnablement,
_logger: Logger,
configFile?: string,
): Promise<void> {
queryUses = queryUses.trim();
@ -551,21 +498,6 @@ async function parseQueryUses(
);
return;
}
// Otherwise, must be a reference to another repo.
// If config parsing is handled in CLI, then this repo will be downloaded
// later by the CLI.
if (!(await useCodeScanningConfigInCli(codeQL, features))) {
await addRemoteQueries(
codeQL,
resultMap,
queryUses,
tempDir,
apiDetails,
logger,
configFile,
);
}
}
// Regex validating stars in paths or paths-ignore entries.
@ -1647,7 +1579,8 @@ export async function initConfig(
languagesInput: string | undefined,
queriesInput: string | undefined,
packsInput: string | undefined,
registriesInput: string | undefined,
// TODO: will clean this up in a future commit
_registriesInput: string | undefined,
configFile: string | undefined,
dbLocation: string | undefined,
configInput: string | undefined,
@ -1721,38 +1654,6 @@ export async function initConfig(
);
}
// When using the codescanning config in the CLI, pack downloads
// happen in the CLI during the `database init` command, so no need
// to download them here.
await logCodeScanningConfigInCli(codeQL, features, logger);
if (!(await useCodeScanningConfigInCli(codeQL, features))) {
// The list of queries should not be empty for any language. If it is then
// it is a user configuration error.
// This check occurs in the CLI when it parses the config file.
for (const language of config.languages) {
const hasBuiltinQueries = config.queries[language]?.builtin.length > 0;
const hasCustomQueries = config.queries[language]?.custom.length > 0;
const hasPacks = (config.packs[language]?.length || 0) > 0;
if (!hasPacks && !hasBuiltinQueries && !hasCustomQueries) {
throw new UserError(
`Did not detect any queries to run for ${language}. ` +
"Please make sure that the default queries are enabled, or you are specifying queries to run.",
);
}
}
await downloadPacks(
codeQL,
config.languages,
config.packs,
apiDetails,
registriesInput,
config.tempDir,
logger,
);
}
// Save the config so we can easily access it again in the future
await saveConfig(config, logger);
return config;

View file

@ -291,8 +291,8 @@ test("Feature flags are saved to disk", async (t) => {
t.true(
await features.getValue(
Feature.CliConfigFileEnabled,
includeCodeQlIfRequired(Feature.CliConfigFileEnabled),
Feature.QaTelemetryEnabled,
includeCodeQlIfRequired(Feature.QaTelemetryEnabled),
),
"Feature flag should be enabled initially",
);
@ -308,7 +308,7 @@ test("Feature flags are saved to disk", async (t) => {
t.deepEqual(actualFeatureEnablement, expectedFeatureEnablement);
// now test that we actually use the feature flag cache instead of the server
actualFeatureEnablement[Feature.CliConfigFileEnabled] = false;
actualFeatureEnablement[Feature.QaTelemetryEnabled] = false;
fs.writeFileSync(
cachedFeatureFlags,
JSON.stringify(actualFeatureEnablement),
@ -319,8 +319,8 @@ test("Feature flags are saved to disk", async (t) => {
t.false(
await features.getValue(
Feature.CliConfigFileEnabled,
includeCodeQlIfRequired(Feature.CliConfigFileEnabled),
Feature.QaTelemetryEnabled,
includeCodeQlIfRequired(Feature.QaTelemetryEnabled),
),
"Feature flag should be enabled after reading from cached file",
);
@ -336,8 +336,8 @@ test("Environment variable can override feature flag cache", async (t) => {
const cachedFeatureFlags = path.join(tmpDir, FEATURE_FLAGS_FILE_NAME);
t.true(
await features.getValue(
Feature.CliConfigFileEnabled,
includeCodeQlIfRequired(Feature.CliConfigFileEnabled),
Feature.QaTelemetryEnabled,
includeCodeQlIfRequired(Feature.QaTelemetryEnabled),
),
"Feature flag should be enabled initially",
);
@ -346,12 +346,12 @@ test("Environment variable can override feature flag cache", async (t) => {
fs.existsSync(cachedFeatureFlags),
"Feature flag cached file should exist after getting feature flags",
);
process.env.CODEQL_PASS_CONFIG_TO_CLI = "false";
process.env.CODEQL_ACTION_QA_TELEMETRY = "false";
t.false(
await features.getValue(
Feature.CliConfigFileEnabled,
includeCodeQlIfRequired(Feature.CliConfigFileEnabled),
Feature.QaTelemetryEnabled,
includeCodeQlIfRequired(Feature.QaTelemetryEnabled),
),
"Feature flag should be disabled after setting env var",
);

View file

@ -44,7 +44,6 @@ export interface FeatureEnablement {
* Each value of this enum should end with `_enabled`.
*/
export enum Feature {
CliConfigFileEnabled = "cli_config_file_enabled",
CodeqlJavaLombokEnabled = "codeql_java_lombok_enabled",
CppDependencyInstallation = "cpp_dependency_installation_enabled",
DisableKotlinAnalysisEnabled = "disable_kotlin_analysis_enabled",
@ -73,11 +72,6 @@ export const featureConfig: Record<
minimumVersion: undefined,
defaultValue: false,
},
[Feature.CliConfigFileEnabled]: {
envVar: "CODEQL_PASS_CONFIG_TO_CLI",
minimumVersion: undefined,
defaultValue: true,
},
[Feature.EvaluatorFineGrainedParallelismEnabled]: {
envVar: "CODEQL_EVALUATOR_FINE_GRAINED_PARALLELISM",
minimumVersion: CODEQL_VERSION_FINE_GRAINED_PARALLELISM,
@ -447,30 +441,3 @@ class GitHubFeatureFlags {
}
}
}
/**
* @returns Whether the Action should generate a code scanning config file
* that gets passed to the CLI.
*/
export async function useCodeScanningConfigInCli(
codeql: CodeQL,
features: FeatureEnablement,
): Promise<boolean> {
return await features.getValue(Feature.CliConfigFileEnabled, codeql);
}
export async function logCodeScanningConfigInCli(
codeql: CodeQL,
features: FeatureEnablement,
logger: Logger,
) {
if (await useCodeScanningConfigInCli(codeql, features)) {
logger.info(
"Code Scanning configuration file being processed in the codeql CLI.",
);
} else {
logger.info(
"Code Scanning configuration file being processed in the codeql-action.",
);
}
}

View file

@ -469,7 +469,6 @@ async function run() {
sourceRoot,
"Runner.Worker.exe",
registriesInput,
features,
apiDetails,
logger,
);

View file

@ -8,11 +8,7 @@ import * as analysisPaths from "./analysis-paths";
import { GitHubApiCombinedDetails, GitHubApiDetails } from "./api-client";
import { CodeQL, setupCodeQL } from "./codeql";
import * as configUtils from "./config-utils";
import {
CodeQLDefaultVersionInfo,
FeatureEnablement,
useCodeScanningConfigInCli,
} from "./feature-flags";
import { CodeQLDefaultVersionInfo, FeatureEnablement } from "./feature-flags";
import { Language } from "./languages";
import { Logger } from "./logging";
import { RepositoryNwo } from "./repository";
@ -103,26 +99,17 @@ export async function runInit(
sourceRoot: string,
processName: string | undefined,
registriesInput: string | undefined,
features: FeatureEnablement,
apiDetails: GitHubApiCombinedDetails,
logger: Logger,
): Promise<TracerConfig | undefined> {
fs.mkdirSync(config.dbLocation, { recursive: true });
try {
// When parsing the codeql config in the CLI, we have not yet created the qlconfig file.
// So, create it now.
// If we are parsing the config file in the Action, then the qlconfig file was already created
// before the `pack download` command was invoked. It is not required for the init command.
let registriesAuthTokens: string | undefined;
let qlconfigFile: string | undefined;
if (await useCodeScanningConfigInCli(codeql, features)) {
({ registriesAuthTokens, qlconfigFile } =
await configUtils.generateRegistries(
registriesInput,
config.tempDir,
logger,
));
}
const { registriesAuthTokens, qlconfigFile } =
await configUtils.generateRegistries(
registriesInput,
config.tempDir,
logger,
);
await configUtils.wrapEnvironment(
{
GITHUB_TOKEN: apiDetails.auth,
@ -135,7 +122,6 @@ export async function runInit(
config,
sourceRoot,
processName,
features,
qlconfigFile,
logger,
),