- Add new configuration Parameter

- Write test to check it is read from configuration
- Update documentation
This commit is contained in:
Tugdual Grall 2023-03-18 06:37:28 +00:00
Родитель fb75ebd750
Коммит ee44252240
16 изменённых файлов: 1644 добавлений и 31 удалений

Просмотреть файл

@ -135,6 +135,62 @@ By default, this will override any queries specified in a config file. If you wi
queries: +<local-or-remote-query>,<another-query>
```
### Configuration
Use the `configuration` parameter of the `init` action to enable a workflow based configuration. The value of `configuration` should be compliant with the configuration file format documented at [Using a custom configuration file](https://help.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#using-a-custom-configuration-file)."
- **Complete Configuration**
```yaml
- uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
configuration: |
disable-default-queries: true
queries:
- uses: security-extended
- uses: security-and-quality
query-filters:
- include:
tags: /cwe-020/
```
- **Actions Variables**
You can use actions or environment variables to use dynamic configuration.
```yaml
- uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
configuration: |
${{vars.CODEQL_CONF}}
```
where `vars.CODEQL_CONF` references a [Action Variables](https://docs.github.com/en/actions/learn-github-actions/variables#defining-configuration-variables-for-multiple-workflows) with the following content, that will only execute the queries related to the [CWE-020](https://cwe.mitre.org/data/definitions/20.html).
- **Input Parameters**
Use workflow input parameter:
```yaml
- uses: tgrall/codeql-action/init@query-filter
with:
languages: ${{ matrix.language }}
configuration: |
disable-default-queries: true
queries:
- uses: security-extended
- uses: security-and-quality
query-filters:
- include:
tags: /${{ github.event.inputs.codeql-include-tags }}/
``
## Troubleshooting
Read about [troubleshooting code scanning](https://help.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/troubleshooting-code-scanning).

Просмотреть файл

@ -44,6 +44,9 @@ inputs:
db-location:
description: Path where CodeQL databases should be created. If not specified, a temporary directory will be used.
required: false
configuration:
description: Configuration passed as YAML object using the same format as the config-file. This takes precedence over the config-file parameter.
required: false
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

9
lib/config-utils.js сгенерированный
Просмотреть файл

@ -932,8 +932,15 @@ function dbLocationOrDefault(dbLocation, tempDir) {
* This will parse the config from the user input if present, or generate
* a default config. The parsed config is then stored to a known location.
*/
async function initConfig(languagesInput, queriesInput, packsInput, registriesInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, features, logger) {
async function initConfig(languagesInput, queriesInput, packsInput, registriesInput, configFile, dbLocation, configuration, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, features, logger) {
let config;
// if configuration is set, it takes precedence over configFile
if (configuration) {
const configFileToCreate = path.resolve(workspacePath, "user-config-from-action.yml");
fs.writeFileSync(configFileToCreate, configuration);
configFile = configFileToCreate;
logger.debug(`Using configuration from action input: ${configFile}`);
}
// If no config file was provided create an empty one
if (!configFile) {
logger.debug("No configuration file was provided");

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

86
lib/config-utils.test.js сгенерированный
Просмотреть файл

@ -102,7 +102,7 @@ function mockListLanguages(languages) {
return { packs: [] };
},
});
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), logger);
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), logger);
t.deepEqual(config, await configUtils.getDefaultConfig(languages, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), logger));
});
});
@ -128,7 +128,7 @@ function mockListLanguages(languages) {
t.false(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
// Sanity check that getConfig returns undefined before we have called initConfig
t.deepEqual(await configUtils.getConfig(tmpDir, logger), undefined);
const config1 = await configUtils.initConfig("javascript,python", undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), logger);
const config1 = await configUtils.initConfig("javascript,python", undefined, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), logger);
// The saved config file should now exist
t.true(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
// And that same newly-initialised config should now be returned by getConfig
@ -144,7 +144,7 @@ function mockListLanguages(languages) {
(0, ava_1.default)("load input outside of workspace", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
try {
await configUtils.initConfig(undefined, undefined, undefined, undefined, "../input", undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(undefined, undefined, undefined, undefined, "../input", undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@ -157,7 +157,7 @@ function mockListLanguages(languages) {
// no filename given, just a repo
const configFile = "octo-org/codeql-config@main";
try {
await configUtils.initConfig(undefined, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(undefined, undefined, undefined, undefined, configFile, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@ -171,7 +171,7 @@ function mockListLanguages(languages) {
const configFile = "input";
t.false(fs.existsSync(path.join(tmpDir, configFile)));
try {
await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@ -247,7 +247,7 @@ function mockListLanguages(languages) {
};
const languages = "javascript";
const configFilePath = createConfigFile(inputFileContents, tmpDir);
const actualConfig = await configUtils.initConfig(languages, undefined, undefined, undefined, configFilePath, undefined, false, false, "my-artifact", "my-db", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
const actualConfig = await configUtils.initConfig(languages, undefined, undefined, undefined, configFilePath, undefined, undefined, false, false, "my-artifact", "my-db", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
// Should exactly equal the object we constructed earlier
t.deepEqual(actualConfig, expectedConfig);
});
@ -286,7 +286,7 @@ function mockListLanguages(languages) {
fs.mkdirSync(path.join(tmpDir, "foo"));
const languages = "javascript";
const configFilePath = createConfigFile(inputFileContents, tmpDir);
await configUtils.initConfig(languages, undefined, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(languages, undefined, undefined, undefined, configFilePath, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
// Check resolve queries was called correctly
t.deepEqual(resolveQueriesArgs.length, 1);
t.deepEqual(resolveQueriesArgs[0].queries, [
@ -332,7 +332,7 @@ function queriesToResolvedQueryForm(queries) {
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, configFilePath, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
// Check resolveQueries was called correctly
// It'll be called once for the default queries
// and once for `./foo` from the config file.
@ -368,7 +368,7 @@ function queriesToResolvedQueryForm(queries) {
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, configFilePath, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
// Check resolveQueries was called correctly
// It'll be called once for the default queries and once for `./override`,
// but won't be called for './foo' from the config file.
@ -403,7 +403,7 @@ function queriesToResolvedQueryForm(queries) {
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, configFilePath, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
// Check resolveQueries was called correctly
// It'll be called once for `./workflow-query`,
// but won't be called for the default one since that was disabled
@ -432,7 +432,7 @@ function queriesToResolvedQueryForm(queries) {
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
// Check resolveQueries was called correctly:
// It'll be called once for the default queries,
// and then once for each of the two queries from the workflow
@ -474,7 +474,7 @@ function queriesToResolvedQueryForm(queries) {
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, configFilePath, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, configFilePath, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
// Check resolveQueries was called correctly
// It'll be called once for the default queries,
// once for each of additional1 and additional2,
@ -495,6 +495,48 @@ function queriesToResolvedQueryForm(queries) {
t.true(config.queries["javascript"].custom[2].queries[0].endsWith(`${path.sep}foo`));
});
});
(0, ava_1.default)("Queries can be specified in configuration, same as file", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const inputFileContents = `
name: my config
queries:
- uses: ./foo
packs:
javascript:
- a/b@1.2.3
python:
- c/d@1.2.3
`;
fs.mkdirSync(path.join(tmpDir, "foo"));
const resolveQueriesArgs = [];
const codeQL = (0, codeql_1.setCodeQL)({
async resolveQueries(queries, extraSearchPath) {
resolveQueriesArgs.push({ queries, extraSearchPath });
return queriesToResolvedQueryForm(queries);
},
async packDownload() {
return { packs: [] };
},
});
// Only JS, python packs will be ignored
const languages = "javascript";
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, undefined, inputFileContents, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
// Check resolveQueries was called correctly
// It'll be called once for the default queries
// and once for `./foo` from the config file.
t.deepEqual(resolveQueriesArgs.length, 2);
t.deepEqual(resolveQueriesArgs[1].queries.length, 1);
t.true(resolveQueriesArgs[1].queries[0].endsWith(`${path.sep}foo`));
t.deepEqual(config.packs, {
[languages_1.Language.javascript]: ["a/b@1.2.3"],
});
// Now check that the end result contains the default queries and the query from config
t.deepEqual(config.queries["javascript"].builtin.length, 1);
t.deepEqual(config.queries["javascript"].custom.length, 1);
t.true(config.queries["javascript"].builtin[0].endsWith("javascript-code-scanning.qls"));
t.true(config.queries["javascript"].custom[0].queries[0].endsWith(`${path.sep}foo`));
});
});
(0, ava_1.default)("Invalid queries in workflow file handled correctly", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const queries = "foo/bar@v1@v3";
@ -516,7 +558,7 @@ function queriesToResolvedQueryForm(queries) {
},
});
try {
await configUtils.initConfig(languages, queries, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(languages, queries, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
t.fail("initConfig did not throw error");
}
catch (err) {
@ -562,7 +604,7 @@ function queriesToResolvedQueryForm(queries) {
fs.mkdirSync(path.join(tmpDir, "foo/bar/dev"), { recursive: true });
const configFile = "octo-org/codeql-config/config.yaml@main";
const languages = "javascript";
await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
t.assert(spyGetContents.called);
});
});
@ -572,7 +614,7 @@ function queriesToResolvedQueryForm(queries) {
mockGetContents(dummyResponse);
const repoReference = "octo-org/codeql-config/config.yaml@main";
try {
await configUtils.initConfig(undefined, undefined, undefined, undefined, repoReference, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(undefined, undefined, undefined, undefined, repoReference, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@ -588,7 +630,7 @@ function queriesToResolvedQueryForm(queries) {
mockGetContents(dummyResponse);
const repoReference = "octo-org/codeql-config/config.yaml@main";
try {
await configUtils.initConfig(undefined, undefined, undefined, undefined, repoReference, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(undefined, undefined, undefined, undefined, repoReference, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@ -608,7 +650,7 @@ function queriesToResolvedQueryForm(queries) {
},
});
try {
await configUtils.initConfig(undefined, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(undefined, undefined, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@ -620,7 +662,7 @@ function queriesToResolvedQueryForm(queries) {
return await util.withTmpDir(async (tmpDir) => {
const languages = "rubbish,english";
try {
await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, (0, codeql_1.getCachedCodeQL)(), tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@ -651,7 +693,7 @@ function queriesToResolvedQueryForm(queries) {
const configFile = path.join(tmpDir, "codeql-config.yaml");
fs.writeFileSync(configFile, inputFileContents);
const languages = "javascript";
const { packs } = await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
const { packs } = await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
t.deepEqual(packs, {
[languages_1.Language.javascript]: ["a/b@1.2.3"],
});
@ -688,7 +730,7 @@ function queriesToResolvedQueryForm(queries) {
fs.writeFileSync(configFile, inputFileContents);
fs.mkdirSync(path.join(tmpDir, "foo"));
const languages = "javascript,python,cpp";
const { packs, queries } = await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example" }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
const { packs, queries } = await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, undefined, false, false, "", "", { owner: "github", repo: "example" }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
t.deepEqual(packs, {
[languages_1.Language.javascript]: ["a/b@1.2.3"],
[languages_1.Language.python]: ["c/d@1.2.3"],
@ -734,7 +776,7 @@ function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGen
const inputFile = path.join(tmpDir, configFile);
fs.writeFileSync(inputFile, inputFileContents, "utf8");
try {
await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
await configUtils.initConfig(languages, undefined, undefined, undefined, configFile, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@ -991,7 +1033,7 @@ const mlPoweredQueriesMacro = ava_1.default.macro({
return { packs: [] };
},
});
const { packs } = await configUtils.initConfig("javascript", queriesInput, packsInput, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)(isMlPoweredQueriesEnabled ? [feature_flags_1.Feature.MlPoweredQueriesEnabled] : []), (0, logging_1.getRunnerLogger)(true));
const { packs } = await configUtils.initConfig("javascript", queriesInput, packsInput, undefined, undefined, undefined, undefined, false, false, "", "", { owner: "github", repo: "example " }, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, (0, testing_utils_1.createFeatures)(isMlPoweredQueriesEnabled ? [feature_flags_1.Feature.MlPoweredQueriesEnabled] : []), (0, logging_1.getRunnerLogger)(true));
if (expectedVersionString !== undefined) {
t.deepEqual(packs, {
[languages_1.Language.javascript]: [

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

2
lib/init-action.js сгенерированный
Просмотреть файл

@ -130,7 +130,7 @@ async function run() {
toolsVersion = initCodeQLResult.toolsVersion;
toolsSource = initCodeQLResult.toolsSource;
await (0, util_1.enrichEnvironment)(codeql);
config = await (0, init_1.initConfig)((0, actions_util_1.getOptionalInput)("languages"), (0, actions_util_1.getOptionalInput)("queries"), (0, actions_util_1.getOptionalInput)("packs"), registriesInput, (0, actions_util_1.getOptionalInput)("config-file"), (0, actions_util_1.getOptionalInput)("db-location"), getTrapCachingEnabled(),
config = await (0, init_1.initConfig)((0, actions_util_1.getOptionalInput)("languages"), (0, actions_util_1.getOptionalInput)("queries"), (0, actions_util_1.getOptionalInput)("packs"), registriesInput, (0, actions_util_1.getOptionalInput)("config-file"), (0, actions_util_1.getOptionalInput)("db-location"), (0, actions_util_1.getOptionalInput)("configuration"), getTrapCachingEnabled(),
// Debug mode is enabled if:
// - The `init` Action is passed `debug: true`.
// - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow),

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

4
lib/init.js сгенерированный
Просмотреть файл

@ -49,9 +49,9 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe
return { codeql, toolsDownloadDurationMs, toolsSource, toolsVersion };
}
exports.initCodeQL = initCodeQL;
async function initConfig(languagesInput, queriesInput, packsInput, registriesInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, features, logger) {
async function initConfig(languagesInput, queriesInput, packsInput, registriesInput, configFile, dbLocation, queryFilters, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, features, logger) {
logger.startGroup("Load language configuration");
const config = await configUtils.initConfig(languagesInput, queriesInput, packsInput, registriesInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, features, logger);
const config = await configUtils.initConfig(languagesInput, queriesInput, packsInput, registriesInput, configFile, dbLocation, queryFilters, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeQL, workspacePath, gitHubVersion, apiDetails, features, logger);
analysisPaths.printPathFiltersWarning(config, logger);
logger.endGroup();
return config;

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

1382
lib/tug-test.test.js сгенерированный Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

1
lib/tug-test.test.js.map Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -105,6 +105,7 @@ test("load empty config", async (t) => {
undefined,
undefined,
undefined,
undefined,
false,
false,
"",
@ -176,6 +177,7 @@ test("loading config saves config", async (t) => {
undefined,
undefined,
undefined,
undefined,
false,
false,
"",
@ -214,6 +216,7 @@ test("load input outside of workspace", async (t) => {
undefined,
"../input",
undefined,
undefined,
false,
false,
"",
@ -254,6 +257,7 @@ test("load non-local input with invalid repo syntax", async (t) => {
undefined,
configFile,
undefined,
undefined,
false,
false,
"",
@ -295,6 +299,7 @@ test("load non-existent input", async (t) => {
undefined,
configFile,
undefined,
undefined,
false,
false,
"",
@ -402,6 +407,7 @@ test("load non-empty input", async (t) => {
undefined,
configFilePath,
undefined,
undefined,
false,
false,
"my-artifact",
@ -473,6 +479,7 @@ test("Default queries are used", async (t) => {
undefined,
configFilePath,
undefined,
undefined,
false,
false,
"",
@ -552,6 +559,7 @@ test("Queries can be specified in config file", async (t) => {
undefined,
configFilePath,
undefined,
undefined,
false,
false,
"",
@ -630,6 +638,7 @@ test("Queries from config file can be overridden in workflow file", async (t) =>
undefined,
configFilePath,
undefined,
undefined,
false,
false,
"",
@ -706,6 +715,7 @@ test("Queries in workflow file can be used in tandem with the 'disable default q
undefined,
configFilePath,
undefined,
undefined,
false,
false,
"",
@ -773,6 +783,7 @@ test("Multiple queries can be specified in workflow file, no config file require
undefined,
undefined,
undefined,
undefined,
false,
false,
"",
@ -861,6 +872,7 @@ test("Queries in workflow file can be added to the set of queries without overri
undefined,
configFilePath,
undefined,
undefined,
false,
false,
"",
@ -913,6 +925,91 @@ test("Queries in workflow file can be added to the set of queries without overri
});
});
test("Queries can be specified in configuration, same as file", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const inputFileContents = `
name: my config
queries:
- uses: ./foo
packs:
javascript:
- a/b@1.2.3
python:
- c/d@1.2.3
`;
fs.mkdirSync(path.join(tmpDir, "foo"));
const resolveQueriesArgs: Array<{
queries: string[];
extraSearchPath: string | undefined;
}> = [];
const codeQL = setCodeQL({
async resolveQueries(
queries: string[],
extraSearchPath: string | undefined
) {
resolveQueriesArgs.push({ queries, extraSearchPath });
return queriesToResolvedQueryForm(queries);
},
async packDownload(): Promise<PackDownloadOutput> {
return { packs: [] };
},
});
// Only JS, python packs will be ignored
const languages = "javascript";
const config = await configUtils.initConfig(
languages,
undefined,
undefined,
undefined,
undefined,
undefined,
inputFileContents,
false,
false,
"",
"",
{ owner: "github", repo: "example " },
tmpDir,
codeQL,
tmpDir,
gitHubVersion,
sampleApiDetails,
createFeatures([]),
getRunnerLogger(true)
);
// Check resolveQueries was called correctly
// It'll be called once for the default queries
// and once for `./foo` from the config file.
t.deepEqual(resolveQueriesArgs.length, 2);
t.deepEqual(resolveQueriesArgs[1].queries.length, 1);
t.true(resolveQueriesArgs[1].queries[0].endsWith(`${path.sep}foo`));
t.deepEqual(config.packs as unknown, {
[Language.javascript]: ["a/b@1.2.3"],
});
// Now check that the end result contains the default queries and the query from config
t.deepEqual(config.queries["javascript"].builtin.length, 1);
t.deepEqual(config.queries["javascript"].custom.length, 1);
t.true(
config.queries["javascript"].builtin[0].endsWith(
"javascript-code-scanning.qls"
)
);
t.true(
config.queries["javascript"].custom[0].queries[0].endsWith(
`${path.sep}foo`
)
);
});
});
test("Invalid queries in workflow file handled correctly", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const queries = "foo/bar@v1@v3";
@ -943,6 +1040,7 @@ test("Invalid queries in workflow file handled correctly", async (t) => {
undefined,
undefined,
undefined,
undefined,
false,
false,
"",
@ -1015,6 +1113,7 @@ test("API client used when reading remote config", async (t) => {
undefined,
configFile,
undefined,
undefined,
false,
false,
"",
@ -1046,6 +1145,7 @@ test("Remote config handles the case where a directory is provided", async (t) =
undefined,
repoReference,
undefined,
undefined,
false,
false,
"",
@ -1085,6 +1185,7 @@ test("Invalid format of remote config handled correctly", async (t) => {
undefined,
repoReference,
undefined,
undefined,
false,
false,
"",
@ -1128,6 +1229,7 @@ test("No detected languages", async (t) => {
undefined,
undefined,
undefined,
undefined,
false,
false,
"",
@ -1160,6 +1262,7 @@ test("Unknown languages", async (t) => {
undefined,
undefined,
undefined,
undefined,
false,
false,
"",
@ -1217,6 +1320,7 @@ test("Config specifies packages", async (t) => {
undefined,
configFile,
undefined,
undefined,
false,
false,
"",
@ -1278,6 +1382,7 @@ test("Config specifies packages for multiple languages", async (t) => {
undefined,
configFile,
undefined,
undefined,
false,
false,
"",
@ -1350,6 +1455,7 @@ function doInvalidInputTest(
undefined,
configFile,
undefined,
undefined,
false,
false,
"",
@ -1934,6 +2040,7 @@ const mlPoweredQueriesMacro = test.macro({
undefined,
undefined,
undefined,
undefined,
false,
false,
"",
@ -2650,3 +2757,5 @@ const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
t.deepEqual(mockRequest.called, args.expectedApiCall);
});
});

Просмотреть файл

@ -1690,6 +1690,7 @@ export async function initConfig(
registriesInput: string | undefined,
configFile: string | undefined,
dbLocation: string | undefined,
configuration: string | undefined,
trapCachingEnabled: boolean,
debugMode: boolean,
debugArtifactName: string,
@ -1705,6 +1706,15 @@ export async function initConfig(
): Promise<Config> {
let config: Config;
// if configuration is set, it takes precedence over configFile
if (configuration) {
const configFileToCreate = path.resolve(workspacePath, "user-config-from-action.yml");
fs.writeFileSync(configFileToCreate, configuration);
configFile = configFileToCreate;
logger.debug(`Using configuration from action input: ${configFile}`);
}
// If no config file was provided create an empty one
if (!configFile) {
logger.debug("No configuration file was provided");
@ -1748,6 +1758,7 @@ 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.

Просмотреть файл

@ -256,6 +256,7 @@ async function run() {
registriesInput,
getOptionalInput("config-file"),
getOptionalInput("db-location"),
getOptionalInput("configuration"),
getTrapCachingEnabled(),
// Debug mode is enabled if:
// - The `init` Action is passed `debug: true`.

Просмотреть файл

@ -58,6 +58,7 @@ export async function initConfig(
registriesInput: string | undefined,
configFile: string | undefined,
dbLocation: string | undefined,
queryFilters: string | undefined,
trapCachingEnabled: boolean,
debugMode: boolean,
debugArtifactName: string,
@ -79,6 +80,7 @@ export async function initConfig(
registriesInput,
configFile,
dbLocation,
queryFilters,
trapCachingEnabled,
debugMode,
debugArtifactName,
@ -108,7 +110,6 @@ export async function runInit(
logger: Logger
): Promise<TracerConfig | undefined> {
fs.mkdirSync(config.dbLocation, { recursive: true });
try {
if (await codeQlVersionAbove(codeql, CODEQL_VERSION_NEW_TRACING)) {
// When parsing the codeql config in the CLI, we have not yet created the qlconfig file.