Skip to content

fix(update): loud appcast publishing + unified channel precedence - #1026

Merged
github-actions[bot] merged 1 commit into
mainfrom
fix/autoupdate-feed-consistency
Aug 22, 2026
Merged

fix(update): loud appcast publishing + unified channel precedence#1026
github-actions[bot] merged 1 commit into
mainfrom
fix/autoupdate-feed-consistency

Conversation

@Dumbris

@Dumbris Dumbris commented Aug 22, 2026

Copy link
Copy Markdown
Member

Problem

Two update mechanisms disagreed on v0.60.0: the Sparkle dialog said "0.59.0 is currently the newest version available" while the tray menu line and mcpproxy doctor offered v0.60.0.

Root cause: the release run's repository-dispatch to the website repo failed with Bad credentials (expired MARKETING_SITE_DISPATCH_TOKEN) under continue-on-error: true — the release stayed green while https://mcpproxy.app/appcast-*.xml kept serving the 0.59.0 feed. Sparkle reads that feed; the menu line and doctor read the GitHub API. Because each feed carries a single item, any stale window also makes updates look sequential (users offered exactly N-1). No code path ever picks a non-latest version — the Go side always resolves /releases/latest (verified across checker, tray, doctor, update).

The 0.60.0 feeds have already been backfilled manually (all four live feeds now serve 0.60.0); this PR prevents the silent recurrence.

Changes

CI

  • release.yml / prerelease.yml: drop continue-on-error from the publish-appcast dispatch steps. They run after every release asset (feeds included) is uploaded, so a red job blocks nothing — it is the recovery signal. The beta feed is the only stable URL for the rc channel (GitHub releases/latest/download never resolves prereleases), so a lost beta dispatch strands every RC user.
  • Both sparkle-appcast jobs get a Verify live feeds are fresh step: poll mcpproxy.app until the live bytes sha256-match the just-generated feeds (one shared 15-min deadline, check-first per feed) — mirroring the site's own verify step, but on the side of the link that actually broke.

Go (divergence found while auditing all update surfaces)

  • mcpproxy update now applies the same build-version-authoritative channel precedence as the daemon's checker, via new exported updatecheck.IncludePrereleasesForBuild: a stable build never resolves against the prerelease list, even with a stale channel: rc config or env opt-in; go-install builds promote their module version first (updatecheck.PromoteGoInstallVersion), exactly like the checker (Spec 079 FR-014/FR-023).
  • Fixed the stale "every 4 hours" doc comment on VersionInfo (actual: 24h + failure backoff).

Operational note (not in this PR)

MARKETING_SITE_DISPATCH_TOKEN is still dead and needs rotation — it also broke trigger-marketing-update on v0.60.0. With this PR, the next release will fail loudly instead of silently if the token is still invalid.

Testing

  • New TestPrereleasePreference_BuildIdentityAuthoritative (env pinned against ambient opt-ins)
  • go test ./internal/updatecheck/... ./cmd/mcpproxy/... green; server edition green
  • ./scripts/test-api-e2e.sh: 65/65
  • golangci-lint v2 (CI config): 0 issues; both workflow YAMLs parse

The v0.60.0 release exposed a silent failure chain: the repository-dispatch
that tells mcpproxy.app to serve the fresh Sparkle feeds 401'd on an expired
MARKETING_SITE_DISPATCH_TOKEN under continue-on-error, so the site kept
serving the 0.59.0 feed. Sparkle told users they were up to date while the
tray menu line and doctor (GitHub API) offered v0.60.0 — and every stale
window makes updates look sequential, since the single-item feed then offers
exactly N-1.

CI:
- release.yml / prerelease.yml: drop continue-on-error from the
  publish-appcast dispatch steps. They run after all release assets
  (feeds included) are uploaded, so a red job blocks nothing — it is the
  recovery signal.
- Add a 'Verify live feeds are fresh' step to both sparkle-appcast jobs:
  poll mcpproxy.app until the live bytes sha256-match the just-generated
  feeds (one shared 15-min deadline), mirroring the site's own verify but
  on the side of the broken link that actually failed.

Go (divergence found while auditing the surfaces):
- mcpproxy update now applies the same build-version-authoritative channel
  precedence as the daemon's checker (exported as
  updatecheck.IncludePrereleasesForBuild): a stable build never resolves
  against the prerelease list, even with a stale 'channel: rc' config or
  env opt-in, and go-install builds promote their module version first
  (updatecheck.PromoteGoInstallVersion) exactly like the checker.
- Fix the stale 'every 4 hours' doc comment on VersionInfo.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6a5c442
Status: ✅  Deploy successful!
Preview URL: https://14f17a6c.mcpproxy-docs.pages.dev
Branch Preview URL: https://fix-autoupdate-feed-consiste.mcpproxy-docs.pages.dev

View logs

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 55.00000% with 9 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/mcpproxy/update_cmd.go 22.22% 7 Missing ⚠️
internal/updatecheck/channel.go 50.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions

Copy link
Copy Markdown

📦 Build Artifacts

Workflow Run: View Run
Branch: fix/autoupdate-feed-consistency

Available Artifacts

  • archive-darwin-amd64 (29 MB)
  • archive-darwin-arm64 (26 MB)
  • archive-linux-amd64 (17 MB)
  • archive-linux-arm64 (15 MB)
  • archive-windows-amd64 (29 MB)
  • archive-windows-arm64 (25 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (23 MB)
  • installer-dmg-darwin-arm64 (20 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 32563959390 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved (Model B): Paperclip review verdicts = ACCEPT and qa-gate green at this head SHA. Arming auto-merge; GitHub merges when all required checks pass.

@github-actions
github-actions Bot merged commit 20a3e50 into main Aug 22, 2026
39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants