DEV-17Recommended
Check for new versions at most once a day and never in scripts
Look for a newer version at most once per 24 hours and cache the answer. Skip the check when CI is set, when standard output or standard error is not a terminal, or when the opt-out variable is set. The check never delays or fails the command.
How to do it
A tool that calls home on every run slows scripts, breaks offline work and floods the release server. Run the check in the background with a 2 second time limit, or show the answer cached from the last check. Store the cache under $XDG_CACHE_HOME, as Read settings in one documented order from standard folders says. Print the notice to standard error after the command's own output. JSON on standard output then stays clean, as Write results to stdout and everything else to stderr says. Name the upgrade command for the way the tool was installed, such as brew upgrade example. Never update without asking. A tool that updates itself verifies the download as Verify every update's signature before installing it says.
Examples
JavaScript example
import { isatty } from 'node:tty'
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000
function shouldCheckForUpdate(env, cache, now = Date.now()) {
if (env.CI || env.EXAMPLE_NO_UPDATE_CHECK === '1') return false
if (!isatty(1) || !isatty(2)) return false
return !cache.checkedAt || now - cache.checkedAt >= CHECK_INTERVAL_MS
}
Python example
import os, sys, time
CHECK_INTERVAL_SECONDS = 24 * 60 * 60
def should_check_for_update(cache, env=os.environ, now=None) -> bool:
if env.get("CI") or env.get("EXAMPLE_NO_UPDATE_CHECK") == "1":
return False
if not (sys.stdout.isatty() and sys.stderr.isatty()):
return False
now = now or time.time()
return cache.checked_at is None or now - cache.checked_at >= CHECK_INTERVAL_SECONDS
How to check
A test runs a command three times within an hour against a fake release server, which gets 1 request. With CI=true, with output piped or with EXAMPLE_NO_UPDATE_CHECK=1, it gets 0 requests. With a release server that never answers, the command ends within 1 second of its usual time with its usual exit code. The notice never appears on standard output.
Related rules
- DEV-14 Read settings in one documented order from standard folders in Developer tools, SDKs and CLIs
- DEV-2 Write results to stdout and everything else to stderr in Developer tools, SDKs and CLIs
- DSK-6 Verify every update's signature before installing it in Desktop apps and extensions
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/developer-tools/help-completion-and-updates/version-check">Agent Wranglers developer tools, SDKs and CLIs playbook</a>. In code you write, add a comment next to it with the same link.