Skip to content

37138 autodetect previous tag - #37140

Merged
sfreudenthaler merged 2 commits into
mainfrom
37138-autodetect-previous-tag
Aug 22, 2026
Merged

37138 autodetect previous tag#37140
sfreudenthaler merged 2 commits into
mainfrom
37138-autodetect-previous-tag

Conversation

@sfreudenthaler

@sfreudenthaler sfreudenthaler commented Aug 20, 2026

Copy link
Copy Markdown
Member

Closes: #37138

Bottom of stack #37143. Independent of the two PRs above it.

Problem

findPreviousTag() returned tags[idx + 1] unconditionally — the tag immediately preceding the target. On a day with more than one release attempt, that preceding tag is another attempt at the same release, whose pipeline died before writing notes. The changelog then covers one attempt instead of one release.

This produced the 26.08.19-04 changelog: auto-detect resolved its predecessor to v26.08.19-03, so the notes described 1 of 19 commits and published "contains internal maintenance only" for a release carrying Accessibility Studio, the Experiments portlet, three roles endpoints and nine fixes.

Three fixes in the same two functions

  • listStandardReleaseTags() returns { tag, hasNotes } and skips drafts. listReleases returns drafts first regardless of date, corrupting the newest-first ordering the docstring promises. Measured against the live API: 6 drafts currently match STANDARD_RELEASE_PATTERN, one duplicates v26.04.11-02, and the v26.07.17-01 / v26.07.27-01 drafts shadow real releases.
  • findPreviousTag() walks back to the first release with notes, so an undocumented attempt's commits stay inside the range instead of being stranded behind its tag.
  • findIndex on tag equality replaces indexOf, which returned the first match for that duplicated tag.

The skip is conditioned on missing notes, not on the date — a same-day attempt that did publish notes remains a valid boundary.

Verification

npx tsc --noEmit clean. npx jest 35/35 passing, including three new cases: skips undocumented predecessors (the 26.08.19 shape), keeps a documented same-day attempt (26.08.12-0226.08.12-01), and returns undefined when every predecessor is undocumented.

Until this merges

Always pass previous_tag explicitly to cicd_ai-release-notes-backfill.yml. Never rely on auto-detect after a day with more than one attempt.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EbgDBJuoBrpJxh5qLMPorL

This PR fixes: #37138

@claude

claude Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Claude finished @sfreudenthaler's task in 1m 15s —— View job


Review

Verified the diff end-to-end: the string[]ReleaseRef[] change is propagated through both index.ts files and every call site (.some((r) => r.tag === ...), findIndex, .find((r) => r.hasNotes)), and the fallback paths degrade correctly to the if (!fromTag) guard when nothing documented remains. Logic and tests match the stated behavior.

