Skip to content

feat(cli): add upgrade command#9546

Open
nhedger wants to merge 40 commits intonextfrom
feat/biome-upgrade-command
Open

feat(cli): add upgrade command#9546
nhedger wants to merge 40 commits intonextfrom
feat/biome-upgrade-command

Conversation

@nhedger
Copy link
Member

@nhedger nhedger commented Mar 18, 2026

Note

AI assistance was used to implement this feature

Summary

This PR implements the biome upgrade command, which allows users to upgrade Biome to the latest version, while handling the following cases gracefully:

  • Standalone binary upgrade (via the self_update crate)
  • Delegate to brew upgrade biome when Biome was installed with Homebrew
  • Prevent upgrade and warn when attempting to upgrade a bin that was installed via npm and alike

Why

Upgrading Biome with a package manager is pretty straightforward. However, it's a bit more involved for users that have installed Biome manually. This command aims to streamline that process.

Pending questions

  • Should we kill the daemon before upgrading
  • Should we restart the daemon after upgrading

Test Plan

Added a bunch of tests, and confirmed it works on the following systems/strategies

  • macOS standalone
  • macOS homebrew
  • macOS npm
  • linux standalone
  • linux homebrew
  • linux npm
  • windows standalone
  • windows npm

Tip

Help me test on Linux and Windows, if you can.

Build with BIOME_VERSION=2.4.6 just to trigger the upgrade

BIOME_VERSION=2.4.6 cargo build 
# linux
BIOME_DISTRIBUTION=standalone ./target/debug/biome upgrade
BIOME_DISTRIBUTION=homebrew ./target/debug/biome upgrade
BIOME_DISTRIBUTION=npm ./target/debug/biome upgrade

# windows
BIOME_DISTRIBUTION=standalone ./target/debug/biome upgrade
BIOME_DISTRIBUTION=npm ./target/debug/biome upgrade

Docs

I plan to add docs to the website at a later time

@changeset-bot
Copy link

changeset-bot bot commented Mar 18, 2026

🦋 Changeset detected

Latest commit: 8063ec3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@biomejs/biome Minor
@biomejs/cli-win32-x64 Minor
@biomejs/cli-win32-arm64 Minor
@biomejs/cli-darwin-x64 Minor
@biomejs/cli-darwin-arm64 Minor
@biomejs/cli-linux-x64 Minor
@biomejs/cli-linux-arm64 Minor
@biomejs/cli-linux-x64-musl Minor
@biomejs/cli-linux-arm64-musl Minor
@biomejs/wasm-web Minor
@biomejs/wasm-bundler Minor
@biomejs/wasm-nodejs Minor
@biomejs/backend-jsonrpc Patch
@biomejs/js-api Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@nhedger nhedger changed the title feat(cli): add upgrade command feat(cli): add upgrade command Mar 18, 2026
@github-actions github-actions bot added A-CLI Area: CLI A-Diagnostic Area: diagnostocis labels Mar 18, 2026
@codspeed-hq
Copy link

codspeed-hq bot commented Mar 18, 2026

Merging this PR will not alter performance

✅ 58 untouched benchmarks
⏩ 156 skipped benchmarks1


Comparing feat/biome-upgrade-command (8063ec3) with next (6d041d9)

Open in CodSpeed

Footnotes

  1. 156 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@nhedger nhedger changed the base branch from main to next March 18, 2026 22:16
@nhedger nhedger force-pushed the feat/biome-upgrade-command branch from 7476043 to 124eaeb Compare March 18, 2026 22:30
@nhedger nhedger marked this pull request as ready for review March 19, 2026 14:44
@nhedger
Copy link
Member Author

nhedger commented Mar 19, 2026

@ematipico I believe I've addressed all your concerns here. Thanks for reviewing. Let me know if there are any other concerns.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a new biome upgrade CLI command and wires it into the command enum and session dispatch. The command refuses to run when BIOME_BINARY is set, uses BIOME_DISTRIBUTION (or path heuristics) to detect npm/Homebrew/standalone installs, errors for npm installs, runs brew upgrade biome for Homebrew installs, and implements a standalone flow that fetches the latest version and performs a GitHub-backed self-update. Also adds upgrade diagnostics, a BIOME_DISTRIBUTION env var, unit and help tests, a changeset entry, and small packaging logic in the npm bin to block the command and mark the distribution as npm.

Suggested labels

L-JavaScript

