diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 23ee4f006..8ef35e4d4 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -65,16 +65,6 @@ function createTestInitConfigInputs( debugDatabaseName: "", repository: { owner: "github", repo: "example" }, tempDir: "", - codeql: createStubCodeQL({ - async betterResolveLanguages() { - return { - extractors: { - html: [{ extractor_root: "" }], - javascript: [{ extractor_root: "" }], - }, - }; - }, - }), workspacePath: "", sourceRoot: "", githubVersion, @@ -99,6 +89,20 @@ function createConfigFile(inputFileContents: string, tmpDir: string): string { return configFilePath; } +// Returns a default CodeQL stub for tests +function createDefaultTestCodeQL() { + return createStubCodeQL({ + async betterResolveLanguages() { + return { + extractors: { + html: [{ extractor_root: "" }], + javascript: [{ extractor_root: "" }], + }, + }; + }, + }); +} + type GetContentsResponse = { content?: string } | object[]; function mockGetContents( @@ -153,19 +157,19 @@ test("load empty config", async (t) => { languagesInput: languages, repository: { owner: "github", repo: "example" }, tempDir, - codeql, logger, }), + codeql, ); const expectedConfig = await configUtils.initActionState( createTestInitConfigInputs({ languagesInput: languages, tempDir, - codeql, logger, }), {}, + codeql, ); t.deepEqual(config, expectedConfig); @@ -193,9 +197,9 @@ test("load code quality config", async (t) => { languagesInput: languages, repository: { owner: "github", repo: "example" }, tempDir, - codeql, logger, }), + codeql, ); // And the config we expect it to result in @@ -277,10 +281,10 @@ test("initActionState doesn't throw if there are queries configured in the repos languagesInput: languages, repository: { owner: "github", repo: "example" }, tempDir, - codeql, repositoryProperties, logger, }), + codeql, ); t.deepEqual(config, expectedConfig); @@ -313,10 +317,10 @@ test("loading a saved config produces the same config", async (t) => { createTestInitConfigInputs({ languagesInput: "javascript,python", tempDir, - codeql, workspacePath: tempDir, logger, }), + codeql, ); await configUtils.saveConfig(config1, logger); @@ -364,10 +368,10 @@ test("loading config with version mismatch throws", async (t) => { createTestInitConfigInputs({ languagesInput: "javascript,python", tempDir, - codeql, workspacePath: tempDir, logger, }), + codeql, ); // initConfig does not save the config, so we do it here. await configUtils.saveConfig(config, logger); @@ -394,6 +398,7 @@ test("load input outside of workspace", async (t) => { tempDir, workspacePath: tempDir, }), + createDefaultTestCodeQL(), ); throw new Error("initConfig did not throw error"); } catch (err) { @@ -421,6 +426,7 @@ test("load non-local input with invalid repo syntax", async (t) => { tempDir, workspacePath: tempDir, }), + createDefaultTestCodeQL(), ); throw new Error("initConfig did not throw error"); } catch (err) { @@ -450,6 +456,7 @@ test("load non-existent input", async (t) => { tempDir, workspacePath: tempDir, }), + createDefaultTestCodeQL(), ); throw new Error("initConfig did not throw error"); } catch (err) { @@ -534,9 +541,9 @@ test("load non-empty input", async (t) => { debugArtifactName: "my-artifact", debugDatabaseName: "my-db", tempDir, - codeql, workspacePath: tempDir, }), + codeql, ); // Should exactly equal the object we constructed earlier @@ -588,9 +595,9 @@ test("Using config input and file together, config input should be used.", async configFile: configFilePath, configInput, tempDir, - codeql, workspacePath: tempDir, }), + codeql, ); t.deepEqual(config.originalUserInput, yaml.load(configInput)); @@ -637,9 +644,9 @@ test("API client used when reading remote config", async (t) => { languagesInput, configFile, tempDir, - codeql, workspacePath: tempDir, }), + codeql, ); t.assert(spyGetContents.called); }); @@ -658,6 +665,7 @@ test("Remote config handles the case where a directory is provided", async (t) = tempDir, workspacePath: tempDir, }), + createDefaultTestCodeQL(), ); throw new Error("initConfig did not throw error"); } catch (err) { @@ -686,6 +694,7 @@ test("Invalid format of remote config handled correctly", async (t) => { tempDir, workspacePath: tempDir, }), + createDefaultTestCodeQL(), ); throw new Error("initConfig did not throw error"); } catch (err) { @@ -712,9 +721,9 @@ test("No detected languages", async (t) => { await configUtils.initConfig( createTestInitConfigInputs({ tempDir, - codeql, workspacePath: tempDir, }), + codeql, ); throw new Error("initConfig did not throw error"); } catch (err) { @@ -737,6 +746,7 @@ test("Unknown languages", async (t) => { tempDir, workspacePath: tempDir, }), + createDefaultTestCodeQL(), ); throw new Error("initConfig did not throw error"); } catch (err) { diff --git a/src/config-utils.ts b/src/config-utils.ts index 05b9e472e..55867138c 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -420,7 +420,6 @@ export interface InitConfigInputs { debugDatabaseName: string; repository: RepositoryNwo; tempDir: string; - codeql: CodeQL; workspacePath: string; sourceRoot: string; githubVersion: GitHubVersion; @@ -450,7 +449,6 @@ export async function initActionState( debugDatabaseName, repository, tempDir, - codeql, sourceRoot, githubVersion, features, @@ -458,6 +456,7 @@ export async function initActionState( logger, }: InitConfigInputs, userConfig: UserConfig, + codeql: CodeQL, ): Promise { const analysisKinds = await parseAnalysisKinds(analysisKindsInput); @@ -834,7 +833,10 @@ function hasQueryCustomisation(userConfig: UserConfig): boolean { * 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(inputs: InitConfigInputs): Promise { +export async function initConfig( + inputs: InitConfigInputs, + codeql: CodeQL, +): Promise { const { logger, tempDir } = inputs; // if configInput is set, it takes precedence over configFile @@ -862,7 +864,7 @@ export async function initConfig(inputs: InitConfigInputs): Promise { ); } - const config = await initActionState(inputs, userConfig); + const config = await initActionState(inputs, userConfig, codeql); // If Code Quality analysis is the only enabled analysis kind, then we will initialise // the database for Code Quality. That entails disabling the default queries and only @@ -889,7 +891,7 @@ export async function initConfig(inputs: InitConfigInputs): Promise { // rest of the config has been populated. const { overlayDatabaseMode, useOverlayDatabaseCaching } = await getOverlayDatabaseMode( - inputs.codeql, + codeql, inputs.repository, inputs.features, config.languages, @@ -908,11 +910,7 @@ export async function initConfig(inputs: InitConfigInputs): Promise { if ( overlayDatabaseMode === OverlayDatabaseMode.Overlay || - (await shouldPerformDiffInformedAnalysis( - inputs.codeql, - inputs.features, - logger, - )) + (await shouldPerformDiffInformedAnalysis(codeql, inputs.features, logger)) ) { config.extraQueryExclusions.push({ exclude: { tags: "exclude-from-incremental" }, diff --git a/src/init-action.ts b/src/init-action.ts index 2b4dba3fc..31531bc50 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -297,38 +297,42 @@ async function run() { ); } - config = await initConfig({ - analysisKindsInput: getRequiredInput("analysis-kinds"), - languagesInput: getOptionalInput("languages"), - queriesInput: getOptionalInput("queries"), - qualityQueriesInput, - packsInput: getOptionalInput("packs"), - buildModeInput: getOptionalInput("build-mode"), - configFile, - dbLocation: getOptionalInput("db-location"), - configInput: getOptionalInput("config"), - trapCachingEnabled: getTrapCachingEnabled(), - dependencyCachingEnabled: getDependencyCachingEnabled(), - // 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`). - 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(), + config = await initConfig( + { + analysisKindsInput: getRequiredInput("analysis-kinds"), + languagesInput: getOptionalInput("languages"), + queriesInput: getOptionalInput("queries"), + qualityQueriesInput, + packsInput: getOptionalInput("packs"), + buildModeInput: getOptionalInput("build-mode"), + configFile, + dbLocation: getOptionalInput("db-location"), + configInput: getOptionalInput("config"), + trapCachingEnabled: getTrapCachingEnabled(), + dependencyCachingEnabled: getDependencyCachingEnabled(), + // 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`). + 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(), + workspacePath: getRequiredEnvParam("GITHUB_WORKSPACE"), + sourceRoot, + githubVersion: gitHubVersion, + apiDetails, + features, + repositoryProperties, + logger, + }, codeql, - workspacePath: getRequiredEnvParam("GITHUB_WORKSPACE"), - sourceRoot, - githubVersion: gitHubVersion, - apiDetails, - features, - repositoryProperties, - logger, - }); + ); await checkInstallPython311(config.languages, codeql); } catch (unwrappedError) { diff --git a/src/init.ts b/src/init.ts index 687afc122..d7c6cb5cc 100644 --- a/src/init.ts +++ b/src/init.ts @@ -60,9 +60,10 @@ export async function initCodeQL( export async function initConfig( inputs: configUtils.InitConfigInputs, + codeql: CodeQL, ): Promise { return await withGroupAsync("Load language configuration", async () => { - return await configUtils.initConfig(inputs); + return await configUtils.initConfig(inputs, codeql); }); }