Verify public appcast publication after releases#896
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThe release workflow now polls the canonical GitHub Pages appcast after publication, validating release metadata and cache age. A standalone verifier, unit tests, preflight integration, and release-readiness documentation were added. ChangesAppcast publication verification
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant ReleaseWorkflow
participant Verifier
participant GitHubPages
ReleaseWorkflow->>Verifier: Invoke with version, build, channel, URL, signature, and length
Verifier->>GitHubPages: Poll canonical appcast URL
GitHubPages-->>Verifier: Return feed and cache headers
Verifier-->>ReleaseWorkflow: Report publication success or timeout
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
fc5ea05 to
5122306
Compare
|
Caution Review failedAn error occurred during the review process. Please try again later. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
5122306 to
c3875d9
Compare
Summary
Issue context
The release workflow updated
appcast.xmlongh-pagesbut completed without checking what Sparkle clients could actually fetch. The canonical endpoint currently advertisesCache-Control: max-age=600, and cache-busting query parameters do not bypass the effective CDN cache.This change keeps the canonical feed URL and adds a release-layer publication gate. After the
gh-pagespush, the workflow polls the unmodified public URL for up to 900 seconds. It succeeds only when the response cache lifetime is at most 600 seconds and the feed contains the exact release metadata and signed ZIP information. This also prevents a rerun of an existing tag from accepting an appcast that still references the previous ZIP signature.Closes #895
Test plan
python3 scripts/test_verify_appcast_publication.pyactionlint -shellcheck= .github/workflows/release.ymlscripts/pr-preflight.shpython3 scripts/verify_appcast_publication.py --url https://typewhisper.github.io/typewhisper-mac/appcast.xml --version 1.6.0-daily.20260714 --build-version 961 --channel daily --download-url https://github.com/TypeWhisper/typewhisper-mac/releases/download/v1.6.0-daily.20260714/TypeWhisper-v1.6.0-daily.20260714.zip --signature 6lhEaHcsakLAzlLI6zISC8A6U1pf3XINWca8OcfOFKpsQjdo3yOgfQhj+WchthR7KsfzX7hIVuyza6x/lgdiDg== --length 13736660 --maximum-cache-age-seconds 600 --timeout-seconds 0 --poll-interval-seconds 1The live verification observed the expected daily entry and matching signed ZIP metadata with
Cache-Control: max-age=600through the canonical URL without a query parameter.Summary by CodeRabbit
Release Reliability
Documentation