release-hub

Crates.iorelease-hub
lib.rsrelease-hub
version0.2.0
created_at2025-11-13 02:26:45.452376+00
updated_at2025-11-13 06:33:56.469572+00
descriptionA simple updater for Rust GUI applications
homepage
repositoryhttps://github.com/tangxiangong/release-hub
max_upload_size
id1930314
size124,223
小雨 (tangxiangong)

documentation

README

ReleaseHub

A simple, cross-platform auto-updater for Rust desktop GUI applications.

Crates.io Version docs.rs License: MIT OR Apache-2.0

This crate helps your application check for the latest GitHub Releases and download/install the proper artifact for the current platform. It focuses on a minimal API surface, safe defaults, and a predictable end-user experience on macOS and Windows.

Features

  • GitHub Releases integration via octocrab
  • Semantic versioning with semver
  • Platform-aware asset selection (macOS .app.zip, Windows .exe/.msi)
  • Progress callback during download
  • Pluggable headers, proxy and timeout
  • Atomic install flow with privilege elevation when required

Supported platforms

  • macOS (unpacks .app.zip and swaps the app bundle atomically)
  • Windows (downloads .exe/.msi installer, launches with elevation when needed)

Linux is currently not supported for install flow. The crate compiles on Linux for development, but installation logic is provided only for macOS and Windows.

Quick start

Add to your Cargo.toml:

[dependencies]
release-hub = "*"

Basic usage:

use release_hub::{UpdaterBuilder};
use semver::Version;

#[tokio::main]
async fn main() -> release_hub::Result<()> {
    let updater = UpdaterBuilder::new(
        "MyApp",                       // Application name (for temp files / logs)
        "0.1.0",                       // Current version
        "owner",                       // GitHub owner
        "repo",                        // GitHub repo
    )
    .build()?;

    // Option A: one-shot convenience
    let updated = updater.update(|chunk| {
        // chunk = size of bytes received in this tick
        let _ = chunk;
    }).await?;

    if updated {
        // Relaunch when appropriate for your app lifecycle
        // updater.relaunch()?;
    }

    Ok(())
}

Manual flow:

let updater = /* build as above */;
if let Some(ready) = updater.check().await? {
    let bytes = ready.download(|_| {}).await?;
    ready.install(bytes)?;
    // ready.relaunch()?; // Optional: relaunch the updated app
}

Configuration highlights

  • Headers: attach custom HTTP headers to the download request
  • Proxy: route download traffic via a proxy (e.g. corporate networks)
  • Timeout: set a global request timeout
  • Executable path: override auto-detected path used to compute install target

Example:

use http::header::{AUTHORIZATION, HeaderValue};
use url::Url;

let updater = UpdaterBuilder::new("MyApp", "0.1.0", "owner", "repo")
    .header(AUTHORIZATION, HeaderValue::from_static("token OAUTH_OR_PAT"))?
    .proxy(Url::parse("http://proxy.local:8080").unwrap())
    .timeout(std::time::Duration::from_secs(60))
    .build()?;

How it works

  1. Queries the GitHub API for the latest release
  2. Parses assets and picks the correct file for the current OS and CPU arch
  3. Downloads the asset with progress callback
  4. Installs it:
    • macOS: extracts .app.zip, replaces the .app atomically, elevating when necessary
    • Windows: writes installer to a temp location and launches it with elevation

Safety and permissions

  • Windows installer is launched with ShellExecuteW and runas verb for elevation
  • macOS uses AppleScript to move bundles when admin privileges are needed
  • Operations attempt to be atomic and restore from backup on failure when possible

FAQ

  • Q: Where should I call relaunch()? A: Only after your UI and background tasks are safely shut down. On Windows, the installer typically handles termination. On macOS, you control when to reopen the app.

  • Q: How are assets matched? A: Filenames are inspected for OS and arch markers, and known extensions are matched: .app.zip, .dmg, .exe, .msi.

Projects using this crate


Third-Party Code Attribution

  • Source: tauri-apps/tauri-plugin-updater
  • Author: The Tauri Programme
  • License: MIT OR MIT/Apache 2.0
  • Usage: Implement updater for Dioxus apps or any other Rust GUI applications
  • Copyright:
    Copyright (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
    
  • Key Modifications:
    • Adapt for universal Rust crate

    • Remove Tauri-specific runtime integration

    • Use octocrab library for GitHub API interaction

Detailed Info: For complete attribution information, please refer to the NOTICE file

License

Licensed under either of:

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 0

cargo fmt