diff --git a/lib/instrumentation/reporting.spec.ts b/lib/instrumentation/reporting.spec.ts index 8705ac618bae93..494e4fd203b0d5 100644 --- a/lib/instrumentation/reporting.spec.ts +++ b/lib/instrumentation/reporting.spec.ts @@ -9,11 +9,13 @@ import { addBranchStats, addExtractionStats, exportStats, + finalizeReport, getReport, } from './reporting'; jest.mock('../util/fs', () => mockDeep()); jest.mock('../util/s3', () => mockDeep()); +jest.mock('../logger', () => mockDeep()); describe('instrumentation/reporting', () => { const branchInformation: Partial[] = [ @@ -52,8 +54,10 @@ describe('instrumentation/reporting', () => { }; const expectedReport = { + problems: [], repositories: { 'myOrg/myRepo': { + problems: [], branches: branchInformation, packageFiles, }, @@ -70,6 +74,7 @@ describe('instrumentation/reporting', () => { }); expect(getReport()).toEqual({ + problems: [], repositories: {}, }); }); @@ -174,4 +179,49 @@ describe('instrumentation/reporting', () => { fs.writeSystemFile.mockRejectedValue(null); await expect(exportStats(config)).toResolve(); }); + + it('should add problems to report', () => { + const config: RenovateConfig = { + repository: 'myOrg/myRepo', + reportType: 'logging', + }; + const expectedReport = { + problems: [ + { + level: 30, + msg: 'a root problem', + }, + ], + repositories: { + 'myOrg/myRepo': { + problems: [ + { + level: 30, + msg: 'a repo problem', + }, + ], + branches: branchInformation, + packageFiles, + }, + }, + }; + + addBranchStats(config, branchInformation); + addExtractionStats(config, { branchList: [], branches: [], packageFiles }); + + logger.getProblems.mockReturnValue([ + { + repository: 'myOrg/myRepo', + level: 30, + msg: 'a repo problem', + }, + { + level: 30, + msg: 'a root problem', + }, + ]); + finalizeReport(); + + expect(getReport()).toEqual(expectedReport); + }); }); diff --git a/lib/instrumentation/reporting.ts b/lib/instrumentation/reporting.ts index 2167212ffba272..8b422f3d3d9b41 100644 --- a/lib/instrumentation/reporting.ts +++ b/lib/instrumentation/reporting.ts @@ -1,7 +1,7 @@ import { PutObjectCommand, PutObjectCommandInput } from '@aws-sdk/client-s3'; import is from '@sindresorhus/is'; import type { RenovateConfig } from '../config/types'; -import { logger } from '../logger'; +import { getProblems, logger } from '../logger'; import type { BranchCache } from '../util/cache/repository/types'; import { writeSystemFile } from '../util/fs'; import { getS3Client, parseS3Url } from '../util/s3'; @@ -9,6 +9,7 @@ import type { ExtractResult } from '../workers/repository/process/extract-update import type { Report } from './types'; const report: Report = { + problems: [], repositories: {}, }; @@ -37,6 +38,22 @@ export function addExtractionStats( extractResult.packageFiles; } +export function finalizeReport(): void { + const allProblems = structuredClone(getProblems()); + for (const problem of allProblems) { + const repository = problem.repository; + delete problem.repository; + + // if the problem can be connected to a repository add it their else add to the root list + if (repository) { + coerceRepo(repository); + report.repositories[repository].problems.push(problem); + } else { + report.problems.push(problem); + } + } +} + export async function exportStats(config: RenovateConfig): Promise { try { if (is.nullOrUndefined(config.reportType)) { @@ -91,6 +108,7 @@ function coerceRepo(repository: string): void { } report.repositories[repository] = { + problems: [], branches: [], packageFiles: {}, }; diff --git a/lib/instrumentation/types.ts b/lib/instrumentation/types.ts index aa29b4ebdbf9b4..d4e86c1c7ea6cc 100644 --- a/lib/instrumentation/types.ts +++ b/lib/instrumentation/types.ts @@ -1,4 +1,5 @@ import type { Attributes, SpanKind } from '@opentelemetry/api'; +import type { BunyanRecord } from '../logger/types'; import type { PackageFile } from '../modules/manager/types'; import type { BranchCache } from '../util/cache/repository/types'; @@ -28,10 +29,12 @@ export interface SpanParameters { } export interface Report { + problems: BunyanRecord[]; repositories: Record; } interface RepoReport { + problems: BunyanRecord[]; branches: Partial[]; packageFiles: Record; } diff --git a/lib/workers/global/index.spec.ts b/lib/workers/global/index.spec.ts index d7085312642119..e5404417a76b2e 100644 --- a/lib/workers/global/index.spec.ts +++ b/lib/workers/global/index.spec.ts @@ -40,7 +40,7 @@ const initPlatform = jest.spyOn(platform, 'initPlatform'); describe('workers/global/index', () => { beforeEach(() => { - logger.getProblems.mockImplementationOnce(() => []); + logger.getProblems.mockImplementation(() => []); initPlatform.mockImplementation((input) => Promise.resolve(input)); delete process.env.AWS_SECRET_ACCESS_KEY; delete process.env.AWS_SESSION_TOKEN; @@ -149,7 +149,7 @@ describe('workers/global/index', () => { repositories: [], }); logger.getProblems.mockReset(); - logger.getProblems.mockImplementationOnce(() => [ + logger.getProblems.mockImplementation(() => [ { level: ERROR, msg: 'meh', @@ -166,7 +166,7 @@ describe('workers/global/index', () => { repositories: [], }); logger.getProblems.mockReset(); - logger.getProblems.mockImplementationOnce(() => [ + logger.getProblems.mockImplementation(() => [ { level: WARN, msg: 'meh', diff --git a/lib/workers/global/index.ts b/lib/workers/global/index.ts index e9b4f5abc6ecd2..1a2e3745d46b0f 100644 --- a/lib/workers/global/index.ts +++ b/lib/workers/global/index.ts @@ -16,7 +16,7 @@ import type { import { CONFIG_PRESETS_INVALID } from '../../constants/error-messages'; import { pkg } from '../../expose.cjs'; import { instrument } from '../../instrumentation'; -import { exportStats } from '../../instrumentation/reporting'; +import { exportStats, finalizeReport } from '../../instrumentation/reporting'; import { getProblems, logger, setMeta } from '../../logger'; import { setGlobalLogLevelRemaps } from '../../logger/remap'; import * as hostRules from '../../util/host-rules'; @@ -212,6 +212,7 @@ export async function start(): Promise { ); } + finalizeReport(); await exportStats(config); } catch (err) /* istanbul ignore next */ { if (err.message.startsWith('Init: ')) {