fix(scripts): preserve manual NOTES block in incremental report generator#1119
fix(scripts): preserve manual NOTES block in incremental report generator#1119carlos-alm wants to merge 6 commits into
Conversation
…ator scripts/update-incremental-report.ts regenerates the report from scratch on every release. PR #1008 added a manual <!-- NOTES_START --> ... <!-- NOTES_END --> block explaining why 3.9.5 had null build metrics, but the 3.9.6 release silently dropped it because the script had no awareness of the sentinel pair. The version-history table now jumps 3.9.4 → 3.9.6 with no explanation. Extract any NOTES block from the existing file (mirroring how INCREMENTAL_BENCHMARK_DATA is preserved) and re-emit it just before the data comment in the regenerated markdown. Restore the lost 3.9.5 note and add a regression test gated on the env-overridable report path. Closes #1042
|
Claude finished @carlos-alm's task —— View job PR Review: Incremental Report NOTES PreservationRoot Cause AnalysisProblem Being Solved: The Why This Approach: The fix properly mirrors the existing pattern used for preserving Risk Assessment: LOW RISK - This is a targeted fix to a specific data loss issue. The changes are additive and follow existing patterns. Backlog Compliance
Code Quality AssessmentChanges Analysis:
Security & Performance:
Minor Observations:
Final Recommendation
|
Greptile SummaryThis PR restores and preserves the manual
Confidence Score: 5/5Safe to merge — the change is narrowly scoped to extracting and re-emitting NOTES blocks, with no effect on the benchmark data or history logic. The NOTES extraction uses a well-bounded non-greedy regex with the g flag (required for matchAll), joins all matches in document order, and guards the emit with a truthiness check so nothing is added when no blocks are present. The existing benchmark-data path is untouched. Three targeted unit tests exercise the added behaviour end-to-end via the real script subprocess. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Read benchmark JSON\nfrom file arg or stdin] --> B[Resolve reportPath\nenv override or default]
B --> C{File exists?}
C -- No --> E[history = empty]
C -- Yes --> D[Read existing file]
D --> D1[Extract INCREMENTAL_BENCHMARK_DATA\nJSON via match]
D --> D2[Extract all NOTES blocks\nvia matchAll]
D1 --> E
D2 --> F[notesBlock = blocks joined with blank lines]
E --> G[Prepend new entry to history]
F --> G
G --> H[Build markdown:\nheader + version table\n+ latest summary]
H --> I{notesBlock non-empty?}
I -- Yes --> J[Append notesBlock]
I -- No --> K
J --> K[Append INCREMENTAL_BENCHMARK_DATA comment]
K --> L[Write reportPath]
L --> M[Run regression detection]
Reviews (7): Last reviewed commit: "Merge branch 'main' into fix/incremental..." | Re-trigger Greptile |
| const notesMatch = content.match(/<!--\s*NOTES_START\s*-->[\s\S]*?<!--\s*NOTES_END\s*-->/); | ||
| if (notesMatch) notesBlock = notesMatch[0]; |
There was a problem hiding this comment.
Only first NOTES block is silently preserved
.match() returns the first regex match, so if a second <!-- NOTES_START --> ... <!-- NOTES_END --> block is ever added (e.g. to annotate a different anomalous release), it would be silently dropped the next time the script runs. This mirrors a real data-loss scenario: the PR itself was created specifically because a block was silently dropped once before. Consider using .matchAll() and concatenating all matched blocks, or at least documenting the single-block constraint as a comment near this code.
There was a problem hiding this comment.
Fixed in d1623f6 — switched to matchAll() and join all matched blocks with blank lines, so any number of NOTES_START/NOTES_END blocks survive regeneration. Added a regression test covering two distinct NOTES blocks (both delimiter pairs preserved, both body texts present after roundtrip).
If multiple NOTES_START/NOTES_END blocks are added to annotate different anomalous releases, .match() silently dropped all but the first — the same data-loss class this PR was created to prevent. Switch to .matchAll() and join with blank lines so every block survives regeneration. Add a test covering two distinct NOTES blocks.
Summary
scripts/update-incremental-report.tsregeneratesgenerated/benchmarks/INCREMENTAL-BENCHMARKS.mdfrom scratch on every release, which silently dropped the manual<!-- NOTES_START --> ... <!-- NOTES_END -->block PR docs: update incremental benchmarks (3.9.5) #1008 added to explain why 3.9.5 hasnullbuild metrics. After 3.9.6, the version-history table jumped 3.9.4 → 3.9.6 with no context.NOTES_START/NOTES_ENDblock from the existing file (mirroring howINCREMENTAL_BENCHMARK_DATAis preserved) and re-emit it just before the data comment in the regenerated markdown.tests/unit/update-incremental-report.test.ts, gated on a newCODEGRAPH_INCREMENTAL_REPORT_PATHenv override so the script can target a temp file from tests.Closes #1042
Test plan
npx vitest run tests/unit/update-incremental-report.test.ts— both cases pass (NOTES preserved on roundtrip, no spurious NOTES when absent)npm run lint— no new errors