From 77caa9d7179cf9e36ba855e08c726b2b816c8419 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Mon, 29 Sep 2025 06:46:19 +0000 Subject: [PATCH] feat: automatically migrate v2 to v3 reports We've recently made breaking changes with https://github.com/angular/web-codegen-scorer/commit/41ada541481a10c99de055ab6bb1c19b06a25b88, and we want to ensure existing reports for users continue to work. This commit lazily migrates v2 to v3 reports when loaded. We can keep this logic for a while; while we also migrate our own Firebase database for permanent storage (maybe we need to expose this script for users as well eventually). --- report-app/report-server.ts | 9 +++-- runner/reporting/migrations/v2_to_v3.ts | 48 +++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 runner/reporting/migrations/v2_to_v3.ts diff --git a/report-app/report-server.ts b/report-app/report-server.ts index f2aeb3b..b61efa5 100644 --- a/report-app/report-server.ts +++ b/report-app/report-server.ts @@ -11,6 +11,8 @@ import { FetchedLocalReports, fetchReportsFromDisk, } from '../runner/reporting/report-local-disk'; +import { RunInfo } from '../runner/shared-interfaces'; +import { convertV2ReportToV3Report } from '../runner/reporting/migrations/v2_to_v3'; const app = express(); const reportsLoader = await getReportLoader(); @@ -39,7 +41,7 @@ app.get('/api/reports', async (_, res) => { app.get('/api/reports/:id', async (req, res) => { const id = req.params.id; const localData = await resolveLocalData(options.reportsRoot); - let result: { group: string }[] | null = null; + let result: RunInfo[] | null = null; if (localData.has(id)) { result = [localData.get(id)!.run]; @@ -47,6 +49,9 @@ app.get('/api/reports/:id', async (req, res) => { result = await reportsLoader.getGroupedReports(id); } + // Convert potential older v2 reports. + result = result.map((r) => convertV2ReportToV3Report(r)); + res.json(result); }); @@ -79,7 +84,7 @@ if (isMainModule(import.meta.url)) { export const reqHandler = createNodeRequestHandler(app); interface ReportLoader { - getGroupedReports: (groupId: string) => Promise<{ group: string }[]>; + getGroupedReports: (groupId: string) => Promise; getGroupsList: () => Promise<{ id: string }[]>; configureEndpoints?: (expressApp: typeof app) => Promise; } diff --git a/runner/reporting/migrations/v2_to_v3.ts b/runner/reporting/migrations/v2_to_v3.ts new file mode 100644 index 0000000..1e4a6fe --- /dev/null +++ b/runner/reporting/migrations/v2_to_v3.ts @@ -0,0 +1,48 @@ +/** + * Migrates a v2 report to a v3 report. + * See: https://github.com/angular/web-codegen-scorer/commit/41ada541481a10c99de055ab6bb1c19b06a25b88. + */ +export function convertV2ReportToV3Report(doc: any) { + if (doc.version === 3) { + return doc; + } + + const migrateFromBuildResultToSplit = (origBuildResult: any) => { + const buildResult = { + status: origBuildResult.status, + message: origBuildResult.message, + errorType: origBuildResult.errorType, + safetyWebReportJson: origBuildResult.safetyWebReportJson, + missingDependency: origBuildResult.missingDependency, + }; + const serveTestingResult = { + errorMessage: undefined, + screenshotPngUrl: origBuildResult.screenshotPngUrl, + runtimeErrors: origBuildResult.runtimeErrors, + userJourneyAgentOutput: origBuildResult.userJourneyAgentOutput, + cspViolations: origBuildResult.cspViolations, + axeViolations: origBuildResult.axeViolations, + }; + + return { buildResult, serveTestingResult }; + }; + + for (const result of doc.results) { + const finalAttemptSplit = migrateFromBuildResultToSplit(result.build); + result.finalAttempt = { + buildResult: finalAttemptSplit.buildResult, + serveTestingResult: finalAttemptSplit.serveTestingResult, + }; + delete result.build; + + for (const attempt of result.attemptDetails) { + const attemptSplit = migrateFromBuildResultToSplit(attempt.buildResult); + attempt.buildResult = attemptSplit.buildResult; + attempt.serveTestingResult = attemptSplit.serveTestingResult; + } + } + + doc.version = 3; + + return doc; +}