Add support for basic query overriding in action file itself
See https://github.com/github/dsp-code-scanning/issues/1446
This commit is contained in:
parent
74268130c6
commit
95cef22589
6 changed files with 141 additions and 2 deletions
18
lib/config-utils.js
generated
18
lib/config-utils.js
generated
|
|
@ -460,6 +460,12 @@ async function initConfig() {
|
|||
else {
|
||||
config = await loadConfig(configFile);
|
||||
}
|
||||
// If queries were provided as using `with` in the action configuration,
|
||||
// they should take precedence over the queries in the config file
|
||||
const queryUses = core.getInput('queries');
|
||||
if (queryUses) {
|
||||
config = await updateConfigWithQueries(config, queryUses, configFile);
|
||||
}
|
||||
// Save the config so we can easily access it again in the future
|
||||
await saveConfig(config);
|
||||
return config;
|
||||
|
|
@ -472,6 +478,18 @@ function isLocal(configPath) {
|
|||
}
|
||||
return (configPath.indexOf("@") === -1);
|
||||
}
|
||||
async function updateConfigWithQueries(config, queryUses, configPath) {
|
||||
if (isLocal(configPath)) {
|
||||
// Treat the config file as relative to the workspace
|
||||
const workspacePath = util.getRequiredEnvParam('GITHUB_WORKSPACE');
|
||||
configPath = path.resolve(workspacePath, configPath);
|
||||
}
|
||||
const languages = await getLanguages();
|
||||
const queries = {};
|
||||
await parseQueryUses(configPath, languages, queries, queryUses);
|
||||
config.queries = queries;
|
||||
return config;
|
||||
}
|
||||
function getLocalConfig(configFile, workspacePath) {
|
||||
// Error if the config file is now outside of the workspace
|
||||
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
45
lib/config-utils.test.js
generated
45
lib/config-utils.test.js
generated
|
|
@ -224,6 +224,51 @@ ava_1.default("default queries are used", async (t) => {
|
|||
t.deepEqual(resolveQueriesArgs[0].extraSearchPath, undefined);
|
||||
});
|
||||
});
|
||||
ava_1.default("Queries can be overridden in action file", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
process.env['RUNNER_TEMP'] = tmpDir;
|
||||
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||
const inputFileContents = `
|
||||
name: my config
|
||||
queries:
|
||||
- uses: ./foo`;
|
||||
fs.mkdirSync(path.join(tmpDir, 'foo'));
|
||||
fs.mkdirSync(path.join(tmpDir, 'override'));
|
||||
// This config item should take precedence.
|
||||
setInput('queries', './override');
|
||||
const resolveQueriesArgs = [];
|
||||
CodeQL.setCodeQL({
|
||||
resolveQueries: async function (queries, extraSearchPath) {
|
||||
resolveQueriesArgs.push({ queries, extraSearchPath });
|
||||
// Return what we're given, just in the right format for a resolved query
|
||||
// This way we can test overriding by seeing which returned items are in
|
||||
// the final configuration.
|
||||
const dummyResolvedQueries = {};
|
||||
queries.forEach(q => { dummyResolvedQueries[q] = {}; });
|
||||
return {
|
||||
byLanguage: {
|
||||
'javascript': dummyResolvedQueries,
|
||||
},
|
||||
noDeclaredLanguage: {},
|
||||
multipleDeclaredLanguages: {},
|
||||
};
|
||||
},
|
||||
});
|
||||
fs.writeFileSync(path.join(tmpDir, 'input'), inputFileContents, 'utf8');
|
||||
setInput('config-file', 'input');
|
||||
setInput('languages', 'javascript');
|
||||
const config = await configUtils.initConfig();
|
||||
// Check resolveQueries was called correctly
|
||||
// It'll be called once for the default queries, once for './foo' (from the config file),
|
||||
// and then finally for './override'
|
||||
t.deepEqual(resolveQueriesArgs.length, 3);
|
||||
t.deepEqual(resolveQueriesArgs[2].queries.length, 1);
|
||||
t.regex(resolveQueriesArgs[2].queries[0], /.*\/override$/);
|
||||
// Now check that the end result contains only the override query, not the others
|
||||
t.deepEqual(config.queries['javascript'].length, 1);
|
||||
t.regex(config.queries['javascript'][0], /.*\/override$/);
|
||||
});
|
||||
});
|
||||
ava_1.default("API client used when reading remote config", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
process.env['RUNNER_TEMP'] = tmpDir;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -254,6 +254,60 @@ test("default queries are used", async t => {
|
|||
});
|
||||
});
|
||||
|
||||
test("Queries can be overridden in action file", async t => {
|
||||
return await util.withTmpDir(async tmpDir => {
|
||||
process.env['RUNNER_TEMP'] = tmpDir;
|
||||
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||
|
||||
const inputFileContents = `
|
||||
name: my config
|
||||
queries:
|
||||
- uses: ./foo`;
|
||||
|
||||
// This config item should take precedence.
|
||||
setInput('queries', './override');
|
||||
|
||||
fs.mkdirSync(path.join(tmpDir, 'foo'));
|
||||
fs.mkdirSync(path.join(tmpDir, 'override'));
|
||||
|
||||
const resolveQueriesArgs: {queries: string[], extraSearchPath: string | undefined}[] = [];
|
||||
CodeQL.setCodeQL({
|
||||
resolveQueries: async function(queries: string[], extraSearchPath: string | undefined) {
|
||||
resolveQueriesArgs.push({queries, extraSearchPath});
|
||||
// Return what we're given, just in the right format for a resolved query
|
||||
// This way we can test overriding by seeing which returned items are in
|
||||
// the final configuration.
|
||||
const dummyResolvedQueries = {};
|
||||
queries.forEach(q => { dummyResolvedQueries[q] = {}; });
|
||||
return {
|
||||
byLanguage: {
|
||||
'javascript': dummyResolvedQueries,
|
||||
},
|
||||
noDeclaredLanguage: {},
|
||||
multipleDeclaredLanguages: {},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
fs.writeFileSync(path.join(tmpDir, 'input'), inputFileContents, 'utf8');
|
||||
setInput('config-file', 'input');
|
||||
setInput('languages', 'javascript');
|
||||
|
||||
const config = await configUtils.initConfig();
|
||||
|
||||
// Check resolveQueries was called correctly
|
||||
// It'll be called once for the default queries, once for './foo' (from the config file),
|
||||
// and then finally for './override'
|
||||
t.deepEqual(resolveQueriesArgs.length, 3);
|
||||
t.deepEqual(resolveQueriesArgs[2].queries.length, 1);
|
||||
t.regex(resolveQueriesArgs[2].queries[0], /.*\/override$/);
|
||||
|
||||
// Now check that the end result contains only the override query, not the others
|
||||
t.deepEqual(config.queries['javascript'].length, 1);
|
||||
t.regex(config.queries['javascript'][0], /.*\/override$/);
|
||||
});
|
||||
});
|
||||
|
||||
test("API client used when reading remote config", async t => {
|
||||
return await util.withTmpDir(async tmpDir => {
|
||||
process.env['RUNNER_TEMP'] = tmpDir;
|
||||
|
|
|
|||
|
|
@ -599,6 +599,13 @@ export async function initConfig(): Promise<Config> {
|
|||
config = await loadConfig(configFile);
|
||||
}
|
||||
|
||||
// If queries were provided as using `with` in the action configuration,
|
||||
// they should take precedence over the queries in the config file
|
||||
const queryUses = core.getInput('queries');
|
||||
if (queryUses) {
|
||||
config = await updateConfigWithQueries(config, queryUses, configFile);
|
||||
}
|
||||
|
||||
// Save the config so we can easily access it again in the future
|
||||
await saveConfig(config);
|
||||
return config;
|
||||
|
|
@ -613,6 +620,21 @@ function isLocal(configPath: string): boolean {
|
|||
return (configPath.indexOf("@") === -1);
|
||||
}
|
||||
|
||||
async function updateConfigWithQueries(config: Config, queryUses: string, configPath: string): Promise<Config> {
|
||||
if (isLocal(configPath)) {
|
||||
// Treat the config file as relative to the workspace
|
||||
const workspacePath = util.getRequiredEnvParam('GITHUB_WORKSPACE');
|
||||
configPath = path.resolve(workspacePath, configPath);
|
||||
}
|
||||
|
||||
const languages = await getLanguages();
|
||||
const queries = {};
|
||||
await parseQueryUses(configPath, languages, queries, queryUses);
|
||||
config.queries = queries;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function getLocalConfig(configFile: string, workspacePath: string): UserConfig {
|
||||
// Error if the config file is now outside of the workspace
|
||||
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue