fix(release): make Homebrew tap a best-effort gate in promote-release - #60
Conversation
A broken tap (lost HOMEBREW_TAP_TOKEN, org migration, etc.) was blocking the promote-release polling loop indefinitely, preventing the GitHub Release from ever reaching Latest and leaving install scripts pointing at a stale prerelease. Remove homebrew_ready from the hard polling condition. Hard gates are now only required platform assets + PyPI — the channels that actually serve the install scripts and in-app updater. Add a best-effort 'Check Homebrew tap' step that runs after promotion: it checks once and emits a warning annotation + step summary note + Slack alert if the tap lags, then exits 0. The job still succeeds; the warning is visible in the run summary without holding the release hostage.
📝 WalkthroughWalkthroughThe promote-release workflow stops blocking on Homebrew during readiness polling; it now promotes when assets and PyPI are ready. After promotion, a non-blocking Homebrew tap check warns if the formula lags. Website sync dispatch is made best-effort with non-fatal token minting and up to three retries before graceful exit. ChangesRelease Promotion Workflow Refactor
Pre-tool changelog gate and repo metadata
Sequence DiagramsequenceDiagram
participant PromoteJob as promote-release job
participant AssetCheck as Asset readiness checks
participant PyPI as PyPI readiness
participant Homebrew as Homebrew tap check (post-promotion)
participant GitHubApp as GitHub App token mint
participant WebsiteDispatch as Website sync dispatch
PromoteJob->>AssetCheck: poll required assets
PromoteJob->>PyPI: poll PyPI serving status
PromoteJob->>Homebrew: post-promotion best-effort check (warn if lag)
PromoteJob->>GitHubApp: mint app token (continue-on-error)
GitHubApp->>WebsiteDispatch: provide token (if minted)
WebsiteDispatch->>WebsiteDispatch: retry up to 3 times with backoff
WebsiteDispatch-->>PromoteJob: warn & exit 0 if dispatch fails
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Blocks gh pr create when shipped-code paths are changed but ## Unreleased in CHANGELOG.md is empty — catches the same gate that changelog-entry-required CI enforces, before the push. Escape hatches (mirroring CI): release/* branch, chore(release) title, or [skip changelog] in the PR body. Also unblocks .claude/settings.json and .claude/hooks/ from .gitignore (changed .claude to .claude/* so negation patterns work) so project-scoped hook config is tracked by the team.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.claude/settings.json:
- Around line 3-14: The PreToolUse hook uses matcher "Bash" but runtime wiring
expects target "Shell", so update the hook matcher from "Bash" to "Shell" (or
add a mapping/alias) and ensure the config loader supports the nested hooks
shape hooks.PreToolUse[].hooks[] (matching how tests exercise TOML [[hooks]]);
specifically, change the matcher string in the PreToolUse entry to "Shell" or
add normalization logic that maps "Bash" → "Shell", and verify the settings
deserialization loads the nested hooks.PreToolUse[].hooks[] structure so the
command hook is actually registered.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 51dc45c7-5ea9-4ba6-a494-60db80feab07
📒 Files selected for processing (3)
.claude/hooks/check-changelog.sh.claude/settings.json.gitignore
|
Re: CodeRabbit inline comment on CodeRabbit suggests changing The There is no |
Problem
promote-release.ymlpolled Homebrew as a hard gate alongside platform assets and PyPI. When the tap is broken (lostHOMEBREW_TAP_TOKEN, org migration, etc.), the loop runs for its full 40-minute budget and then fails — leaving the GitHub Release permanently as a prerelease and/releases/latestpointing at the last good version (was: 0.28.0, even after 0.29.0 and 0.30.0 shipped to PyPI).Fix
Hard gates (still block promotion):
.exe,.deb,.rpm, tarballs)Soft gate — moved to best-effort step after promotion (warn, never block):
The new
Check Homebrew tap (best-effort)step mirrors the existingTrigger pythinker-home sync (best-effort)pattern exactly: checks once, emits a::warningannotation + step summary note + Slack alert if behind, thenexit 0. The job succeeds; the gap is visible without holding the release hostage.What doesn't change
workflow_dispatchre-promote still worksnotify-failurejob only fires on hard-gate failures (assets/PyPI timeout)Summary by CodeRabbit
Chores
Documentation