feat(ci): manual changelog site publish + fix release-notes auto-detect - #37137
feat(ci): manual changelog site publish + fix release-notes auto-detect#37137sfreudenthaler wants to merge 2 commits into
Conversation
The changelog site publish phase is workflow_call: only, so when the release pipeline skips it -- any upstream failure or cancellation, since the job is gated on success() -- the only recovery is running the publisher locally with DOTCMS_DEVSITE_URL, _RELEASENOTES_TOKEN and _RELEASENOTES_ACCOUNT in hand. Adds cicd_manual_changelog-site-publish.yml, a workflow_dispatch wrapper around the existing phase, mirroring cicd_ai-release-notes-backfill.yml. Credentials stay in repo vars/secrets; an operator supplies only the release tag. The wrapper derives release_version from the tag, the sha-tagged docker image from Docker Hub's public API, and released_date from the release's own publishedAt so backfilling an older release does not stamp today's date. The phase gains force and released_date inputs, both defaulting to current behavior, so the release pipeline path is unchanged. force makes the --force override the phase comments already describe reachable from CI. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EbgDBJuoBrpJxh5qLMPorL
|
Claude finished @sfreudenthaler's task in 3m 2s —— View job Code Review — feat(ci): manual trigger for changelog site publishReviewed the full diff (workflow wrapper, phase changes, and the New Issues
Notes (non-blocking)
Verified clean
No blocking issues. The two 🟡 items are worth addressing but don't block merge. · branch |
…tag (#37138) 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. Also gates the manual publish workflow behind the changelog-site-publish environment (required_reviewers: dotDevelopers), matching the evergreen promote apply gate. workflow_dispatch is open to all 45 accounts with write access, and this writes to the public docs site with a service-account token. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EbgDBJuoBrpJxh5qLMPorL
|
Superseded by stack #37143, which splits this into three reviewable PRs:
Same content, verified tree-identical to this branch before splitting. Closing in favor of the stack. |
Closes: #37136
Closes: #37138
Two related changes: a manual publish path, and the auto-detect bug that made one necessary.
1. Manual trigger for changelog site publish (#37136)
Adds
cicd_manual_changelog-site-publish.yml, aworkflow_dispatchwrapper around the existing phase — the patterncicd_ai-release-notes-backfill.ymlalready uses.Why: the phase is
workflow_call:only and gated onsuccess(), so any upstream failure or cancellation skips it with no CI path to recover. Today that means a local checkout plus three values that otherwise never leave GitHub —DOTCMS_DEVSITE_URL,DOTCMS_DEVSITE_RELEASENOTES_TOKEN,DOTCMS_DEVSITE_RELEASENOTES_ACCOUNT. The phase's comments also describe--forceas "a manual operator re-run only", but no manual re-run path existed, so the flag was unreachable.The wrapper derives what the pipeline would have passed:
release_versionvdocker_tagsversion_shatag so a manual entry matches a pipeline-written onereleased_datepublishedAt, so backfilling an older release does not stamp today's dateThe phase gains
forceandreleased_date, both defaulting to current behavior. The release pipeline path is unchanged —cicd_6-release.ymlsets neither input.Access control
workflow_dispatchis limited to accounts with write access — never forks, never the public — but that is 45 accounts today, and this writes to the public docs site with a service-account token. So the publish job sits behind a no-op approval gate on thechangelog-site-publishenvironment (required_reviewers: dotDevelopers), matchingcicd_evergreen-tracks-promote.yml's apply gate.The environment has been created with that protection rule. It must keep it: GitHub auto-creates a missing environment unprotected on first use, which would silently remove the gate.
2. Auto-detect picks an undocumented tag (#37138)
findPreviousTag()returnedtags[idx + 1]unconditionally. On a multi-attempt day that is another attempt at the same release, whose pipeline died before writing notes — so the changelog covers one attempt instead of the release.This is what produced the 26.08.19-04 changelog: auto-detect resolved its predecessor to
v26.08.19-03, and the release notes described 1 of 19 commits, publishing "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.listReleasesreturns drafts first regardless of date, corrupting the newest-first ordering the docstring promises — 6 drafts currently match the standard pattern, and one duplicatesv26.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.findIndexon tag equality replacesindexOf, 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, and there is a test for exactly that (26.08.12-02 → 26.08.12-01).
Verification
npx tsc --noEmitclean;npx jest35/35 passing, including three newfindPreviousTagcases: skips undocumented predecessors, keeps a documented same-day attempt, returns undefined when every predecessor is undocumented.26.08.19-04_a0181f9, released date →2026-08-20, both matching the entry now live on the site.Not exercised end-to-end against the live site: the only release currently needing a publish was already published by hand, and re-running would trip human-edit protection. A run on the next release that needs it is the real test.
🤖 Generated with Claude Code
https://claude.ai/code/session_01EbgDBJuoBrpJxh5qLMPorL