mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-09 03:20:56 +00:00
test(cli): cover Homebrew upgrade behavior end to end
Some checks are pending
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Typecheck (push) Waiting to run
TypeScript / Test (push) Waiting to run
TypeScript / Build (push) Waiting to run
Some checks are pending
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Typecheck (push) Waiting to run
TypeScript / Test (push) Waiting to run
TypeScript / Build (push) Waiting to run
Add process-level upgrade tests that invoke the real fabro binary from a fake Homebrew Cellar path so current_exe() detection is exercised end to end. Update the CLI reference and changelog to document the Homebrew-managed upgrade path and the flags that remain self-managed-only.
This commit is contained in:
parent
1530ba4e93
commit
e891cb3961
3 changed files with 109 additions and 7 deletions
|
|
@ -15,7 +15,7 @@ fabro fork <run_id> @3 # fork from checkpoint index 3
|
|||
|
||||
## Self-update with fabro upgrade
|
||||
|
||||
Fabro can now update itself. `fabro upgrade` downloads the latest release from GitHub, verifies its SHA256 checksum, and atomically replaces the binary. Downgrade protection prevents accidentally installing an older version (override with `--force`). A daily background check notifies you when a new version is available — disable it with `upgrade_check = false` in `~/.fabro/cli.toml` or `--no-upgrade-check`.
|
||||
Fabro can now update itself. For self-managed installs, `fabro upgrade` downloads the latest release from GitHub, verifies its SHA256 checksum, and atomically replaces the binary. Downgrade protection prevents accidentally installing an older version (override with `--force`). On Homebrew installs, `fabro upgrade` leaves the Homebrew-managed binary alone and prints the matching `brew upgrade fabro` or `brew upgrade fabro-nightly` command instead. A daily background check notifies you when a new version is available — disable it with `upgrade_check = false` in `~/.fabro/cli.toml` or `--no-upgrade-check`.
|
||||
|
||||
```bash
|
||||
fabro upgrade # upgrade to latest
|
||||
|
|
|
|||
|
|
@ -770,7 +770,9 @@ fabro doctor --server https://fabro.example.com:3000/api/v1
|
|||
|
||||
## `fabro upgrade`
|
||||
|
||||
Download and install a newer version of Fabro from GitHub releases. Verifies the download with SHA256 checksums and atomically replaces the binary.
|
||||
For self-managed installs, download and install a newer version of Fabro from GitHub releases. The CLI verifies the download with SHA256 checksums and atomically replaces the binary.
|
||||
|
||||
If Fabro was installed via Homebrew, `fabro upgrade` does not overwrite the Homebrew-managed binary. It prints the matching `brew upgrade fabro` or `brew upgrade fabro-nightly` command instead.
|
||||
|
||||
```bash
|
||||
fabro upgrade
|
||||
|
|
@ -781,13 +783,14 @@ fabro upgrade --version v0.177.0-alpha.1
|
|||
|
||||
| Flag | Description |
|
||||
|---|---|
|
||||
| `--version <VERSION>` | Target version (e.g. `0.5.0`, `v0.5.0`, or `v0.177.0-alpha.1`). Defaults to the latest stable release. |
|
||||
| `--force` | Upgrade even if already on the target version |
|
||||
| `--version <VERSION>` | Target version (e.g. `0.5.0`, `v0.5.0`, or `v0.177.0-alpha.1`) for self-managed installs. Defaults to the latest stable release. |
|
||||
| `--prerelease` | For self-managed installs, select the highest semver across stable and prerelease tags. |
|
||||
| `--force` | For self-managed installs, upgrade even if already on the target version. |
|
||||
| `--dry-run` | Preview what would happen without making changes |
|
||||
|
||||
Plain `fabro upgrade` tracks the latest stable release. Use `--version` to install an explicitly named pre-release.
|
||||
Plain `fabro upgrade` tracks the latest stable release. On self-managed installs, use `--version` to install an explicitly named pre-release or `--prerelease` to follow the newest prerelease automatically.
|
||||
|
||||
Fabro refuses to downgrade unless you specify an explicit `--version`. A daily background check notifies you when a new version is available — disable it with `upgrade_check = false` in [`settings.toml`](/reference/user-configuration#upgrade_check) or the `--no-upgrade-check` global flag.
|
||||
Fabro refuses to downgrade unless you specify an explicit `--version`. On Homebrew installs, `--version`, `--prerelease`, and `--force` are not supported because Homebrew selects the version/channel. A daily background check notifies you when a new version is available — disable it with `upgrade_check = false` in [`settings.toml`](/reference/user-configuration#upgrade_check) or the `--no-upgrade-check` global flag.
|
||||
|
||||
## `fabro artifact list`
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,50 @@
|
|||
use fabro_test::{fabro_snapshot, test_context};
|
||||
use assert_cmd::Command;
|
||||
use fabro_test::{TestContext, fabro_snapshot, test_context};
|
||||
|
||||
fn hard_link_or_copy(src: &std::path::Path, dest: &std::path::Path) {
|
||||
match std::fs::hard_link(src, dest) {
|
||||
Ok(()) => {}
|
||||
Err(_) => {
|
||||
std::fs::copy(src, dest).expect("copy test binary into fake Cellar");
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
let perms = std::fs::metadata(src)
|
||||
.expect("read source binary metadata")
|
||||
.permissions()
|
||||
.mode();
|
||||
std::fs::set_permissions(dest, std::fs::Permissions::from_mode(perms))
|
||||
.expect("preserve executable permissions");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn brew_command(context: &TestContext, formula: &str, version: &str) -> Command {
|
||||
let bin_dir = context.temp_dir.join("Cellar").join(formula).join(version).join("bin");
|
||||
std::fs::create_dir_all(&bin_dir).expect("create fake Cellar bin dir");
|
||||
let brew_fabro = bin_dir.join("fabro");
|
||||
hard_link_or_copy(std::path::Path::new(env!("CARGO_BIN_EXE_fabro")), &brew_fabro);
|
||||
|
||||
let mut cmd = Command::new(&brew_fabro);
|
||||
cmd.current_dir(&context.temp_dir);
|
||||
for (key, _) in std::env::vars_os() {
|
||||
if let Some(s) = key.to_str() {
|
||||
if s.starts_with("FABRO_") {
|
||||
cmd.env_remove(&key);
|
||||
}
|
||||
}
|
||||
}
|
||||
cmd.env("NO_COLOR", "1");
|
||||
cmd.env("HOME", &context.home_dir);
|
||||
cmd.env("FABRO_NO_UPGRADE_CHECK", "true")
|
||||
.env("FABRO_HTTP_PROXY_POLICY", "disabled")
|
||||
.env("FABRO_TELEMETRY", "off")
|
||||
.env("FABRO_SERVER_MAX_CONCURRENT_RUNS", "64")
|
||||
.env("FABRO_TEST_IN_MEMORY_STORE", "1");
|
||||
cmd
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn help() {
|
||||
|
|
@ -133,3 +179,56 @@ esac
|
|||
target: [TARGET]
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn upgrade_brew_install_refuses_and_prints_brew_command() {
|
||||
let context = test_context!();
|
||||
let mut cmd = brew_command(&context, "fabro", "0.176.2");
|
||||
cmd.args(["upgrade"]);
|
||||
|
||||
fabro_snapshot!(context.filters(), cmd, @"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
----- stderr -----
|
||||
fabro was installed via Homebrew.
|
||||
Run `brew upgrade fabro` to update.
|
||||
error: refusing to overwrite a Homebrew-managed binary
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn upgrade_brew_install_dry_run_json_reports_brew_command() {
|
||||
let context = test_context!();
|
||||
let mut cmd = brew_command(&context, "fabro-nightly", "0.205.0-nightly.0");
|
||||
cmd.args(["--json", "upgrade", "--dry-run"]);
|
||||
|
||||
fabro_snapshot!(context.filters(), cmd, @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
{
|
||||
"install_source": "homebrew",
|
||||
"formula": "fabro-nightly",
|
||||
"brew_command": "brew upgrade fabro-nightly",
|
||||
"dry_run": true,
|
||||
"note": "fabro is Homebrew-managed; no in-place upgrade attempted"
|
||||
}
|
||||
----- stderr -----
|
||||
"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn upgrade_brew_install_rejects_version_flag() {
|
||||
let context = test_context!();
|
||||
let mut cmd = brew_command(&context, "fabro", "0.176.2");
|
||||
cmd.args(["upgrade", "--version", "0.1.0"]);
|
||||
|
||||
fabro_snapshot!(context.filters(), cmd, @"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
----- stderr -----
|
||||
error: fabro is managed by Homebrew (formula `fabro`); Homebrew selects the version and channel. Use `brew upgrade fabro` (or reinstall with a different formula) instead of `fabro upgrade --version`/`--prerelease`/`--force`.
|
||||
");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue