Problem
findPreviousTag() (.github/scripts/gather-release-data/src/github.ts:57) returns tags[idx + 1] unconditionally — the tag immediately preceding the target in the releases list. On a day with more than one release attempt, that preceding tag is another attempt at the same release, whose pipeline died before writing any notes.
The result is a changelog whose range is one attempt wide instead of one release wide.
Observed on 26.08.19. Four attempts were cut. -01, -02 and -03 all pushed real Docker images but died in Deployment, so their release bodies are the empty string. -04 succeeded, auto-detect resolved its previous tag to v26.08.19-03, and the generated changelog described 1 of the 19 commits in the release — publishing to dev.dotcms.com that a release containing Accessibility Studio, the Experiments portlet, three roles endpoints and nine fixes "contains internal maintenance only."
That is worse than a missing changelog: it is an affirmatively false "nothing changed" statement that customers may act on when deciding whether to upgrade.
Root cause
Three compounding defects in the same two functions:
- No notion of whether a predecessor was ever documented. An empty-bodied release is treated as a valid range boundary, which strands every commit behind it.
listStandardReleaseTags() does not filter drafts. listReleases returns drafts first regardless of date, so drafts corrupt the newest-first ordering the function's own docstring promises. Six draft releases currently match STANDARD_RELEASE_PATTERN.
indexOf on a duplicated tag returns the first match. One of those drafts duplicates v26.04.11-02, so the index — and therefore the resolved fromTag — can be wrong. Latent today; filtering drafts closes it.
Proposed fix
Carry per-release notes state alongside the tag, skip drafts when listing, and walk back past undocumented releases when resolving:
listStandardReleaseTags() returns { tag, hasNotes }[] and skips drafts
findPreviousTag() walks backwards to the first entry with hasNotes, so an undocumented attempt's commits stay inside the range rather than being stranded behind its tag
Same-day attempts that did complete keep working exactly as they do now — the skip is conditioned on missing notes, not on the date.
Workaround until fixed
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.
Problem
findPreviousTag()(.github/scripts/gather-release-data/src/github.ts:57) returnstags[idx + 1]unconditionally — the tag immediately preceding the target in the releases list. On a day with more than one release attempt, that preceding tag is another attempt at the same release, whose pipeline died before writing any notes.The result is a changelog whose range is one attempt wide instead of one release wide.
Observed on 26.08.19. Four attempts were cut.
-01,-02and-03all pushed real Docker images but died in Deployment, so their release bodies are the empty string.-04succeeded, auto-detect resolved its previous tag tov26.08.19-03, and the generated changelog described 1 of the 19 commits in the release — publishing to dev.dotcms.com that a release containing Accessibility Studio, the Experiments portlet, three roles endpoints and nine fixes "contains internal maintenance only."That is worse than a missing changelog: it is an affirmatively false "nothing changed" statement that customers may act on when deciding whether to upgrade.
Root cause
Three compounding defects in the same two functions:
listStandardReleaseTags()does not filter drafts.listReleasesreturns drafts first regardless of date, so drafts corrupt the newest-first ordering the function's own docstring promises. Six draft releases currently matchSTANDARD_RELEASE_PATTERN.indexOfon a duplicated tag returns the first match. One of those drafts duplicatesv26.04.11-02, so the index — and therefore the resolvedfromTag— can be wrong. Latent today; filtering drafts closes it.Proposed fix
Carry per-release notes state alongside the tag, skip drafts when listing, and walk back past undocumented releases when resolving:
listStandardReleaseTags()returns{ tag, hasNotes }[]and skips draftsfindPreviousTag()walks backwards to the first entry withhasNotes, so an undocumented attempt's commits stay inside the range rather than being stranded behind its tagSame-day attempts that did complete keep working exactly as they do now — the skip is conditioned on missing notes, not on the date.
Workaround until fixed
Always pass
previous_tagexplicitly tocicd_ai-release-notes-backfill.yml. Never rely on auto-detect after a day with more than one attempt.