Skip to content

Conversation

@matiasdaloia
Copy link
Collaborator

@matiasdaloia matiasdaloia commented Nov 7, 2025

Summary by CodeRabbit

  • New Features

    • Added pending update verification for Linux to finalize staged updates at application startup.
  • Bug Fixes

    • Enhanced macOS update flow with improved DMG mounting, app bundle installation, and quarantine attribute handling.
    • Improved Linux binary identification and verification with staged swap approach for safer updates.
    • Updated Windows update extraction and application process with better restart handling.
  • Changed

    • macOS wrapper script now uses CLI binary invocation instead of GUI launching for better consistency.

@matiasdaloia matiasdaloia self-assigned this Nov 7, 2025
@matiasdaloia matiasdaloia added the bug Something isn't working label Nov 7, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 7, 2025

Walkthrough

Update service enhancements across macOS, Windows, and Linux with platform-specific workflows. macOS now handles DMG mounting and app bundle installation, Linux introduces staged binary updates with verification, Windows uses the go-update library, and the macOS wrapper script now invokes the CLI binary directly instead of the GUI.

Changes

Cohort / File(s) Change Summary
Version Management
CHANGELOG.md
Added version 0.9.5 entry (2025-11-07) documenting macOS, Windows, and Linux update improvements plus error handling enhancements.
Update Service Implementation
backend/service/update_service_impl.go
Rewrote platform-specific update flows: macOS handles DMG mounting and rsync/cp-based app installation with quarantine clearing; Linux uses staged binary swaps with verification (ELF magic, size checks) and new CheckPendingUpdate() API for atomic binary finalization; Windows leverages go-update library. Adds file copy helpers, restart mechanics, and webkit version detection.
Dependency Management
go.mod
Added indirect dependency on github.com/inconshreveable/go-update for Windows update handling.
Application Startup
main.go
Added CheckPendingUpdate() call in run() before cmd.Execute() to finalize pending Linux updates during startup.
Installation Script
scripts/install-macos.sh
Refactored wrapper script to invoke CLI binary directly instead of launching GUI app; routes version, help, and scan operations through the binary with proper --scan-root handling.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant Main as main.go
    participant UpdateSvc as UpdateService
    participant FileSystem as File System

    App->>Main: Start Application
    Main->>UpdateSvc: CheckPendingUpdate()
    alt Pending Update Exists
        UpdateSvc->>FileSystem: Read .next binary
        UpdateSvc->>FileSystem: Verify binary (ELF magic, size)
        UpdateSvc->>FileSystem: Atomic swap .next → current binary
        UpdateSvc->>UpdateSvc: Restart into new binary
        UpdateSvc-->>Main: Success (or Rollback on failure)
    else No Pending Update
        UpdateSvc-->>Main: Return nil
    end
    Main->>Main: cmd.Execute()
Loading
sequenceDiagram
    participant Update as Update Process
    participant Asset as Asset Source
    participant Binary as Binary Staging
    participant Verify as Verification
    participant Restart as Restart Handler

    rect rgb(200, 230, 255)
    Note over Update,Restart: macOS Update Flow
    Update->>Asset: Download DMG
    Update->>Binary: Mount DMG, locate .app
    Update->>Binary: Copy app to /Applications (rsync/cp)
    Update->>Verify: Clear quarantine attributes
    Update->>Restart: Restart updated app
    end

    rect rgb(230, 200, 255)
    Note over Update,Restart: Linux Update Flow
    Update->>Asset: Download ZIP, detect binary (webkit version)
    Update->>Binary: Identify executable (prefer "scanoss" in name)
    Update->>Verify: Verify binary (ELF magic, size)
    Update->>Binary: Stage to .next path
    Update->>Restart: Trigger restart (finalize on next run via CheckPendingUpdate)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Platform-specific logic complexity: Each platform (macOS, Windows, Linux) has distinct update mechanics requiring separate reasoning; macOS DMG handling and Linux staged-swap approach are particularly intricate.
  • New public API (CheckPendingUpdate): Requires verification of error handling paths, atomic swap logic, and rollback mechanisms.
  • Binary verification and file operations: ELF header checks and file staging logic need careful review for edge cases and cleanup paths.
  • Integration point in main.go: Timing of CheckPendingUpdate() call relative to command execution should be validated.

Possibly related PRs

Poem

