fix(release-controller): refresh stale changelog on release notes branch - #2112
Open
pietrodimarco-dfinity wants to merge 1 commit into
Open
fix(release-controller): refresh stale changelog on release notes branch#2112pietrodimarco-dfinity wants to merge 1 commit into
pietrodimarco-dfinity wants to merge 1 commit into
Conversation
ensure_published() wrote the changelog with Repository.create_file(), which is the GitHub *create* endpoint and returns 422 when the path already exists. The failure was swallowed by a bare `except`, and create_pull() then ran anyway -- so a branch left over from an earlier reconciler pass kept its original changelog while a pull request was opened advertising it. Observed in production today. rc--2026-07-23_04-21 security hotfix notes were committed to their branches at 16:11 and 16:14, before #2105 pinned changelog_base. After that merged, the Google Docs were regenerated against the new bases but the branches could not be updated: II:publish_notes.0c121276... - Creating file on branch replica-release-notes-0c121276... WW:publish_notes.0c121276... - Failed to create file on branch replica-release-notes-0c121276... II:publish_notes.0c121276... - Creating pull request for branch replica-release-notes-0c121276... The resulting PRs cited release-2026-07-23_04-21-base while the docs cited release-2026-07-17_04-19-base. Recovery required closing both PRs and deleting both branches by hand; the reconciler could not heal itself. Update the file in place when it already exists, skip the write entirely when the committed content already matches (the reconciler runs every 30s), and do not open a pull request when the write failed -- a PR on top of a failed write advertises content that was never committed. Adds the first tests for ensure_published(), which had none. All three new tests fail without this change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ensure_published()writes the changelog withRepository.create_file()— the GitHub create endpoint, which returns 422 when the path already exists. The failure is swallowed by a bareexcept, andcreate_pull()then runs anyway:So a branch left over from an earlier reconciler pass keeps its original changelog forever, and a PR gets opened advertising it.
Observed in production
rc--2026-07-23_04-21security hotfix notes were committed to their branches at 16:11 and 16:14, before #2105 pinnedchangelog_base(merged 16:44). The Google Docs were then correctly regenerated against the new bases — but the branches could not be:Net effect — doc and PR disagreed about which commits the release contained:
security-hotfixrelease-2026-07-17_04-19-baserelease-2026-07-23_04-21-basedeterministic-tracker-security-hotfixrelease-2026-07-23_04-21-security-hotfixrelease-2026-07-23_04-21-deterministic-trackerRecovery required closing both PRs (#2108, #2109) and deleting both branches by hand. The reconciler cannot heal this on its own — it logs the same warning every 30s forever.
Fix
_write_changelog():update_filewhen the path exists, so a stale branch gets refreshed instead of silently keeping old content.Tests
ensure_published()previously had no coverage — every existing test mocks it out. Four added:…creates_file_when_branch_is_freshcreate_file, noupdate_file…updates_stale_changelog_on_existing_branchupdate_filewith the new content + blob sha, nocreate_file…does_not_recommit_identical_changelog…opens_no_pull_request_when_the_write_failscreate_pullnot calledVerified they actually catch the bug — with the fix reverted:
and with it applied,
9 passed.mypy --strictclean on both files.Note
This is the third existence-only guard in this path today, after
markdown_file()andgoogle_docs.ensure()— neither compares content either. Those two are working as intended given a manual doc deletion; this one had no recovery path at all.🤖 Generated with Claude Code