Suggested reviewers

  • ematipico
  • siketyan
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding a new 'upgrade' command to the CLI.
Description check ✅ Passed The PR description clearly outlines the implementation of the biome upgrade command with specific handling for three installation scenarios (standalone, Homebrew, npm) and includes test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/biome-upgrade-command

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.

Tip

CodeRabbit can generate a title for your PR based on the changes.

Add @coderabbitai placeholder anywhere in the title of your PR and CodeRabbit will replace it with a title based on the changes in the PR. You can change the placeholder by changing the reviews.auto_title_placeholder setting.

Copy link
Contributor

@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: 4

🧹 Nitpick comments (1)
crates/biome_flags/src/lib.rs (1)

20-20: Consider printing BIOME_DISTRIBUTION in the env dump too.

You register the variable, but it is not emitted by Display for BiomeEnv, so debugging distribution-specific upgrade paths is harder than it needs to be.

Suggested follow-up patch
 impl Display for BiomeEnv {
     fn fmt(&self, fmt: &mut Formatter) -> std::io::Result<()> {
         let padding = 35usize;
+        match self.biome_distribution.value() {
+            None => {
+                KeyValuePair::new(self.biome_distribution.name, markup! { <Dim>"unset"</Dim> })
+                    .with_padding(padding)
+                    .fmt(fmt)?;
+            }
+            Some(value) => {
+                KeyValuePair::new(self.biome_distribution.name, markup! {{DebugDisplay(value)}})
+                    .with_padding(padding)
+                    .fmt(fmt)?;
+            }
+        };
         match self.biome_log_path.value() {
             None => {
                 KeyValuePair::new(self.biome_log_path.name, markup! { <Dim>"unset"</Dim> })
                     .with_padding(padding)
                     .fmt(fmt)?;

Also applies to: 36-39

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_flags/src/lib.rs` at line 20, The Display implementation for
BiomeEnv currently omits the BIOME_DISTRIBUTION field, so add the
biome_distribution (type BiomeEnvVariable) to the string emitted by Display for
BiomeEnv (and the similar display logic around lines 36-39) so the env dump
prints BIOME_DISTRIBUTION; locate the BiomeEnv struct (field name
biome_distribution) and the impl Display for BiomeEnv and append a formatted
entry for biome_distribution (using its Debug/Display formatting) into the
output so distribution-specific upgrade paths are visible in logs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.changeset/add-upgrade-command.md:
- Line 2: The changeset for the new `biome upgrade` feature incorrectly lists
the release type as `patch`; update the value for the package key
"@biomejs/biome" in the .changeset/add-upgrade-command.md file from `patch` to
`minor` so the new user-facing command targeting the `next` branch is released
as a minor change.

In `@crates/biome_cli/src/commands/upgrade.rs`:
- Around line 33-40: The match in upgrade.rs that handles InstallSource
currently treats any non-Npm/Homebrew case as InstallSource::Standalone and
calls upgrade_standalone(session); instead, explicitly refuse to self-update
when the install source is unknown or not one of the expected channels: change
the match so Npm returns the existing upgrade_error, Homebrew calls
upgrade_with_homebrew(session), Standalone calls upgrade_standalone(session),
and add a catch-all arm (or handle the InstallSource::Other/Unknown variant)
that returns Err(CliDiagnostic::upgrade_error(...)) with a message instructing
the user to upgrade via their original installer; keep upgrade_with_homebrew and
upgrade_standalone unchanged but ensure the unknown-arm prevents cross-channel
self-update.
- Around line 60-63: Remove the HOMEBREW_NO_AUTO_UPDATE env var so Homebrew can
refresh formula metadata before upgrading: in the Command invocation that
constructs the brew call (Command::new("brew") building the process for
.arg("upgrade").arg(BREW_BINARY_NAME) in upgrade.rs), delete the
.env("HOMEBREW_NO_AUTO_UPDATE", "1") call so the process uses Homebrew's normal
auto-update behavior.
- Around line 8-10: The reqwest blocking Client is built without a timeout which
can hang; update the Client construction to set a finite timeout (e.g.,
Client::builder().timeout(Duration::from_secs(10)).build() ) and import
std::time::Duration (or read a timeout value from config/env) so the
version-check HTTP call cannot block indefinitely; locate the client creation
(calls to reqwest::blocking::Client or Client::builder()) in this module and
replace it with a builder that sets .timeout(...) and propagate/handle any build
errors accordingly.

---

Nitpick comments:
In `@crates/biome_flags/src/lib.rs`:
- Line 20: The Display implementation for BiomeEnv currently omits the
BIOME_DISTRIBUTION field, so add the biome_distribution (type BiomeEnvVariable)
to the string emitted by Display for BiomeEnv (and the similar display logic
around lines 36-39) so the env dump prints BIOME_DISTRIBUTION; locate the
BiomeEnv struct (field name biome_distribution) and the impl Display for
BiomeEnv and append a formatted entry for biome_distribution (using its
Debug/Display formatting) into the output so distribution-specific upgrade paths
are visible in logs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c040f36a-f2cf-4438-bfb4-42ffaf893fd4

📥 Commits

Reviewing files that changed from the base of the PR and between 4d251d4 and d63a56b.

⛔ Files ignored due to path filters (4)
  • Cargo.lock is excluded by !**/*.lock and included by **
  • crates/biome_cli/tests/snapshots/main_cases_help/upgrade_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
📒 Files selected for processing (10)
  • .changeset/add-upgrade-command.md
  • Cargo.toml
  • crates/biome_cli/Cargo.toml
  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/commands/upgrade.rs
  • crates/biome_cli/src/diagnostics.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_cli/tests/cases/help.rs
  • crates/biome_flags/src/lib.rs
  • packages/@biomejs/biome/bin/biome

Copy link
Contributor

@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.

♻️ Duplicate comments (2)
crates/biome_cli/src/commands/upgrade.rs (2)

62-65: ⚠️ Potential issue | 🟠 Major

Remove HOMEBREW_NO_AUTO_UPDATE to let Homebrew refresh formula metadata.

With this environment variable set, brew upgrade biome runs against stale formula metadata and won't detect the latest release—defeating the purpose of the command.

Suggested fix
     let status = Command::new("brew")
-        .env("HOMEBREW_NO_AUTO_UPDATE", "1")
         .arg("upgrade")
         .arg(BREW_BINARY_NAME)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_cli/src/commands/upgrade.rs` around lines 62 - 65, The call
building the Homebrew command in the upgrade flow sets HOMEBREW_NO_AUTO_UPDATE
which prevents Homebrew from refreshing formula metadata; remove the
.env("HOMEBREW_NO_AUTO_UPDATE", "1") from the Command::new("brew") chain (the
block that sets .arg("upgrade").arg(BREW_BINARY_NAME)) so brew can auto-update
metadata before running the upgrade.

35-42: ⚠️ Potential issue | 🟠 Major

Consider treating unknown installs explicitly rather than defaulting to standalone.

When the binary path doesn't match npm or Homebrew patterns, it falls through to InstallSource::Standalone. This could inadvertently trigger a GitHub self-update for distro packages, source builds, or other installation methods—potentially overwriting a binary managed by another tool.

Safer approach
 enum InstallSource {
     Homebrew,
     Npm,
     Standalone,
+    Unknown,
 }

 // In detect_install_source:
     } else {
-        InstallSource::Standalone
+        InstallSource::Unknown
     }

 // In match:
+        InstallSource::Unknown => Err(CliDiagnostic::upgrade_error(
+            "Could not determine how Biome was installed. Upgrade it with your original installer, or set `BIOME_DISTRIBUTION` explicitly.",
+            None,
+        )),

Also applies to: 237-238

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_cli/src/commands/upgrade.rs` around lines 35 - 42, The match on
InstallSource currently defaults unknown paths to InstallSource::Standalone
which can trigger a self-update inappropriately; update the match in the upgrade
command so that unknown or Unrecognized install sources are handled explicitly
(e.g., introduce or use an InstallSource::Unknown/Unrecognized variant or
pattern and return a CliDiagnostic::upgrade_error or a no-op with a clear
message) instead of calling upgrade_standalone(session); change the branches
that call upgrade_standalone(session) to only match the explicit Standalone
variant and add a new branch that returns an error/diagnostic for unknown
installs so distro/source-managed binaries are not overwritten.
🧹 Nitpick comments (2)
crates/biome_cli/src/commands/upgrade.rs (2)

279-291: Fallback in release_target may produce an invalid asset identifier.

If a user runs on an unsupported OS/arch combination, the fallback format!("{os}-{arch}") (line 289) won't match any GitHub release asset, leading to a confusing download failure. Consider returning a Result or a clearer error.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_cli/src/commands/upgrade.rs` around lines 279 - 291, The
fallback in release_target() returns a guessed "{os}-{arch}" string that may not
match any release asset; change release_target() to return Result<String,
UpgradeError> (or anyhow::Result) and replace the generic fallback arm (os,
arch, _) with an Err that includes the observed os and arch; update callers to
propagate or display a clear error message explaining the unsupported OS/arch
instead of attempting to download a non-existent asset. Refer to the function
release_target() and ensure all call sites that currently expect a String are
updated to handle the Result.

243-250: Warn or error on unrecognised BIOME_DISTRIBUTION values.

Currently, an invalid value (e.g. a typo like "standlone") silently falls through to path-based detection. Users might believe their override is active when it isn't.

Suggested approach
 fn install_source_from_env() -> Option<InstallSource> {
-    match env::var_os("BIOME_DISTRIBUTION")?.to_str()? {
+    let value = env::var_os("BIOME_DISTRIBUTION")?;
+    let value_str = value.to_str()?;
+    match value_str {
         "npm" => Some(InstallSource::Npm),
         "homebrew" => Some(InstallSource::Homebrew),
         "standalone" => Some(InstallSource::Standalone),
-        _ => None,
+        other => {
+            // Consider logging a warning or returning an error variant
+            eprintln!("Warning: Unrecognised BIOME_DISTRIBUTION value '{}', falling back to path detection", other);
+            None
+        }
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_cli/src/commands/upgrade.rs` around lines 243 - 250,
install_source_from_env currently silently ignores unrecognised
BIOME_DISTRIBUTION values; update it to log a clear warning or return an error
when the env var exists but does not match a known InstallSource. Locate the
function install_source_from_env and the InstallSource enum and: if
env::var_os("BIOME_DISTRIBUTION") is present but the to_str() value doesn’t
match "npm"|"homebrew"|"standalone", emit a warning (e.g., via log::warn! or
eprintln!) that includes the invalid value and that path-based detection will be
used (or change the function to return a Result and propagate an explicit
error). Ensure the warning/error message includes the raw BIOME_DISTRIBUTION
value so users can see the typo.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@crates/biome_cli/src/commands/upgrade.rs`:
- Around line 62-65: The call building the Homebrew command in the upgrade flow
sets HOMEBREW_NO_AUTO_UPDATE which prevents Homebrew from refreshing formula
metadata; remove the .env("HOMEBREW_NO_AUTO_UPDATE", "1") from the
Command::new("brew") chain (the block that sets
.arg("upgrade").arg(BREW_BINARY_NAME)) so brew can auto-update metadata before
running the upgrade.
- Around line 35-42: The match on InstallSource currently defaults unknown paths
to InstallSource::Standalone which can trigger a self-update inappropriately;
update the match in the upgrade command so that unknown or Unrecognized install
sources are handled explicitly (e.g., introduce or use an
InstallSource::Unknown/Unrecognized variant or pattern and return a
CliDiagnostic::upgrade_error or a no-op with a clear message) instead of calling
upgrade_standalone(session); change the branches that call
upgrade_standalone(session) to only match the explicit Standalone variant and
add a new branch that returns an error/diagnostic for unknown installs so
distro/source-managed binaries are not overwritten.

---

Nitpick comments:
In `@crates/biome_cli/src/commands/upgrade.rs`:
- Around line 279-291: The fallback in release_target() returns a guessed
"{os}-{arch}" string that may not match any release asset; change
release_target() to return Result<String, UpgradeError> (or anyhow::Result) and
replace the generic fallback arm (os, arch, _) with an Err that includes the
observed os and arch; update callers to propagate or display a clear error
message explaining the unsupported OS/arch instead of attempting to download a
non-existent asset. Refer to the function release_target() and ensure all call
sites that currently expect a String are updated to handle the Result.
- Around line 243-250: install_source_from_env currently silently ignores
unrecognised BIOME_DISTRIBUTION values; update it to log a clear warning or
return an error when the env var exists but does not match a known
InstallSource. Locate the function install_source_from_env and the InstallSource
enum and: if env::var_os("BIOME_DISTRIBUTION") is present but the to_str() value
doesn’t match "npm"|"homebrew"|"standalone", emit a warning (e.g., via
log::warn! or eprintln!) that includes the invalid value and that path-based
detection will be used (or change the function to return a Result and propagate
an explicit error). Ensure the warning/error message includes the raw
BIOME_DISTRIBUTION value so users can see the typo.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 88e82e7f-7ae4-4018-8095-90e99b64f86c

📥 Commits

Reviewing files that changed from the base of the PR and between d63a56b and c3d07fe.

📒 Files selected for processing (3)
  • .changeset/add-upgrade-command.md
  • crates/biome_cli/src/commands/upgrade.rs
  • crates/biome_flags/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/biome_flags/src/lib.rs

Copy link
Contributor

@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: 1

🧹 Nitpick comments (1)
crates/biome_cli/src/commands/upgrade.rs (1)

241-249: Consider warning on unrecognised BIOME_DISTRIBUTION values.

If a user sets BIOME_DISTRIBUTION=standalon (typo), it silently falls through to path-based detection. A warning would help catch misconfiguration.

♻️ Suggested approach
 fn install_source_from_env() -> Option<InstallSource> {
-    match env::var_os("BIOME_DISTRIBUTION")?.to_str()? {
-        "npm" => Some(InstallSource::Npm),
-        "homebrew" => Some(InstallSource::Homebrew),
-        "standalone" => Some(InstallSource::Standalone),
-        _ => None,
+    let value = env::var_os("BIOME_DISTRIBUTION")?;
+    let value_str = value.to_str()?;
+    match value_str {
+        "npm" => Some(InstallSource::Npm),
+        "homebrew" => Some(InstallSource::Homebrew),
+        "standalone" => Some(InstallSource::Standalone),
+        other => {
+            eprintln!("Warning: unrecognised BIOME_DISTRIBUTION value '{other}', falling back to path detection");
+            None
+        }
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_cli/src/commands/upgrade.rs` around lines 241 - 249, The
function install_source_from_env currently ignores unknown BIOME_DISTRIBUTION
values; change it to detect when the env var is present but not one of the
recognized strings and emit a warning (including the raw value) before returning
None. Specifically, in install_source_from_env, capture
env::var_os("BIOME_DISTRIBUTION") into an Option, attempt to convert to &str,
and if conversion fails or the value doesn't match "npm"/"homebrew"/"standalone"
call the project's logging facility (or eprintln!) to warn that the
BIOME_DISTRIBUTION value is unrecognized (include the bad value) and then fall
through returning None; keep InstallSource::Npm / Homebrew / Standalone branches
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/biome_cli/src/commands/upgrade.rs`:
- Around line 278-290: The release_target() function currently returns a
best-effort String and falls back to formats like "freebsd-x86_64" which won't
match release assets; change release_target() to return Result<String, Error>
(or a suitable custom error) and explicitly return Err for unsupported OS/ARCH
combinations with a clear message, e.g., "unsupported platform: <os>-<arch>";
update every caller of release_target (e.g., code paths invoking
release_target() in the upgrade flow) to propagate or handle the Result (use ?
to propagate where appropriate) so callers can surface a clear error instead of
letting self_update fail with a download error.

---

Nitpick comments:
In `@crates/biome_cli/src/commands/upgrade.rs`:
- Around line 241-249: The function install_source_from_env currently ignores
unknown BIOME_DISTRIBUTION values; change it to detect when the env var is
present but not one of the recognized strings and emit a warning (including the
raw value) before returning None. Specifically, in install_source_from_env,
capture env::var_os("BIOME_DISTRIBUTION") into an Option, attempt to convert to
&str, and if conversion fails or the value doesn't match
"npm"/"homebrew"/"standalone" call the project's logging facility (or eprintln!)
to warn that the BIOME_DISTRIBUTION value is unrecognized (include the bad
value) and then fall through returning None; keep InstallSource::Npm / Homebrew
/ Standalone branches unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2139f53c-bfee-49a0-9f6d-2e590d8a6edb

📥 Commits

Reviewing files that changed from the base of the PR and between c3d07fe and a9ec947.

📒 Files selected for processing (1)
  • crates/biome_cli/src/commands/upgrade.rs

Copy link
Contributor

@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.

♻️ Duplicate comments (2)
crates/biome_cli/src/commands/upgrade.rs (2)

70-71: ⚠️ Potential issue | 🟠 Major

HOMEBREW_NO_AUTO_UPDATE=1 prevents detection of latest release.

This environment variable was flagged in a prior review but appears unresolved in the current code. With it set, brew upgrade runs against stale formula metadata and may not see the newest version—rather defeating the purpose of an upgrade command.

Suggested fix
     let status = Command::new("brew")
-        .env("HOMEBREW_NO_AUTO_UPDATE", "1")
         .arg("upgrade")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_cli/src/commands/upgrade.rs` around lines 70 - 71, The brew
invocation currently sets HOMEBREW_NO_AUTO_UPDATE=1 which prevents Homebrew from
refreshing formula metadata and can cause upgrades to miss new releases; locate
the Command::new("brew") call in upgrade.rs (the block that builds the status
variable) and remove the env("HOMEBREW_NO_AUTO_UPDATE", "1") setting so brew can
perform its normal auto-update behavior before running upgrade.

292-304: ⚠️ Potential issue | 🟡 Minor

Unsupported platforms will cause confusing download errors.

The catch-all arm produces identifiers like "freebsd-x86_64" that won't match any GitHub release asset. self_update will then fail with a cryptic download error rather than a clear "platform not supported" message.

Suggested approach
-fn release_target() -> String {
+fn release_target() -> Result<String, CliDiagnostic> {
     match (env::consts::OS, env::consts::ARCH, is_musl()) {
-        ("macos", "x86_64", _) => String::from("darwin-x64"),
+        ("macos", "x86_64", _) => Ok(String::from("darwin-x64")),
         // ... other arms similarly wrapped in Ok(...)
-        (os, arch, _) => format!("{os}-{arch}"),
+        (os, arch, _) => Err(CliDiagnostic::upgrade_error(
+            format!("Standalone upgrade is not supported on {os}-{arch}."),
+            None,
+        )),
     }
 }

Callers (upgrade_standalone, release_asset_identifier) would need to propagate the Result.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_cli/src/commands/upgrade.rs` around lines 292 - 304, The
release_target() function currently returns a String for any platform which
yields unsupported identifiers (e.g., "freebsd-x86_64") and causes cryptic
download errors; change release_target() to return Result<String, UpgradeError>
(or Option<String>) and have it return an
Err(UpgradeError::UnsupportedPlatform{os,arch}) for the catch-all branch instead
of formatting an identifier, then update callers upgrade_standalone and
release_asset_identifier to propagate the Result (using ? or map_err) so they
can surface a clear "platform not supported" error to users; ensure you add or
reuse an UpgradeError enum variant and update function signatures and any tests
accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@crates/biome_cli/src/commands/upgrade.rs`:
- Around line 70-71: The brew invocation currently sets
HOMEBREW_NO_AUTO_UPDATE=1 which prevents Homebrew from refreshing formula
metadata and can cause upgrades to miss new releases; locate the
Command::new("brew") call in upgrade.rs (the block that builds the status
variable) and remove the env("HOMEBREW_NO_AUTO_UPDATE", "1") setting so brew can
perform its normal auto-update behavior before running upgrade.
- Around line 292-304: The release_target() function currently returns a String
for any platform which yields unsupported identifiers (e.g., "freebsd-x86_64")
and causes cryptic download errors; change release_target() to return
Result<String, UpgradeError> (or Option<String>) and have it return an
Err(UpgradeError::UnsupportedPlatform{os,arch}) for the catch-all branch instead
of formatting an identifier, then update callers upgrade_standalone and
release_asset_identifier to propagate the Result (using ? or map_err) so they
can surface a clear "platform not supported" error to users; ensure you add or
reuse an UpgradeError enum variant and update function signatures and any tests
accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0cc0c852-36f8-4fd3-8da9-7c2f1e4b2d81

📥 Commits

Reviewing files that changed from the base of the PR and between a9ec947 and 2ef30e8.

⛔ Files ignored due to path filters (7)
  • crates/biome_cli/tests/snapshots/main_commands_rage/rage_ok.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_rage/with_configuration.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_rage/with_formatter_configuration.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_rage/with_jsonc_configuration.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_rage/with_linter_configuration.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_rage/with_malformed_configuration.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_rage/with_no_configuration.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (1)
  • crates/biome_cli/src/commands/upgrade.rs

Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

Looking good! I have major concerns about tests that lock the environment. It's fine, if we can't test it. I think the best way to test things is by mocking the env values.

@nhedger nhedger requested a review from ematipico March 20, 2026 12:51
@ematipico
Copy link
Member

For new features, we usually want at least docs PR ready before merging.

In past we shipped features without documentation because we forgot, so now we're a bit more strict

@nhedger

This comment was marked as resolved.

Comment on lines +157 to +160
session.app.console.log(markup! {
<Info>
"Your editor may still be using the previous Biome version. Reload it to pick up the updated binary."
</Info>
Copy link
Member Author

Choose a reason for hiding this comment

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

Added this to tell the user to reload his editor instead of force killing the daemon. This matches what happens when upgrading biome with homebrew AFAICT

@nhedger nhedger force-pushed the feat/biome-upgrade-command branch from b8ca9a2 to 8063ec3 Compare March 22, 2026 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Diagnostic Area: diagnostocis

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants