百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
S

self_update

> 编程语言
开源

Rust 可执行文件的自我更新

952 stars0 点赞0 次浏览
访问官网GitHub

工具介绍

Rust 可执行文件的自我更新

self_update

self_update provides updaters for updating rust executables in-place from various release distribution backends.

Supported backends: GitHub, GitLab, Gitea, Gitee, S3 (Amazon S3, Google GCS, DigitalOcean Spaces, or any S3-compatible endpoint), and Manifest (any static file server). The forge and S3 backends each expose a ReleaseList builder alongside the Update (configure -> build -> update) API; the manifest backend exposes Update only.

Quick start

use self_update::cargo_crate_version;

fn update() -> Result> {
    let status = self_update::backends::github::Update::configure()
        .repo_owner("jaemk")
        .repo_name("self_update")
        .bin_name("github")
        .show_download_progress(true)
        .current_version(cargo_crate_version!())
        .build()?
        .update()?;
    println!("Update status: `{}`!", status.version());
    Ok(())
}

Upgrading from 0.x? 1.0 makes a focused set of breaking changes to clean up the public API. See the 1.0 migration guide for a step-by-step walkthrough, or the agent-oriented guide for automated migration tooling.

Running unattended (daemon / CI / service)? The defaults are interactive: show_output is true and no_confirm is false, so update() prints a release-status block to stdout and then blocks on an interactive yes/no prompt waiting on stdin. With no terminal attached this stalls (or aborts). For any non-interactive caller set .no_confirm(true) to skip the prompt, and usually .show_output(false) to silence the status block. These are settings only -- the defaults are unchanged. Note the status block is printed before the confirmation prompt, so suppressing one does not suppress the other.

Usage

Features

At least one HTTP client must be selected. A build with no client -- for example default-features = false with only a TLS feature such as features = ["rustls"] -- fails to compile with no HTTP client selected - enable at least one of the reqwest (default) or ureq features. Add a client explicitly, e.g. default-features = false, features = ["ureq", "rustls", "github"]. Multiple clients and multiple TLS backends may coexist (reqwest is preferred when both are present):

  • reqwest (default): use the reqwest HTTP client;
  • ureq: use the ureq HTTP client, either alongside reqwest or as a drop-in replacement (set default-features = false to drop reqwest);
  • rustls (default): pure-Rust TLS; does not support 32-bit macOS;
  • native-tls: opt-in native/OpenSSL TLS for the selected client;
  • native-tls-vendored: build OpenSSL from source and link it statically (for targets where a usable system OpenSSL is awkward, e.g. musl or some cross-compiles); implies native-tls, applies to the reqwest client;

Note that enabling a client with neither TLS feature compiles (plain-http release hosts remain reachable) but any https URL then fails at request time with a transport error; enable rustls or native-tls for https.

The following cargo features are enabled by default:

  • github: the GitHub Releases backend;
  • progress-bar: terminal download progress bar;

The following are opt-in; activate the one(s) your release files need:

  • gitlab: the GitLab Releases backend;
  • gitea: the Gitea Releases backend;
  • gitee: the Gitee Releases backend;
  • s3: the S3-compatible backend (Amazon S3, GCS, DigitalOcean Spaces, etc.);
  • s3-auth: sign S3 requests (AWS SigV4) for private buckets; implies s3;
  • manifest: the static-file manifest backend; fetches releases from a manifest.json served by any HTTP endpoint; no new dependencies;
  • archive-tar: support for tar archive format;
  • archive-zip: support for zip archive format;
  • compression-tar-gz: support for gzip compression (.tar.gz, .tgz, plain .gz);
  • compression-tar-xz: support for xz compression (.tar.xz, .txz, plain .xz); pure-Rust, no C liblzma dependency;
  • compression-zip-deflate: support for zip's deflate compression format;
  • compression-zip-bzip2: support for zip's bzip2 compression format;
  • signatures: use zipsign to verify .zip and .tar.gz artifacts. Artifacts are assumed to have been signed using zipsign;
  • checksums: verify a downloaded artifact against a SHA-256/SHA-512 checksum before installing it -- automatically against the digest github publishes per release asset, and/or against a known checksum you pass in (e.g. from a SHA256SUMS file); see Checksum verification below;
  • async: add async (*_async) update methods alongside the unchanged blocking API; tokio-only, requires reqwest (ureq and reqwest can coexist -- reqwest serves the async path, and the sync API prefers reqwest when both are present); see Async below.

github is the only backend in the default feature set. The S3 backend requires the s3 feature; s3-auth implies s3. gitlab, gitea, gitee, and manifest each require their own feature.

Example

Run the following example to see self_update in action:

cargo run --example github --features "signatures archive-tar compression-tar-gz".

There are equivalent examples for the other backends (gitlab, gitea, gitee, s3), e.g.:

