Ensure qlconfig file is created when config parsing in cli is on

Previously, with the config parsing in the cli feature flag turned on,
the CLI was not able to download packs from other registries. This PR
adds the codeql-action changes required for this. The CLI changes will
be in a separate, internal PR.
This commit is contained in:
Andrew Eisenberg 2023-02-07 10:40:49 -08:00
parent 4369dda4ae
commit bbe8d375fd
20 changed files with 480 additions and 138 deletions

View file

@ -1403,7 +1403,7 @@ function parseQueriesFromInput(
const trimmedInput = queriesInputCombines
? rawQueriesInput.trim().slice(1).trim()
: rawQueriesInput?.trim();
: rawQueriesInput?.trim() ?? "";
if (queriesInputCombines && trimmedInput.length === 0) {
throw new Error(
getConfigFilePropertyError(
@ -1769,13 +1769,12 @@ export async function initConfig(
}
}
const registries = parseRegistries(registriesInput);
await downloadPacks(
codeQL,
config.languages,
config.packs,
registries,
apiDetails,
registriesInput,
config.tempDir,
logger
);
@ -1899,32 +1898,19 @@ export async function downloadPacks(
codeQL: CodeQL,
languages: Language[],
packs: Packs,
registries: RegistryConfigWithCredentials[] | undefined,
apiDetails: api.GitHubApiDetails,
tmpDir: string,
registriesInput: string | undefined,
tempDir: string,
logger: Logger
) {
let qlconfigFile: string | undefined;
let registriesAuthTokens: string | undefined;
if (registries) {
if (
!(await codeQlVersionAbove(codeQL, CODEQL_VERSION_GHES_PACK_DOWNLOAD))
) {
throw new Error(
`'registries' input is not supported on CodeQL versions less than ${CODEQL_VERSION_GHES_PACK_DOWNLOAD}.`
);
}
// generate a qlconfig.yml file to hold the registry configs.
const qlconfig = createRegistriesBlock(registries);
qlconfigFile = path.join(tmpDir, "qlconfig.yml");
fs.writeFileSync(qlconfigFile, yaml.dump(qlconfig), "utf8");
registriesAuthTokens = registries
.map((registry) => `${registry.url}=${registry.token}`)
.join(",");
}
// When config parsing in the cli is used, the registries will be generated
// immediately before the call to database init.
const { registriesAuthTokens, qlconfigFile } = await generateRegistries(
registriesInput,
codeQL,
tempDir,
logger
);
await wrapEnvironment(
{
GITHUB_TOKEN: apiDetails.auth,
@ -1963,6 +1949,51 @@ export async function downloadPacks(
);
}
/**
* Generate a `qlconfig.yml` file from the `registries` input.
* This file is used by the CodeQL CLI to list the registries to use for each
* pack.
*
* @param registriesInput The value of the `registries` input.
* @param codeQL a codeQL object, used only for checking the version of CodeQL.
* @param tmpDir a temporary directory to store the generated qlconfig.yml file.
* @param logger a logger object.
* @returns The path to the generated `qlconfig.yml` file and the auth tokens to
* use for each registry.
*/
export async function generateRegistries(
registriesInput: string | undefined,
codeQL: CodeQL,
tmpDir: string,
logger: Logger
) {
const registries = parseRegistries(registriesInput);
let registriesAuthTokens: string | undefined;
let qlconfigFile: string | undefined;
if (registries) {
if (
!(await codeQlVersionAbove(codeQL, CODEQL_VERSION_GHES_PACK_DOWNLOAD))
) {
throw new Error(
`'registries' input is not supported on CodeQL versions less than ${CODEQL_VERSION_GHES_PACK_DOWNLOAD}.`
);
}
// generate a qlconfig.yml file to hold the registry configs.
const qlconfig = createRegistriesBlock(registries);
qlconfigFile = path.join(tmpDir, "qlconfig.yml");
const qlconfigContents = yaml.dump(qlconfig);
fs.writeFileSync(qlconfigFile, qlconfigContents, "utf8");
logger.debug("Generated qlconfig.yml:");
logger.debug(qlconfigContents);
registriesAuthTokens = registries
.map((registry) => `${registry.url}=${registry.token}`)
.join(",");
}
return { registriesAuthTokens, qlconfigFile };
}
function createRegistriesBlock(registries: RegistryConfigWithCredentials[]): {
registries: RegistryConfigNoCredentials[];
} {
@ -1999,7 +2030,7 @@ function createRegistriesBlock(registries: RegistryConfigWithCredentials[]): {
* @param env
* @param operation
*/
async function wrapEnvironment(
export async function wrapEnvironment(
env: Record<string, string | undefined>,
operation: Function
) {