updates: use brew api for version check (#10809)

## Problem

`codex` currently prompts you to update via `brew upgrade --cask codex`
but the brew api does not return the new version

> <img width="1500" height="822" alt="Screenshot 2026-02-05 at 12 36
09 PM"
src="https://github.com/user-attachments/assets/9e12929d-95e8-43f4-8fba-ab93f5f76e73"
/>

## Solution

`codex-rs/tui/src/updates.rs` was using the [latest cask in
github](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/c/codex.rb)
but this does not agree with the brew api, which leads to the issue
above. Instead we use the [brew api json
endpoint](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/c/codex.rb)
to ensure our version check agrees with the upgrade command.
This commit is contained in:
Noah Jorgensen authored and GitHub committed 2026-02-05 15:12:27 -08:00
1 parent dbe47ea01a
commit dcea972db8
1 file changed
+22 -28
+22 -28
View File
@@ -56,8 +56,7 @@ struct VersionInfo {
const VERSION_FILENAME: &str = "version.json"; const VERSION_FILENAME: &str = "version.json";
// We use the latest version from the cask if installation is via homebrew - homebrew does not immediately pick up the latest release and can lag behind. // We use the latest version from the cask if installation is via homebrew - homebrew does not immediately pick up the latest release and can lag behind.
const HOMEBREW_CASK_URL: &str = const HOMEBREW_CASK_API_URL: &str = "https://formulae.brew.sh/api/cask/codex.json";
"https://raw.githubusercontent.com/Homebrew/homebrew-cask/HEAD/Casks/c/codex.rb";
const LATEST_RELEASE_URL: &str = "https://api.github.com/repos/openai/codex/releases/latest"; const LATEST_RELEASE_URL: &str = "https://api.github.com/repos/openai/codex/releases/latest";
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
@@ -65,6 +64,11 @@ struct ReleaseInfo {
tag_name: String, tag_name: String,
} }
#[derive(Deserialize, Debug, Clone)]
struct HomebrewCaskInfo {
version: String,
}
fn version_filepath(config: &Config) -> PathBuf { fn version_filepath(config: &Config) -> PathBuf {
config.codex_home.join(VERSION_FILENAME) config.codex_home.join(VERSION_FILENAME)
} }
@@ -77,14 +81,14 @@ fn read_version_info(version_file: &Path) -> anyhow::Result<VersionInfo> {
async fn check_for_update(version_file: &Path) -> anyhow::Result<()> { async fn check_for_update(version_file: &Path) -> anyhow::Result<()> {
let latest_version = match update_action::get_update_action() { let latest_version = match update_action::get_update_action() {
Some(UpdateAction::BrewUpgrade) => { Some(UpdateAction::BrewUpgrade) => {
let cask_contents = create_client() let HomebrewCaskInfo { version } = create_client()
.get(HOMEBREW_CASK_URL) .get(HOMEBREW_CASK_API_URL)
.send() .send()
.await? .await?
.error_for_status()? .error_for_status()?
.text() .json::<HomebrewCaskInfo>()
.await?; .await?;
extract_version_from_cask(&cask_contents)? version
} }
_ => { _ => {
let ReleaseInfo { let ReleaseInfo {
@@ -123,18 +127,6 @@ fn is_newer(latest: &str, current: &str) -> Option<bool> {
} }
} }
fn extract_version_from_cask(cask_contents: &str) -> anyhow::Result<String> {
cask_contents
.lines()
.find_map(|line| {
let line = line.trim();
line.strip_prefix("version \"")
.and_then(|rest| rest.strip_suffix('"'))
.map(ToString::to_string)
})
.ok_or_else(|| anyhow::anyhow!("Failed to find version in Homebrew cask file"))
}
fn extract_version_from_latest_tag(latest_tag_name: &str) -> anyhow::Result<String> { fn extract_version_from_latest_tag(latest_tag_name: &str) -> anyhow::Result<String> {
latest_tag_name latest_tag_name
.strip_prefix("rust-v") .strip_prefix("rust-v")
@@ -190,16 +182,18 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn parses_version_from_cask_contents() { fn extract_version_from_brew_api_json() {
let cask = r#" //
cask "codex" do // https://formulae.brew.sh/api/cask/codex.json
version "0.55.0" let cask_json = r#"{
end "token": "codex",
"#; "full_token": "codex",
assert_eq!( "tap": "homebrew/cask",
extract_version_from_cask(cask).expect("failed to parse version"), "version": "0.96.0",
"0.55.0" }"#;
); let HomebrewCaskInfo { version } = serde_json::from_str::<HomebrewCaskInfo>(cask_json)
.expect("failed to parse version from cask json");
assert_eq!(version, "0.96.0");
} }
#[test] #[test]