🐰 Hop along the update trail so fine,
DMGs mount, binaries staged in line.
Linux swaps with verification tight,
macOS bundles installed just right.
Windows leaps with go-update's might—
Cross-platform updates, bundled right! 🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title mentions only the macOS postinstall script fix, but the changeset includes significant updates to Windows/Linux update flows, changelog, main.go integration, and go.mod dependencies. Revise the title to accurately reflect the scope of changes, such as: 'feat: implement cross-platform auto-update mechanism with macOS/Linux/Windows enhancements' or consider splitting into multiple focused pull requests.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/mdaloia/macos-install-script-script

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.5.0)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link

github-actions bot commented Nov 7, 2025

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 184
  • Detected files undeclared: 0
  • Detected files declared: 184
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

Copy link

@coderabbitai coderabbitai bot left a comment

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)
backend/service/update_service_impl.go (1)

303-315: Consider letting hdiutil create the mount point.

The code creates the mountPoint directory before calling hdiutil attach. While hdiutil can use an existing directory, it's more idiomatic to let it create the mount point automatically by omitting the -mountpoint flag and parsing the output to determine where it was mounted.

However, the current approach works correctly and provides explicit control over the mount location for cleanup purposes.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 98f63ee and 3e9a515.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (5)
  • CHANGELOG.md (2 hunks)
  • backend/service/update_service_impl.go (7 hunks)
  • go.mod (1 hunks)
  • main.go (1 hunks)
  • scripts/install-macos.sh (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
main.go (1)
backend/service/update_service_impl.go (1)
  • CheckPendingUpdate (637-690)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (7)
main.go (1)

66-68: LGTM! Intentional error handling for startup update check.

The error from CheckPendingUpdate() is intentionally ignored, which is appropriate given the function's design:

  • It returns nil for non-Linux platforms
  • It silently handles errors during startup to avoid blocking application launch
  • On successful update, it re-execs into the new binary, so this code path doesn't return

The implementation in CheckPendingUpdate() also correctly handles the restart scenario by cleaning up the .old backup file when no pending update exists.

backend/service/update_service_impl.go (5)

337-375: LGTM! Robust macOS update implementation with fallback.

The implementation properly handles:

  • Atomic installation using rsync with --delete flag
  • Fallback to cp if rsync is unavailable
  • Quarantine attribute clearing to avoid security warnings
  • Proper application restart using the open command
  • Clean shutdown of the current instance

395-470: LGTM! Windows update correctly uses go-update library.

The implementation properly addresses Windows-specific challenges:

  • Uses PowerShell's Expand-Archive for ZIP extraction (available on all modern Windows)
  • Leverages the go-update library to handle Windows file locking issues when replacing running executables
  • Preserves command-line arguments when restarting
  • Properly shuts down the current instance

507-579: LGTM! Linux update uses robust staging approach.

The implementation correctly handles Linux-specific constraints:

  • Intelligent binary detection that prefers files with "scanoss" in the name, with fallback to first executable
  • Verifies the binary before staging (ELF magic check, size check)
  • Uses a staging approach (.next file) to avoid issues with replacing running executables
  • Atomic swap is deferred to application startup via CheckPendingUpdate()
  • Proper error handling with cleanup on failure

581-633: LGTM! Good basic verification and file copy utilities.

verifyLinuxBinary() provides essential checks:

  • Minimum size validation (1MB threshold)
  • ELF magic number verification to ensure it's a valid Linux binary

copyFile() implements a reliable file copy with Sync() to ensure data is persisted to disk.


635-695: LGTM! Well-designed startup update mechanism.

CheckPendingUpdate() is correctly implemented:

  • Platform-specific (Linux only)
  • Silently handles errors to avoid blocking startup
  • Performs atomic binary swap with rollback on failure
  • Cleans up old backups automatically
  • Re-execs into the new binary on successful update

restartApplication() provides a clean abstraction for the restart operation.

go.mod (1)

34-34: Consider migrating to a maintained alternative for go-update.

The version v0.0.0-20160112193335-8152e7eb6ccf is confirmed to be the latest available from the repository, last updated on 2016-01-12, and no known security vulnerabilities are registered. However, the original repository is low-activity with no strong active maintenance guarantees. Actively maintained alternatives include minio/selfupdate (a drop-in replacement), rhysd/go-github-selfupdate (for GitHub-release-driven workflows), and creativeprojects/go-selfupdate (with broader provider support). Evaluate whether migrating to one of these maintained forks is feasible for your use case.

@matiasdaloia matiasdaloia merged commit 8c1a838 into main Nov 7, 2025
6 checks passed
@matiasdaloia matiasdaloia deleted the fix/mdaloia/macos-install-script-script branch November 7, 2025 10:56
@coderabbitai coderabbitai bot mentioned this pull request Nov 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants