From d332aa98b64c96450544b3f8a518430e89ced7d1 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 2 Sep 2025 18:14:32 +0100 Subject: [PATCH 1/8] Use `computedConfig` for pack telemetry --- lib/init-action.js | 19 ++++--------------- src/init-action.ts | 27 ++++----------------------- 2 files changed, 8 insertions(+), 38 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index bedab733cf..fe6f4a6a15 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -90195,21 +90195,10 @@ async function sendCompletedStatusReport(startedAt, config, configFile, toolsDow queries.push(...queriesInput.split(",")); } let packs = {}; - if ((config.augmentationProperties.packsInputCombines || !config.augmentationProperties.packsInput) && config.originalUserInput.packs) { - const copyPacksFromOriginalUserInput = cloneObject( - config.originalUserInput.packs - ); - if (Array.isArray(copyPacksFromOriginalUserInput)) { - packs[config.languages[0]] = copyPacksFromOriginalUserInput; - } else { - packs = copyPacksFromOriginalUserInput; - } - } - if (config.augmentationProperties.packsInput) { - packs[config.languages[0]] ??= []; - packs[config.languages[0]].push( - ...config.augmentationProperties.packsInput - ); + if (Array.isArray(config.computedConfig.packs)) { + packs[config.languages[0]] = config.computedConfig.packs; + } else if (config.computedConfig.packs !== void 0) { + packs = config.computedConfig.packs; } const initWithConfigStatusReport = { ...initStatusReport, diff --git a/src/init-action.ts b/src/init-action.ts index 35bc83d2df..637fd2c3da 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -75,7 +75,6 @@ import { ConfigurationError, wrapError, checkActionVersion, - cloneObject, getErrorMessage, } from "./util"; import { validateWorkflow } from "./workflow"; @@ -206,28 +205,10 @@ async function sendCompletedStatusReport( } let packs: Record = {}; - if ( - (config.augmentationProperties.packsInputCombines || - !config.augmentationProperties.packsInput) && - config.originalUserInput.packs - ) { - // Make a copy, because we might modify `packs`. - const copyPacksFromOriginalUserInput = cloneObject( - config.originalUserInput.packs, - ); - // If it is an array, then assume there is only a single language being analyzed. - if (Array.isArray(copyPacksFromOriginalUserInput)) { - packs[config.languages[0]] = copyPacksFromOriginalUserInput; - } else { - packs = copyPacksFromOriginalUserInput; - } - } - - if (config.augmentationProperties.packsInput) { - packs[config.languages[0]] ??= []; - packs[config.languages[0]].push( - ...config.augmentationProperties.packsInput, - ); + if (Array.isArray(config.computedConfig.packs)) { + packs[config.languages[0]] = config.computedConfig.packs; + } else if (config.computedConfig.packs !== undefined) { + packs = config.computedConfig.packs; } // Append fields that are dependent on `config` From 87c5b58925cff033edb2bd0991042f0031eaf878 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 2 Sep 2025 18:20:56 +0100 Subject: [PATCH 2/8] Remove `augmentationProperties` from `Config` --- lib/init-action.js | 4 ++-- src/codeql.test.ts | 3 +-- src/config-utils.test.ts | 10 +++++----- src/config-utils.ts | 14 +++++--------- src/testing-utils.ts | 6 +----- 5 files changed, 14 insertions(+), 23 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index fe6f4a6a15..ac9358f219 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -87601,11 +87601,11 @@ async function initConfig(inputs) { tempDir ); } - const config = await getDefaultConfig(inputs); + const { augmentationProperties, ...config } = await getDefaultConfig(inputs); config.originalUserInput = userConfig; config.computedConfig = generateCodeScanningConfig( userConfig, - config.augmentationProperties + augmentationProperties ); const { overlayDatabaseMode, useOverlayDatabaseCaching } = await getOverlayDatabaseMode( inputs.codeql, diff --git a/src/codeql.test.ts b/src/codeql.test.ts index e6df746c73..ece6ab878a 100644 --- a/src/codeql.test.ts +++ b/src/codeql.test.ts @@ -503,11 +503,10 @@ const injectedConfigMacro = test.macro({ ...stubConfig, ...configOverride, tempDir, - augmentationProperties, }; thisStubConfig.computedConfig = generateCodeScanningConfig( thisStubConfig.originalUserInput, - thisStubConfig.augmentationProperties, + augmentationProperties, ); await codeqlObject.databaseInitCluster( diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index b133f500bc..a67e3cf653 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -157,8 +157,8 @@ test("load empty config", async (t) => { }), ); - t.deepEqual( - config, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { augmentationProperties, ...expectedConfig } = await configUtils.getDefaultConfig( createTestInitConfigInputs({ languagesInput: languages, @@ -166,8 +166,9 @@ test("load empty config", async (t) => { codeql, logger, }), - ), - ); + ); + + t.deepEqual(config, expectedConfig); }); }); @@ -344,7 +345,6 @@ test("load non-empty input", async (t) => { debugMode: false, debugArtifactName: "my-artifact", debugDatabaseName: "my-db", - augmentationProperties: configUtils.defaultAugmentationProperties, trapCaches: {}, trapCacheDownloadTime: 0, dependencyCachingEnabled: CachingKind.None, diff --git a/src/config-utils.ts b/src/config-utils.ts index 64a1c93b9d..e8c97a854c 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -144,12 +144,6 @@ export interface Config { * Specifies the name of the database in the debugging artifact. */ debugDatabaseName: string; - - /** - * Describes how to augment the user configuration with inputs from the action. - */ - augmentationProperties: AugmentationProperties; - /** * The configuration we computed by combining `originalUserInput` with `augmentationProperties`, * as well as adjustments made to it based on unsupported or required options. @@ -536,7 +530,9 @@ export async function getDefaultConfig({ githubVersion, features, logger, -}: InitConfigInputs): Promise { +}: InitConfigInputs): Promise< + Config & { augmentationProperties: AugmentationProperties } +> { const analysisKinds = await parseAnalysisKinds(analysisKindsInput); // For backwards compatibility, add Code Quality to the enabled analysis kinds @@ -1104,14 +1100,14 @@ export async function initConfig(inputs: InitConfigInputs): Promise { ); } - const config = await getDefaultConfig(inputs); + const { augmentationProperties, ...config } = await getDefaultConfig(inputs); config.originalUserInput = userConfig; // Compute the full Code Scanning configuration that combines the configuration from the // configuration file / `config` input with other inputs, such as `queries`. config.computedConfig = generateCodeScanningConfig( userConfig, - config.augmentationProperties, + augmentationProperties, ); // The choice of overlay database mode depends on the selection of languages diff --git a/src/testing-utils.ts b/src/testing-utils.ts index 6e1763b00f..a12c995851 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -11,7 +11,7 @@ import * as apiClient from "./api-client"; import { GitHubApiDetails } from "./api-client"; import { CachingKind } from "./caching-utils"; import * as codeql from "./codeql"; -import { AugmentationProperties, Config } from "./config-utils"; +import { Config } from "./config-utils"; import * as defaults from "./defaults.json"; import { CodeQLDefaultVersionInfo, @@ -370,10 +370,6 @@ export function createTestConfig(overrides: Partial): Config { debugMode: false, debugArtifactName: DEFAULT_DEBUG_ARTIFACT_NAME, debugDatabaseName: DEFAULT_DEBUG_DATABASE_NAME, - augmentationProperties: { - packsInputCombines: false, - queriesInputCombines: false, - } satisfies AugmentationProperties, trapCaches: {}, trapCacheDownloadTime: 0, dependencyCachingEnabled: CachingKind.None, From 0fb047d929b48f67b01e5ac61a84b33658c33fad Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 09:55:00 +0100 Subject: [PATCH 3/8] Set user-provided `UserConfig` in `getDefaultConfig` --- lib/init-action.js | 9 ++++--- src/config-utils.test.ts | 1 + src/config-utils.ts | 55 +++++++++++++++++++++------------------- 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index ac9358f219..b61db8292f 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -87258,7 +87258,7 @@ async function getDefaultConfig({ githubVersion, features, logger -}) { +}, userConfig) { const analysisKinds = await parseAnalysisKinds(analysisKindsInput); if (!analysisKinds.includes("code-quality" /* CodeQuality */) && qualityQueriesInput !== void 0) { analysisKinds.push("code-quality" /* CodeQuality */); @@ -87291,7 +87291,7 @@ async function getDefaultConfig({ analysisKinds, languages, buildMode, - originalUserInput: {}, + originalUserInput: userConfig, computedConfig: {}, tempDir, codeQLCmd: codeql.getPath(), @@ -87601,7 +87601,10 @@ async function initConfig(inputs) { tempDir ); } - const { augmentationProperties, ...config } = await getDefaultConfig(inputs); + const { augmentationProperties, ...config } = await getDefaultConfig( + inputs, + userConfig + ); config.originalUserInput = userConfig; config.computedConfig = generateCodeScanningConfig( userConfig, diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index a67e3cf653..5bcfcf1e2d 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -166,6 +166,7 @@ test("load empty config", async (t) => { codeql, logger, }), + {}, ); t.deepEqual(config, expectedConfig); diff --git a/src/config-utils.ts b/src/config-utils.ts index e8c97a854c..69ae4c7cfc 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -510,29 +510,30 @@ export interface InitConfigInputs { /** * Get the default config, populated without user configuration file. */ -export async function getDefaultConfig({ - analysisKindsInput, - languagesInput, - queriesInput, - qualityQueriesInput, - packsInput, - buildModeInput, - dbLocation, - trapCachingEnabled, - dependencyCachingEnabled, - debugMode, - debugArtifactName, - debugDatabaseName, - repository, - tempDir, - codeql, - sourceRoot, - githubVersion, - features, - logger, -}: InitConfigInputs): Promise< - Config & { augmentationProperties: AugmentationProperties } -> { +export async function getDefaultConfig( + { + analysisKindsInput, + languagesInput, + queriesInput, + qualityQueriesInput, + packsInput, + buildModeInput, + dbLocation, + trapCachingEnabled, + dependencyCachingEnabled, + debugMode, + debugArtifactName, + debugDatabaseName, + repository, + tempDir, + codeql, + sourceRoot, + githubVersion, + features, + logger, + }: InitConfigInputs, + userConfig: UserConfig, +): Promise { const analysisKinds = await parseAnalysisKinds(analysisKindsInput); // For backwards compatibility, add Code Quality to the enabled analysis kinds @@ -577,7 +578,7 @@ export async function getDefaultConfig({ analysisKinds, languages, buildMode, - originalUserInput: {}, + originalUserInput: userConfig, computedConfig: {}, tempDir, codeQLCmd: codeql.getPath(), @@ -1100,8 +1101,10 @@ export async function initConfig(inputs: InitConfigInputs): Promise { ); } - const { augmentationProperties, ...config } = await getDefaultConfig(inputs); - config.originalUserInput = userConfig; + const { augmentationProperties, ...config } = await getDefaultConfig( + inputs, + userConfig, + ); // Compute the full Code Scanning configuration that combines the configuration from the // configuration file / `config` input with other inputs, such as `queries`. From 8d623f4184c9c6a6252b3de9d3f6f0b79b033e34 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 09:57:29 +0100 Subject: [PATCH 4/8] Populate `computedConfig` in `getDefaultConfig` --- lib/init-action.js | 17 ++++++----------- src/config-utils.test.ts | 20 +++++++++----------- src/config-utils.ts | 24 ++++++++++-------------- 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index b61db8292f..ccfd602058 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -87287,12 +87287,16 @@ async function getDefaultConfig({ languages, logger ); + const computedConfig = generateCodeScanningConfig( + userConfig, + augmentationProperties + ); return { analysisKinds, languages, buildMode, originalUserInput: userConfig, - computedConfig: {}, + computedConfig, tempDir, codeQLCmd: codeql.getPath(), gitHubVersion: githubVersion, @@ -87300,7 +87304,6 @@ async function getDefaultConfig({ debugMode, debugArtifactName, debugDatabaseName, - augmentationProperties, trapCaches, trapCacheDownloadTime, dependencyCachingEnabled: getCachingKind(dependencyCachingEnabled), @@ -87601,15 +87604,7 @@ async function initConfig(inputs) { tempDir ); } - const { augmentationProperties, ...config } = await getDefaultConfig( - inputs, - userConfig - ); - config.originalUserInput = userConfig; - config.computedConfig = generateCodeScanningConfig( - userConfig, - augmentationProperties - ); + const config = await getDefaultConfig(inputs, userConfig); const { overlayDatabaseMode, useOverlayDatabaseCaching } = await getOverlayDatabaseMode( inputs.codeql, inputs.repository, diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 5bcfcf1e2d..98b5491ad2 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -157,17 +157,15 @@ test("load empty config", async (t) => { }), ); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { augmentationProperties, ...expectedConfig } = - await configUtils.getDefaultConfig( - createTestInitConfigInputs({ - languagesInput: languages, - tempDir, - codeql, - logger, - }), - {}, - ); + const expectedConfig = await configUtils.getDefaultConfig( + createTestInitConfigInputs({ + languagesInput: languages, + tempDir, + codeql, + logger, + }), + {}, + ); t.deepEqual(config, expectedConfig); }); diff --git a/src/config-utils.ts b/src/config-utils.ts index 69ae4c7cfc..af768ad114 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -533,7 +533,7 @@ export async function getDefaultConfig( logger, }: InitConfigInputs, userConfig: UserConfig, -): Promise { +): Promise { const analysisKinds = await parseAnalysisKinds(analysisKindsInput); // For backwards compatibility, add Code Quality to the enabled analysis kinds @@ -574,12 +574,19 @@ export async function getDefaultConfig( logger, ); + // Compute the full Code Scanning configuration that combines the configuration from the + // configuration file / `config` input with other inputs, such as `queries`. + const computedConfig = generateCodeScanningConfig( + userConfig, + augmentationProperties, + ); + return { analysisKinds, languages, buildMode, originalUserInput: userConfig, - computedConfig: {}, + computedConfig, tempDir, codeQLCmd: codeql.getPath(), gitHubVersion: githubVersion, @@ -587,7 +594,6 @@ export async function getDefaultConfig( debugMode, debugArtifactName, debugDatabaseName, - augmentationProperties, trapCaches, trapCacheDownloadTime, dependencyCachingEnabled: getCachingKind(dependencyCachingEnabled), @@ -1101,17 +1107,7 @@ export async function initConfig(inputs: InitConfigInputs): Promise { ); } - const { augmentationProperties, ...config } = await getDefaultConfig( - inputs, - userConfig, - ); - - // Compute the full Code Scanning configuration that combines the configuration from the - // configuration file / `config` input with other inputs, such as `queries`. - config.computedConfig = generateCodeScanningConfig( - userConfig, - augmentationProperties, - ); + const config = await getDefaultConfig(inputs, userConfig); // The choice of overlay database mode depends on the selection of languages // and queries, which in turn depends on the user config and the augmentation From f2e20f52e0afc1acc15601808782eb3495331ec9 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 10:01:17 +0100 Subject: [PATCH 5/8] Rename `getDefaultConfig` and update doc comment --- lib/init-action.js | 4 ++-- src/config-utils.test.ts | 2 +- src/config-utils.ts | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index ccfd602058..af7beae481 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -87238,7 +87238,7 @@ async function getRawLanguages(languagesInput, repository, sourceRoot, logger) { autodetected: true }; } -async function getDefaultConfig({ +async function initActionState({ analysisKindsInput, languagesInput, queriesInput, @@ -87604,7 +87604,7 @@ async function initConfig(inputs) { tempDir ); } - const config = await getDefaultConfig(inputs, userConfig); + const config = await initActionState(inputs, userConfig); const { overlayDatabaseMode, useOverlayDatabaseCaching } = await getOverlayDatabaseMode( inputs.codeql, inputs.repository, diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 98b5491ad2..c78ba6a33d 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -157,7 +157,7 @@ test("load empty config", async (t) => { }), ); - const expectedConfig = await configUtils.getDefaultConfig( + const expectedConfig = await configUtils.initActionState( createTestInitConfigInputs({ languagesInput: languages, tempDir, diff --git a/src/config-utils.ts b/src/config-utils.ts index af768ad114..66e50e74d0 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -508,9 +508,10 @@ export interface InitConfigInputs { } /** - * Get the default config, populated without user configuration file. + * Initialise the CodeQL Action state, which includes the base configuration for the Action + * and computes the configuration for the CodeQL CLI. */ -export async function getDefaultConfig( +export async function initActionState( { analysisKindsInput, languagesInput, @@ -1107,7 +1108,7 @@ export async function initConfig(inputs: InitConfigInputs): Promise { ); } - const config = await getDefaultConfig(inputs, userConfig); + const config = await initActionState(inputs, userConfig); // The choice of overlay database mode depends on the selection of languages // and queries, which in turn depends on the user config and the augmentation From da9299646d7be37ceddc8a4d40e568d80ffb158e Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 10:06:34 +0100 Subject: [PATCH 6/8] Move `InitStatusReport` types to `status-report.ts` --- src/init-action.ts | 45 ++------------------------------------------ src/status-report.ts | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/init-action.ts b/src/init-action.ts index 637fd2c3da..33914c6cdd 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -51,7 +51,8 @@ import { getRepositoryNwo } from "./repository"; import { ToolsSource } from "./setup-codeql"; import { ActionName, - StatusReportBase, + InitStatusReport, + InitWithConfigStatusReport, createStatusReportBase, getActionsStatus, sendStatusReport, @@ -78,48 +79,6 @@ import { getErrorMessage, } from "./util"; import { validateWorkflow } from "./workflow"; -/** Fields of the init status report that can be sent before `config` is populated. */ -interface InitStatusReport extends StatusReportBase { - /** Value given by the user as the "tools" input. */ - tools_input: string; - /** Version of the bundle used. */ - tools_resolved_version: string; - /** Where the bundle originated from. */ - tools_source: ToolsSource; - /** Comma-separated list of languages specified explicitly in the workflow file. */ - workflow_languages: string; -} - -/** Fields of the init status report that are populated using values from `config`. */ -interface InitWithConfigStatusReport extends InitStatusReport { - /** Comma-separated list of languages where the default queries are disabled. */ - disable_default_queries: string; - /** Comma-separated list of paths, from the 'paths' config field. */ - paths: string; - /** Comma-separated list of paths, from the 'paths-ignore' config field. */ - paths_ignore: string; - /** Comma-separated list of queries sources, from the 'queries' config field or workflow input. */ - queries: string; - /** Stringified JSON object of packs, from the 'packs' config field or workflow input. */ - packs: string; - /** Comma-separated list of languages for which we are using TRAP caching. */ - trap_cache_languages: string; - /** Size of TRAP caches that we downloaded, in bytes. */ - trap_cache_download_size_bytes: number; - /** Time taken to download TRAP caches, in milliseconds. */ - trap_cache_download_duration_ms: number; - /** Size of the overlay-base database that we downloaded, in bytes. */ - overlay_base_database_download_size_bytes?: number; - /** Time taken to download the overlay-base database, in milliseconds. */ - overlay_base_database_download_duration_ms?: number; - /** Stringified JSON array of registry configuration objects, from the 'registries' config field - or workflow input. **/ - registries: string; - /** Stringified JSON object representing a query-filters, from the 'query-filters' config field. **/ - query_filters: string; - /** Path to the specified code scanning config file, from the 'config-file' config field. */ - config_file: string; -} /** Fields of the init status report populated when the tools source is `download`. */ interface InitToolsDownloadFields { diff --git a/src/status-report.ts b/src/status-report.ts index e75698e9e0..336ae4676c 100644 --- a/src/status-report.ts +++ b/src/status-report.ts @@ -18,6 +18,7 @@ import { EnvVar } from "./environment"; import { getRef } from "./git-utils"; import { Logger } from "./logging"; import { getRepositoryNwo } from "./repository"; +import { ToolsSource } from "./setup-codeql"; import { ConfigurationError, isHTTPError, @@ -460,3 +461,46 @@ export async function sendStatusReport( ); } } + +/** Fields of the init status report that can be sent before `config` is populated. */ +export interface InitStatusReport extends StatusReportBase { + /** Value given by the user as the "tools" input. */ + tools_input: string; + /** Version of the bundle used. */ + tools_resolved_version: string; + /** Where the bundle originated from. */ + tools_source: ToolsSource; + /** Comma-separated list of languages specified explicitly in the workflow file. */ + workflow_languages: string; +} + +/** Fields of the init status report that are populated using values from `config`. */ +export interface InitWithConfigStatusReport extends InitStatusReport { + /** Comma-separated list of languages where the default queries are disabled. */ + disable_default_queries: string; + /** Comma-separated list of paths, from the 'paths' config field. */ + paths: string; + /** Comma-separated list of paths, from the 'paths-ignore' config field. */ + paths_ignore: string; + /** Comma-separated list of queries sources, from the 'queries' config field or workflow input. */ + queries: string; + /** Stringified JSON object of packs, from the 'packs' config field or workflow input. */ + packs: string; + /** Comma-separated list of languages for which we are using TRAP caching. */ + trap_cache_languages: string; + /** Size of TRAP caches that we downloaded, in bytes. */ + trap_cache_download_size_bytes: number; + /** Time taken to download TRAP caches, in milliseconds. */ + trap_cache_download_duration_ms: number; + /** Size of the overlay-base database that we downloaded, in bytes. */ + overlay_base_database_download_size_bytes?: number; + /** Time taken to download the overlay-base database, in milliseconds. */ + overlay_base_database_download_duration_ms?: number; + /** Stringified JSON array of registry configuration objects, from the 'registries' config field + or workflow input. **/ + registries: string; + /** Stringified JSON object representing a query-filters, from the 'query-filters' config field. **/ + query_filters: string; + /** Path to the specified code scanning config file, from the 'config-file' config field. */ + config_file: string; +} From 37ddb03e0d7f9f4f374a33bd14142694e5c89b0b Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 10:16:25 +0100 Subject: [PATCH 7/8] Add `createInitWithConfigStatusReport` function --- lib/init-action.js | 97 ++++++++-------- lib/upload-sarif-action.js | 230 +++++++++++++++++++------------------ src/init-action.ts | 69 ++--------- src/status-report.ts | 76 +++++++++++- 4 files changed, 254 insertions(+), 218 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index af7beae481..4dfe82bc41 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -89988,6 +89988,51 @@ async function sendStatusReport(statusReport) { ); } } +async function createInitWithConfigStatusReport(config, initStatusReport, configFile, totalCacheSize, overlayBaseDatabaseStats) { + const languages = config.languages.join(","); + const paths = (config.originalUserInput.paths || []).join(","); + const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join( + "," + ); + const disableDefaultQueries = config.originalUserInput["disable-default-queries"] ? languages : ""; + const queries = []; + let queriesInput = getOptionalInput("queries")?.trim(); + if (queriesInput === void 0 || queriesInput.startsWith("+")) { + queries.push( + ...(config.originalUserInput.queries || []).map((q) => q.uses) + ); + } + if (queriesInput !== void 0) { + queriesInput = queriesInput.startsWith("+") ? queriesInput.slice(1) : queriesInput; + queries.push(...queriesInput.split(",")); + } + let packs = {}; + if (Array.isArray(config.computedConfig.packs)) { + packs[config.languages[0]] = config.computedConfig.packs; + } else if (config.computedConfig.packs !== void 0) { + packs = config.computedConfig.packs; + } + return { + ...initStatusReport, + config_file: configFile ?? "", + disable_default_queries: disableDefaultQueries, + paths, + paths_ignore: pathsIgnore, + queries: queries.join(","), + packs: JSON.stringify(packs), + trap_cache_languages: Object.keys(config.trapCaches).join(","), + trap_cache_download_size_bytes: totalCacheSize, + trap_cache_download_duration_ms: Math.round(config.trapCacheDownloadTime), + overlay_base_database_download_size_bytes: overlayBaseDatabaseStats?.databaseSizeBytes, + overlay_base_database_download_duration_ms: overlayBaseDatabaseStats?.databaseDownloadDurationMs, + query_filters: JSON.stringify( + config.originalUserInput["query-filters"] ?? [] + ), + registries: JSON.stringify( + parseRegistriesWithoutCredentials(getOptionalInput("registries")) ?? [] + ) + }; +} // src/workflow.ts var fs16 = __toESM(require("fs")); @@ -90175,53 +90220,15 @@ async function sendCompletedStatusReport(startedAt, config, configFile, toolsDow initToolsDownloadFields.tools_feature_flags_valid = toolsFeatureFlagsValid; } if (config !== void 0) { - const languages = config.languages.join(","); - const paths = (config.originalUserInput.paths || []).join(","); - const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join( - "," - ); - const disableDefaultQueries = config.originalUserInput["disable-default-queries"] ? languages : ""; - const queries = []; - let queriesInput = getOptionalInput("queries")?.trim(); - if (queriesInput === void 0 || queriesInput.startsWith("+")) { - queries.push( - ...(config.originalUserInput.queries || []).map((q) => q.uses) - ); - } - if (queriesInput !== void 0) { - queriesInput = queriesInput.startsWith("+") ? queriesInput.slice(1) : queriesInput; - queries.push(...queriesInput.split(",")); - } - let packs = {}; - if (Array.isArray(config.computedConfig.packs)) { - packs[config.languages[0]] = config.computedConfig.packs; - } else if (config.computedConfig.packs !== void 0) { - packs = config.computedConfig.packs; - } - const initWithConfigStatusReport = { - ...initStatusReport, - config_file: configFile ?? "", - disable_default_queries: disableDefaultQueries, - paths, - paths_ignore: pathsIgnore, - queries: queries.join(","), - packs: JSON.stringify(packs), - trap_cache_languages: Object.keys(config.trapCaches).join(","), - trap_cache_download_size_bytes: Math.round( + const initWithConfigStatusReport = await createInitWithConfigStatusReport( + config, + initStatusReport, + configFile, + Math.round( await getTotalCacheSize(Object.values(config.trapCaches), logger) ), - trap_cache_download_duration_ms: Math.round(config.trapCacheDownloadTime), - overlay_base_database_download_size_bytes: overlayBaseDatabaseStats?.databaseSizeBytes, - overlay_base_database_download_duration_ms: overlayBaseDatabaseStats?.databaseDownloadDurationMs, - query_filters: JSON.stringify( - config.originalUserInput["query-filters"] ?? [] - ), - registries: JSON.stringify( - parseRegistriesWithoutCredentials( - getOptionalInput("registries") - ) ?? [] - ) - }; + overlayBaseDatabaseStats + ); await sendStatusReport({ ...initWithConfigStatusReport, ...initToolsDownloadFields diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index a1ba491b14..3bef471000 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -89580,7 +89580,111 @@ var GitHubFeatureFlags = class { // src/status-report.ts var os = __toESM(require("os")); +var core9 = __toESM(require_core()); + +// src/config-utils.ts +var fs8 = __toESM(require("fs")); +var path10 = __toESM(require("path")); +var semver4 = __toESM(require_semver2()); + +// src/analyses.ts +var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { + AnalysisKind2["CodeScanning"] = "code-scanning"; + AnalysisKind2["CodeQuality"] = "code-quality"; + return AnalysisKind2; +})(AnalysisKind || {}); +var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); + +// src/caching-utils.ts var core8 = __toESM(require_core()); + +// src/diff-informed-analysis-utils.ts +var fs7 = __toESM(require("fs")); +var path9 = __toESM(require("path")); +function getDiffRangesJsonFilePath() { + return path9.join(getTemporaryDirectory(), "pr-diff-range.json"); +} +function readDiffRangesJsonFile(logger) { + const jsonFilePath = getDiffRangesJsonFilePath(); + if (!fs7.existsSync(jsonFilePath)) { + logger.debug(`Diff ranges JSON file does not exist at ${jsonFilePath}`); + return void 0; + } + const jsonContents = fs7.readFileSync(jsonFilePath, "utf8"); + logger.debug( + `Read pr-diff-range JSON file from ${jsonFilePath}: +${jsonContents}` + ); + return JSON.parse(jsonContents); +} + +// src/trap-caching.ts +var actionsCache2 = __toESM(require_cache3()); + +// src/config-utils.ts +var OVERLAY_ANALYSIS_FEATURES = { + actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, + cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, + csharp: "overlay_analysis_csharp" /* OverlayAnalysisCsharp */, + go: "overlay_analysis_go" /* OverlayAnalysisGo */, + java: "overlay_analysis_java" /* OverlayAnalysisJava */, + javascript: "overlay_analysis_javascript" /* OverlayAnalysisJavascript */, + python: "overlay_analysis_python" /* OverlayAnalysisPython */, + ruby: "overlay_analysis_ruby" /* OverlayAnalysisRuby */, + rust: "overlay_analysis_rust" /* OverlayAnalysisRust */, + swift: "overlay_analysis_swift" /* OverlayAnalysisSwift */ +}; +var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { + actions: "overlay_analysis_code_scanning_actions" /* OverlayAnalysisCodeScanningActions */, + cpp: "overlay_analysis_code_scanning_cpp" /* OverlayAnalysisCodeScanningCpp */, + csharp: "overlay_analysis_code_scanning_csharp" /* OverlayAnalysisCodeScanningCsharp */, + go: "overlay_analysis_code_scanning_go" /* OverlayAnalysisCodeScanningGo */, + java: "overlay_analysis_code_scanning_java" /* OverlayAnalysisCodeScanningJava */, + javascript: "overlay_analysis_code_scanning_javascript" /* OverlayAnalysisCodeScanningJavascript */, + python: "overlay_analysis_code_scanning_python" /* OverlayAnalysisCodeScanningPython */, + ruby: "overlay_analysis_code_scanning_ruby" /* OverlayAnalysisCodeScanningRuby */, + rust: "overlay_analysis_code_scanning_rust" /* OverlayAnalysisCodeScanningRust */, + swift: "overlay_analysis_code_scanning_swift" /* OverlayAnalysisCodeScanningSwift */ +}; +var PACK_IDENTIFIER_PATTERN = (function() { + const alphaNumeric = "[a-z0-9]"; + const alphaNumericDash = "[a-z0-9-]"; + const component = `${alphaNumeric}(${alphaNumericDash}*${alphaNumeric})?`; + return new RegExp(`^${component}/${component}$`); +})(); +function getPathToParsedConfigFile(tempDir) { + return path10.join(tempDir, "config"); +} +async function getConfig(tempDir, logger) { + const configFile = getPathToParsedConfigFile(tempDir); + if (!fs8.existsSync(configFile)) { + return void 0; + } + const configString = fs8.readFileSync(configFile, "utf8"); + logger.debug("Loaded config:"); + logger.debug(configString); + return JSON.parse(configString); +} +function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { + const augmentedConfig = cloneObject(cliConfig); + if (extraQueryExclusions.length === 0) { + return augmentedConfig; + } + augmentedConfig["query-filters"] = [ + // Ordering matters. If the first filter is an inclusion, it implicitly + // excludes all queries that are not included. If it is an exclusion, + // it implicitly includes all queries that are not excluded. So user + // filters (if any) should always be first to preserve intent. + ...augmentedConfig["query-filters"] || [], + ...extraQueryExclusions + ]; + if (augmentedConfig["query-filters"]?.length === 0) { + delete augmentedConfig["query-filters"]; + } + return augmentedConfig; +} + +// src/status-report.ts function isFirstPartyAnalysis(actionName) { if (actionName !== "upload-sarif" /* UploadSarif */) { return true; @@ -89599,12 +89703,12 @@ function getActionsStatus(error2, otherFailureCause) { } function setJobStatusIfUnsuccessful(actionStatus) { if (actionStatus === "user-error") { - core8.exportVariable( + core9.exportVariable( "CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */] ?? "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */ ); } else if (actionStatus === "failure" || actionStatus === "aborted") { - core8.exportVariable( + core9.exportVariable( "CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */] ?? "JOB_STATUS_FAILURE" /* FailureStatus */ ); @@ -89623,14 +89727,14 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi let workflowStartedAt = process.env["CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */]; if (workflowStartedAt === void 0) { workflowStartedAt = actionStartedAt.toISOString(); - core8.exportVariable("CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */, workflowStartedAt); + core9.exportVariable("CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */, workflowStartedAt); } const runnerOs = getRequiredEnvParam("RUNNER_OS"); const codeQlCliVersion = getCachedCodeQlVersion(); const actionRef = process.env["GITHUB_ACTION_REF"] || ""; const testingEnvironment = getTestingEnvironment(); if (testingEnvironment) { - core8.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment); + core9.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment); } const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true"; const statusReport = { @@ -89708,9 +89812,9 @@ var INCOMPATIBLE_MSG = "CodeQL Action version is incompatible with the code scan async function sendStatusReport(statusReport) { setJobStatusIfUnsuccessful(statusReport.status); const statusReportJSON = JSON.stringify(statusReport); - core8.debug(`Sending status report: ${statusReportJSON}`); + core9.debug(`Sending status report: ${statusReportJSON}`); if (isInTestMode()) { - core8.debug("In test mode. Status reports are not uploaded."); + core9.debug("In test mode. Status reports are not uploaded."); return; } const nwo = getRepositoryNwo(); @@ -89729,26 +89833,26 @@ async function sendStatusReport(statusReport) { switch (e.status) { case 403: if (getWorkflowEventName() === "push" && process.env["GITHUB_ACTOR"] === "dependabot[bot]") { - core8.warning( + core9.warning( `Workflows triggered by Dependabot on the "push" event run with read-only access. Uploading Code Scanning results requires write access. To use Code Scanning with Dependabot, please ensure you are using the "pull_request" event for this workflow and avoid triggering on the "push" event for Dependabot branches. See ${"https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#scanning-on-push" /* SCANNING_ON_PUSH */} for more information on how to configure these events.` ); } else { - core8.warning(e.message); + core9.warning(e.message); } return; case 404: - core8.warning(e.message); + core9.warning(e.message); return; case 422: if (getRequiredEnvParam("GITHUB_SERVER_URL") !== GITHUB_DOTCOM_URL) { - core8.debug(INCOMPATIBLE_MSG); + core9.debug(INCOMPATIBLE_MSG); } else { - core8.debug(OUT_OF_DATE_MSG); + core9.debug(OUT_OF_DATE_MSG); } return; } } - core8.warning( + core9.warning( `An unexpected error occurred when sending code scanning status report: ${getErrorMessage( e )}` @@ -90007,108 +90111,6 @@ function wrapCliConfigurationError(cliError) { return new ConfigurationError(errorMessageBuilder); } -// src/config-utils.ts -var fs8 = __toESM(require("fs")); -var path10 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); - -// src/analyses.ts -var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { - AnalysisKind2["CodeScanning"] = "code-scanning"; - AnalysisKind2["CodeQuality"] = "code-quality"; - return AnalysisKind2; -})(AnalysisKind || {}); -var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); - -// src/caching-utils.ts -var core9 = __toESM(require_core()); - -// src/diff-informed-analysis-utils.ts -var fs7 = __toESM(require("fs")); -var path9 = __toESM(require("path")); -function getDiffRangesJsonFilePath() { - return path9.join(getTemporaryDirectory(), "pr-diff-range.json"); -} -function readDiffRangesJsonFile(logger) { - const jsonFilePath = getDiffRangesJsonFilePath(); - if (!fs7.existsSync(jsonFilePath)) { - logger.debug(`Diff ranges JSON file does not exist at ${jsonFilePath}`); - return void 0; - } - const jsonContents = fs7.readFileSync(jsonFilePath, "utf8"); - logger.debug( - `Read pr-diff-range JSON file from ${jsonFilePath}: -${jsonContents}` - ); - return JSON.parse(jsonContents); -} - -// src/trap-caching.ts -var actionsCache2 = __toESM(require_cache3()); - -// src/config-utils.ts -var OVERLAY_ANALYSIS_FEATURES = { - actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, - cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, - csharp: "overlay_analysis_csharp" /* OverlayAnalysisCsharp */, - go: "overlay_analysis_go" /* OverlayAnalysisGo */, - java: "overlay_analysis_java" /* OverlayAnalysisJava */, - javascript: "overlay_analysis_javascript" /* OverlayAnalysisJavascript */, - python: "overlay_analysis_python" /* OverlayAnalysisPython */, - ruby: "overlay_analysis_ruby" /* OverlayAnalysisRuby */, - rust: "overlay_analysis_rust" /* OverlayAnalysisRust */, - swift: "overlay_analysis_swift" /* OverlayAnalysisSwift */ -}; -var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { - actions: "overlay_analysis_code_scanning_actions" /* OverlayAnalysisCodeScanningActions */, - cpp: "overlay_analysis_code_scanning_cpp" /* OverlayAnalysisCodeScanningCpp */, - csharp: "overlay_analysis_code_scanning_csharp" /* OverlayAnalysisCodeScanningCsharp */, - go: "overlay_analysis_code_scanning_go" /* OverlayAnalysisCodeScanningGo */, - java: "overlay_analysis_code_scanning_java" /* OverlayAnalysisCodeScanningJava */, - javascript: "overlay_analysis_code_scanning_javascript" /* OverlayAnalysisCodeScanningJavascript */, - python: "overlay_analysis_code_scanning_python" /* OverlayAnalysisCodeScanningPython */, - ruby: "overlay_analysis_code_scanning_ruby" /* OverlayAnalysisCodeScanningRuby */, - rust: "overlay_analysis_code_scanning_rust" /* OverlayAnalysisCodeScanningRust */, - swift: "overlay_analysis_code_scanning_swift" /* OverlayAnalysisCodeScanningSwift */ -}; -var PACK_IDENTIFIER_PATTERN = (function() { - const alphaNumeric = "[a-z0-9]"; - const alphaNumericDash = "[a-z0-9-]"; - const component = `${alphaNumeric}(${alphaNumericDash}*${alphaNumeric})?`; - return new RegExp(`^${component}/${component}$`); -})(); -function getPathToParsedConfigFile(tempDir) { - return path10.join(tempDir, "config"); -} -async function getConfig(tempDir, logger) { - const configFile = getPathToParsedConfigFile(tempDir); - if (!fs8.existsSync(configFile)) { - return void 0; - } - const configString = fs8.readFileSync(configFile, "utf8"); - logger.debug("Loaded config:"); - logger.debug(configString); - return JSON.parse(configString); -} -function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { - const augmentedConfig = cloneObject(cliConfig); - if (extraQueryExclusions.length === 0) { - return augmentedConfig; - } - augmentedConfig["query-filters"] = [ - // Ordering matters. If the first filter is an inclusion, it implicitly - // excludes all queries that are not included. If it is an exclusion, - // it implicitly includes all queries that are not excluded. So user - // filters (if any) should always be first to preserve intent. - ...augmentedConfig["query-filters"] || [], - ...extraQueryExclusions - ]; - if (augmentedConfig["query-filters"]?.length === 0) { - delete augmentedConfig["query-filters"]; - } - return augmentedConfig; -} - // src/setup-codeql.ts var fs11 = __toESM(require("fs")); var path12 = __toESM(require("path")); diff --git a/src/init-action.ts b/src/init-action.ts index 33914c6cdd..8c9e2f36b8 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -53,6 +53,7 @@ import { ActionName, InitStatusReport, InitWithConfigStatusReport, + createInitWithConfigStatusReport, createStatusReportBase, getActionsStatus, sendStatusReport, @@ -138,65 +139,17 @@ async function sendCompletedStatusReport( } if (config !== undefined) { - const languages = config.languages.join(","); - const paths = (config.originalUserInput.paths || []).join(","); - const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join( - ",", - ); - const disableDefaultQueries = config.originalUserInput[ - "disable-default-queries" - ] - ? languages - : ""; - - const queries: string[] = []; - let queriesInput = getOptionalInput("queries")?.trim(); - if (queriesInput === undefined || queriesInput.startsWith("+")) { - queries.push( - ...(config.originalUserInput.queries || []).map((q) => q.uses), - ); - } - if (queriesInput !== undefined) { - queriesInput = queriesInput.startsWith("+") - ? queriesInput.slice(1) - : queriesInput; - queries.push(...queriesInput.split(",")); - } - - let packs: Record = {}; - if (Array.isArray(config.computedConfig.packs)) { - packs[config.languages[0]] = config.computedConfig.packs; - } else if (config.computedConfig.packs !== undefined) { - packs = config.computedConfig.packs; - } - // Append fields that are dependent on `config` - const initWithConfigStatusReport: InitWithConfigStatusReport = { - ...initStatusReport, - config_file: configFile ?? "", - disable_default_queries: disableDefaultQueries, - paths, - paths_ignore: pathsIgnore, - queries: queries.join(","), - packs: JSON.stringify(packs), - trap_cache_languages: Object.keys(config.trapCaches).join(","), - trap_cache_download_size_bytes: Math.round( - await getTotalCacheSize(Object.values(config.trapCaches), logger), - ), - trap_cache_download_duration_ms: Math.round(config.trapCacheDownloadTime), - overlay_base_database_download_size_bytes: - overlayBaseDatabaseStats?.databaseSizeBytes, - overlay_base_database_download_duration_ms: - overlayBaseDatabaseStats?.databaseDownloadDurationMs, - query_filters: JSON.stringify( - config.originalUserInput["query-filters"] ?? [], - ), - registries: JSON.stringify( - configUtils.parseRegistriesWithoutCredentials( - getOptionalInput("registries"), - ) ?? [], - ), - }; + const initWithConfigStatusReport: InitWithConfigStatusReport = + await createInitWithConfigStatusReport( + config, + initStatusReport, + configFile, + Math.round( + await getTotalCacheSize(Object.values(config.trapCaches), logger), + ), + overlayBaseDatabaseStats, + ); await sendStatusReport({ ...initWithConfigStatusReport, ...initToolsDownloadFields, diff --git a/src/status-report.ts b/src/status-report.ts index 336ae4676c..75f4002214 100644 --- a/src/status-report.ts +++ b/src/status-report.ts @@ -12,11 +12,12 @@ import { isSelfHostedRunner, } from "./actions-util"; import { getAnalysisKey, getApiClient } from "./api-client"; -import { type Config } from "./config-utils"; +import { parseRegistriesWithoutCredentials, type Config } from "./config-utils"; import { DocUrl } from "./doc-url"; import { EnvVar } from "./environment"; import { getRef } from "./git-utils"; import { Logger } from "./logging"; +import { OverlayBaseDatabaseDownloadStats } from "./overlay-database-utils"; import { getRepositoryNwo } from "./repository"; import { ToolsSource } from "./setup-codeql"; import { @@ -504,3 +505,76 @@ export interface InitWithConfigStatusReport extends InitStatusReport { /** Path to the specified code scanning config file, from the 'config-file' config field. */ config_file: string; } + +/** + * Composes a `InitWithConfigStatusReport` from the given values. + * + * @param config The CodeQL Action configuration whose values should be added to the base status report. + * @param initStatusReport The base status report. + * @param configFile Optionally, the filename of the configuration file that was read. + * @param totalCacheSize The computed total TRAP cache size. + * @param overlayBaseDatabaseStats Statistics about the overlay database, if any. + * @returns + */ +export async function createInitWithConfigStatusReport( + config: Config, + initStatusReport: InitStatusReport, + configFile: string | undefined, + totalCacheSize: number, + overlayBaseDatabaseStats: OverlayBaseDatabaseDownloadStats | undefined, +): Promise { + const languages = config.languages.join(","); + const paths = (config.originalUserInput.paths || []).join(","); + const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join( + ",", + ); + const disableDefaultQueries = config.originalUserInput[ + "disable-default-queries" + ] + ? languages + : ""; + + const queries: string[] = []; + let queriesInput = getOptionalInput("queries")?.trim(); + if (queriesInput === undefined || queriesInput.startsWith("+")) { + queries.push( + ...(config.originalUserInput.queries || []).map((q) => q.uses), + ); + } + if (queriesInput !== undefined) { + queriesInput = queriesInput.startsWith("+") + ? queriesInput.slice(1) + : queriesInput; + queries.push(...queriesInput.split(",")); + } + + let packs: Record = {}; + if (Array.isArray(config.computedConfig.packs)) { + packs[config.languages[0]] = config.computedConfig.packs; + } else if (config.computedConfig.packs !== undefined) { + packs = config.computedConfig.packs; + } + + return { + ...initStatusReport, + config_file: configFile ?? "", + disable_default_queries: disableDefaultQueries, + paths, + paths_ignore: pathsIgnore, + queries: queries.join(","), + packs: JSON.stringify(packs), + trap_cache_languages: Object.keys(config.trapCaches).join(","), + trap_cache_download_size_bytes: totalCacheSize, + trap_cache_download_duration_ms: Math.round(config.trapCacheDownloadTime), + overlay_base_database_download_size_bytes: + overlayBaseDatabaseStats?.databaseSizeBytes, + overlay_base_database_download_duration_ms: + overlayBaseDatabaseStats?.databaseDownloadDurationMs, + query_filters: JSON.stringify( + config.originalUserInput["query-filters"] ?? [], + ), + registries: JSON.stringify( + parseRegistriesWithoutCredentials(getOptionalInput("registries")) ?? [], + ), + }; +} From 920bba1769f279c4373d93131c769e74bc258100 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 10:59:23 +0100 Subject: [PATCH 8/8] Add unit tests for `createInitWithConfigStatusReport` --- src/status-report.test.ts | 105 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/src/status-report.test.ts b/src/status-report.test.ts index 9a61fcee08..0d3292637c 100644 --- a/src/status-report.test.ts +++ b/src/status-report.test.ts @@ -2,13 +2,18 @@ import test from "ava"; import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; +import { Config } from "./config-utils"; import { EnvVar } from "./environment"; import { KnownLanguage } from "./languages"; import { getRunnerLogger } from "./logging"; +import { ToolsSource } from "./setup-codeql"; import { ActionName, + createInitWithConfigStatusReport, createStatusReportBase, getActionsStatus, + InitStatusReport, + InitWithConfigStatusReport, } from "./status-report"; import { setupTests, @@ -243,3 +248,103 @@ test("getActionStatus handling correctly various types of errors", (t) => { "We still recognise a wrapped ConfigurationError as a user error", ); }); + +const testCreateInitWithConfigStatusReport = test.macro({ + exec: async ( + t, + _title: string, + config: Config, + expectedReportProperties: Partial, + ) => { + await withTmpDir(async (tmpDir: string) => { + setupEnvironmentAndStub(tmpDir); + + const statusReportBase = await createStatusReportBase( + ActionName.Init, + "failure", + new Date("May 19, 2023 05:19:00"), + config, + { numAvailableBytes: 100, numTotalBytes: 500 }, + getRunnerLogger(false), + "failure cause", + "exception stack trace", + ); + + if (t.truthy(statusReportBase)) { + const initStatusReport: InitStatusReport = { + ...statusReportBase, + tools_input: "", + tools_resolved_version: "foo", + tools_source: ToolsSource.Unknown, + workflow_languages: "actions", + }; + + const initWithConfigStatusReport = + await createInitWithConfigStatusReport( + config, + initStatusReport, + undefined, + 1024, + undefined, + ); + + if (t.truthy(initWithConfigStatusReport)) { + t.like(initWithConfigStatusReport, expectedReportProperties); + } + } + }); + }, + title: (_, title) => `createInitWithConfigStatusReport: ${title}`, +}); + +test( + testCreateInitWithConfigStatusReport, + "returns a value", + createTestConfig({ + buildMode: BuildMode.None, + languages: [KnownLanguage.java, KnownLanguage.swift], + }), + { + trap_cache_download_size_bytes: 1024, + registries: "[]", + query_filters: "[]", + packs: "{}", + }, +); + +test( + testCreateInitWithConfigStatusReport, + "includes packs for a single language", + createTestConfig({ + buildMode: BuildMode.None, + languages: [KnownLanguage.java], + computedConfig: { + packs: ["foo", "bar"], + }, + }), + { + registries: "[]", + query_filters: "[]", + packs: JSON.stringify({ java: ["foo", "bar"] }), + }, +); + +test( + testCreateInitWithConfigStatusReport, + "includes packs for multiple languages", + createTestConfig({ + buildMode: BuildMode.None, + languages: [KnownLanguage.java, KnownLanguage.swift], + computedConfig: { + packs: { java: ["java-foo", "java-bar"], swift: ["swift-bar"] }, + }, + }), + { + registries: "[]", + query_filters: "[]", + packs: JSON.stringify({ + java: ["java-foo", "java-bar"], + swift: ["swift-bar"], + }), + }, +);