fix(update): derive RC/stable channel from the running build, not config - #978
Merged
Merged
Conversation
A stable user was being offered RC updates. Root cause: the update channel was resolved purely from update_check.channel / MCPPROXY_ALLOW_PRERELEASE_UPDATES, so a stale `rc` opt-in left over from a previously-installed RC kept a stable build on the rc channel — the core then reported update_policy.channel=rc over /api/v1/info, and the Swift Sparkle tray (allowedChannels + feed selection) plus the Go checker offered the next RC. Make the running build's own version authoritative (Checker.IncludePrereleases): - stable build (valid semver, no prerelease suffix) → NEVER offered an RC, regardless of config/env; - RC build (-rc.N / -next.*) → tracks the rc channel by default (offered the next RC, and its graduating stable via existing pure-semver comparison); - dev/unstamped build (invalid semver) → keeps the config/env opt-in, the only path that can exercise the rc channel without a released RC binary. This one core change governs every surface: the Go checker's GitHub query, the policy the Swift tray consumes over /api/v1/info, and the legacy Go-tray self-update path (App.includePrereleases, gated the same way). Config update_check.channel and the env flag now only affect dev builds; documented in the field comment and docs/prerelease-builds.md. Verified: TDD (build-identity + policy tests, tray gate test); full internal/updatecheck and internal/tray green under -race; both editions build; lint clean; live /api/v1/info proof — a stable v0.56.0 core with update_check.channel=rc reports channel=stable, an rc-stamped core reports channel=rc.
Deploying mcpproxy-docs with
|
| Latest commit: |
3212433
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://b66dae3d.mcpproxy-docs.pages.dev |
| Branch Preview URL: | https://fix-update-channel-build-ide.mcpproxy-docs.pages.dev |
…ion handling Codex cross-review round 1 on #978, all four findings: - [P1] Swift Sparkle tray clamped against the CORE's version, not the app's. Mixed app+core versions are supported (a stable app can attach to a newer external RC core reporting channel=rc), so a stable app would inherit rc and offer ITSELF an RC. UpdatePolicyResolver.resolve now takes the app's own CFBundleShortVersionString and pins a stable bundle to the stable channel regardless of core policy; UpdateService resolves it once (injectable for deterministic tests). All three Sparkle hooks (feed URL, allowedChannels, comparator) inherit the clamp. - [P2] go-install pseudo-versions (valid semver WITH a prerelease component, e.g. v0.47.1-0.2026...-abc) were force-tracked onto rc like a real -rc build. versionChannelKind now classifies module.IsPseudoVersion as unknown/dev, so the config/env opt-in governs them. - [P2] Corrected the dev/unstamped comment: invalid-semver builds are skipped by the Start/CheckNow semver guard entirely; the reachable "unknown" path is the pseudo-version go-install build. - [P2] Updated the docs/spec that still asserted the old config/env precedence: version-updates.md, configuration.md, rest-api.md, and a build-identity amendment (FR-013a) to specs/079. New tests: pseudo-version classification (Go); host-bundle clamp at the resolver and end-to-end through UpdateService→feed (Swift). Full Go updatecheck/tray green under -race; Swift UpdatePolicy/UpdateServiceFeed green (the remaining AppLifecycle journal failure is a pre-existing environmental tray-lifecycle.jsonl issue, untouched by this diff).
… narrowing Codex round 2: prerelease-builds.md said the tray simply inherits the core channel and 'all surfaces agree', which is intentionally false for a stable tray attached to a newer RC core — the tray narrows to stable on top of the core policy. Document core policy as an input followed by the host-bundle clamp.
internal/tray is //go:build !nogui && !headless && !linux (the systray App type does not exist on Linux), so an untagged test referencing App.version / includePrereleases broke the Linux unit-test build — cascading to all CI jobs. Match the constraint the other tray tests carry. Local darwin builds masked it.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…s link check) The relative ../prerelease-builds.md link broke the docs build — Docusaurus resolves it to /prerelease-builds (prerelease-builds.md is a repo doc, not a routed site page). Match the sibling convention in docs/features/auto-update.md, which links it via the GitHub blob URL.
📦 Build ArtifactsWorkflow Run: View Run Available Artifacts
How to DownloadOption 1: GitHub Web UI (easiest)
Option 2: GitHub CLI gh run download 31774197969 --repo smart-mcp-proxy/mcpproxy-go
|
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
A user on a stable build was being offered RC updates. The update channel was resolved purely from
update_check.channel/MCPPROXY_ALLOW_PRERELEASE_UPDATES, so a stalercopt-in left over from a previously-installed RC kept a stable build on the rc channel. The core then reportedupdate_policy.channel=rcoverGET /api/v1/info, and both the Swift Sparkle tray (allowedChannels+ feed selection) and the Go checker offered the next RC.Fix
The running build's own version is now authoritative (
Checker.IncludePrereleases):v0.56.0)v0.56.0-rc.1)An RC build tracks the rc channel by default, so an RC user is offered the next RC and — via the existing pure-semver comparison — its graduating stable (
-rc.1→ stable).update_check.channeland the env flag now only affect dev builds (documented in the field comment +docs/prerelease-builds.md).This one core change governs every surface: the Go checker's GitHub query, the policy the Swift Sparkle tray consumes over
/api/v1/info, and the legacy Go-tray self-update path (App.includePrereleases, gated identically).Verification
internal/updatecheck), tray gate test (internal/tray); full packages green under-race; both editions build; lint clean./api/v1/infoproof: a stablev0.56.0core withupdate_check.channel: rcreportschannel: stable; an rc-stamped core reportschannel: rc.Behavior decision confirmed with maintainer: the stable→never-RC rule is absolute (build identity overrides the config/env opt-in), fixing the bug even when a stale
rcconfig lingers.