# How the Forge Update Mechanism Works: Environment Variables and Auto-Update Configuration

> Discover how the Forge update mechanism works and the environment variables like FORGE_UPDATES__AUTO_UPDATE that control its silent and automatic installation of GitHub releases.

- Repository: [Forge Code/forgecode](https://github.com/antinomyhq/forgecode)
- Tags: internals
- Published: 2026-04-08

---

**Forge automatically checks GitHub for newer releases and can silently install them using environment variables like `FORGE_UPDATES__AUTO_UPDATE` and `FORGE_UPDATES__FREQUENCY`, or fall back to interactive confirmation when automatic updates are disabled.**

The **Forge update mechanism** in the `antinomyhq/forgecode` repository provides a configurable pipeline that queries GitHub releases, evaluates user preferences, and executes shell-based installations. Understanding how this system parses configuration and which environment variables override defaults is essential for managing deployments in both interactive and CI/CD environments.

## How the Forge Auto-Update System Works

### Configuration Loading and Environment Variable Parsing

The update process begins when `ForgeConfig::read()` merges configuration sources using the `ConfigReader` struct located in [`crates/forge_config/src/reader.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_config/src/reader.rs). The `read_env` builder method specifically handles the ingestion of environment variables prefixed with `FORGE_`, using double-underscore separators to map values to nested TOML fields. For example, `FORGE_SESSION__PROVIDER_ID` maps to the `provider_id` field inside the `session` struct, following the same convention used for update settings.

### Update Settings Structure

In [`crates/forge_config/src/config.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_config/src/config.rs) (lines 106-110), the `ForgeConfig` struct declares an optional `updates` field of type `Update`. This struct, defined in [`crates/forge_config/src/compact.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_config/src/compact.rs), exposes two critical options:

- **`auto_update`**: An `Option<bool>` that enables silent installation without user prompts
- **`frequency`**: An `Option<UpdateFrequency>` specifying how often to check GitHub, defaulting to `Always`

### Version Checking Logic

When the UI layer initializes, it triggers the update flow from [`crates/forge_main/src/ui.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_main/src/ui.rs) at line 690 by calling `on_update`. This function creates an `update_informer` client targeting the `antinomyhq/forge` repository and invokes `check_version()` defined in [`crates/forge_main/src/update.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_main/src/update.rs) (lines 68-85) to query the GitHub API for the latest release tag.

### Update Decision and Execution

The core logic in [`crates/forge_main/src/update.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_main/src/update.rs) evaluates the following condition:

```rust
if auto_update || confirm_update(version).await {
    execute_update_command(api, auto_update).await;
}

```

When **`auto_update`** evaluates to `true`, the system immediately proceeds to `execute_update_command`, which runs the official installer (`curl -fsSL https://forgecode.dev/cli | sh`) through the API's shell executor. If `auto_update` is `false`, the code calls `ForgeWidget::confirm` to prompt the user for approval. Upon successful installation with `auto_update` enabled, Forge calls `std::process::exit(0)` to terminate the current process, ensuring the new binary is used on the next launch.

## Environment Variables That Control Auto-Update Behavior

Four specific environment variables govern the Forge update mechanism, parsed by `ConfigReader::read_env`:

**`FORGE_UPDATES__AUTO_UPDATE`**
Controls whether Forge installs updates silently without prompting. Set to `true` to enable automatic installation, or `false` to require interactive confirmation via `ForgeWidget::confirm`.

**`FORGE_UPDATES__FREQUENCY`**
Sets the interval for checking GitHub releases. Accepts `daily`, `weekly`, or `always` (default), determining how often `check_version()` queries the remote repository.

**`FORGE_SKIP_INTERACTIVE`**
When set to any non-empty value (e.g., `1` or `true`), Forge bypasses all interactive prompts. This affects the confirmation step used when `auto_update` is disabled, forcing an immediate exit rather than waiting for user input.

**`FORGE_CONFIG`**
Overrides the default directory path containing the user's [`.forge.toml`](https://github.com/antinomyhq/forgecode/blob/main/.forge.toml) configuration file. Use this to relocate the `updates` section to a custom path (e.g., `/etc/forge/config`).

## Configuration Examples

Enable silent automatic updates via shell environment variables:

```bash

# Check for updates every start and install without prompting

export FORGE_UPDATES__AUTO_UPDATE=true
export FORGE_UPDATES__FREQUENCY=always
export FORGE_CONFIG="$HOME/.config/forge"

```

Configure the same settings programmatically in Rust before initializing the UI:

```rust
use std::env;
use std::sync::Arc;

// Set environment variables before config loading
env::set_var("FORGE_UPDATES__AUTO_UPDATE", "true");
env::set_var("FORGE_UPDATES__FREQUENCY", "always");

// Initialize API and trigger update check
let api = Arc::new(MyApiImpl::new());
forge_main::update::on_update(api.clone(), None).await;

```

Alternatively, configure via the TOML configuration file at `~/.forge/.forge.toml`:

```toml
[updates]
auto_update = true
frequency = "always"

```

## Summary

- The **Forge update mechanism** uses the `update_informer` crate to check `antinomyhq/forge` releases and can automatically execute the installer script hosted at `forgecode.dev`
- Configuration merges TOML files with environment variables parsed by `ConfigReader::read_env` in [`crates/forge_config/src/reader.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_config/src/reader.rs), using double-underscore notation (e.g., `FORGE_UPDATES__AUTO_UPDATE`) for nested struct fields
- Setting **`FORGE_UPDATES__AUTO_UPDATE=true`** bypasses the `confirm_update` logic and triggers immediate installation via `execute_update_command`
- When automatic updates are enabled, successful installation calls `std::process::exit(0)` to force a clean restart on the updated binary

## Frequently Asked Questions

### How does Forge detect that a new version is available?

Forge initializes an `update_informer` client in [`crates/forge_main/src/update.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_main/src/update.rs) that queries the GitHub API for the `antinomyhq/forge` repository. The `check_version()` method compares the running binary's version against the latest release tag and returns the newer version string if an update exists.

### What happens if I set FORGE_UPDATES__AUTO_UPDATE to false?

When this variable is `false` or unset, Forge evaluates `confirm_update(version).await` instead of proceeding automatically. This displays a confirmation prompt using `ForgeWidget::confirm` in the UI layer. The update only proceeds if the user explicitly approves it, or if `FORGE_SKIP_INTERACTIVE` is set to bypass the prompt.

### Can I change how often Forge checks for updates?

Yes. Set `FORGE_UPDATES__FREQUENCY` to `daily`, `weekly`, or `always`. This value is deserialized into the `UpdateFrequency` enum in the `Update` struct and controls the polling logic within the `update_informer` client configuration.

### Where does Forge look for the .forge.toml configuration file?

By default, Forge looks in `~/.forge/` for [`.forge.toml`](https://github.com/antinomyhq/forgecode/blob/main/.forge.toml). You can override this directory by setting the `FORGE_CONFIG` environment variable to a custom path. This file contains the `[updates]` section where `auto_update` and `frequency` can be specified persistently rather than via environment variables.