Skip to content

feat: daily update notifier - #7

Open
RogerCecilpot wants to merge 1 commit into
feat/236-api-clientsfrom
feat/259-update-notifier
Open

RogerCecilpot wants to merge 1 commit into
feat/236-api-clientsfrom
feat/259-update-notifier

Conversation

@RogerCecilpot

Copy link
Copy Markdown

Closes devlyft/devlyft#259. Stacked on #5 (which is stacked on #2); retarget once those merge.

What

  • internal/update: Enabled (off when CI is set, DEVLYFT_NO_UPDATE_NOTIFIER is set, stderr isn't a TTY, or the build has no semver version, e.g. dev), Checker.Check (unauthenticated GET of https://api.github.com/repos/devlyft/cli/releases/latest, compared with golang.org/x/mod/semver), Notice, IsHomebrew.
  • At most once a day: the time of the last successful check is stored in os.UserCacheDir()/devlyft/update-state.json (0600, written atomically). Within 24h no request is made and no notice is printed. A failed check isn't recorded, so the next run retries. A check time in the future (clock moved back) doesn't suppress checks.
  • cli.Execute starts the check in a goroutine before the command and, after a successful command, prints the notice to stderr only if the result arrives within 250ms (the request itself times out after 2s). Failed commands print nothing extra, so --format json errors on stderr stay a single JSON object. version and completion (and Cobra's hidden __complete) never show it.
  • Notice: A new release of devlyft is available: 0.1.0 → 0.2.0 + the release URL, plus brew upgrade devlyft/tap/devlyft when the executable is under a Homebrew prefix (tap from #258).
  • README: no telemetry in v1; the update check is the only extra network call; how to disable it.

Tests

A test for each disable path (CI, env var, non-TTY, dev build), newer/equal/older/prerelease versions, the 24h cache making no request, state file mode, server errors/rate limiting/invalid tags/network failure being silent and retried, and the notifier only printing after success when the result is ready. make lint, make test, make vuln pass.

Notes

  • GitHub's unauthenticated limit is 60 requests/hour per IP; one request a day per user is well inside it.
  • Until the first release is tagged, /releases/latest returns 404, which is silent.

🤖 Generated with Claude Code

@RogerCecilpot
RogerCecilpot force-pushed the feat/259-update-notifier branch from 40661da to 479e755 Compare October 25, 2026 12:56
@RogerCecilpot
RogerCecilpot changed the base branch from feat/246-output-errors-exit-codes to feat/236-api-clients October 25, 2026 12:57
@RogerCecilpot
RogerCecilpot force-pushed the feat/259-update-notifier branch from 479e755 to 4bfb39f Compare October 25, 2026 13:00
At most once a day, check the latest GitHub release in the background
while the command runs and, if it is newer, print a notice to stderr
after a successful command (with the brew upgrade command for Homebrew
installs). The finished command waits at most 250ms for the check, which
itself times out after 2s; failures are silent.

Skipped when CI is set, stderr is not a terminal,
DEVLYFT_NO_UPDATE_NOTIFIER is set, for dev builds, and for `version` and
`completion`. The last check time is cached in the user cache directory
(0600). The README documents that there is no telemetry in v1.

Refs devlyft/devlyft#259

Co-Authored-By: Claude Opus 5.5 <[email protected]>
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.

1 participant