cargo run --example gitlab --features "gitlab archive-tar compression-tar-gz".

Amazon S3, Google GCS, and DigitalOcean Spaces, as well as any S3 compatible server are also supported through the S3 backend to check for new releases. Provided a bucket_name and asset_prefix string, self_update will look up all matching files using the following format as a convention for the filenames: [directory/]--.. Leading directories will be stripped from the file name allowing the use of subdirectories in the S3 bucket, and any file not matching the format, or not matching the provided prefix string, will be ignored.

…

The manifest backend (manifest feature) serves releases from a manifest.json file hosted on any static file server. The tool author publishes the manifest at a stable URL; assets may be absolute URLs or relative paths resolved against that URL. Asset digest fields (sha256:) plug into the existing checksum verification path when the checksums feature is on. See specs/ref-manifest-backend.md for the full schema.

use self_update::cargo_crate_version;

fn update() -> Result> {
    let status = self_update::backends::manifest::Update::configure()
        .manifest_url("https://example.net/releases/manifest.json")
        .bin_name("app")
        .current_version(cargo_crate_version!())
        .build()?
        .update()?;
    println!("Manifest update status: `{}`!", status.version());
    Ok(())
}

Separate utilities are also exposed (NOTE: the following example extracts a .tar.gz, which requires both the archive-tar and compression-tar-gz features -- archive-tar reads the tar archive and compression-tar-gz decodes the gzip layer; see the features section above). It downloads, extracts, and replaces the running binary by hand; the staging directory and the in-place replacement use the tempfile and self_replace crates, which you add as your own dependencies (they are no longer re-exported from self_update):

…

Multi-file / non-executable install

The high-level update() flow replaces a single executable. To update a tool that ships more than one file (a binary plus sidecar libraries/resources), or to install files that aren't the running executable, download and extract the whole archive yourself and then install the files with MoveAll, which applies a set of (source -> dest) moves transactionally: either every move succeeds, or — on the first failure — all already-applied moves are rolled back, so a failed update can't leave a half-installed tool. Because it uses rename (which can't cross filesystems), the source files, every destination, and the temp dir must all be on the same filesystem.

NOTE: this example extracts a .tar.gz, which requires both the archive-tar and compression-tar-gz features.

…

Bundle installs (macOS .app)

A macOS application is a directory bundle, so replacing only the executable inside MyApp.app/Contents/MacOS/ leaves stale resources behind and breaks the bundle's code signature. Set bundle_path_in_archive to name the bundle directory inside the release archive and the whole tree is installed as one unit:

…

How the swap works, and what it guarantees:

  • The archive is extracted in full into a temporary directory inside the install path's parent, so every rename is on one filesystem (there is no cross-device fallback, and the parent needs room for one more copy of the bundle). A symlinked bundle_install_path is resolved first, so the tree behind the link is replaced, the link survives, and staging still lands beside the real tree.
  • The installed tree is stashed, then the staged tree is renamed into place. A failure at any step restores the original bundle, and the error names the bundle path. Once the final rename lands the update is committed.
  • When the running executable lives inside the bundle it is renamed aside first, so the old tree holds no running image. After a successful update the running executable's path holds the new bundle's executable, and the process can relaunch itself with restart() (see Restarting after an update).
  • Bundle mode replaces a directory, so combining it with an explicit bin_install_path or bin_path_in_archive is rejected by build() (Error::ConflictingConfig), and setting bundle_install_path without bundle_path_in_archive is an Error::MissingField rather than a silently discarded path. bin_name is still required: it selects the asset and feeds {{ bin }}.
  • The verify_binary hook receives the staged bundle root, which is what codesign --verify --deep wants; a rejection aborts before anything is replaced.
  • The crate never signs, notarizes, or staples: ship an already-signed (and, for Gatekeeper, notarized) .app and the swap preserves exactly what you shipped. A quarantined app running from a read-only App Translocation mount cannot update itself in place; that is detected up front as Error::AppTranslocated, and the fix is to move the app (which clears the quarantine) and relaunch it.

Directory bundles on linux and windows go through the same code path. On windows the swap fails, and rolls back, if the process holds files inside the bundle open beyond its own executable (a DLL loaded from the bundle, for example). .deb / .msi packages are a different shape entirely -- hand the downloaded file to dpkg -i / msiexec /i yourself; the crate's replace-and-verify semantics do not apply to a system installer.

Checksum verification

With the checksums feature, the crate verifies the downloaded artifact against a digest before installing — a mismatch aborts the update. Two sources of digests, independently applied (when both apply, both must pass):

  • Release-published digests, automatic. GitHub publishes a sha256: digest per release asset; the updater verifies the download against it whenever the selected asset carries one. This is on by default with the checksums feature — no configuration needed — and can be disabled with verify_release_digest(false). The other

Issues· 0 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

Rustrustrust-executablesupdateupgrade

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言