Dashboard: "new release available" badge linking to the GitHub release (#224)#225
Merged
Conversation
#224) A notify-only callout: when dashboard.check_for_updates is enabled, the dashboard periodically asks GitHub for the latest release and, if it's newer than the running version, shows a header badge next to the version badge — "New release vX.Y.Z available ↗" — linking to that release. It never updates anything (the one-click upgrade is the separate #59); you upgrade with ./pithead upgrade on your own terms. Privacy: OFF by default, so the appliance never contacts GitHub unbidden. When on, the check is routed over the bridge Tor SOCKS (reusing XVB_TOR_PROXY, like the XvB fetch #163) so it can't reveal the host IP to GitHub; it's cached hourly and fails silently offline. Added to docs/privacy.md's egress table per the #160 policy. - service/update_checker.py: parse_semver + compute_update (pure), GitHubReleaseClient (Tor fetch, fail-silent), UpdateChecker (hourly throttle, keeps last result on a blip). - data_service runs the check in its poll loop (gated, throttled, asyncio.to_thread) -> latest_data["update"]; build_state surfaces state.update; components.mjs renders an UpdateBadge (accent, opens the release in a new tab) in the Header. - config: dashboard.check_for_updates (default false) -> DASHBOARD_CHECK_UPDATES via pithead + compose; describe_change names GitHub/Tor; config.advanced.example.json. Tests: 17 dashboard tests (semver/compute_update/client fail-silent/throttle + the build_state surfacing) — update_checker.py 100% covered; 5 shell tests (render default-off + opt-in propagation + describe_change). Verified the badge end to end in a real browser: "New release v1.4.0 available ↗" links to the release, new tab, accent styling. Full suite green; coverage 94%; lint clean. Closes #224. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
VijitSingh97
force-pushed
the
feat/224-update-badge
branch
from
June 12, 2026 02:10
0ab08e1 to
7faa8a3
Compare
15 tasks
…s audit (#224) Per maintainer steer: since the new-release check is routed over Tor (socks5h, so neither the host IP nor a DNS lookup reaches GitHub — GitHub only ever sees a Tor exit), there's no privacy leak, so make it the default. dashboard.check_for_updates flips to default true; set it false to opt out. config.py / pithead / compose / config example / docs / tests updated accordingly. Stack-wide egress audit (the rest of the stack), reconciled into docs/privacy.md + a comment on the #160 epic: - No new RUNTIME clearnet leaks. The only on-by-default clearnet runtime egress remains #165 (p2pool outbound peers) and #166 (XvB donation mining), both already tracked for v1.1 (the Tor flip needs orphan/reject benchmarking — not easy). - monerod/Tari DNS stay closed/sinkholed (#161/#162); monerod RPC-to-remote is clearnet only in the opt-in monero.mode:remote path; pithead makes no egress. - Documented the one gap the audit found: the GHCR image pull #44 introduced (release installs pull pithead-* from ghcr.io) — an inherent build/setup egress, now in privacy.md's build/setup table alongside the github/getmonero downloads. Tests: the shell render test now asserts default-on + the opt-out (false) path; the describe_change + update_checker (Tor-routing, fail-silent) tests are unchanged. Full suite green; coverage 94%; lint + compose clean. Closes #224.
Collaborator
Author
|
Update (follow-up commit): flipped to default-on + a stack-wide egress audit.
CI 12/12 green. |
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.
Closes #224. A small, notify-only callout: a header badge that links to a newer GitHub release. Exactly what was asked — an extra badge on top, "New release vX.Y.Z available", clickable, no self-updating.
What it does
When
dashboard.check_for_updatesis enabled, the dashboard periodically asks GitHub for the latest release and — if it's newer than the running version (#58'sPITHEAD_VERSION) — shows a badge next to the version badge:It never updates anything; you upgrade with
./pithead upgradeon your own terms (the one-click upgrade is the separate #59).Privacy (the important bit)
A dashboard→GitHub check is a new outbound egress, so per the #160 policy:
dashboard.check_for_updates: false) — the appliance never contacts GitHub unbidden.XVB_TOR_PROXY, same pattern as the XvB fetch Dashboard: route XvB stats through Tor + gate behind XVB_ENABLED (IP↔wallet leak) #163), so enabling it can't reveal the host IP to GitHub.docs/privacy.md's egress table + documented indocs/configuration.md.Implementation
service/update_checker.py—parse_semver+compute_update(pure),GitHubReleaseClient(Tor fetch, fail-silent),UpdateChecker(hourly throttle; keeps the last result through a transient blip so the badge doesn't flicker).data_serviceruns it in the existing poll loop (gated on the flag, throttled,asyncio.to_thread) →latest_data["update"];build_statesurfacesstate.update;components.mjsrenders theUpdateBadgein theHeader.dashboard.check_for_updates(defaultfalse) →DASHBOARD_CHECK_UPDATESvia pithead + compose;describe_changenames GitHub/Tor.Tests + validation
update_checker.py100% covered; 5 shell tests (default-off render, opt-in propagation, describe_change).🤖 Generated with Claude Code