Skip to content

Commit 2c8d410

Browse files
authored
Merge pull request #4184 from github/henrymercer/per-language-pr-check-failures
Use the combined bundle when queries may need other languages' library packs
2 parents 1767808 + 12db63b commit 2c8d410

21 files changed

Lines changed: 698 additions & 204 deletions

‎.github/workflows/__export-file-baseline-information.yml‎

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎lib/entry-points.js‎

Lines changed: 110 additions & 60 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pr-checks/checks/export-file-baseline-information.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ installDotNet: true
1111
env:
1212
CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS: false
1313
CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true
14+
# To balance speed and coverage, we analyze only a single language (JavaScript), but use the
15+
# combined bundle so we can test that baseline information is reported for each language in the
16+
# multi-language source directory.
17+
CODEQL_ACTION_PER_LANGUAGE_BUNDLES: false
1418
steps:
1519
- uses: ./../action/init
1620
id: init

‎setup-codeql/action.yml‎

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,16 @@ inputs:
2121
required: false
2222
languages:
2323
description: >-
24-
A comma-separated list of CodeQL languages that will be analyzed in subsequent
25-
`github/codeql-action/init` and `github/codeql-action/analyze` invocations. If specified, the
26-
Action may use this list to select a CodeQL CLI version that is best suited to analyzing those
27-
languages, for example by preferring a version that has a cached overlay-base database for the
28-
specified languages. This input is not remembered and must also be passed to
29-
`github/codeql-action/init`.
24+
A comma-separated list of CodeQL languages that the installed CodeQL CLI will be used to
25+
analyze. If specified, the Action may use this list to select a CodeQL CLI version that is
26+
best suited to analyzing those languages, for example by preferring a version that has a
27+
cached overlay-base database for the specified languages.
3028
required: false
3129
analysis-kinds:
3230
description: >-
33-
[Internal] A comma-separated list of analysis kinds that subsequent
34-
`github/codeql-action/init` invocations will enable. If specified, the Action may use this
35-
list to select a CodeQL CLI version that is best suited to those analysis kinds. This input is
36-
not remembered and must also be passed to `github/codeql-action/init`.
31+
[Internal] A comma-separated list of analysis kinds that the installed CodeQL CLI will be used
32+
for. If specified, the Action may use this list to select a CodeQL CLI version that is best
33+
suited to those analysis kinds.
3734
3835
Available options are the same as for the `analysis-kinds` input on the `init` Action.
3936
default: 'code-scanning'

‎src/analyze.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import * as sinon from "sinon";
77
import { CodeQuality, CodeScanning, RiskAssessment } from "./analyses";
88
import {
99
runQueries,
10-
defaultSuites,
1110
resolveQuerySuiteAlias,
1211
addSarifExtension,
1312
diffRangeExtensionPackContents,
1413
} from "./analyze";
1514
import { createStubCodeQL } from "./codeql";
15+
import { defaultSuites } from "./config/db-config";
1616
import { Feature } from "./feature-flags";
1717
import { BuiltInLanguage } from "./languages";
1818
import { getRunnerLogger } from "./logging";

‎src/analyze.ts‎

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getTemporaryDirectory } from "./actions-util";
99
import * as analyses from "./analyses";
1010
import { setupCppAutobuild } from "./autobuild";
1111
import { type CodeQL } from "./codeql";
12+
import { defaultSuites } from "./config/db-config";
1213
import * as configUtils from "./config-utils";
1314
import {
1415
getCsharpTempDependencyDir,
@@ -357,15 +358,6 @@ dataExtensions:
357358
return diffRangeDir;
358359
}
359360

360-
// A set of default query suite names that are understood by the CLI.
361-
export const defaultSuites: Set<string> = new Set([
362-
"security-experimental",
363-
"security-extended",
364-
"security-and-quality",
365-
"code-quality",
366-
"code-scanning",
367-
]);
368-
369361
/**
370362
* If `maybeSuite` is the name of a default query suite, it is resolved into the corresponding
371363
* query suite name for the given `language`. Otherwise, `maybeSuite` is returned as is.

‎src/codeql.test.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ async function installIntoToolcache({
9999
? { enabledVersions: [{ cliVersion, tagName }] }
100100
: SAMPLE_DEFAULT_CLI_VERSION,
101101
undefined, // rawLanguages
102+
undefined, // otherLanguagePacksReason
102103
false, // useOverlayAwareDefaultCliVersion
103104
createFeatures([]),
104105
getRunnerLogger(true),
@@ -172,6 +173,7 @@ test.serial(
172173
util.GitHubVariant.DOTCOM,
173174
SAMPLE_DEFAULT_CLI_VERSION,
174175
undefined, // rawLanguages
176+
undefined, // otherLanguagePacksReason
175177
false, // useOverlayAwareDefaultCliVersion
176178
features,
177179
getRunnerLogger(true),
@@ -207,6 +209,7 @@ test.serial(
207209
util.GitHubVariant.DOTCOM,
208210
SAMPLE_DEFAULT_CLI_VERSION,
209211
undefined, // rawLanguages
212+
undefined, // otherLanguagePacksReason
210213
false, // useOverlayAwareDefaultCliVersion
211214
features,
212215
getRunnerLogger(true),
@@ -246,6 +249,7 @@ test.serial(
246249
util.GitHubVariant.DOTCOM,
247250
SAMPLE_DEFAULT_CLI_VERSION,
248251
undefined, // rawLanguages
252+
undefined, // otherLanguagePacksReason
249253
false, // useOverlayAwareDefaultCliVersion
250254
features,
251255
getRunnerLogger(true),
@@ -355,6 +359,7 @@ for (const {
355359
util.GitHubVariant.DOTCOM,
356360
SAMPLE_DEFAULT_CLI_VERSION,
357361
undefined, // rawLanguages
362+
undefined, // otherLanguagePacksReason
358363
false, // useOverlayAwareDefaultCliVersion
359364
features,
360365
getRunnerLogger(true),
@@ -397,6 +402,7 @@ for (const toolcacheVersion of [
397402
util.GitHubVariant.DOTCOM,
398403
SAMPLE_DEFAULT_CLI_VERSION,
399404
undefined, // rawLanguages
405+
undefined, // otherLanguagePacksReason
400406
false, // useOverlayAwareDefaultCliVersion
401407
features,
402408
getRunnerLogger(true),
@@ -441,6 +447,7 @@ test.serial(
441447
],
442448
},
443449
undefined, // rawLanguages
450+
undefined, // otherLanguagePacksReason
444451
false, // useOverlayAwareDefaultCliVersion
445452
features,
446453
getRunnerLogger(true),
@@ -487,6 +494,7 @@ test.serial(
487494
],
488495
},
489496
undefined, // rawLanguages
497+
undefined, // otherLanguagePacksReason
490498
false, // useOverlayAwareDefaultCliVersion
491499
features,
492500
getRunnerLogger(true),
@@ -526,6 +534,7 @@ test.serial(
526534
util.GitHubVariant.DOTCOM,
527535
SAMPLE_DEFAULT_CLI_VERSION,
528536
undefined, // rawLanguages
537+
undefined, // otherLanguagePacksReason
529538
false, // useOverlayAwareDefaultCliVersion
530539
features,
531540
getRunnerLogger(true),
@@ -567,6 +576,7 @@ test.serial(
567576
util.GitHubVariant.DOTCOM,
568577
SAMPLE_DEFAULT_CLI_VERSION,
569578
undefined, // rawLanguages
579+
undefined, // otherLanguagePacksReason
570580
false, // useOverlayAwareDefaultCliVersion
571581
features,
572582
getRunnerLogger(true),

‎src/codeql.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@ export function isDiskConfigurationError(e: unknown): boolean {
302302
* @param variant
303303
* @param defaultCliVersion
304304
* @param rawLanguages Raw set of languages.
305+
* @param otherLanguagePacksReason Why the CodeQL CLI may need packs for languages other than
306+
* `rawLanguages`, or `undefined` if it won't. If defined, the combined bundle is used. See
307+
* `PerLanguageBundleOptions.otherLanguagePacksReason`.
305308
* @param useOverlayAwareDefaultCliVersion Whether to select an overlay-aware default CLI version.
306309
* @param features Information about the features that are enabled.
307310
* @param logger
@@ -316,6 +319,7 @@ export async function setupCodeQL(
316319
variant: util.GitHubVariant,
317320
defaultCliVersion: CodeQLDefaultVersionInfo,
318321
rawLanguages: string[] | undefined,
322+
otherLanguagePacksReason: string | undefined,
319323
useOverlayAwareDefaultCliVersion: boolean,
320324
features: FeatureEnablement,
321325
logger: Logger,
@@ -339,6 +343,7 @@ export async function setupCodeQL(
339343
variant,
340344
defaultCliVersion,
341345
rawLanguages,
346+
otherLanguagePacksReason,
342347
useOverlayAwareDefaultCliVersion,
343348
features,
344349
logger,

‎src/config-utils.test.ts‎

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,12 @@ const simpleConfigFileContents = `
473473
queries:
474474
- uses: ./foo_file`;
475475

476+
/** The configuration in `simpleConfigFileContents`. */
477+
const simpleConfigInput: UserConfig = {
478+
name: "my config",
479+
queries: [{ uses: "./foo_file" }],
480+
};
481+
476482
/** A less minimal configuration file. */
477483
const otherConfigFileContents = `
478484
name: my config
@@ -558,16 +564,14 @@ test.serial(
558564
tempDir,
559565
);
560566

561-
const configInput = `
562-
name: my config
563-
queries:
564-
- uses: ./foo
565-
packs:
566-
javascript:
567-
- a/b@1.2.3
568-
python:
569-
- c/d@1.2.3
570-
`;
567+
const configInput: UserConfig = {
568+
name: "my config",
569+
queries: [{ uses: "./foo" }],
570+
packs: {
571+
javascript: ["a/b@1.2.3"],
572+
python: ["c/d@1.2.3"],
573+
},
574+
};
571575

572576
fs.mkdirSync(path.join(tempDir, "foo"));
573577

@@ -598,7 +602,16 @@ test.serial(
598602
}),
599603
);
600604

601-
t.deepEqual(config.originalUserInput, yaml.load(configInput));
605+
// Compare with a separate object rather than `configInput` itself, so that the test catches
606+
// changes made to the input in place.
607+
t.deepEqual(config.originalUserInput, {
608+
name: "my config",
609+
queries: [{ uses: "./foo" }],
610+
packs: {
611+
javascript: ["a/b@1.2.3"],
612+
python: ["c/d@1.2.3"],
613+
},
614+
});
602615
});
603616
},
604617
);
@@ -2413,7 +2426,7 @@ test("determineUserConfig - loads config input", async (t) => {
24132426
const expectedConfigPath = configUtils.userConfigFromActionPath(tmpDir);
24142427

24152428
const inputs = createTestInitConfigInputs({
2416-
configInput: simpleConfigFileContents,
2429+
configInput: simpleConfigInput,
24172430
configFile: undefined,
24182431
workspacePath: tmpDir,
24192432
});
@@ -2423,17 +2436,15 @@ test("determineUserConfig - loads config input", async (t) => {
24232436

24242437
await target
24252438
// The input source and path of the generated config file should have been logged.
2426-
.logs(
2427-
t,
2428-
"Using config from action input:",
2429-
`Using configuration file: ${expectedConfigPath}`,
2430-
)
2431-
// The message about no configuration input and
2432-
// the warning about both inputs should not have been logged.
2439+
.logs(t, `Using config from action input: ${expectedConfigPath}`)
2440+
// The message about no configuration input and the warning about both inputs should not have
2441+
// been logged. The generated config file isn't loaded, since the `config` input has already
2442+
// been parsed.
24332443
.notLogs(
24342444
t,
24352445
"No configuration file was provided",
24362446
"Both a config file and config input were provided. Ignoring config file.",
2447+
`Using configuration file: ${expectedConfigPath}`,
24372448
)
24382449
// The loaded configuration should match `simpleConfigFileContents`.
24392450
.passes(t.deepEqual, {
@@ -2452,7 +2463,7 @@ test("determineUserConfig - ignores config file input when both specified", asyn
24522463
const expectedConfigPath = configUtils.userConfigFromActionPath(tmpDir);
24532464

24542465
const inputs = createTestInitConfigInputs({
2455-
configInput: simpleConfigFileContents,
2466+
configInput: simpleConfigInput,
24562467
configFile: configFilePath,
24572468
workspacePath: tmpDir,
24582469
});
@@ -2466,10 +2477,14 @@ test("determineUserConfig - ignores config file input when both specified", asyn
24662477
.logs(
24672478
t,
24682479
`Using config from action input: ${expectedConfigPath}`,
2469-
`Using configuration file: ${expectedConfigPath}`,
24702480
"Both a config file and config input were provided. Ignoring config file.",
24712481
)
2472-
.notLogs(t, "No configuration file was provided")
2482+
// The generated config file isn't loaded, since the `config` input has already been parsed.
2483+
.notLogs(
2484+
t,
2485+
"No configuration file was provided",
2486+
`Using configuration file: ${expectedConfigPath}`,
2487+
)
24732488
// The loaded configuration should match `simpleConfigFileContents`.
24742489
.passes(t.deepEqual, {
24752490
name: "my config",
@@ -2482,11 +2497,14 @@ test("determineUserConfig - ignores config file input when both specified", asyn
24822497
});
24832498

24842499
/** A `config` input that we might get from Default Setup. */
2485-
const defaultSetupConfigInput = `
2486-
threat-models: [local, remote]
2487-
default-setup:
2488-
org:
2489-
model-packs: [foo, bar]`;
2500+
const defaultSetupConfigInput: UserConfig = {
2501+
"threat-models": ["local", "remote"],
2502+
"default-setup": {
2503+
org: {
2504+
"model-packs": ["foo", "bar"],
2505+
},
2506+
},
2507+
};
24902508

24912509
test("determineUserConfig - merges configs if FF is enabled in Default Setup", async (t) => {
24922510
await withTmpDir(async (tmpDir) => {
@@ -2555,7 +2573,7 @@ test("determineUserConfig - ignores config file input in Default Setup if FF is
25552573
.withArgs(
25562574
tmpDir,
25572575
createTestInitConfigInputs({
2558-
configInput: simpleConfigFileContents,
2576+
configInput: simpleConfigInput,
25592577
configFile: configFilePath,
25602578
workspacePath: tmpDir,
25612579
}),
@@ -2565,10 +2583,14 @@ test("determineUserConfig - ignores config file input in Default Setup if FF is
25652583
.logs(
25662584
t,
25672585
`Using config from action input: ${expectedConfigPath}`,
2568-
`Using configuration file: ${expectedConfigPath}`,
25692586
"Both a config file and config input were provided. Ignoring config file.",
25702587
)
2571-
.notLogs(t, "No configuration file was provided")
2588+
// The generated config file isn't loaded, since the `config` input has already been parsed.
2589+
.notLogs(
2590+
t,
2591+
"No configuration file was provided",
2592+
`Using configuration file: ${expectedConfigPath}`,
2593+
)
25722594
.passes(t.deepEqual, {
25732595
name: "my config",
25742596
queries: [{ uses: "./foo_file" }],
@@ -2587,7 +2609,7 @@ test("determineUserConfig - ignores config file input outside Default Setup if F
25872609
.withArgs(
25882610
tmpDir,
25892611
createTestInitConfigInputs({
2590-
configInput: simpleConfigFileContents,
2612+
configInput: simpleConfigInput,
25912613
configFile: configFilePath,
25922614
workspacePath: tmpDir,
25932615
}),
@@ -2597,10 +2619,14 @@ test("determineUserConfig - ignores config file input outside Default Setup if F
25972619
.logs(
25982620
t,
25992621
`Using config from action input: ${expectedConfigPath}`,
2600-
`Using configuration file: ${expectedConfigPath}`,
26012622
"Both a config file and config input were provided. Ignoring config file.",
26022623
)
2603-
.notLogs(t, "No configuration file was provided")
2624+
// The generated config file isn't loaded, since the `config` input has already been parsed.
2625+
.notLogs(
2626+
t,
2627+
"No configuration file was provided",
2628+
`Using configuration file: ${expectedConfigPath}`,
2629+
)
26042630
.passes(t.deepEqual, {
26052631
name: "my config",
26062632
queries: [{ uses: "./foo_file" }],

0 commit comments

Comments
 (0)