From 9633382129f3644758305bdfe60fa75d76c2fa94 Mon Sep 17 00:00:00 2001 From: Agents Date: Thu, 6 Aug 2026 09:45:56 +0100 Subject: [PATCH] fix(report): publish exhaustive JSON evidence --- CHANGELOG.md | 5 +++++ src/report-publish.ts | 9 +++++++-- test/report-publish.test.mjs | 21 +++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31579bd..dce74b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Fixed +- **Durable reports now publish their exhaustive `report.json` source of truth.** + The report branch previously received only `report.md` and crop PNGs even when + a byte-capped Markdown report directed reviewers to `report.json`. Publication + now includes the generated JSON alongside the Markdown and crops. + - **`styleproof-map` no longer selects consumer tests that merely mention "styleproof capture".** Playwright compiles a plain `--grep` string as `new RegExp(pattern, 'gi')` — case-insensitive — and matches it against the whole title path, so the bare diff --git a/src/report-publish.ts b/src/report-publish.ts index 62a5a9e..75dabf8 100644 --- a/src/report-publish.ts +++ b/src/report-publish.ts @@ -306,14 +306,19 @@ export async function verifyPublishedReceipt(options: { ); } -/** Collect exactly what the report step publishes: `report.md` plus every - * generated crop it references. Nothing else in the report directory travels. */ +/** Collect exactly what the report step publishes: `report.md`, the exhaustive + * `report.json`, plus every generated crop the Markdown references. Nothing + * else in the report directory travels. */ export function collectReportFiles(reportDirectory: string): ReportPublishFile[] { const files: ReportPublishFile[] = [ { relativePath: 'report.md', content: fs.readFileSync(path.join(reportDirectory, 'report.md')), }, + { + relativePath: 'report.json', + content: fs.readFileSync(path.join(reportDirectory, 'report.json')), + }, ]; const cropsDirectory = path.join(reportDirectory, 'crops'); if (fs.existsSync(cropsDirectory)) { diff --git a/test/report-publish.test.mjs b/test/report-publish.test.mjs index 20792e9..17363ef 100644 --- a/test/report-publish.test.mjs +++ b/test/report-publish.test.mjs @@ -1,6 +1,10 @@ import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; import test from 'node:test'; import { + collectReportFiles, REPORT_BRANCH_SIZE_WARNING_BYTES, publishReportFolder, verifyPublishedReceipt, @@ -94,6 +98,23 @@ const reportFiles = [ { relativePath: 'crops/hero.png', content: Buffer.from([1, 2, 3]) }, ]; +test('collectReportFiles publishes report.json with markdown and crops', (t) => { + const reportDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'styleproof-report-publish-')); + t.after(() => fs.rmSync(reportDirectory, { recursive: true, force: true })); + fs.mkdirSync(path.join(reportDirectory, 'crops')); + fs.writeFileSync(path.join(reportDirectory, 'report.md'), '# report'); + fs.writeFileSync(path.join(reportDirectory, 'report.json'), '{"surfaces":[]}'); + fs.writeFileSync(path.join(reportDirectory, 'crops', 'hero.png'), Buffer.from([1, 2, 3])); + + const files = collectReportFiles(reportDirectory); + + assert.deepEqual( + files.map((file) => file.relativePath), + ['report.md', 'report.json', 'crops/hero.png'], + ); + assert.equal(files[1].content.toString('utf8'), '{"surfaces":[]}'); +}); + test('publishes onto an existing branch without downloading any report bytes', async () => { const fake = buildFakeGitHub({ branchTip: 'tip-sha',