From 82e65975b27d92089654932f3f6698c1d08b690b Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Wed, 24 Sep 2025 09:15:03 -0700 Subject: [PATCH 1/3] fix: add tolerance for ambiguous behavior in `gh run list` (#4162) I am not sure what is going on, as https://github.com/openai/codex/pull/3660 introduced this new logic and I swear that CI was green before I merged that PR, but I am seeing failures in this CI job this morning. This feels like a non-backwards-compatible change in `gh`, but that feels unlikely... Nevertheless, this is what I currently see on my laptop: ``` $ gh --version gh version 2.76.2 (2025-07-30) https://github.com/cli/cli/releases/tag/v2.76.2 $ gh run list --workflow .github/workflows/rust-release.yml --branch rust-v0.40.0 --json workflowName,url,headSha --jq 'first(.[])' { "headSha": "5268705a69713752adcbd8416ef9e84a683f7aa3", "url": "https://github.com/openai/codex/actions/runs/17952349351", "workflowName": ".github/workflows/rust-release.yml" } ``` Looking at sample output from an old GitHub issue (https://github.com/cli/cli/issues/6678), it appears that, at least at one point in time, the `workflowName` was _not_ the path to the workflow. --- codex-cli/scripts/build_npm_package.py | 47 ++++++-------------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/codex-cli/scripts/build_npm_package.py b/codex-cli/scripts/build_npm_package.py index 2b35999033..0401f10385 100755 --- a/codex-cli/scripts/build_npm_package.py +++ b/codex-cli/scripts/build_npm_package.py @@ -15,6 +15,11 @@ CODEX_CLI_ROOT = SCRIPT_DIR.parent REPO_ROOT = CODEX_CLI_ROOT.parent GITHUB_REPO = "openai/codex" +# The docs are not clear on what the expected value/format of +# workflow/workflowName is: +# https://cli.github.com/manual/gh_run_list +WORKFLOW_NAME = ".github/workflows/rust-release.yml" + def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="Build or stage the Codex CLI npm package.") @@ -163,10 +168,8 @@ def install_native_binaries(staging_dir: Path, workflow_url: str | None) -> None def resolve_latest_alpha_workflow_url() -> str: version = determine_latest_alpha_version() - workflow_url = fetch_workflow_url_for_version(version) - if not workflow_url: - raise RuntimeError(f"Unable to locate workflow for version {version}.") - return workflow_url + workflow = resolve_release_workflow(version) + return workflow["url"] def determine_latest_alpha_version() -> str: @@ -205,36 +208,6 @@ def list_releases() -> list[dict]: return releases -def fetch_workflow_url_for_version(version: str) -> str | None: - ref = f"rust-v{version}" - stdout = subprocess.check_output( - [ - "gh", - "run", - "list", - "--branch", - ref, - "--limit", - "20", - "--json", - "workflowName,url", - ], - text=True, - ) - - try: - runs = json.loads(stdout or "[]") - except json.JSONDecodeError as exc: - raise RuntimeError("Unable to parse workflow run listing.") from exc - - for run in runs: - if run.get("workflowName") == "rust-release": - url = run.get("url") - if url: - return url - return None - - def resolve_release_workflow(version: str) -> dict: stdout = subprocess.check_output( [ @@ -245,12 +218,14 @@ def resolve_release_workflow(version: str) -> dict: f"rust-v{version}", "--json", "workflowName,url,headSha", + "--workflow", + WORKFLOW_NAME, "--jq", - 'first(.[] | select(.workflowName == "rust-release"))', + "first(.[])", ], text=True, ) - workflow = json.loads(stdout) + workflow = json.loads(stdout or "[]") if not workflow: raise RuntimeError(f"Unable to find rust-release workflow for version {version}.") return workflow From 00c7f7a16cc172e7d6272dc7f17550ec068be11a Mon Sep 17 00:00:00 2001 From: Tien Nguyen <116023870+htiennv@users.noreply.github.com> Date: Wed, 24 Sep 2025 23:15:57 +0700 Subject: [PATCH 2/3] chore: remove `once_cell` dependency from multiple crates (#4154) This commit removes the `once_cell` dependency from `Cargo.toml` files in the `codex-rs` and `apply-patch` directories, replacing its usage with `std::sync::LazyLock` and `std::sync::OnceLock` where applicable. This change simplifies the dependency tree and utilizes standard library features for lazy initialization. # External (non-OpenAI) Pull Request Requirements Before opening this Pull Request, please read the dedicated "Contributing" markdown file or your PR may be closed: https://github.com/openai/codex/blob/main/docs/contributing.md If your PR conforms to our contribution guidelines, replace this text with a detailed and high quality description of your changes. --- codex-rs/Cargo.lock | 2 -- codex-rs/Cargo.toml | 1 - codex-rs/apply-patch/Cargo.toml | 1 - codex-rs/apply-patch/src/lib.rs | 4 ++-- codex-rs/tui/Cargo.toml | 1 - codex-rs/tui/src/session_log.rs | 16 ++++++---------- 6 files changed, 8 insertions(+), 17 deletions(-) diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index a90b17214b..420e556528 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -595,7 +595,6 @@ version = "0.0.0" dependencies = [ "anyhow", "assert_cmd", - "once_cell", "pretty_assertions", "similar", "tempfile", @@ -956,7 +955,6 @@ dependencies = [ "lazy_static", "libc", "mcp-types", - "once_cell", "path-clean", "pathdiff", "pretty_assertions", diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index 56bdf090e6..cade2cb1c3 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -94,7 +94,6 @@ maplit = "1.0.2" mime_guess = "2.0.5" multimap = "0.10.0" nucleo-matcher = "0.3.1" -once_cell = "1" openssl-sys = "*" os_info = "3.12.0" owo-colors = "4.2.0" diff --git a/codex-rs/apply-patch/Cargo.toml b/codex-rs/apply-patch/Cargo.toml index d37404c15b..9445ae08b7 100644 --- a/codex-rs/apply-patch/Cargo.toml +++ b/codex-rs/apply-patch/Cargo.toml @@ -20,7 +20,6 @@ similar = { workspace = true } thiserror = { workspace = true } tree-sitter = { workspace = true } tree-sitter-bash = { workspace = true } -once_cell = { workspace = true } [dev-dependencies] assert_cmd = { workspace = true } diff --git a/codex-rs/apply-patch/src/lib.rs b/codex-rs/apply-patch/src/lib.rs index 189c1a07d0..3737c6ea6d 100644 --- a/codex-rs/apply-patch/src/lib.rs +++ b/codex-rs/apply-patch/src/lib.rs @@ -6,10 +6,10 @@ use std::collections::HashMap; use std::path::Path; use std::path::PathBuf; use std::str::Utf8Error; +use std::sync::LazyLock; use anyhow::Context; use anyhow::Result; -use once_cell::sync::Lazy; pub use parser::Hunk; pub use parser::ParseError; use parser::ParseError::*; @@ -351,7 +351,7 @@ fn extract_apply_patch_from_bash( // also run an arbitrary query against the AST. This is useful for understanding // how tree-sitter parses the script and whether the query syntax is correct. Be sure // to test both positive and negative cases. - static APPLY_PATCH_QUERY: Lazy = Lazy::new(|| { + static APPLY_PATCH_QUERY: LazyLock = LazyLock::new(|| { let language = BASH.into(); #[expect(clippy::expect_used)] Query::new( diff --git a/codex-rs/tui/Cargo.toml b/codex-rs/tui/Cargo.toml index 6de2a3476b..ffc49fd3b6 100644 --- a/codex-rs/tui/Cargo.toml +++ b/codex-rs/tui/Cargo.toml @@ -53,7 +53,6 @@ image = { workspace = true, features = [ itertools = { workspace = true } lazy_static = { workspace = true } mcp-types = { workspace = true } -once_cell = { workspace = true } path-clean = { workspace = true } rand = { workspace = true } ratatui = { workspace = true, features = [ diff --git a/codex-rs/tui/src/session_log.rs b/codex-rs/tui/src/session_log.rs index 3118800b71..75946edb5c 100644 --- a/codex-rs/tui/src/session_log.rs +++ b/codex-rs/tui/src/session_log.rs @@ -2,27 +2,27 @@ use std::fs::File; use std::fs::OpenOptions; use std::io::Write; use std::path::PathBuf; +use std::sync::LazyLock; use std::sync::Mutex; +use std::sync::OnceLock; use codex_core::config::Config; use codex_core::protocol::Op; -use once_cell::sync::Lazy; -use once_cell::sync::OnceCell; use serde::Serialize; use serde_json::json; use crate::app_event::AppEvent; -static LOGGER: Lazy = Lazy::new(SessionLogger::new); +static LOGGER: LazyLock = LazyLock::new(SessionLogger::new); struct SessionLogger { - file: OnceCell>, + file: OnceLock>, } impl SessionLogger { fn new() -> Self { Self { - file: OnceCell::new(), + file: OnceLock::new(), } } @@ -37,11 +37,7 @@ impl SessionLogger { } let file = opts.open(path)?; - // If already initialized, ignore and succeed. - if self.file.get().is_some() { - return Ok(()); - } - let _ = self.file.set(Mutex::new(file)); + self.file.get_or_init(|| Mutex::new(file)); Ok(()) } From 4fb5dc058c0cce0fecf628497fe6e3d995eb5798 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Wed, 24 Sep 2025 13:02:55 -0700 Subject: [PATCH 3/3] chore: drop unused values from env_flags --- codex-rs/core/src/flags.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/codex-rs/core/src/flags.rs b/codex-rs/core/src/flags.rs index 60201a3b18..de693868df 100644 --- a/codex-rs/core/src/flags.rs +++ b/codex-rs/core/src/flags.rs @@ -1,16 +1,6 @@ -use std::time::Duration; - use env_flags::env_flags; env_flags! { - pub OPENAI_API_BASE: &str = "https://api.openai.com/v1"; - - /// Fallback when the provider-specific key is not set. - pub OPENAI_API_KEY: Option<&str> = None; - pub OPENAI_TIMEOUT_MS: Duration = Duration::from_millis(300_000), |value| { - value.parse().map(Duration::from_millis) - }; - /// Fixture path for offline tests (see client.rs). pub CODEX_RS_SSE_FIXTURE: Option<&str> = None; }