New Issues

  • 🟡 Medium: .github/scripts/release-qa-status/src/index.ts:216 — the stderr note interpolates ${newest?.tag} unconditionally, so when every tag is undocumented it prints using newest documented tag undefined as previous. before the if (!fromTag) branch reports the real error two lines later. Cosmetic only (the exit path is correct), but the undefined in the log is misleading during exactly the failure it's meant to explain.

  • 🟡 Medium: .github/scripts/*/src/github.tshasNotes is derived from (release.body ?? '').trim().length > 0. Assumption: every real release always publishes a non-empty body, and only a died-mid-pipeline cut leaves it empty. What to verify: a legitimately-documented release can't end up with an empty body (e.g. notes stored only as an attached asset, or a release whose body is later cleared) — if it can, that release would be silently skipped as a boundary and its commits folded into the next range. Given the release convention this is likely safe; flagging so it's a conscious choice rather than an implicit one.

Notes (non-blocking)

  • ReleaseRef + findPreviousTag are now duplicated verbatim across the two script packages, guarded only by a sync comment and the parallel test files. That's the pre-existing structure of these two scripts, and the added release-qa-status/src/github.test.ts mirrors the regression cases specifically to catch drift — reasonable mitigation, just noting the divergence risk remains if only one copy is edited later.

Nice touch conditioning the skip on missing notes rather than on same-day date — the 26.08.12-02 → 26.08.12-01 test correctly proves a documented same-day attempt stays a valid boundary.

No blocking issues.

· 37138-autodetect-previous-tag

sfreudenthaler and others added 2 commits August 20, 2026 14:23
findPreviousTag returned tags[idx + 1] unconditionally. On a day with more than
one release attempt that preceding tag is another attempt at the same release,
whose pipeline died before writing notes -- so the generated changelog covered
one attempt instead of the whole release. On 26.08.19 that published "internal
maintenance only" for a release carrying 19 commits.

Three fixes in the same two functions:

- listStandardReleaseTags now returns {tag, hasNotes} and skips drafts.
  listReleases returns drafts first regardless of date, corrupting the
  newest-first ordering the docstring promises; 6 drafts currently match the
  standard pattern and one duplicates v26.04.11-02.
- findPreviousTag walks back to the first release with notes, so an
  undocumented attempt's commits stay inside the range instead of being
  stranded behind its tag.
- findIndex on tag equality replaces indexOf, which returned the first match
  for a duplicated tag.

A same-day attempt that DID publish notes is still a valid boundary -- the skip
is conditioned on missing notes, not on the date.

Closes: #37138

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EbgDBJuoBrpJxh5qLMPorL
release-qa-status carries a forked copy of listStandardReleaseTags and
findPreviousTag with the identical bug, and cicd_6-release.yml calls it -- so
on a multi-attempt day the QA status reported on one attempt while the
changelog reported on another.

Applies the same fix: skip drafts, carry hasNotes, walk back to the first
documented release. Its eventual-consistency fallback (toTag not yet indexed)
now also picks the newest *documented* tag rather than tags[0], which could
otherwise be a failed earlier attempt.

Adds a github.test.ts covering the same three cases as gather-release-data, so
drift between the two copies fails a test instead of silently disagreeing.

Found in review of #37140.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EbgDBJuoBrpJxh5qLMPorL
@sfreudenthaler
sfreudenthaler force-pushed the 37138-autodetect-previous-tag branch from 56b59c2 to 573f058 Compare August 20, 2026 18:24
@sfreudenthaler

Copy link
Copy Markdown
Member Author

Addressed the duplicate-logic finding — it was a real bug, not just a consistency smell.

release-qa-status is called from cicd_6-release.yml, so on a multi-attempt day its range stopped at an undocumented attempt while the changelog used a different one. Applied the same fix there: skip drafts, carry hasNotes, walk back to the first documented release.

One thing beyond what the review flagged: that script's eventual-consistency fallback (toTag not yet indexed by the releases API) used tags[0], which on a multi-attempt day is a failed earlier attempt of the same release. It now picks the newest documented tag.

Rather than consolidate the two copies — separate npm packages, so sharing means new build wiring — I added release-qa-status/src/github.test.ts covering the same three cases as gather-release-data. Drift between the copies now fails a test instead of silently disagreeing. Both suites green: 35/35 and 40/40, tsc --noEmit clean on both.

On the non-blocking note about whitespace-only bodies: agreed, and it is intentional. Widening the range re-describes already-shipped commits, which is recoverable; narrowing it silently drops them, which is what shipped the wrong 26.08.19 changelog. Prefer the failure that is visible.

@dcolina dcolina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sfreudenthaler
sfreudenthaler added this pull request to the merge queue Aug 22, 2026
Merged via the queue into main with commit 2825aff Aug 22, 2026
44 checks passed
@sfreudenthaler
sfreudenthaler deleted the 37138-autodetect-previous-tag branch August 22, 2026 01:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Release-notes auto-detect picks an undocumented tag, producing a changelog that covers a fraction of the release

2 participants