mirror of
https://github.com/github/codeql-action.git
synced 2026-01-05 14:10:11 +08:00
Refactoring: Create interface for config initialization
This eliminates argument order mistakes, and also lets us add new inputs without having to update every test.
This commit is contained in:
@@ -7,7 +7,12 @@ import * as yaml from "js-yaml";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as api from "./api-client";
|
||||
import { getCachedCodeQL, PackDownloadOutput, setCodeQL } from "./codeql";
|
||||
import {
|
||||
CodeQL,
|
||||
getCachedCodeQL,
|
||||
PackDownloadOutput,
|
||||
setCodeQL,
|
||||
} from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { Language } from "./languages";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
@@ -26,15 +31,41 @@ import {
|
||||
|
||||
setupTests(test);
|
||||
|
||||
const sampleApiDetails = {
|
||||
auth: "token",
|
||||
externalRepoAuth: "token",
|
||||
url: "https://github.example.com",
|
||||
apiURL: undefined,
|
||||
registriesAuthTokens: undefined,
|
||||
};
|
||||
const githubVersion = { type: GitHubVariant.DOTCOM } as GitHubVersion;
|
||||
|
||||
const gitHubVersion = { type: GitHubVariant.DOTCOM } as GitHubVersion;
|
||||
function createTestInitConfigInputs(
|
||||
overrides: Partial<configUtils.InitConfigInputs>,
|
||||
): configUtils.InitConfigInputs {
|
||||
return Object.assign(
|
||||
{},
|
||||
{
|
||||
languagesInput: undefined,
|
||||
queriesInput: undefined,
|
||||
packsInput: undefined,
|
||||
configFile: undefined,
|
||||
dbLocation: undefined,
|
||||
configInput: undefined,
|
||||
trapCachingEnabled: false,
|
||||
debugMode: false,
|
||||
debugArtifactName: "",
|
||||
debugDatabaseName: "",
|
||||
repository: { owner: "github", repo: "example" },
|
||||
tempDir: "",
|
||||
codeql: {} as CodeQL,
|
||||
workspacePath: "",
|
||||
githubVersion,
|
||||
apiDetails: {
|
||||
auth: "token",
|
||||
externalRepoAuth: "token",
|
||||
url: "https://github.example.com",
|
||||
apiURL: undefined,
|
||||
registriesAuthTokens: undefined,
|
||||
},
|
||||
logger: getRunnerLogger(true),
|
||||
},
|
||||
overrides,
|
||||
);
|
||||
}
|
||||
|
||||
// Returns the filepath of the newly-created file
|
||||
function createConfigFile(inputFileContents: string, tmpDir: string): string {
|
||||
@@ -77,11 +108,11 @@ function mockListLanguages(languages: string[]) {
|
||||
}
|
||||
|
||||
test("load empty config", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
const logger = getRunnerLogger(true);
|
||||
const languages = "javascript,python";
|
||||
|
||||
const codeQL = setCodeQL({
|
||||
const codeql = setCodeQL({
|
||||
async resolveQueries() {
|
||||
return {
|
||||
byLanguage: {
|
||||
@@ -98,51 +129,34 @@ test("load empty config", async (t) => {
|
||||
});
|
||||
|
||||
const config = await configUtils.initConfig(
|
||||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
logger,
|
||||
createTestInitConfigInputs({
|
||||
languagesInput: languages,
|
||||
repository: { owner: "github", repo: "example" },
|
||||
tempDir,
|
||||
codeql,
|
||||
logger,
|
||||
}),
|
||||
);
|
||||
|
||||
t.deepEqual(
|
||||
config,
|
||||
await configUtils.getDefaultConfig(
|
||||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
codeQL,
|
||||
gitHubVersion,
|
||||
logger,
|
||||
createTestInitConfigInputs({
|
||||
languagesInput: languages,
|
||||
tempDir,
|
||||
codeql,
|
||||
logger,
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test("loading config saves config", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
const logger = getRunnerLogger(true);
|
||||
|
||||
const codeQL = setCodeQL({
|
||||
const codeql = setCodeQL({
|
||||
async resolveQueries() {
|
||||
return {
|
||||
byLanguage: {
|
||||
@@ -159,36 +173,26 @@ test("loading config saves config", async (t) => {
|
||||
});
|
||||
|
||||
// Sanity check the saved config file does not already exist
|
||||
t.false(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
|
||||
t.false(fs.existsSync(configUtils.getPathToParsedConfigFile(tempDir)));
|
||||
|
||||
// Sanity check that getConfig returns undefined before we have called initConfig
|
||||
t.deepEqual(await configUtils.getConfig(tmpDir, logger), undefined);
|
||||
t.deepEqual(await configUtils.getConfig(tempDir, 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,
|
||||
logger,
|
||||
createTestInitConfigInputs({
|
||||
languagesInput: "javascript,python",
|
||||
tempDir,
|
||||
codeql,
|
||||
workspacePath: tempDir,
|
||||
logger,
|
||||
}),
|
||||
);
|
||||
|
||||
// The saved config file should now exist
|
||||
t.true(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
|
||||
t.true(fs.existsSync(configUtils.getPathToParsedConfigFile(tempDir)));
|
||||
|
||||
// And that same newly-initialised config should now be returned by getConfig
|
||||
const config2 = await configUtils.getConfig(tmpDir, logger);
|
||||
const config2 = await configUtils.getConfig(tempDir, logger);
|
||||
t.not(config2, undefined);
|
||||
if (config2 !== undefined) {
|
||||
// removes properties assigned to undefined.
|
||||
@@ -199,26 +203,15 @@ test("loading config saves config", async (t) => {
|
||||
});
|
||||
|
||||
test("load input outside of workspace", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
"../input",
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true),
|
||||
createTestInitConfigInputs({
|
||||
configFile: "../input",
|
||||
tempDir,
|
||||
codeql: getCachedCodeQL(),
|
||||
workspacePath: tempDir,
|
||||
}),
|
||||
);
|
||||
throw new Error("initConfig did not throw error");
|
||||
} catch (err) {
|
||||
@@ -226,7 +219,7 @@ test("load input outside of workspace", async (t) => {
|
||||
err,
|
||||
new UserError(
|
||||
configUtils.getConfigFileOutsideWorkspaceErrorMessage(
|
||||
path.join(tmpDir, "../input"),
|
||||
path.join(tempDir, "../input"),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -235,29 +228,18 @@ test("load input outside of workspace", async (t) => {
|
||||
});
|
||||
|
||||
test("load non-local input with invalid repo syntax", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
// no filename given, just a repo
|
||||
const configFile = "octo-org/codeql-config@main";
|
||||
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFile,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true),
|
||||
createTestInitConfigInputs({
|
||||
configFile,
|
||||
tempDir,
|
||||
codeql: getCachedCodeQL(),
|
||||
workspacePath: tempDir,
|
||||
}),
|
||||
);
|
||||
throw new Error("initConfig did not throw error");
|
||||
} catch (err) {
|
||||
@@ -274,30 +256,20 @@ test("load non-local input with invalid repo syntax", async (t) => {
|
||||
});
|
||||
|
||||
test("load non-existent input", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
const languages = "javascript";
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
const languagesInput = "javascript";
|
||||
const configFile = "input";
|
||||
t.false(fs.existsSync(path.join(tmpDir, configFile)));
|
||||
t.false(fs.existsSync(path.join(tempDir, configFile)));
|
||||
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
configFile,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput,
|
||||
configFile,
|
||||
tempDir,
|
||||
codeql: getCachedCodeQL(),
|
||||
workspacePath: tempDir,
|
||||
}),
|
||||
);
|
||||
throw new Error("initConfig did not throw error");
|
||||
} catch (err) {
|
||||
@@ -305,7 +277,7 @@ test("load non-existent input", async (t) => {
|
||||
err,
|
||||
new UserError(
|
||||
configUtils.getConfigFileDoesNotExistErrorMessage(
|
||||
path.join(tmpDir, "input"),
|
||||
path.join(tempDir, "input"),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -314,8 +286,8 @@ test("load non-existent input", async (t) => {
|
||||
});
|
||||
|
||||
test("load non-empty input", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
const codeQL = setCodeQL({
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
const codeql = setCodeQL({
|
||||
async resolveQueries() {
|
||||
return {
|
||||
byLanguage: {
|
||||
@@ -345,7 +317,7 @@ test("load non-empty input", async (t) => {
|
||||
paths:
|
||||
- c/d`;
|
||||
|
||||
fs.mkdirSync(path.join(tmpDir, "foo"));
|
||||
fs.mkdirSync(path.join(tempDir, "foo"));
|
||||
|
||||
// And the config we expect it to parse to
|
||||
const expectedConfig: configUtils.Config = {
|
||||
@@ -357,10 +329,10 @@ test("load non-empty input", async (t) => {
|
||||
"paths-ignore": ["a", "b"],
|
||||
paths: ["c/d"],
|
||||
},
|
||||
tempDir: tmpDir,
|
||||
codeQLCmd: codeQL.getPath(),
|
||||
gitHubVersion,
|
||||
dbLocation: path.resolve(tmpDir, "codeql_databases"),
|
||||
tempDir,
|
||||
codeQLCmd: codeql.getPath(),
|
||||
gitHubVersion: githubVersion,
|
||||
dbLocation: path.resolve(tempDir, "codeql_databases"),
|
||||
debugMode: false,
|
||||
debugArtifactName: "my-artifact",
|
||||
debugDatabaseName: "my-db",
|
||||
@@ -369,27 +341,19 @@ test("load non-empty input", async (t) => {
|
||||
trapCacheDownloadTime: 0,
|
||||
};
|
||||
|
||||
const languages = "javascript";
|
||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||
const languagesInput = "javascript";
|
||||
const configFilePath = createConfigFile(inputFileContents, tempDir);
|
||||
|
||||
const actualConfig = await configUtils.initConfig(
|
||||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
configFilePath,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"my-artifact",
|
||||
"my-db",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput,
|
||||
configFile: configFilePath,
|
||||
debugArtifactName: "my-artifact",
|
||||
debugDatabaseName: "my-db",
|
||||
tempDir,
|
||||
codeql,
|
||||
workspacePath: tempDir,
|
||||
}),
|
||||
);
|
||||
|
||||
// Should exactly equal the object we constructed earlier
|
||||
@@ -417,15 +381,15 @@ function queriesToResolvedQueryForm(queries: string[]) {
|
||||
}
|
||||
|
||||
test("Using config input and file together, config input should be used.", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
process.env["RUNNER_TEMP"] = tmpDir;
|
||||
process.env["GITHUB_WORKSPACE"] = tmpDir;
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
process.env["RUNNER_TEMP"] = tempDir;
|
||||
process.env["GITHUB_WORKSPACE"] = tempDir;
|
||||
|
||||
const inputFileContents = `
|
||||
name: my config
|
||||
queries:
|
||||
- uses: ./foo_file`;
|
||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||
const configFilePath = createConfigFile(inputFileContents, tempDir);
|
||||
|
||||
const configInput = `
|
||||
name: my config
|
||||
@@ -438,13 +402,13 @@ test("Using config input and file together, config input should be used.", async
|
||||
- c/d@1.2.3
|
||||
`;
|
||||
|
||||
fs.mkdirSync(path.join(tmpDir, "foo"));
|
||||
fs.mkdirSync(path.join(tempDir, "foo"));
|
||||
|
||||
const resolveQueriesArgs: Array<{
|
||||
queries: string[];
|
||||
extraSearchPath: string | undefined;
|
||||
}> = [];
|
||||
const codeQL = setCodeQL({
|
||||
const codeql = setCodeQL({
|
||||
async resolveQueries(
|
||||
queries: string[],
|
||||
extraSearchPath: string | undefined,
|
||||
@@ -458,26 +422,17 @@ test("Using config input and file together, config input should be used.", async
|
||||
});
|
||||
|
||||
// Only JS, python packs will be ignored
|
||||
const languages = "javascript";
|
||||
const languagesInput = "javascript";
|
||||
|
||||
const config = await configUtils.initConfig(
|
||||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
configFilePath,
|
||||
configInput,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput,
|
||||
configFile: configFilePath,
|
||||
configInput,
|
||||
tempDir,
|
||||
codeql,
|
||||
workspacePath: tempDir,
|
||||
}),
|
||||
);
|
||||
|
||||
t.deepEqual(config.originalUserInput, yaml.load(configInput));
|
||||
@@ -485,8 +440,8 @@ test("Using config input and file together, config input should be used.", async
|
||||
});
|
||||
|
||||
test("API client used when reading remote config", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
const codeQL = setCodeQL({
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
const codeql = setCodeQL({
|
||||
async resolveQueries() {
|
||||
return {
|
||||
byLanguage: {
|
||||
@@ -521,59 +476,38 @@ test("API client used when reading remote config", async (t) => {
|
||||
const spyGetContents = mockGetContents(dummyResponse);
|
||||
|
||||
// Create checkout directory for remote queries repository
|
||||
fs.mkdirSync(path.join(tmpDir, "foo/bar/dev"), { recursive: true });
|
||||
fs.mkdirSync(path.join(tempDir, "foo/bar/dev"), { recursive: true });
|
||||
|
||||
const configFile = "octo-org/codeql-config/config.yaml@main";
|
||||
const languages = "javascript";
|
||||
const languagesInput = "javascript";
|
||||
|
||||
await configUtils.initConfig(
|
||||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
configFile,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput,
|
||||
configFile,
|
||||
tempDir,
|
||||
codeql,
|
||||
workspacePath: tempDir,
|
||||
}),
|
||||
);
|
||||
t.assert(spyGetContents.called);
|
||||
});
|
||||
});
|
||||
|
||||
test("Remote config handles the case where a directory is provided", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
const dummyResponse = []; // directories are returned as arrays
|
||||
mockGetContents(dummyResponse);
|
||||
|
||||
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
repoReference,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true),
|
||||
createTestInitConfigInputs({
|
||||
configFile: repoReference,
|
||||
tempDir,
|
||||
codeql: getCachedCodeQL(),
|
||||
workspacePath: tempDir,
|
||||
}),
|
||||
);
|
||||
throw new Error("initConfig did not throw error");
|
||||
} catch (err) {
|
||||
@@ -588,7 +522,7 @@ test("Remote config handles the case where a directory is provided", async (t) =
|
||||
});
|
||||
|
||||
test("Invalid format of remote config handled correctly", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
const dummyResponse = {
|
||||
// note no "content" property here
|
||||
};
|
||||
@@ -597,23 +531,12 @@ test("Invalid format of remote config handled correctly", async (t) => {
|
||||
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
repoReference,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true),
|
||||
createTestInitConfigInputs({
|
||||
configFile: repoReference,
|
||||
tempDir,
|
||||
codeql: getCachedCodeQL(),
|
||||
workspacePath: tempDir,
|
||||
}),
|
||||
);
|
||||
throw new Error("initConfig did not throw error");
|
||||
} catch (err) {
|
||||
@@ -628,9 +551,9 @@ test("Invalid format of remote config handled correctly", async (t) => {
|
||||
});
|
||||
|
||||
test("No detected languages", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
mockListLanguages([]);
|
||||
const codeQL = setCodeQL({
|
||||
const codeql = setCodeQL({
|
||||
async resolveLanguages() {
|
||||
return {};
|
||||
},
|
||||
@@ -641,23 +564,11 @@ test("No detected languages", async (t) => {
|
||||
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true),
|
||||
createTestInitConfigInputs({
|
||||
tempDir,
|
||||
codeql,
|
||||
workspacePath: tempDir,
|
||||
}),
|
||||
);
|
||||
throw new Error("initConfig did not throw error");
|
||||
} catch (err) {
|
||||
@@ -667,28 +578,17 @@ test("No detected languages", async (t) => {
|
||||
});
|
||||
|
||||
test("Unknown languages", async (t) => {
|
||||
return await withTmpDir(async (tmpDir) => {
|
||||
const languages = "rubbish,english";
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
const languagesInput = "rubbish,english";
|
||||
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
languages,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
{ owner: "github", repo: "example" },
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput,
|
||||
tempDir,
|
||||
codeql: getCachedCodeQL(),
|
||||
workspacePath: tempDir,
|
||||
}),
|
||||
);
|
||||
throw new Error("initConfig did not throw error");
|
||||
} catch (err) {
|
||||
|
||||
@@ -391,39 +391,69 @@ export async function getRawLanguages(
|
||||
return { rawLanguages, autodetected };
|
||||
}
|
||||
|
||||
/** Inputs required to initialize a configuration. */
|
||||
export interface InitConfigInputs {
|
||||
languagesInput: string | undefined;
|
||||
queriesInput: string | undefined;
|
||||
packsInput: string | undefined;
|
||||
configFile: string | undefined;
|
||||
dbLocation: string | undefined;
|
||||
configInput: string | undefined;
|
||||
trapCachingEnabled: boolean;
|
||||
debugMode: boolean;
|
||||
debugArtifactName: string;
|
||||
debugDatabaseName: string;
|
||||
repository: RepositoryNwo;
|
||||
tempDir: string;
|
||||
codeql: CodeQL;
|
||||
workspacePath: string;
|
||||
githubVersion: GitHubVersion;
|
||||
apiDetails: api.GitHubApiCombinedDetails;
|
||||
logger: Logger;
|
||||
}
|
||||
|
||||
type GetDefaultConfigInputs = Omit<
|
||||
InitConfigInputs,
|
||||
"configFile" | "configInput"
|
||||
>;
|
||||
|
||||
type LoadConfigInputs = Omit<InitConfigInputs, "configInput"> & {
|
||||
configFile: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the default config for when the user has not supplied one.
|
||||
*/
|
||||
export async function getDefaultConfig(
|
||||
languagesInput: string | undefined,
|
||||
rawQueriesInput: string | undefined,
|
||||
rawPacksInput: string | undefined,
|
||||
dbLocation: string | undefined,
|
||||
trapCachingEnabled: boolean,
|
||||
debugMode: boolean,
|
||||
debugArtifactName: string,
|
||||
debugDatabaseName: string,
|
||||
repository: RepositoryNwo,
|
||||
tempDir: string,
|
||||
codeQL: CodeQL,
|
||||
gitHubVersion: GitHubVersion,
|
||||
logger: Logger,
|
||||
): Promise<Config> {
|
||||
export async function getDefaultConfig({
|
||||
languagesInput,
|
||||
queriesInput,
|
||||
packsInput,
|
||||
dbLocation,
|
||||
trapCachingEnabled,
|
||||
debugMode,
|
||||
debugArtifactName,
|
||||
debugDatabaseName,
|
||||
repository,
|
||||
tempDir,
|
||||
codeql,
|
||||
githubVersion,
|
||||
logger,
|
||||
}: GetDefaultConfigInputs): Promise<Config> {
|
||||
const languages = await getLanguages(
|
||||
codeQL,
|
||||
codeql,
|
||||
languagesInput,
|
||||
repository,
|
||||
logger,
|
||||
);
|
||||
const augmentationProperties = calculateAugmentation(
|
||||
rawPacksInput,
|
||||
rawQueriesInput,
|
||||
packsInput,
|
||||
queriesInput,
|
||||
languages,
|
||||
);
|
||||
|
||||
const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime(
|
||||
trapCachingEnabled,
|
||||
codeQL,
|
||||
codeql,
|
||||
languages,
|
||||
logger,
|
||||
);
|
||||
@@ -432,8 +462,8 @@ export async function getDefaultConfig(
|
||||
languages,
|
||||
originalUserInput: {},
|
||||
tempDir,
|
||||
codeQLCmd: codeQL.getPath(),
|
||||
gitHubVersion,
|
||||
codeQLCmd: codeql.getPath(),
|
||||
gitHubVersion: githubVersion,
|
||||
dbLocation: dbLocationOrDefault(dbLocation, tempDir),
|
||||
debugMode,
|
||||
debugArtifactName,
|
||||
@@ -466,24 +496,24 @@ async function downloadCacheWithTime(
|
||||
/**
|
||||
* Load the config from the given file.
|
||||
*/
|
||||
async function loadConfig(
|
||||
languagesInput: string | undefined,
|
||||
rawQueriesInput: string | undefined,
|
||||
rawPacksInput: string | undefined,
|
||||
configFile: string,
|
||||
dbLocation: string | undefined,
|
||||
trapCachingEnabled: boolean,
|
||||
debugMode: boolean,
|
||||
debugArtifactName: string,
|
||||
debugDatabaseName: string,
|
||||
repository: RepositoryNwo,
|
||||
tempDir: string,
|
||||
codeQL: CodeQL,
|
||||
workspacePath: string,
|
||||
gitHubVersion: GitHubVersion,
|
||||
apiDetails: api.GitHubApiCombinedDetails,
|
||||
logger: Logger,
|
||||
): Promise<Config> {
|
||||
async function loadConfig({
|
||||
languagesInput,
|
||||
queriesInput,
|
||||
packsInput,
|
||||
configFile,
|
||||
dbLocation,
|
||||
trapCachingEnabled,
|
||||
debugMode,
|
||||
debugArtifactName,
|
||||
debugDatabaseName,
|
||||
repository,
|
||||
tempDir,
|
||||
codeql,
|
||||
workspacePath,
|
||||
githubVersion,
|
||||
apiDetails,
|
||||
logger,
|
||||
}: LoadConfigInputs): Promise<Config> {
|
||||
let parsedYAML: UserConfig;
|
||||
|
||||
if (isLocal(configFile)) {
|
||||
@@ -495,21 +525,21 @@ async function loadConfig(
|
||||
}
|
||||
|
||||
const languages = await getLanguages(
|
||||
codeQL,
|
||||
codeql,
|
||||
languagesInput,
|
||||
repository,
|
||||
logger,
|
||||
);
|
||||
|
||||
const augmentationProperties = calculateAugmentation(
|
||||
rawPacksInput,
|
||||
rawQueriesInput,
|
||||
packsInput,
|
||||
queriesInput,
|
||||
languages,
|
||||
);
|
||||
|
||||
const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime(
|
||||
trapCachingEnabled,
|
||||
codeQL,
|
||||
codeql,
|
||||
languages,
|
||||
logger,
|
||||
);
|
||||
@@ -518,8 +548,8 @@ async function loadConfig(
|
||||
languages,
|
||||
originalUserInput: parsedYAML,
|
||||
tempDir,
|
||||
codeQLCmd: codeQL.getPath(),
|
||||
gitHubVersion,
|
||||
codeQLCmd: codeql.getPath(),
|
||||
gitHubVersion: githubVersion,
|
||||
dbLocation: dbLocationOrDefault(dbLocation, tempDir),
|
||||
debugMode,
|
||||
debugArtifactName,
|
||||
@@ -765,76 +795,33 @@ function dbLocationOrDefault(
|
||||
* 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.
|
||||
*/
|
||||
export async function initConfig(
|
||||
languagesInput: string | undefined,
|
||||
queriesInput: string | undefined,
|
||||
packsInput: string | undefined,
|
||||
configFile: string | undefined,
|
||||
dbLocation: string | undefined,
|
||||
configInput: string | undefined,
|
||||
trapCachingEnabled: boolean,
|
||||
debugMode: boolean,
|
||||
debugArtifactName: string,
|
||||
debugDatabaseName: string,
|
||||
repository: RepositoryNwo,
|
||||
tempDir: string,
|
||||
codeQL: CodeQL,
|
||||
workspacePath: string,
|
||||
gitHubVersion: GitHubVersion,
|
||||
apiDetails: api.GitHubApiCombinedDetails,
|
||||
logger: Logger,
|
||||
): Promise<Config> {
|
||||
export async function initConfig(inputs: InitConfigInputs): Promise<Config> {
|
||||
let config: Config;
|
||||
|
||||
const { logger, workspacePath } = inputs;
|
||||
|
||||
// if configInput is set, it takes precedence over configFile
|
||||
if (configInput) {
|
||||
if (configFile) {
|
||||
if (inputs.configInput) {
|
||||
if (inputs.configFile) {
|
||||
logger.warning(
|
||||
`Both a config file and config input were provided. Ignoring config file.`,
|
||||
);
|
||||
}
|
||||
configFile = path.resolve(workspacePath, "user-config-from-action.yml");
|
||||
fs.writeFileSync(configFile, configInput);
|
||||
logger.debug(`Using config from action input: ${configFile}`);
|
||||
inputs.configFile = path.resolve(
|
||||
workspacePath,
|
||||
"user-config-from-action.yml",
|
||||
);
|
||||
fs.writeFileSync(inputs.configFile, inputs.configInput);
|
||||
logger.debug(`Using config from action input: ${inputs.configFile}`);
|
||||
}
|
||||
|
||||
// If no config file was provided create an empty one
|
||||
if (!configFile) {
|
||||
if (!inputs.configFile) {
|
||||
logger.debug("No configuration file was provided");
|
||||
config = await getDefaultConfig(
|
||||
languagesInput,
|
||||
queriesInput,
|
||||
packsInput,
|
||||
dbLocation,
|
||||
trapCachingEnabled,
|
||||
debugMode,
|
||||
debugArtifactName,
|
||||
debugDatabaseName,
|
||||
repository,
|
||||
tempDir,
|
||||
codeQL,
|
||||
gitHubVersion,
|
||||
logger,
|
||||
);
|
||||
config = await getDefaultConfig(inputs);
|
||||
} else {
|
||||
config = await loadConfig(
|
||||
languagesInput,
|
||||
queriesInput,
|
||||
packsInput,
|
||||
configFile,
|
||||
dbLocation,
|
||||
trapCachingEnabled,
|
||||
debugMode,
|
||||
debugArtifactName,
|
||||
debugDatabaseName,
|
||||
repository,
|
||||
tempDir,
|
||||
codeQL,
|
||||
workspacePath,
|
||||
gitHubVersion,
|
||||
apiDetails,
|
||||
logger,
|
||||
);
|
||||
// Convince the type checker that inputs.configFile is defined.
|
||||
config = await loadConfig({ ...inputs, configFile: inputs.configFile });
|
||||
}
|
||||
|
||||
// Save the config so we can easily access it again in the future
|
||||
|
||||
@@ -265,29 +265,31 @@ async function run() {
|
||||
}
|
||||
core.endGroup();
|
||||
|
||||
config = await initConfig(
|
||||
getOptionalInput("languages"),
|
||||
getOptionalInput("queries"),
|
||||
getOptionalInput("packs"),
|
||||
getOptionalInput("config-file"),
|
||||
getOptionalInput("db-location"),
|
||||
getOptionalInput("config"),
|
||||
getTrapCachingEnabled(),
|
||||
config = await initConfig({
|
||||
languagesInput: getOptionalInput("languages"),
|
||||
queriesInput: getOptionalInput("queries"),
|
||||
packsInput: getOptionalInput("packs"),
|
||||
configFile: getOptionalInput("config-file"),
|
||||
dbLocation: getOptionalInput("db-location"),
|
||||
configInput: getOptionalInput("config"),
|
||||
trapCachingEnabled: 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),
|
||||
// or by setting the `ACTIONS_STEP_DEBUG` secret to `true`).
|
||||
getOptionalInput("debug") === "true" || core.isDebug(),
|
||||
getOptionalInput("debug-artifact-name") || DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||
getOptionalInput("debug-database-name") || DEFAULT_DEBUG_DATABASE_NAME,
|
||||
repositoryNwo,
|
||||
getTemporaryDirectory(),
|
||||
debugMode: getOptionalInput("debug") === "true" || core.isDebug(),
|
||||
debugArtifactName:
|
||||
getOptionalInput("debug-artifact-name") || DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||
debugDatabaseName:
|
||||
getOptionalInput("debug-database-name") || DEFAULT_DEBUG_DATABASE_NAME,
|
||||
repository: repositoryNwo,
|
||||
tempDir: getTemporaryDirectory(),
|
||||
codeql,
|
||||
getRequiredEnvParam("GITHUB_WORKSPACE"),
|
||||
gitHubVersion,
|
||||
workspacePath: getRequiredEnvParam("GITHUB_WORKSPACE"),
|
||||
githubVersion: gitHubVersion,
|
||||
apiDetails,
|
||||
logger,
|
||||
);
|
||||
});
|
||||
|
||||
await checkInstallPython311(config.languages, codeql);
|
||||
|
||||
|
||||
40
src/init.ts
40
src/init.ts
@@ -10,7 +10,6 @@ import * as configUtils from "./config-utils";
|
||||
import { CodeQLDefaultVersionInfo } from "./feature-flags";
|
||||
import { Language, isScannedLanguage } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { RepositoryNwo } from "./repository";
|
||||
import { ToolsSource } from "./setup-codeql";
|
||||
import { TracerConfig, getCombinedTracerConfig } from "./tracer-config";
|
||||
import * as util from "./util";
|
||||
@@ -45,44 +44,11 @@ export async function initCodeQL(
|
||||
}
|
||||
|
||||
export async function initConfig(
|
||||
languagesInput: string | undefined,
|
||||
queriesInput: string | undefined,
|
||||
packsInput: string | undefined,
|
||||
configFile: string | undefined,
|
||||
dbLocation: string | undefined,
|
||||
configInput: string | undefined,
|
||||
trapCachingEnabled: boolean,
|
||||
debugMode: boolean,
|
||||
debugArtifactName: string,
|
||||
debugDatabaseName: string,
|
||||
repository: RepositoryNwo,
|
||||
tempDir: string,
|
||||
codeQL: CodeQL,
|
||||
workspacePath: string,
|
||||
gitHubVersion: util.GitHubVersion,
|
||||
apiDetails: GitHubApiCombinedDetails,
|
||||
logger: Logger,
|
||||
inputs: configUtils.InitConfigInputs,
|
||||
): Promise<configUtils.Config> {
|
||||
const logger = inputs.logger;
|
||||
logger.startGroup("Load language configuration");
|
||||
const config = await configUtils.initConfig(
|
||||
languagesInput,
|
||||
queriesInput,
|
||||
packsInput,
|
||||
configFile,
|
||||
dbLocation,
|
||||
configInput,
|
||||
trapCachingEnabled,
|
||||
debugMode,
|
||||
debugArtifactName,
|
||||
debugDatabaseName,
|
||||
repository,
|
||||
tempDir,
|
||||
codeQL,
|
||||
workspacePath,
|
||||
gitHubVersion,
|
||||
apiDetails,
|
||||
logger,
|
||||
);
|
||||
const config = await configUtils.initConfig(inputs);
|
||||
printPathFiltersWarning(config, logger);
|
||||
logger.endGroup();
|
||||
return config;
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as sinon from "sinon";
|
||||
|
||||
import * as apiClient from "./api-client";
|
||||
import { GitHubApiDetails } from "./api-client";
|
||||
import * as CodeQL from "./codeql";
|
||||
import * as codeql from "./codeql";
|
||||
import {
|
||||
CodeQLDefaultVersionInfo,
|
||||
Feature,
|
||||
@@ -73,7 +73,7 @@ export function setupTests(test: TestFn<any>) {
|
||||
typedTest.beforeEach((t) => {
|
||||
// Set an empty CodeQL object so that all method calls will fail
|
||||
// unless the test explicitly sets one up.
|
||||
CodeQL.setCodeQL({});
|
||||
codeql.setCodeQL({});
|
||||
|
||||
// Replace stdout and stderr so we can record output during tests
|
||||
t.context.testOutput = "";
|
||||
@@ -214,7 +214,7 @@ export function mockLanguagesInRepo(languages: string[]) {
|
||||
export const makeVersionInfo = (
|
||||
version: string,
|
||||
features?: { [name: string]: boolean },
|
||||
): CodeQL.VersionInfo => ({
|
||||
): codeql.VersionInfo => ({
|
||||
version,
|
||||
features,
|
||||
});
|
||||
@@ -227,7 +227,7 @@ export function mockCodeQLVersion(
|
||||
async getVersion() {
|
||||
return makeVersionInfo(version, features);
|
||||
},
|
||||
} as CodeQL.CodeQL;
|
||||
} as codeql.CodeQL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user