Merge pull request #2917 from github/mbg/use-cq-endpoint

Add new `quality-queries` input
This commit is contained in:
Michael B. Gale 2025-06-16 13:54:01 +01:00 committed by GitHub
commit 3de706a4a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 305 additions and 29 deletions

100
.github/workflows/__quality-queries.yml generated vendored Normal file
View file

@ -0,0 +1,100 @@
# Warning: This file is generated automatically, and should not be modified.
# Instead, please modify the template in the pr-checks directory and run:
# (cd pr-checks; pip install ruamel.yaml@0.17.31 && python3 sync.py)
# to regenerate this file.
name: PR Check - Quality queries input
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GO111MODULE: auto
on:
push:
branches:
- main
- releases/v*
pull_request:
types:
- opened
- synchronize
- reopened
- ready_for_review
schedule:
- cron: '0 5 * * *'
workflow_dispatch: {}
jobs:
quality-queries:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: linked
- os: macos-latest
version: linked
- os: windows-latest
version: linked
- os: ubuntu-latest
version: nightly-latest
- os: macos-latest
version: nightly-latest
- os: windows-latest
version: nightly-latest
name: Quality queries input
permissions:
contents: read
security-events: read
timeout-minutes: 45
runs-on: ${{ matrix.os }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Prepare test
id: prepare-test
uses: ./.github/actions/prepare-test
with:
version: ${{ matrix.version }}
use-all-platform-bundle: 'false'
setup-kotlin: 'true'
- uses: ./../action/init
with:
languages: javascript
quality-queries: code-quality
tools: ${{ steps.prepare-test.outputs.tools-url }}
- uses: ./../action/analyze
with:
output: ${{ runner.temp }}/results
upload-database: false
- name: Upload SARIF
uses: actions/upload-artifact@v4
with:
name: config-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: ${{ runner.temp }}/results/javascript.sarif
retention-days: 7
- name: Check config properties appear in SARIF
uses: actions/github-script@v7
env:
SARIF_PATH: ${{ runner.temp }}/results/javascript.sarif
with:
script: |
const fs = require('fs');
const sarif = JSON.parse(fs.readFileSync(process.env['SARIF_PATH'], 'utf8'));
const run = sarif.runs[0];
const configSummary = run.properties.codeqlConfigSummary;
if (configSummary === undefined) {
core.setFailed('`codeqlConfigSummary` property not found in the SARIF run property bag.');
}
if (configSummary.disableDefaultQueries !== false) {
core.setFailed('`disableDefaultQueries` property incorrect: expected false, got ' +
`${JSON.stringify(configSummary.disableDefaultQueries)}.`);
}
const expectedQueries = [{ type: 'builtinSuite', uses: 'code-quality' }];
// Use JSON.stringify to deep-equal the arrays.
if (JSON.stringify(configSummary.queries) !== JSON.stringify(expectedQueries)) {
core.setFailed(`\`queries\` property incorrect: expected ${JSON.stringify(expectedQueries)}, got ` +
`${JSON.stringify(configSummary.queries)}.`);
}
core.info('Finished config export tests.');
env:
CODEQL_ACTION_TEST_MODE: true

View file

@ -83,6 +83,9 @@ inputs:
queries: queries:
description: Comma-separated list of additional queries to run. By default, this overrides the same setting in a configuration file; prefix with "+" to use both sets of queries. description: Comma-separated list of additional queries to run. By default, this overrides the same setting in a configuration file; prefix with "+" to use both sets of queries.
required: false required: false
quality-queries:
description: '[Internal] Comma-separated list of code quality queries to run.'
required: false
packs: packs:
description: >- description: >-
Comma-separated list of packs to run. Reference a pack in the format `scope/name[@version]`. If `version` is not Comma-separated list of packs to run. Reference a pack in the format `scope/name[@version]`. If `version` is not

8
lib/codeql.js generated
View file

@ -759,12 +759,14 @@ async function generateCodeScanningConfig(config, logger) {
// make a copy so we can modify it // make a copy so we can modify it
const augmentedConfig = (0, util_1.cloneObject)(config.originalUserInput); const augmentedConfig = (0, util_1.cloneObject)(config.originalUserInput);
// Inject the queries from the input // Inject the queries from the input
if (config.augmentationProperties.queriesInput) { if (config.augmentationProperties.queriesInput ||
config.augmentationProperties.qualityQueriesInput) {
const queryInputs = (config.augmentationProperties.queriesInput || []).concat(config.augmentationProperties.qualityQueriesInput || []);
if (config.augmentationProperties.queriesInputCombines) { if (config.augmentationProperties.queriesInputCombines) {
augmentedConfig.queries = (augmentedConfig.queries || []).concat(config.augmentationProperties.queriesInput); augmentedConfig.queries = (augmentedConfig.queries || []).concat(queryInputs);
} }
else { else {
augmentedConfig.queries = config.augmentationProperties.queriesInput; augmentedConfig.queries = queryInputs;
} }
} }
if (augmentedConfig.queries?.length === 0) { if (augmentedConfig.queries?.length === 0) {

File diff suppressed because one or more lines are too long

13
lib/config-utils.js generated
View file

@ -80,6 +80,7 @@ exports.defaultAugmentationProperties = {
packsInputCombines: false, packsInputCombines: false,
packsInput: undefined, packsInput: undefined,
queriesInput: undefined, queriesInput: undefined,
qualityQueriesInput: undefined,
defaultQueryFilters: [], defaultQueryFilters: [],
}; };
function getPacksStrInvalid(packStr, configFile) { function getPacksStrInvalid(packStr, configFile) {
@ -226,10 +227,10 @@ async function getRawLanguages(languagesInput, repository, logger) {
/** /**
* Get the default config for when the user has not supplied one. * Get the default config for when the user has not supplied one.
*/ */
async function getDefaultConfig({ languagesInput, queriesInput, packsInput, buildModeInput, dbLocation, trapCachingEnabled, dependencyCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeql, githubVersion, features, logger, }) { async function getDefaultConfig({ languagesInput, queriesInput, qualityQueriesInput, packsInput, buildModeInput, dbLocation, trapCachingEnabled, dependencyCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeql, githubVersion, features, logger, }) {
const languages = await getLanguages(codeql, languagesInput, repository, logger); const languages = await getLanguages(codeql, languagesInput, repository, logger);
const buildMode = await parseBuildModeInput(buildModeInput, languages, features, logger); const buildMode = await parseBuildModeInput(buildModeInput, languages, features, logger);
const augmentationProperties = await calculateAugmentation(codeql, features, packsInput, queriesInput, languages, logger); const augmentationProperties = await calculateAugmentation(codeql, features, packsInput, queriesInput, qualityQueriesInput, languages, logger);
const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime(trapCachingEnabled, codeql, languages, logger); const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime(trapCachingEnabled, codeql, languages, logger);
return { return {
languages, languages,
@ -261,7 +262,7 @@ async function downloadCacheWithTime(trapCachingEnabled, codeQL, languages, logg
/** /**
* Load the config from the given file. * Load the config from the given file.
*/ */
async function loadConfig({ languagesInput, queriesInput, packsInput, buildModeInput, configFile, dbLocation, trapCachingEnabled, dependencyCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeql, workspacePath, githubVersion, apiDetails, features, logger, }) { async function loadConfig({ languagesInput, queriesInput, qualityQueriesInput, packsInput, buildModeInput, configFile, dbLocation, trapCachingEnabled, dependencyCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeql, workspacePath, githubVersion, apiDetails, features, logger, }) {
let parsedYAML; let parsedYAML;
if (isLocal(configFile)) { if (isLocal(configFile)) {
if (configFile !== userConfigFromActionPath(tempDir)) { if (configFile !== userConfigFromActionPath(tempDir)) {
@ -279,7 +280,7 @@ async function loadConfig({ languagesInput, queriesInput, packsInput, buildModeI
} }
const languages = await getLanguages(codeql, languagesInput, repository, logger); const languages = await getLanguages(codeql, languagesInput, repository, logger);
const buildMode = await parseBuildModeInput(buildModeInput, languages, features, logger); const buildMode = await parseBuildModeInput(buildModeInput, languages, features, logger);
const augmentationProperties = await calculateAugmentation(codeql, features, packsInput, queriesInput, languages, logger); const augmentationProperties = await calculateAugmentation(codeql, features, packsInput, queriesInput, qualityQueriesInput, languages, logger);
const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime(trapCachingEnabled, codeql, languages, logger); const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime(trapCachingEnabled, codeql, languages, logger);
return { return {
languages, languages,
@ -320,11 +321,12 @@ async function loadConfig({ languagesInput, queriesInput, packsInput, buildModeI
* not have exactly one language. * not have exactly one language.
*/ */
// exported for testing. // exported for testing.
async function calculateAugmentation(codeql, features, rawPacksInput, rawQueriesInput, languages, logger) { async function calculateAugmentation(codeql, features, rawPacksInput, rawQueriesInput, rawQualityQueriesInput, languages, logger) {
const packsInputCombines = shouldCombine(rawPacksInput); const packsInputCombines = shouldCombine(rawPacksInput);
const packsInput = parsePacksFromInput(rawPacksInput, languages, packsInputCombines); const packsInput = parsePacksFromInput(rawPacksInput, languages, packsInputCombines);
const queriesInputCombines = shouldCombine(rawQueriesInput); const queriesInputCombines = shouldCombine(rawQueriesInput);
const queriesInput = parseQueriesFromInput(rawQueriesInput, queriesInputCombines); const queriesInput = parseQueriesFromInput(rawQueriesInput, queriesInputCombines);
const qualityQueriesInput = parseQueriesFromInput(rawQualityQueriesInput, false);
const defaultQueryFilters = []; const defaultQueryFilters = [];
if (await (0, diff_informed_analysis_utils_1.shouldPerformDiffInformedAnalysis)(codeql, features, logger)) { if (await (0, diff_informed_analysis_utils_1.shouldPerformDiffInformedAnalysis)(codeql, features, logger)) {
defaultQueryFilters.push({ exclude: { tags: "exclude-from-incremental" } }); defaultQueryFilters.push({ exclude: { tags: "exclude-from-incremental" } });
@ -334,6 +336,7 @@ async function calculateAugmentation(codeql, features, rawPacksInput, rawQueries
packsInput: packsInput?.[languages[0]], packsInput: packsInput?.[languages[0]],
queriesInput, queriesInput,
queriesInputCombines, queriesInputCombines,
qualityQueriesInput,
defaultQueryFilters, defaultQueryFilters,
}; };
} }

File diff suppressed because one or more lines are too long

View file

@ -58,6 +58,7 @@ function createTestInitConfigInputs(overrides) {
return Object.assign({}, { return Object.assign({}, {
languagesInput: undefined, languagesInput: undefined,
queriesInput: undefined, queriesInput: undefined,
qualityQueriesInput: undefined,
packsInput: undefined, packsInput: undefined,
configFile: undefined, configFile: undefined,
dbLocation: undefined, dbLocation: undefined,
@ -623,58 +624,89 @@ const packSpecPrettyPrintingMacro = ava_1.default.macro({
}); });
const mockLogger = (0, logging_1.getRunnerLogger)(true); const mockLogger = (0, logging_1.getRunnerLogger)(true);
const calculateAugmentationMacro = ava_1.default.macro({ const calculateAugmentationMacro = ava_1.default.macro({
exec: async (t, _title, rawPacksInput, rawQueriesInput, languages, expectedAugmentationProperties) => { exec: async (t, _title, rawPacksInput, rawQueriesInput, rawQualityQueriesInput, languages, expectedAugmentationProperties) => {
const actualAugmentationProperties = await configUtils.calculateAugmentation((0, codeql_1.getCachedCodeQL)(), (0, testing_utils_1.createFeatures)([]), rawPacksInput, rawQueriesInput, languages, mockLogger); const actualAugmentationProperties = await configUtils.calculateAugmentation((0, codeql_1.getCachedCodeQL)(), (0, testing_utils_1.createFeatures)([]), rawPacksInput, rawQueriesInput, rawQualityQueriesInput, languages, mockLogger);
t.deepEqual(actualAugmentationProperties, expectedAugmentationProperties); t.deepEqual(actualAugmentationProperties, expectedAugmentationProperties);
}, },
title: (_, title) => `Calculate Augmentation: ${title}`, title: (_, title) => `Calculate Augmentation: ${title}`,
}); });
(0, ava_1.default)(calculateAugmentationMacro, "All empty", undefined, undefined, [languages_1.Language.javascript], { (0, ava_1.default)(calculateAugmentationMacro, "All empty", undefined, undefined, undefined, [languages_1.Language.javascript], {
queriesInputCombines: false, queriesInputCombines: false,
queriesInput: undefined, queriesInput: undefined,
qualityQueriesInput: undefined,
packsInputCombines: false, packsInputCombines: false,
packsInput: undefined, packsInput: undefined,
defaultQueryFilters: [], defaultQueryFilters: [],
}); });
(0, ava_1.default)(calculateAugmentationMacro, "With queries", undefined, " a, b , c, d", [languages_1.Language.javascript], { (0, ava_1.default)(calculateAugmentationMacro, "With queries", undefined, " a, b , c, d", undefined, [languages_1.Language.javascript], {
queriesInputCombines: false, queriesInputCombines: false,
queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }], queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }],
qualityQueriesInput: undefined,
packsInputCombines: false, packsInputCombines: false,
packsInput: undefined, packsInput: undefined,
defaultQueryFilters: [], defaultQueryFilters: [],
}); });
(0, ava_1.default)(calculateAugmentationMacro, "With queries combining", undefined, " + a, b , c, d ", [languages_1.Language.javascript], { (0, ava_1.default)(calculateAugmentationMacro, "With queries combining", undefined, " + a, b , c, d ", undefined, [languages_1.Language.javascript], {
queriesInputCombines: true, queriesInputCombines: true,
queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }], queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }],
qualityQueriesInput: undefined,
packsInputCombines: false, packsInputCombines: false,
packsInput: undefined, packsInput: undefined,
defaultQueryFilters: [], defaultQueryFilters: [],
}); });
(0, ava_1.default)(calculateAugmentationMacro, "With packs", " codeql/a , codeql/b , codeql/c , codeql/d ", undefined, [languages_1.Language.javascript], { (0, ava_1.default)(calculateAugmentationMacro, "With quality queries", undefined, undefined, " a, b , c, d", [languages_1.Language.javascript], {
queriesInputCombines: false, queriesInputCombines: false,
queriesInput: undefined, queriesInput: undefined,
qualityQueriesInput: [
{ uses: "a" },
{ uses: "b" },
{ uses: "c" },
{ uses: "d" },
],
packsInputCombines: false,
packsInput: undefined,
defaultQueryFilters: [],
});
(0, ava_1.default)(calculateAugmentationMacro, "With security and quality queries", undefined, " a, b , c, d", "e, f , g,h", [languages_1.Language.javascript], {
queriesInputCombines: false,
queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }],
qualityQueriesInput: [
{ uses: "e" },
{ uses: "f" },
{ uses: "g" },
{ uses: "h" },
],
packsInputCombines: false,
packsInput: undefined,
defaultQueryFilters: [],
});
(0, ava_1.default)(calculateAugmentationMacro, "With packs", " codeql/a , codeql/b , codeql/c , codeql/d ", undefined, undefined, [languages_1.Language.javascript], {
queriesInputCombines: false,
queriesInput: undefined,
qualityQueriesInput: undefined,
packsInputCombines: false, packsInputCombines: false,
packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"], packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"],
defaultQueryFilters: [], defaultQueryFilters: [],
}); });
(0, ava_1.default)(calculateAugmentationMacro, "With packs combining", " + codeql/a, codeql/b, codeql/c, codeql/d", undefined, [languages_1.Language.javascript], { (0, ava_1.default)(calculateAugmentationMacro, "With packs combining", " + codeql/a, codeql/b, codeql/c, codeql/d", undefined, undefined, [languages_1.Language.javascript], {
queriesInputCombines: false, queriesInputCombines: false,
queriesInput: undefined, queriesInput: undefined,
qualityQueriesInput: undefined,
packsInputCombines: true, packsInputCombines: true,
packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"], packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"],
defaultQueryFilters: [], defaultQueryFilters: [],
}); });
const calculateAugmentationErrorMacro = ava_1.default.macro({ const calculateAugmentationErrorMacro = ava_1.default.macro({
exec: async (t, _title, rawPacksInput, rawQueriesInput, languages, expectedError) => { exec: async (t, _title, rawPacksInput, rawQueriesInput, rawQualityQueriesInput, languages, expectedError) => {
await t.throwsAsync(() => configUtils.calculateAugmentation((0, codeql_1.getCachedCodeQL)(), (0, testing_utils_1.createFeatures)([]), rawPacksInput, rawQueriesInput, languages, mockLogger), { message: expectedError }); await t.throwsAsync(() => configUtils.calculateAugmentation((0, codeql_1.getCachedCodeQL)(), (0, testing_utils_1.createFeatures)([]), rawPacksInput, rawQueriesInput, rawQualityQueriesInput, languages, mockLogger), { message: expectedError });
}, },
title: (_, title) => `Calculate Augmentation Error: ${title}`, title: (_, title) => `Calculate Augmentation Error: ${title}`,
}); });
(0, ava_1.default)(calculateAugmentationErrorMacro, "Plus (+) with nothing else (queries)", undefined, " + ", [languages_1.Language.javascript], /The workflow property "queries" is invalid/); (0, ava_1.default)(calculateAugmentationErrorMacro, "Plus (+) with nothing else (queries)", undefined, " + ", undefined, [languages_1.Language.javascript], /The workflow property "queries" is invalid/);
(0, ava_1.default)(calculateAugmentationErrorMacro, "Plus (+) with nothing else (packs)", " + ", undefined, [languages_1.Language.javascript], /The workflow property "packs" is invalid/); (0, ava_1.default)(calculateAugmentationErrorMacro, "Plus (+) with nothing else (packs)", " + ", undefined, undefined, [languages_1.Language.javascript], /The workflow property "packs" is invalid/);
(0, ava_1.default)(calculateAugmentationErrorMacro, "Packs input with multiple languages", " + a/b, c/d ", undefined, [languages_1.Language.javascript, languages_1.Language.java], /Cannot specify a 'packs' input in a multi-language analysis/); (0, ava_1.default)(calculateAugmentationErrorMacro, "Packs input with multiple languages", " + a/b, c/d ", undefined, undefined, [languages_1.Language.javascript, languages_1.Language.java], /Cannot specify a 'packs' input in a multi-language analysis/);
(0, ava_1.default)(calculateAugmentationErrorMacro, "Packs input with no languages", " + a/b, c/d ", undefined, [], /No languages specified/); (0, ava_1.default)(calculateAugmentationErrorMacro, "Packs input with no languages", " + a/b, c/d ", undefined, undefined, [], /No languages specified/);
(0, ava_1.default)(calculateAugmentationErrorMacro, "Invalid packs", " a-pack-without-a-scope ", undefined, [languages_1.Language.javascript], /"a-pack-without-a-scope" is not a valid pack/); (0, ava_1.default)(calculateAugmentationErrorMacro, "Invalid packs", " a-pack-without-a-scope ", undefined, undefined, [languages_1.Language.javascript], /"a-pack-without-a-scope" is not a valid pack/);
(0, ava_1.default)("no generateRegistries when registries is undefined", async (t) => { (0, ava_1.default)("no generateRegistries when registries is undefined", async (t) => {
return await (0, util_1.withTmpDir)(async (tmpDir) => { return await (0, util_1.withTmpDir)(async (tmpDir) => {
const registriesInput = undefined; const registriesInput = undefined;

File diff suppressed because one or more lines are too long

1
lib/init-action.js generated
View file

@ -192,6 +192,7 @@ async function run() {
config = await (0, init_1.initConfig)({ config = await (0, init_1.initConfig)({
languagesInput: (0, actions_util_1.getOptionalInput)("languages"), languagesInput: (0, actions_util_1.getOptionalInput)("languages"),
queriesInput: (0, actions_util_1.getOptionalInput)("queries"), queriesInput: (0, actions_util_1.getOptionalInput)("queries"),
qualityQueriesInput: (0, actions_util_1.getOptionalInput)("quality-queries"),
packsInput: (0, actions_util_1.getOptionalInput)("packs"), packsInput: (0, actions_util_1.getOptionalInput)("packs"),
buildModeInput: (0, actions_util_1.getOptionalInput)("build-mode"), buildModeInput: (0, actions_util_1.getOptionalInput)("build-mode"),
configFile, configFile,

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,45 @@
name: "Quality queries input"
description: "Tests that queries specified in the quality-queries input are used."
versions: ["linked", "nightly-latest"]
steps:
- uses: ./../action/init
with:
languages: javascript
quality-queries: code-quality
tools: ${{ steps.prepare-test.outputs.tools-url }}
- uses: ./../action/analyze
with:
output: "${{ runner.temp }}/results"
upload-database: false
- name: Upload SARIF
uses: actions/upload-artifact@v4
with:
name: config-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: "${{ runner.temp }}/results/javascript.sarif"
retention-days: 7
- name: Check config properties appear in SARIF
uses: actions/github-script@v7
env:
SARIF_PATH: "${{ runner.temp }}/results/javascript.sarif"
with:
script: |
const fs = require('fs');
const sarif = JSON.parse(fs.readFileSync(process.env['SARIF_PATH'], 'utf8'));
const run = sarif.runs[0];
const configSummary = run.properties.codeqlConfigSummary;
if (configSummary === undefined) {
core.setFailed('`codeqlConfigSummary` property not found in the SARIF run property bag.');
}
if (configSummary.disableDefaultQueries !== false) {
core.setFailed('`disableDefaultQueries` property incorrect: expected false, got ' +
`${JSON.stringify(configSummary.disableDefaultQueries)}.`);
}
const expectedQueries = [{ type: 'builtinSuite', uses: 'code-quality' }];
// Use JSON.stringify to deep-equal the arrays.
if (JSON.stringify(configSummary.queries) !== JSON.stringify(expectedQueries)) {
core.setFailed(`\`queries\` property incorrect: expected ${JSON.stringify(expectedQueries)}, got ` +
`${JSON.stringify(configSummary.queries)}.`);
}
core.info('Finished config export tests.');

View file

@ -1219,13 +1219,20 @@ async function generateCodeScanningConfig(
const augmentedConfig = cloneObject(config.originalUserInput); const augmentedConfig = cloneObject(config.originalUserInput);
// Inject the queries from the input // Inject the queries from the input
if (config.augmentationProperties.queriesInput) { if (
config.augmentationProperties.queriesInput ||
config.augmentationProperties.qualityQueriesInput
) {
const queryInputs = (
config.augmentationProperties.queriesInput || []
).concat(config.augmentationProperties.qualityQueriesInput || []);
if (config.augmentationProperties.queriesInputCombines) { if (config.augmentationProperties.queriesInputCombines) {
augmentedConfig.queries = (augmentedConfig.queries || []).concat( augmentedConfig.queries = (augmentedConfig.queries || []).concat(
config.augmentationProperties.queriesInput, queryInputs,
); );
} else { } else {
augmentedConfig.queries = config.augmentationProperties.queriesInput; augmentedConfig.queries = queryInputs;
} }
} }
if (augmentedConfig.queries?.length === 0) { if (augmentedConfig.queries?.length === 0) {

View file

@ -47,6 +47,7 @@ function createTestInitConfigInputs(
{ {
languagesInput: undefined, languagesInput: undefined,
queriesInput: undefined, queriesInput: undefined,
qualityQueriesInput: undefined,
packsInput: undefined, packsInput: undefined,
configFile: undefined, configFile: undefined,
dbLocation: undefined, dbLocation: undefined,
@ -806,6 +807,7 @@ const calculateAugmentationMacro = test.macro({
_title: string, _title: string,
rawPacksInput: string | undefined, rawPacksInput: string | undefined,
rawQueriesInput: string | undefined, rawQueriesInput: string | undefined,
rawQualityQueriesInput: string | undefined,
languages: Language[], languages: Language[],
expectedAugmentationProperties: configUtils.AugmentationProperties, expectedAugmentationProperties: configUtils.AugmentationProperties,
) => { ) => {
@ -815,6 +817,7 @@ const calculateAugmentationMacro = test.macro({
createFeatures([]), createFeatures([]),
rawPacksInput, rawPacksInput,
rawQueriesInput, rawQueriesInput,
rawQualityQueriesInput,
languages, languages,
mockLogger, mockLogger,
); );
@ -828,10 +831,12 @@ test(
"All empty", "All empty",
undefined, undefined,
undefined, undefined,
undefined,
[Language.javascript], [Language.javascript],
{ {
queriesInputCombines: false, queriesInputCombines: false,
queriesInput: undefined, queriesInput: undefined,
qualityQueriesInput: undefined,
packsInputCombines: false, packsInputCombines: false,
packsInput: undefined, packsInput: undefined,
defaultQueryFilters: [], defaultQueryFilters: [],
@ -843,10 +848,12 @@ test(
"With queries", "With queries",
undefined, undefined,
" a, b , c, d", " a, b , c, d",
undefined,
[Language.javascript], [Language.javascript],
{ {
queriesInputCombines: false, queriesInputCombines: false,
queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }], queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }],
qualityQueriesInput: undefined,
packsInputCombines: false, packsInputCombines: false,
packsInput: undefined, packsInput: undefined,
defaultQueryFilters: [], defaultQueryFilters: [],
@ -858,10 +865,56 @@ test(
"With queries combining", "With queries combining",
undefined, undefined,
" + a, b , c, d ", " + a, b , c, d ",
undefined,
[Language.javascript], [Language.javascript],
{ {
queriesInputCombines: true, queriesInputCombines: true,
queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }], queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }],
qualityQueriesInput: undefined,
packsInputCombines: false,
packsInput: undefined,
defaultQueryFilters: [],
} as configUtils.AugmentationProperties,
);
test(
calculateAugmentationMacro,
"With quality queries",
undefined,
undefined,
" a, b , c, d",
[Language.javascript],
{
queriesInputCombines: false,
queriesInput: undefined,
qualityQueriesInput: [
{ uses: "a" },
{ uses: "b" },
{ uses: "c" },
{ uses: "d" },
],
packsInputCombines: false,
packsInput: undefined,
defaultQueryFilters: [],
} as configUtils.AugmentationProperties,
);
test(
calculateAugmentationMacro,
"With security and quality queries",
undefined,
" a, b , c, d",
"e, f , g,h",
[Language.javascript],
{
queriesInputCombines: false,
queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }],
qualityQueriesInput: [
{ uses: "e" },
{ uses: "f" },
{ uses: "g" },
{ uses: "h" },
],
packsInputCombines: false, packsInputCombines: false,
packsInput: undefined, packsInput: undefined,
defaultQueryFilters: [], defaultQueryFilters: [],
@ -873,10 +926,12 @@ test(
"With packs", "With packs",
" codeql/a , codeql/b , codeql/c , codeql/d ", " codeql/a , codeql/b , codeql/c , codeql/d ",
undefined, undefined,
undefined,
[Language.javascript], [Language.javascript],
{ {
queriesInputCombines: false, queriesInputCombines: false,
queriesInput: undefined, queriesInput: undefined,
qualityQueriesInput: undefined,
packsInputCombines: false, packsInputCombines: false,
packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"], packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"],
defaultQueryFilters: [], defaultQueryFilters: [],
@ -888,10 +943,12 @@ test(
"With packs combining", "With packs combining",
" + codeql/a, codeql/b, codeql/c, codeql/d", " + codeql/a, codeql/b, codeql/c, codeql/d",
undefined, undefined,
undefined,
[Language.javascript], [Language.javascript],
{ {
queriesInputCombines: false, queriesInputCombines: false,
queriesInput: undefined, queriesInput: undefined,
qualityQueriesInput: undefined,
packsInputCombines: true, packsInputCombines: true,
packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"], packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"],
defaultQueryFilters: [], defaultQueryFilters: [],
@ -904,6 +961,7 @@ const calculateAugmentationErrorMacro = test.macro({
_title: string, _title: string,
rawPacksInput: string | undefined, rawPacksInput: string | undefined,
rawQueriesInput: string | undefined, rawQueriesInput: string | undefined,
rawQualityQueriesInput: string | undefined,
languages: Language[], languages: Language[],
expectedError: RegExp | string, expectedError: RegExp | string,
) => { ) => {
@ -914,6 +972,7 @@ const calculateAugmentationErrorMacro = test.macro({
createFeatures([]), createFeatures([]),
rawPacksInput, rawPacksInput,
rawQueriesInput, rawQueriesInput,
rawQualityQueriesInput,
languages, languages,
mockLogger, mockLogger,
), ),
@ -928,6 +987,7 @@ test(
"Plus (+) with nothing else (queries)", "Plus (+) with nothing else (queries)",
undefined, undefined,
" + ", " + ",
undefined,
[Language.javascript], [Language.javascript],
/The workflow property "queries" is invalid/, /The workflow property "queries" is invalid/,
); );
@ -937,6 +997,7 @@ test(
"Plus (+) with nothing else (packs)", "Plus (+) with nothing else (packs)",
" + ", " + ",
undefined, undefined,
undefined,
[Language.javascript], [Language.javascript],
/The workflow property "packs" is invalid/, /The workflow property "packs" is invalid/,
); );
@ -946,6 +1007,7 @@ test(
"Packs input with multiple languages", "Packs input with multiple languages",
" + a/b, c/d ", " + a/b, c/d ",
undefined, undefined,
undefined,
[Language.javascript, Language.java], [Language.javascript, Language.java],
/Cannot specify a 'packs' input in a multi-language analysis/, /Cannot specify a 'packs' input in a multi-language analysis/,
); );
@ -955,6 +1017,7 @@ test(
"Packs input with no languages", "Packs input with no languages",
" + a/b, c/d ", " + a/b, c/d ",
undefined, undefined,
undefined,
[], [],
/No languages specified/, /No languages specified/,
); );
@ -964,6 +1027,7 @@ test(
"Invalid packs", "Invalid packs",
" a-pack-without-a-scope ", " a-pack-without-a-scope ",
undefined, undefined,
undefined,
[Language.javascript], [Language.javascript],
/"a-pack-without-a-scope" is not a valid pack/, /"a-pack-without-a-scope" is not a valid pack/,
); );

View file

@ -170,6 +170,11 @@ export interface AugmentationProperties {
*/ */
queriesInput?: Array<{ uses: string }>; queriesInput?: Array<{ uses: string }>;
/**
* The quality queries input from the `with` block of the action declaration.
*/
qualityQueriesInput?: Array<{ uses: string }>;
/** /**
* Whether or not the packs input combines with the packs in the config. * Whether or not the packs input combines with the packs in the config.
*/ */
@ -195,6 +200,7 @@ export const defaultAugmentationProperties: AugmentationProperties = {
packsInputCombines: false, packsInputCombines: false,
packsInput: undefined, packsInput: undefined,
queriesInput: undefined, queriesInput: undefined,
qualityQueriesInput: undefined,
defaultQueryFilters: [], defaultQueryFilters: [],
}; };
export type Packs = Partial<Record<Language, string[]>>; export type Packs = Partial<Record<Language, string[]>>;
@ -405,6 +411,7 @@ export async function getRawLanguages(
export interface InitConfigInputs { export interface InitConfigInputs {
languagesInput: string | undefined; languagesInput: string | undefined;
queriesInput: string | undefined; queriesInput: string | undefined;
qualityQueriesInput: string | undefined;
packsInput: string | undefined; packsInput: string | undefined;
configFile: string | undefined; configFile: string | undefined;
dbLocation: string | undefined; dbLocation: string | undefined;
@ -440,6 +447,7 @@ type LoadConfigInputs = Omit<InitConfigInputs, "configInput"> & {
export async function getDefaultConfig({ export async function getDefaultConfig({
languagesInput, languagesInput,
queriesInput, queriesInput,
qualityQueriesInput,
packsInput, packsInput,
buildModeInput, buildModeInput,
dbLocation, dbLocation,
@ -474,6 +482,7 @@ export async function getDefaultConfig({
features, features,
packsInput, packsInput,
queriesInput, queriesInput,
qualityQueriesInput,
languages, languages,
logger, logger,
); );
@ -528,6 +537,7 @@ async function downloadCacheWithTime(
async function loadConfig({ async function loadConfig({
languagesInput, languagesInput,
queriesInput, queriesInput,
qualityQueriesInput,
packsInput, packsInput,
buildModeInput, buildModeInput,
configFile, configFile,
@ -583,6 +593,7 @@ async function loadConfig({
features, features,
packsInput, packsInput,
queriesInput, queriesInput,
qualityQueriesInput,
languages, languages,
logger, logger,
); );
@ -639,6 +650,7 @@ export async function calculateAugmentation(
features: FeatureEnablement, features: FeatureEnablement,
rawPacksInput: string | undefined, rawPacksInput: string | undefined,
rawQueriesInput: string | undefined, rawQueriesInput: string | undefined,
rawQualityQueriesInput: string | undefined,
languages: Language[], languages: Language[],
logger: Logger, logger: Logger,
): Promise<AugmentationProperties> { ): Promise<AugmentationProperties> {
@ -654,6 +666,11 @@ export async function calculateAugmentation(
queriesInputCombines, queriesInputCombines,
); );
const qualityQueriesInput = parseQueriesFromInput(
rawQualityQueriesInput,
false,
);
const defaultQueryFilters: QueryFilter[] = []; const defaultQueryFilters: QueryFilter[] = [];
if (await shouldPerformDiffInformedAnalysis(codeql, features, logger)) { if (await shouldPerformDiffInformedAnalysis(codeql, features, logger)) {
defaultQueryFilters.push({ exclude: { tags: "exclude-from-incremental" } }); defaultQueryFilters.push({ exclude: { tags: "exclude-from-incremental" } });
@ -664,6 +681,7 @@ export async function calculateAugmentation(
packsInput: packsInput?.[languages[0]], packsInput: packsInput?.[languages[0]],
queriesInput, queriesInput,
queriesInputCombines, queriesInputCombines,
qualityQueriesInput,
defaultQueryFilters, defaultQueryFilters,
}; };
} }

View file

@ -342,6 +342,7 @@ async function run() {
config = await initConfig({ config = await initConfig({
languagesInput: getOptionalInput("languages"), languagesInput: getOptionalInput("languages"),
queriesInput: getOptionalInput("queries"), queriesInput: getOptionalInput("queries"),
qualityQueriesInput: getOptionalInput("quality-queries"),
packsInput: getOptionalInput("packs"), packsInput: getOptionalInput("packs"),
buildModeInput: getOptionalInput("build-mode"), buildModeInput: getOptionalInput("build-mode"),
configFile, configFile,