You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In #586 the vitest test normalizeHistoryEntries > dry-runs every historical changelog entry without parse failures (packages/changelog-generator/src/__tests__/normalize-history.test.ts) was skipped (it.skip) so the suite could go green. This issue tracks fixing the root cause and re-enabling it.
The history normalizer (packages/changelog-generator/src/commands/normalize-history.ts → normalizeRelease / renderNormalizedRelease) re-renders every entry through a flat NormalizedChange model. That model can't represent several constructs used by rich, hand-authored entries, so re-normalizing them is lossy and the test's expect(result.rewritten).toBe(0) invariant fails.
Failure modes
Markdown links stripped — [Label](/relative/path) becomes bare Label. (relative links aren't recognized as source refs).
Prose sections deleted — anything that isn't a ## Changes / ## Source bullet list (e.g. a "When to use it" paragraph) is dropped.
Nested lists flattened — sub-bullets are collapsed to a single level.
Frontmatter tags dropped — not re-emitted by the renderer.
Stray trailing periods — a . is appended even to lines ending in : or to URL paths (e.g. /people/{person_id}/photo → /people/{person_id}/photo.).
Example cases (use as test fixtures)
Case 1 — 2026-05-18-custom-metadata-api-ga.md (rich entry)
Input (excerpt):
---title: 'Custom Metadata API is Generally Available'categories: ['API']tags: ['Indexing API', 'Feature']---## What's new-**New endpoints** under `/rest/api/index`:
-`PUT /custom-metadata/schema/{groupName}` — create or update a metadata group schema
-`GET /custom-metadata/schema/{groupName}` — retrieve a metadata group schema
## When to use it
Custom Metadata works with any document already indexed in Glean. ... see [Custom Properties vs Custom Metadata](/api-info/indexing/custom-metadata/custom-properties-vs-custom-metadata).
## Documentation-[Custom Metadata Overview](/api-info/indexing/custom-metadata/overview)-[Authentication](/api-info/indexing/custom-metadata/authentication)
Current normalizer output (degraded):
---title: 'Custom Metadata API is Generally Available'categories: ['API']---## Changes-**New endpoints** under `/rest/api/index`:.
-`PUT /custom-metadata/schema/{groupName}` — create or update a metadata group schema.
-`GET /custom-metadata/schema/{groupName}` — retrieve a metadata group schema.
...
- Custom Metadata Overview.
- Authentication.
Regressions: tags dropped, ## When to use it section deleted, nested endpoint list flattened, doc links → orphaned bare-text bullets, stray :..
Case 2 — 2026-05-05-rest-api-changes-open-api.md (URL period + spurious source)
Regressions: trailing . appended to a URL path; an inferred "Release notes" source link added.
The full set of entries that currently fail to normalize idempotently (7): 2026-05-05, 2026-05-07, 2026-05-11, 2026-05-12, 2026-05-13 (-rest-api-changes-open-api), 2026-05-18-custom-metadata-api-ga, 2026-06-09-rest-api-changes-open-api.
Possible approaches
Idempotency guard — leave already-well-formed entries untouched (entry has a title + none of the known broken-formatting patterns the sibling test enforces). Lowest risk; doesn't touch the live release-generation renderer. (A prototype of this existed earlier in fix(test): repair vitest suite (JSX transform) + run tests in CI #586.)
Enrich the model — teach NormalizedChange/renderNormalizedRelease to preserve links, prose sections, nesting, and tags. Higher value but changes the shared renderer used by live changelog generation (broader blast radius).
Fix the narrow bugs regardless of approach: don't append . after : or to URL paths; preserve relative-link bullets.
Acceptance criteria
Re-running the normalizer over current history reports 0 rewrites with no content loss (links, sections, nesting, tags preserved).
The narrow bugs above are fixed (no stray periods on :/URLs).
Add the example cases above as regression test fixtures.
Un-skip normalizeHistoryEntries > dry-runs every historical changelog entry without parse failures and confirm it passes.
renderNormalizedRelease output for live release generation is unchanged (or intentionally improved with sign-off).
Background
In #586 the vitest test
normalizeHistoryEntries > dry-runs every historical changelog entry without parse failures(packages/changelog-generator/src/__tests__/normalize-history.test.ts) was skipped (it.skip) so the suite could go green. This issue tracks fixing the root cause and re-enabling it.Requested in #586 (comment).
Problem
The history normalizer (
packages/changelog-generator/src/commands/normalize-history.ts→normalizeRelease/renderNormalizedRelease) re-renders every entry through a flatNormalizedChangemodel. That model can't represent several constructs used by rich, hand-authored entries, so re-normalizing them is lossy and the test'sexpect(result.rewritten).toBe(0)invariant fails.Failure modes
[Label](/relative/path)becomes bareLabel.(relative links aren't recognized as source refs).## Changes/## Sourcebullet list (e.g. a "When to use it" paragraph) is dropped.tagsdropped — not re-emitted by the renderer..is appended even to lines ending in:or to URL paths (e.g./people/{person_id}/photo→/people/{person_id}/photo.).Example cases (use as test fixtures)
Case 1 —
2026-05-18-custom-metadata-api-ga.md(rich entry)Input (excerpt):
Current normalizer output (degraded):
Regressions:
tagsdropped,## When to use itsection deleted, nested endpoint list flattened, doc links → orphaned bare-text bullets, stray:..Case 2 —
2026-05-05-rest-api-changes-open-api.md(URL period + spurious source)Regressions: trailing
.appended to a URL path; an inferred "Release notes" source link added.The full set of entries that currently fail to normalize idempotently (7):
2026-05-05,2026-05-07,2026-05-11,2026-05-12,2026-05-13(-rest-api-changes-open-api),2026-05-18-custom-metadata-api-ga,2026-06-09-rest-api-changes-open-api.Possible approaches
NormalizedChange/renderNormalizedReleaseto preserve links, prose sections, nesting, and tags. Higher value but changes the shared renderer used by live changelog generation (broader blast radius)..after:or to URL paths; preserve relative-link bullets.Acceptance criteria
:/URLs).normalizeHistoryEntries > dry-runs every historical changelog entry without parse failuresand confirm it passes.renderNormalizedReleaseoutput for live release generation is unchanged (or intentionally improved with sign-off).