Skip to content

feat(cli): add installation-aware update command#263

Merged
fahimfaisaal merged 3 commits into
mainfrom
feat/vizb-update-command
Jul 26, 2026
Merged

feat(cli): add installation-aware update command#263
fahimfaisaal merged 3 commits into
mainfrom
feat/vizb-update-command

Conversation

@fahimfaisaal

@fahimfaisaal fahimfaisaal commented Jul 22, 2026

Copy link
Copy Markdown
Member

Summary

  • add an installation-aware vizb update command that delegates Go and WinGet installations and refuses unidentified builds
  • resolve stable GitHub releases, verify the existing GoReleaser SHA-256 checksum, prevent downgrades, and atomically replace standalone Linux/macOS binaries
  • leave Windows standalone binaries unchanged and print the existing PowerShell reinstall command; Windows native self-update is deferred
  • mark official release archives as standalone and document update behavior without adding a local receipt or remote manifest

Installation behavior

Installation vizb update behavior
Standalone Linux/macOS checksum-verified in-place update
Standalone Windows prints irm https://vizb.goptics.org/install.ps1 | iex; no network request or binary change
Go toolchain prints go install github.com/goptics/vizb@latest
WinGet prints winget upgrade --id goptics.vizb --exact
Development/unknown refuses to modify the executable

The existing install.sh and install.ps1 files remain the initial-install entry points. No installer script is embedded in the Vizb binary.

Validation

  • task format:check — Go and UI formatting pass
  • task test — all Go tests and 503 UI tests pass
  • task lint — Go lint and UI typecheck pass
  • task build:docs — documentation build passes
  • task release:check — GoReleaser configuration is valid
  • Windows amd64 and arm64 cross-builds pass
  • live Linux smoke update replaced a temporary v0.16.0 standalone build with the published v0.16.1 binary

Closes #262

Summary by CodeRabbit

  • New Features
    • Added the vizb update command for safely updating standalone installations.
    • Verifies release checksums before replacing the executable.
    • Provides installation-specific guidance for Windows and package-managed installations.
  • Documentation
    • Added comprehensive update command documentation and installation guidance.
  • Bug Fixes
    • Improved temporary-file cleanup to remove tracked directories recursively.
  • Tests
    • Added coverage for update detection, validation, failures, checksum safety, and executable replacement.

Detect Go and WinGet installations, checksum and atomically replace standalone releases, and use a versioned junction layout for safe Windows updates.

Closes #262
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an installation-aware vizb update command that detects package-managed and standalone installations, verifies GitHub release archives, atomically replaces Linux/macOS binaries, provides Windows and package-manager instructions, and documents the behavior.

Changes

Installation-aware update command

Layer / File(s) Summary
Installation detection and release contracts
.goreleaser.yml, version/version.go, internal/updater/installation.go, internal/updater/release.go, go.mod, .github/workflows/cli.yml
Builds now carry a distribution marker; installation detection distinguishes standalone, Go toolchain, WinGet, and unknown builds; release versions and platform assets are resolved and validated.
Release acquisition and executable update
internal/updater/download.go, internal/updater/archive.go, internal/updater/updater.go, internal/updater/updater_test.go
Downloads bounded release assets, verifies checksums, extracts .tar.gz binaries, avoids downgrades, handles Windows and managed installations, and atomically replaces standalone executables with failure-preservation tests.
Cobra command integration
cmd/update.go, cmd/testing.go, cmd/update_test.go
Registers the no-argument update command, passes standard streams to the updater, resets command state between tests, and validates argument, I/O, and error behavior.
Update documentation
docs/astro.config.mjs, docs/src/content/docs/commands/update.mdx, docs/src/content/docs/installation.mdx
Adds update navigation and documents installation-specific update instructions, checksum verification, permissions, and Windows limitations.
Recursive temporary cleanup
shared/tmp_files_manager.go, shared/tmp_files_manager_test.go
Tracked temporary directories are removed recursively, with coverage for nested files.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant UpdateCommand
  participant Updater
  participant GitHubReleases
  participant Filesystem
  User->>UpdateCommand: run vizb update
  UpdateCommand->>Updater: Run with CLI streams
  Updater->>Filesystem: detect installation and executable
  Updater->>GitHubReleases: resolve release and download assets
  GitHubReleases-->>Updater: checksums.txt and archive
  Updater->>Filesystem: verify, extract, and stage binary
  Updater->>Filesystem: atomically replace executable
  Updater-->>UpdateCommand: status or error
  UpdateCommand-->>User: output
Loading

Possibly related PRs

  • goptics/vizb#238: Both changes modify TmpFilesManager.RemoveAll; that PR adds concurrency protection while this PR adds recursive directory removal.

Suggested labels: cli

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement the no-arg update command, install detection, safe standalone updates, delegation, docs, and tests required by #262.
Out of Scope Changes check ✅ Passed The diff stays focused on the update command and supporting docs, release config, tests, and updater helpers.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding an installation-aware update command to the CLI.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
internal/updater/updater.go (1)

151-154: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Store the updater’s temp paths in shared.TempFiles. prepareCandidate, replaceExecutable, and runWindowsInstaller still create their own workspace/staging/script files with os.MkdirTemp and os.CreateTemp; adding those paths to the shared manager would align this flow with the rest of the app’s temp-file cleanup.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/updater/updater.go` around lines 151 - 154, Update prepareCandidate,
replaceExecutable, and runWindowsInstaller to register every path created by
os.MkdirTemp or os.CreateTemp with the shared shared.TempFiles manager. Preserve
the existing cleanup and error-handling behavior while ensuring all updater
workspace, staging, and script files are tracked for centralized cleanup.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/cli.yml:
- Around line 31-34: Harden the windows-installer job by adding a
least-privilege permissions block with no write access and configuring its
actions/checkout step to disable persisted credentials. Update only the
windows-installer job and its checkout configuration.

In `@internal/updater/install.ps1`:
- Around line 205-220: Add a one-time TLS 1.2 security protocol assignment near
the top of the PowerShell script, before Get-LatestVersion and the
archive/checksum download logic execute. Ensure all GitHub WebRequest operations
use this pinned protocol rather than the Windows PowerShell 5.1 host default.

---

Nitpick comments:
In `@internal/updater/updater.go`:
- Around line 151-154: Update prepareCandidate, replaceExecutable, and
runWindowsInstaller to register every path created by os.MkdirTemp or
os.CreateTemp with the shared shared.TempFiles manager. Preserve the existing
cleanup and error-handling behavior while ensuring all updater workspace,
staging, and script files are tracked for centralized cleanup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 74a08caa-cb87-45c8-b31d-46a36d46a084

📥 Commits

Reviewing files that changed from the base of the PR and between 6d9b88f and a78617b.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (19)
  • .github/workflows/cli.yml
  • .goreleaser.yml
  • cmd/testing.go
  • cmd/update.go
  • cmd/update_test.go
  • docs/astro.config.mjs
  • docs/public/install.ps1
  • docs/public/install.ps1
  • docs/src/content/docs/commands/update.mdx
  • docs/src/content/docs/installation.mdx
  • go.mod
  • internal/updater/archive.go
  • internal/updater/download.go
  • internal/updater/install.ps1
  • internal/updater/installation.go
  • internal/updater/release.go
  • internal/updater/updater.go
  • internal/updater/updater_test.go
  • version/version.go

Comment thread .github/workflows/cli.yml Outdated
Comment thread internal/updater/install.ps1 Outdated
Pin the Windows validation job to read-only checkout permissions, enable TLS 1.2 for Windows PowerShell, and register updater workspaces with centralized temporary-path cleanup.
Keep standalone self-update native to Linux and macOS. Windows standalone builds now print the existing PowerShell reinstall command, while WinGet and Go installations remain delegated to their package managers.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/updater/updater_test.go`:
- Around line 395-397: Update the test around extractBinary to create the
archive fixture and extraction workspace through shared.TempFiles instead of
s.T().TempDir(). Preserve the temporary-file manager’s cleanup registration
across all exit paths while keeping the existing missingArchive and extraction
assertions unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 81bd7f45-9f99-4f4c-888c-a7c1b2d5d38e

📥 Commits

Reviewing files that changed from the base of the PR and between db78d02 and 93a5663.

📒 Files selected for processing (7)
  • .github/workflows/cli.yml
  • docs/src/content/docs/commands/update.mdx
  • docs/src/content/docs/installation.mdx
  • internal/updater/archive.go
  • internal/updater/release.go
  • internal/updater/updater.go
  • internal/updater/updater_test.go
💤 Files with no reviewable changes (2)
  • .github/workflows/cli.yml
  • internal/updater/archive.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/src/content/docs/installation.mdx
  • internal/updater/release.go

Comment on lines +395 to +397
missingPath := filepath.Join(s.T().TempDir(), "release.tar.gz")
s.Require().NoError(os.WriteFile(missingPath, missingArchive, 0o600))
err := extractBinary(missingPath, ".tar.gz", filepath.Join(s.T().TempDir(), "vizb"), "vizb")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Use shared.TempFiles for the archive fixture.

This test bypasses the repository-required temporary-file manager by using s.T().TempDir() directly. Allocate the temporary workspace through shared.TempFiles and preserve its cleanup registration.

As per coding guidelines, **/*.go must manage temporary files through shared.TempFiles and preserve cleanup on all exit paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/updater/updater_test.go` around lines 395 - 397, Update the test
around extractBinary to create the archive fixture and extraction workspace
through shared.TempFiles instead of s.T().TempDir(). Preserve the temporary-file
manager’s cleanup registration across all exit paths while keeping the existing
missingArchive and extraction assertions unchanged.

Source: Coding guidelines

@fahimfaisaal
fahimfaisaal merged commit 3adfb71 into main Jul 26, 2026
14 checks passed
@fahimfaisaal
fahimfaisaal deleted the feat/vizb-update-command branch July 26, 2026 07:14
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.

[feat]: Add installation-aware vizb update command

1 participant