Skip to content

feat: add version check notifications and self-update command#6

Merged
kehoej merged 15 commits intomainfrom
feature/version-check
Apr 8, 2026
Merged

feat: add version check notifications and self-update command#6
kehoej merged 15 commits intomainfrom
feature/version-check

Conversation

@kehoej
Copy link
Copy Markdown
Owner

@kehoej kehoej commented Apr 7, 2026

Summary

Adds automatic version check notifications and a contextception update self-update command.

Version Check:

  • Cache-then-notify pattern: reads local JSON cache synchronously on every CLI invocation
  • Background goroutine refreshes cache from GitHub Releases API (24h TTL)
  • Prints one-line notification to stderr when a newer version exists
  • Suppresses repeat notifications for 7 days per version
  • Suppressible via --no-update-check flag, CONTEXTCEPTION_NO_UPDATE_CHECK=1 env var, or global config

Self-Update (contextception update):

  • Detects install method: Homebrew, go install, or direct download
  • Homebrew/go-install: prints the appropriate upgrade command
  • Direct download: downloads release archive, verifies SHA256 checksum, extracts binary, atomic replacement
  • Windows support: rename-dance for locked binary replacement
  • Security hardening: size limits on downloads (100MB), extraction (200MB), API responses (1MB), semver validation

Global Config:

  • Platform-native path via os.UserConfigDir()/contextception/config.yaml
  • Tolerant parsing (malformed YAML returns defaults)

Test Coverage

28 tests across 4 test files:

  • internal/config/global_test.go (4 tests): config loading, defaults, malformed YAML
  • internal/update/check_test.go (13 tests): semver comparison, cache, GitHub API mock, notification suppression
  • internal/update/selfupdate_test.go (10 tests): install detection, checksum, archive extraction, full self-update mock
  • internal/update/integration_test.go (1 test): full multi-run flow

All paths covered. Coverage gate: PASS.

Pre-Landing Review

2 informational issues found, both auto-fixed:

  • Added semver validation guard at SelfUpdate entry point
  • Fixed flaky integration test (replaced time.Sleep with channel-based synchronization)

Test plan

  • All Go tests pass with -race (23 packages, 0 failures)
  • go vet clean
  • golangci-lint 0 issues
  • Cross-compiles for all 6 targets (darwin/linux/windows x amd64/arm64)
  • Manual verification: notification, suppression, self-update, install detection

🤖 Generated with Claude Code

kehoej added 15 commits April 7, 2026 14:53
- Add HTTP status check in fetchLatestVersion (CRITICAL-1)
- Add 1MB response limit on GitHub API body (IMPORTANT-2)
- Add 100MB limit on httpGet for archive downloads (CRITICAL-2)
- Add 200MB limit on tar/zip extraction to prevent decompression bombs (CRITICAL-3)
- Skip version check notification when running 'update' command (IMPORTANT-5)
- Guard .bak cleanup to Windows only (IMPORTANT-6)
- Compute checksum in memory instead of temp file (MINOR-3)
Return a RefreshDone channel from CheckForUpdate so callers can
wait for the goroutine. PostRunE blocks on it to guarantee the
cache is populated for the next run.
…n handling

- Changed LoadGlobal to return *GlobalConfig directly instead of (*GlobalConfig, error).
- Updated NewRootCmd to use cobra.OnFinalize for update notification, ensuring it runs even on errors.
- Removed PersistentPostRunE in favor of the new finalizer approach for better cleanup.
- Enhanced error handling in update checks and cache refresh logic.
- Added support for release signing with minisign, enhancing security during self-update.
- Updated .goreleaser.yml to include signing configuration for checksums.
- Modified self-update logic to verify checksums.txt signatures before proceeding with updates.
- Enhanced documentation to reflect the new release signing feature and its implications for self-update.
@kehoej kehoej merged commit e18d6cf into main Apr 8, 2026
2 checks passed
@kehoej kehoej deleted the feature/version-check branch April 9, 2026 20:33
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