From f4d0cbfda61ad81559cb8d7b800b67fef2034748 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Fri, 27 Mar 2026 20:47:22 -0700 Subject: [PATCH 1/3] ci: run Bazel clippy on Windows gnullvm (#16067) ## Why We want more of the pre-merge Rust signal to come from `bazel.yml`, especially on Windows. The Bazel test workflow already exercises `x86_64-pc-windows-gnullvm`, but the Bazel clippy job still only ran on Linux x64 and macOS arm64. That left a gap where Windows-only Bazel lint breakages could slip through until the Cargo-based workflow ran. This change keeps the fix narrow. Rather than expanding the Bazel clippy target set or changing the shared setup logic, it extends the existing clippy matrix to the same Windows GNU toolchain that the Bazel test job already uses. ## What Changed - add `windows-latest` / `x86_64-pc-windows-gnullvm` to the `clippy` job matrix in `.github/workflows/bazel.yml` - update the nearby workflow comment to explain that the goal is to get Bazel-native Windows lint coverage on the same toolchain as the Bazel test lane - leave the Bazel clippy scope unchanged at `//codex-rs/... -//codex-rs/v8-poc:all` ## Verification - parsed `.github/workflows/bazel.yml` successfully with Ruby `YAML.load_file` --- .github/workflows/bazel.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index afabdb4314..2636213af9 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -103,11 +103,15 @@ jobs: matrix: include: # Keep Linux lint coverage on x64 and add the arm64 macOS path that - # the Bazel test job already exercises. + # the Bazel test job already exercises. Add Windows gnullvm as well + # so PRs get Bazel-native lint signal on the same Windows toolchain + # that the Bazel test job uses. - os: ubuntu-24.04 target: x86_64-unknown-linux-gnu - os: macos-15-xlarge target: aarch64-apple-darwin + - os: windows-latest + target: x86_64-pc-windows-gnullvm runs-on: ${{ matrix.os }} name: Bazel clippy on ${{ matrix.os }} for ${{ matrix.target }} From e02fd6e1d3d0ee7a47780ab3efc1c769cd373337 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Fri, 27 Mar 2026 20:48:21 -0700 Subject: [PATCH 2/3] fix: clean up remaining Windows argument-comment-lint violations (#16071) ## Why The initial `argument-comment-lint` rollout left Windows on default-target coverage because there were still Windows-only callsites failing under `--all-targets`. This follow-up cleans up those remaining Windows-specific violations so the Windows CI lane can enforce the same stricter coverage, leaving Linux as the remaining platform-specific follow-up. ## What changed - switched the Windows `rust-ci` argument-comment-lint step back to the default wrapper invocation so it runs full-target coverage again - added the required `/*param_name*/` annotations at Windows-gated literal callsites in: - `codex-rs/windows-sandbox-rs/src/lib.rs` - `codex-rs/windows-sandbox-rs/src/elevated_impl.rs` - `codex-rs/tui_app_server/src/multi_agents.rs` - `codex-rs/network-proxy/src/proxy.rs` ## Validation - Windows `argument comment lint` CI on this PR --- .github/workflows/rust-ci.yml | 4 ++-- codex-rs/network-proxy/src/proxy.rs | 2 +- codex-rs/tui_app_server/src/multi_agents.rs | 8 ++++---- codex-rs/windows-sandbox-rs/src/elevated_impl.rs | 4 ++-- codex-rs/windows-sandbox-rs/src/lib.rs | 8 ++++++-- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 6c93a27006..345c9f9d1e 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -163,10 +163,10 @@ jobs: if: ${{ runner.os == 'Linux' }} shell: bash run: python3 ./tools/argument-comment-lint/run-prebuilt-linter.py -- --lib --bins - - name: Run argument comment lint on codex-rs (default targets only) + - name: Run argument comment lint on codex-rs if: ${{ runner.os == 'Windows' }} shell: bash - run: python ./tools/argument-comment-lint/run-prebuilt-linter.py -- --lib --bins + run: python ./tools/argument-comment-lint/run-prebuilt-linter.py # --- CI to validate on different os/targets -------------------------------- lint_build: diff --git a/codex-rs/network-proxy/src/proxy.rs b/codex-rs/network-proxy/src/proxy.rs index 715e762b58..c334e817d0 100644 --- a/codex-rs/network-proxy/src/proxy.rs +++ b/codex-rs/network-proxy/src/proxy.rs @@ -780,7 +780,7 @@ mod tests { let reserved = reserve_windows_managed_listeners( SocketAddr::from(([127, 0, 0, 1], busy_port)), SocketAddr::from(([127, 0, 0, 1], 48081)), - false, + /*reserve_socks_listener*/ false, ) .unwrap(); diff --git a/codex-rs/tui_app_server/src/multi_agents.rs b/codex-rs/tui_app_server/src/multi_agents.rs index a1b0e57ff8..293c80fcf0 100644 --- a/codex-rs/tui_app_server/src/multi_agents.rs +++ b/codex-rs/tui_app_server/src/multi_agents.rs @@ -717,19 +717,19 @@ mod tests { fn agent_shortcut_matches_option_arrows_only() { assert!(previous_agent_shortcut_matches( KeyEvent::new(KeyCode::Left, crossterm::event::KeyModifiers::ALT,), - false + /*allow_word_motion_fallback*/ false )); assert!(next_agent_shortcut_matches( KeyEvent::new(KeyCode::Right, crossterm::event::KeyModifiers::ALT,), - false + /*allow_word_motion_fallback*/ false )); assert!(!previous_agent_shortcut_matches( KeyEvent::new(KeyCode::Char('b'), crossterm::event::KeyModifiers::ALT,), - false + /*allow_word_motion_fallback*/ false )); assert!(!next_agent_shortcut_matches( KeyEvent::new(KeyCode::Char('f'), crossterm::event::KeyModifiers::ALT,), - false + /*allow_word_motion_fallback*/ false )); } diff --git a/codex-rs/windows-sandbox-rs/src/elevated_impl.rs b/codex-rs/windows-sandbox-rs/src/elevated_impl.rs index cc2b7fdad6..588e65d963 100644 --- a/codex-rs/windows-sandbox-rs/src/elevated_impl.rs +++ b/codex-rs/windows-sandbox-rs/src/elevated_impl.rs @@ -490,12 +490,12 @@ mod windows_impl { #[test] fn applies_network_block_when_access_is_disabled() { - assert!(!workspace_policy(false).has_full_network_access()); + assert!(!workspace_policy(/*network_access*/ false).has_full_network_access()); } #[test] fn skips_network_block_when_access_is_allowed() { - assert!(workspace_policy(true).has_full_network_access()); + assert!(workspace_policy(/*network_access*/ true).has_full_network_access()); } #[test] diff --git a/codex-rs/windows-sandbox-rs/src/lib.rs b/codex-rs/windows-sandbox-rs/src/lib.rs index b0de8c2e02..2030919fd3 100644 --- a/codex-rs/windows-sandbox-rs/src/lib.rs +++ b/codex-rs/windows-sandbox-rs/src/lib.rs @@ -617,12 +617,16 @@ mod windows_impl { #[test] fn applies_network_block_when_access_is_disabled() { - assert!(should_apply_network_block(&workspace_policy(false))); + assert!(should_apply_network_block(&workspace_policy( + /*network_access*/ false + ))); } #[test] fn skips_network_block_when_access_is_allowed() { - assert!(!should_apply_network_block(&workspace_policy(true))); + assert!(!should_apply_network_block(&workspace_policy( + /*network_access*/ true + ))); } #[test] From 83f2a4ca1546f61c051cb9648c1648377e39b578 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Fri, 27 Mar 2026 20:52:30 -0700 Subject: [PATCH 3/3] ci: split fast PR Rust CI from full post-merge Cargo CI --- .github/workflows/README.md | 33 ++ .github/workflows/rust-ci-full.yml | 761 +++++++++++++++++++++++++++++ .github/workflows/rust-ci.yml | 691 +------------------------- 3 files changed, 812 insertions(+), 673 deletions(-) create mode 100644 .github/workflows/README.md create mode 100644 .github/workflows/rust-ci-full.yml diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000000..b2e871693a --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,33 @@ +# Workflow Strategy + +The workflows in this directory are split so that pull requests get fast, review-friendly signal while `main` still gets the full cross-platform verification pass. + +## Pull Requests + +- `bazel.yml` is the main pre-merge verification path for Rust code. + It runs Bazel `test` and Bazel `clippy` on the supported Bazel targets. +- `rust-ci.yml` keeps the Cargo-native PR checks intentionally small: + - `cargo fmt --check` + - `cargo shear` + - `argument-comment-lint` + - `tools/argument-comment-lint` package tests when the lint or its workflow wiring changes + +The PR workflow keeps `argument-comment-lint` on Linux only. The lint semantics are platform-independent, and trimming the PR-time matrix here leaves more of the latency budget for Bazel build/test/clippy. + +## Post-Merge On `main` + +- `bazel.yml` also runs on pushes to `main`. + This re-verifies the merged Bazel path and helps keep the BuildBuddy caches warm. +- `rust-ci-full.yml` is the full Cargo-native verification workflow. + It keeps the heavier checks off the PR path while still validating them after merge: + - the full Cargo `clippy` matrix + - the full Cargo `nextest` matrix + - release-profile Cargo builds + - cross-platform `argument-comment-lint` + - Linux remote-env tests + +## Rule Of Thumb + +- If a build/test/clippy check can be expressed in Bazel, prefer putting the PR-time version in `bazel.yml`. +- Keep `rust-ci.yml` fast enough that it usually does not dominate PR latency. +- Reserve `rust-ci-full.yml` for heavyweight Cargo-native coverage that Bazel does not replace yet. diff --git a/.github/workflows/rust-ci-full.yml b/.github/workflows/rust-ci-full.yml new file mode 100644 index 0000000000..43ce57cd47 --- /dev/null +++ b/.github/workflows/rust-ci-full.yml @@ -0,0 +1,761 @@ +name: rust-ci-full +on: + push: + branches: + - main + workflow_dispatch: + +# CI builds in debug (dev) for faster signal. + +jobs: + # --- CI that doesn't need specific targets --------------------------------- + general: + name: Format / etc + runs-on: ubuntu-24.04 + defaults: + run: + working-directory: codex-rs + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 + with: + components: rustfmt + - name: cargo fmt + run: cargo fmt -- --config imports_granularity=Item --check + + cargo_shear: + name: cargo shear + runs-on: ubuntu-24.04 + defaults: + run: + working-directory: codex-rs + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 + - uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2 + with: + tool: cargo-shear + version: 1.5.1 + - name: cargo shear + run: cargo shear + + argument_comment_lint_package: + name: Argument comment lint package + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 + with: + toolchain: nightly-2025-09-18 + components: llvm-tools-preview, rustc-dev, rust-src + - name: Cache cargo-dylint tooling + id: cargo_dylint_cache + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: | + ~/.cargo/bin/cargo-dylint + ~/.cargo/bin/dylint-link + ~/.cargo/registry/index + ~/.cargo/registry/cache + ~/.cargo/git/db + key: argument-comment-lint-${{ runner.os }}-${{ hashFiles('tools/argument-comment-lint/Cargo.lock', 'tools/argument-comment-lint/rust-toolchain', '.github/workflows/rust-ci.yml', '.github/workflows/rust-ci-full.yml') }} + - name: Install cargo-dylint tooling + if: ${{ steps.cargo_dylint_cache.outputs.cache-hit != 'true' }} + run: cargo install --locked cargo-dylint dylint-link + - name: Check Python wrapper syntax + run: python3 -m py_compile tools/argument-comment-lint/wrapper_common.py tools/argument-comment-lint/run.py tools/argument-comment-lint/run-prebuilt-linter.py tools/argument-comment-lint/test_wrapper_common.py + - name: Test Python wrapper helpers + run: python3 -m unittest discover -s tools/argument-comment-lint -p 'test_*.py' + - name: Test argument comment lint package + working-directory: tools/argument-comment-lint + run: cargo test + + argument_comment_lint_prebuilt: + name: Argument comment lint - ${{ matrix.name }} + runs-on: ${{ matrix.runs_on || matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - name: Linux + runner: ubuntu-24.04 + - name: macOS + runner: macos-15-xlarge + - name: Windows + runner: windows-x64 + runs_on: + group: codex-runners + labels: codex-windows-x64 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Install Linux sandbox build dependencies + if: ${{ runner.os == 'Linux' }} + shell: bash + run: | + sudo DEBIAN_FRONTEND=noninteractive apt-get update + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev + - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 + with: + toolchain: nightly-2025-09-18 + components: llvm-tools-preview, rustc-dev, rust-src + - uses: facebook/install-dotslash@1e4e7b3e07eaca387acb98f1d4720e0bee8dbb6a # v2 + - name: Run argument comment lint on codex-rs + if: ${{ runner.os == 'macOS' }} + shell: bash + run: python3 ./tools/argument-comment-lint/run-prebuilt-linter.py + - name: Run argument comment lint on codex-rs (default targets only) + if: ${{ runner.os == 'Linux' }} + shell: bash + run: python3 ./tools/argument-comment-lint/run-prebuilt-linter.py -- --lib --bins + - name: Run argument comment lint on codex-rs + if: ${{ runner.os == 'Windows' }} + shell: bash + run: python ./tools/argument-comment-lint/run-prebuilt-linter.py + + # --- CI to validate on different os/targets -------------------------------- + lint_build: + name: Lint/Build — ${{ matrix.runner }} - ${{ matrix.target }}${{ matrix.profile == 'release' && ' (release)' || '' }} + runs-on: ${{ matrix.runs_on || matrix.runner }} + timeout-minutes: 30 + defaults: + run: + working-directory: codex-rs + env: + # Speed up repeated builds across CI runs by caching compiled objects, except on + # arm64 macOS runners cross-targeting x86_64 where ring/cc-rs can produce + # mixed-architecture archives under sccache. + USE_SCCACHE: ${{ (startsWith(matrix.runner, 'windows') || (matrix.runner == 'macos-15-xlarge' && matrix.target == 'x86_64-apple-darwin')) && 'false' || 'true' }} + CARGO_INCREMENTAL: "0" + SCCACHE_CACHE_SIZE: 10G + # In rust-ci, representative release-profile checks use thin LTO for faster feedback. + CARGO_PROFILE_RELEASE_LTO: ${{ matrix.profile == 'release' && 'thin' || 'fat' }} + + strategy: + fail-fast: false + matrix: + include: + - runner: macos-15-xlarge + target: aarch64-apple-darwin + profile: dev + - runner: macos-15-xlarge + target: x86_64-apple-darwin + profile: dev + - runner: ubuntu-24.04 + target: x86_64-unknown-linux-musl + profile: dev + runs_on: + group: codex-runners + labels: codex-linux-x64 + - runner: ubuntu-24.04 + target: x86_64-unknown-linux-gnu + profile: dev + runs_on: + group: codex-runners + labels: codex-linux-x64 + - runner: ubuntu-24.04-arm + target: aarch64-unknown-linux-musl + profile: dev + runs_on: + group: codex-runners + labels: codex-linux-arm64 + - runner: ubuntu-24.04-arm + target: aarch64-unknown-linux-gnu + profile: dev + runs_on: + group: codex-runners + labels: codex-linux-arm64 + - runner: windows-x64 + target: x86_64-pc-windows-msvc + profile: dev + runs_on: + group: codex-runners + labels: codex-windows-x64 + - runner: windows-arm64 + target: aarch64-pc-windows-msvc + profile: dev + runs_on: + group: codex-runners + labels: codex-windows-arm64 + + # Also run representative release builds on Mac and Linux because + # there could be release-only build errors we want to catch. + # Hopefully this also pre-populates the build cache to speed up + # releases. + - runner: macos-15-xlarge + target: aarch64-apple-darwin + profile: release + - runner: ubuntu-24.04 + target: x86_64-unknown-linux-musl + profile: release + runs_on: + group: codex-runners + labels: codex-linux-x64 + - runner: ubuntu-24.04-arm + target: aarch64-unknown-linux-musl + profile: release + runs_on: + group: codex-runners + labels: codex-linux-arm64 + - runner: windows-x64 + target: x86_64-pc-windows-msvc + profile: release + runs_on: + group: codex-runners + labels: codex-windows-x64 + - runner: windows-arm64 + target: aarch64-pc-windows-msvc + profile: release + runs_on: + group: codex-runners + labels: codex-windows-arm64 + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Install Linux build dependencies + if: ${{ runner.os == 'Linux' }} + shell: bash + run: | + set -euo pipefail + if command -v apt-get >/dev/null 2>&1; then + sudo apt-get update -y + packages=(pkg-config libcap-dev) + if [[ "${{ matrix.target }}" == 'x86_64-unknown-linux-musl' || "${{ matrix.target }}" == 'aarch64-unknown-linux-musl' ]]; then + packages+=(libubsan1) + fi + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "${packages[@]}" + fi + - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 + with: + targets: ${{ matrix.target }} + components: clippy + + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} + name: Use hermetic Cargo home (musl) + shell: bash + run: | + set -euo pipefail + cargo_home="${GITHUB_WORKSPACE}/.cargo-home" + mkdir -p "${cargo_home}/bin" + echo "CARGO_HOME=${cargo_home}" >> "$GITHUB_ENV" + echo "${cargo_home}/bin" >> "$GITHUB_PATH" + : > "${cargo_home}/config.toml" + + - name: Compute lockfile hash + id: lockhash + working-directory: codex-rs + shell: bash + run: | + set -euo pipefail + echo "hash=$(sha256sum Cargo.lock | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" + echo "toolchain_hash=$(sha256sum rust-toolchain.toml | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" + + # Explicit cache restore: split cargo home vs target, so we can + # avoid caching the large target dir on the gnu-dev job. + - name: Restore cargo home cache + id: cache_cargo_home_restore + uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ${{ github.workspace }}/.cargo-home/bin/ + ${{ github.workspace }}/.cargo-home/registry/index/ + ${{ github.workspace }}/.cargo-home/registry/cache/ + ${{ github.workspace }}/.cargo-home/git/db/ + key: cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ steps.lockhash.outputs.toolchain_hash }} + restore-keys: | + cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}- + + # Install and restore sccache cache + - name: Install sccache + if: ${{ env.USE_SCCACHE == 'true' }} + uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2 + with: + tool: sccache + version: 0.7.5 + + - name: Configure sccache backend + if: ${{ env.USE_SCCACHE == 'true' }} + shell: bash + run: | + set -euo pipefail + if [[ -n "${ACTIONS_CACHE_URL:-}" && -n "${ACTIONS_RUNTIME_TOKEN:-}" ]]; then + echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV" + echo "Using sccache GitHub backend" + else + echo "SCCACHE_GHA_ENABLED=false" >> "$GITHUB_ENV" + echo "SCCACHE_DIR=${{ github.workspace }}/.sccache" >> "$GITHUB_ENV" + echo "Using sccache local disk + actions/cache fallback" + fi + + - name: Enable sccache wrapper + if: ${{ env.USE_SCCACHE == 'true' }} + shell: bash + run: echo "RUSTC_WRAPPER=sccache" >> "$GITHUB_ENV" + + - name: Restore sccache cache (fallback) + if: ${{ env.USE_SCCACHE == 'true' && env.SCCACHE_GHA_ENABLED != 'true' }} + id: cache_sccache_restore + uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: ${{ github.workspace }}/.sccache/ + key: sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ github.run_id }} + restore-keys: | + sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}- + sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}- + + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} + name: Disable sccache wrapper (musl) + shell: bash + run: | + set -euo pipefail + echo "RUSTC_WRAPPER=" >> "$GITHUB_ENV" + echo "RUSTC_WORKSPACE_WRAPPER=" >> "$GITHUB_ENV" + + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} + name: Prepare APT cache directories (musl) + shell: bash + run: | + set -euo pipefail + sudo mkdir -p /var/cache/apt/archives /var/lib/apt/lists + sudo chown -R "$USER:$USER" /var/cache/apt /var/lib/apt/lists + + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} + name: Restore APT cache (musl) + id: cache_apt_restore + uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: | + /var/cache/apt + key: apt-${{ matrix.runner }}-${{ matrix.target }}-v1 + + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} + name: Install Zig + uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 + with: + version: 0.14.0 + + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} + name: Install musl build tools + env: + DEBIAN_FRONTEND: noninteractive + TARGET: ${{ matrix.target }} + APT_UPDATE_ARGS: -o Acquire::Retries=3 + APT_INSTALL_ARGS: --no-install-recommends + shell: bash + run: bash "${GITHUB_WORKSPACE}/.github/scripts/install-musl-build-tools.sh" + + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} + name: Configure rustc UBSan wrapper (musl host) + shell: bash + run: | + set -euo pipefail + ubsan="" + if command -v ldconfig >/dev/null 2>&1; then + ubsan="$(ldconfig -p | grep -m1 'libubsan\.so\.1' | sed -E 's/.*=> (.*)$/\1/')" + fi + wrapper_root="${RUNNER_TEMP:-/tmp}" + wrapper="${wrapper_root}/rustc-ubsan-wrapper" + cat > "${wrapper}" <> "$GITHUB_ENV" + echo "RUSTC_WORKSPACE_WRAPPER=" >> "$GITHUB_ENV" + + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} + name: Clear sanitizer flags (musl) + shell: bash + run: | + set -euo pipefail + # Clear global Rust flags so host/proc-macro builds don't pull in UBSan. + echo "RUSTFLAGS=" >> "$GITHUB_ENV" + echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV" + echo "RUSTDOCFLAGS=" >> "$GITHUB_ENV" + # Override any runner-level Cargo config rustflags as well. + echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV" + echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV" + echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV" + echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV" + echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV" + + sanitize_flags() { + local input="$1" + input="${input//-fsanitize=undefined/}" + input="${input//-fno-sanitize-recover=undefined/}" + input="${input//-fno-sanitize-trap=undefined/}" + echo "$input" + } + + cflags="$(sanitize_flags "${CFLAGS-}")" + cxxflags="$(sanitize_flags "${CXXFLAGS-}")" + echo "CFLAGS=${cflags}" >> "$GITHUB_ENV" + echo "CXXFLAGS=${cxxflags}" >> "$GITHUB_ENV" + + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl' }} + name: Configure musl rusty_v8 artifact overrides + env: + TARGET: ${{ matrix.target }} + shell: bash + run: | + set -euo pipefail + version="$(python3 "${GITHUB_WORKSPACE}/.github/scripts/rusty_v8_bazel.py" resolved-v8-crate-version)" + release_tag="rusty-v8-v${version}" + base_url="https://github.com/openai/codex/releases/download/${release_tag}" + archive="https://github.com/openai/codex/releases/download/rusty-v8-v${version}/librusty_v8_release_${TARGET}.a.gz" + binding_dir="${RUNNER_TEMP}/rusty_v8" + binding_path="${binding_dir}/src_binding_release_${TARGET}.rs" + mkdir -p "${binding_dir}" + curl -fsSL "${base_url}/src_binding_release_${TARGET}.rs" -o "${binding_path}" + echo "RUSTY_V8_ARCHIVE=${archive}" >> "$GITHUB_ENV" + echo "RUSTY_V8_SRC_BINDING_PATH=${binding_path}" >> "$GITHUB_ENV" + + - name: Install cargo-chef + if: ${{ matrix.profile == 'release' }} + uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2 + with: + tool: cargo-chef + version: 0.1.71 + + - name: Pre-warm dependency cache (cargo-chef) + if: ${{ matrix.profile == 'release' }} + shell: bash + run: | + set -euo pipefail + RECIPE="${RUNNER_TEMP}/chef-recipe.json" + cargo chef prepare --recipe-path "$RECIPE" + cargo chef cook --recipe-path "$RECIPE" --target ${{ matrix.target }} --release --all-features + + - name: cargo clippy + run: cargo clippy --target ${{ matrix.target }} --all-features --tests --profile ${{ matrix.profile }} --timings -- -D warnings + + - name: Upload Cargo timings (clippy) + if: always() + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 + with: + name: cargo-timings-rust-ci-clippy-${{ matrix.target }}-${{ matrix.profile }} + path: codex-rs/target/**/cargo-timings/cargo-timing.html + if-no-files-found: warn + + # Save caches explicitly; make non-fatal so cache packaging + # never fails the overall job. Only save when key wasn't hit. + - name: Save cargo home cache + if: always() && !cancelled() && steps.cache_cargo_home_restore.outputs.cache-hit != 'true' + continue-on-error: true + uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ${{ github.workspace }}/.cargo-home/bin/ + ${{ github.workspace }}/.cargo-home/registry/index/ + ${{ github.workspace }}/.cargo-home/registry/cache/ + ${{ github.workspace }}/.cargo-home/git/db/ + key: cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ steps.lockhash.outputs.toolchain_hash }} + + - name: Save sccache cache (fallback) + if: always() && !cancelled() && env.USE_SCCACHE == 'true' && env.SCCACHE_GHA_ENABLED != 'true' + continue-on-error: true + uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: ${{ github.workspace }}/.sccache/ + key: sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ github.run_id }} + + - name: sccache stats + if: always() && env.USE_SCCACHE == 'true' + continue-on-error: true + run: sccache --show-stats || true + + - name: sccache summary + if: always() && env.USE_SCCACHE == 'true' + shell: bash + run: | + { + echo "### sccache stats — ${{ matrix.target }} (${{ matrix.profile }})"; + echo; + echo '```'; + sccache --show-stats || true; + echo '```'; + } >> "$GITHUB_STEP_SUMMARY" + + - name: Save APT cache (musl) + if: always() && !cancelled() && (matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl') && steps.cache_apt_restore.outputs.cache-hit != 'true' + continue-on-error: true + uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: | + /var/cache/apt + key: apt-${{ matrix.runner }}-${{ matrix.target }}-v1 + + tests: + name: Tests — ${{ matrix.runner }} - ${{ matrix.target }}${{ matrix.remote_env == 'true' && ' (remote)' || '' }} + runs-on: ${{ matrix.runs_on || matrix.runner }} + # Perhaps we can bring this back down to 30m once we finish the cutover + # from tui_app_server/ to tui/. Incidentally, windows-arm64 was the main + # offender for exceeding the timeout. + timeout-minutes: 45 + defaults: + run: + working-directory: codex-rs + env: + # Speed up repeated builds across CI runs by caching compiled objects, except on + # arm64 macOS runners cross-targeting x86_64 where ring/cc-rs can produce + # mixed-architecture archives under sccache. + USE_SCCACHE: ${{ (startsWith(matrix.runner, 'windows') || (matrix.runner == 'macos-15-xlarge' && matrix.target == 'x86_64-apple-darwin')) && 'false' || 'true' }} + CARGO_INCREMENTAL: "0" + SCCACHE_CACHE_SIZE: 10G + + strategy: + fail-fast: false + matrix: + include: + - runner: macos-15-xlarge + target: aarch64-apple-darwin + profile: dev + - runner: ubuntu-24.04 + target: x86_64-unknown-linux-gnu + profile: dev + remote_env: "true" + runs_on: + group: codex-runners + labels: codex-linux-x64 + - runner: ubuntu-24.04-arm + target: aarch64-unknown-linux-gnu + profile: dev + runs_on: + group: codex-runners + labels: codex-linux-arm64 + - runner: windows-x64 + target: x86_64-pc-windows-msvc + profile: dev + runs_on: + group: codex-runners + labels: codex-windows-x64 + - runner: windows-arm64 + target: aarch64-pc-windows-msvc + profile: dev + runs_on: + group: codex-runners + labels: codex-windows-arm64 + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Set up Node.js for js_repl tests + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + with: + node-version-file: codex-rs/node-version.txt + - name: Install Linux build dependencies + if: ${{ runner.os == 'Linux' }} + shell: bash + run: | + set -euo pipefail + if command -v apt-get >/dev/null 2>&1; then + sudo apt-get update -y + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev + fi + + # Some integration tests rely on DotSlash being installed. + # See https://github.com/openai/codex/pull/7617. + - name: Install DotSlash + uses: facebook/install-dotslash@1e4e7b3e07eaca387acb98f1d4720e0bee8dbb6a # v2 + + - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 + with: + targets: ${{ matrix.target }} + + - name: Compute lockfile hash + id: lockhash + working-directory: codex-rs + shell: bash + run: | + set -euo pipefail + echo "hash=$(sha256sum Cargo.lock | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" + echo "toolchain_hash=$(sha256sum rust-toolchain.toml | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" + + - name: Restore cargo home cache + id: cache_cargo_home_restore + uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + key: cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ steps.lockhash.outputs.toolchain_hash }} + restore-keys: | + cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}- + + - name: Install sccache + if: ${{ env.USE_SCCACHE == 'true' }} + uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2 + with: + tool: sccache + version: 0.7.5 + + - name: Configure sccache backend + if: ${{ env.USE_SCCACHE == 'true' }} + shell: bash + run: | + set -euo pipefail + if [[ -n "${ACTIONS_CACHE_URL:-}" && -n "${ACTIONS_RUNTIME_TOKEN:-}" ]]; then + echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV" + echo "Using sccache GitHub backend" + else + echo "SCCACHE_GHA_ENABLED=false" >> "$GITHUB_ENV" + echo "SCCACHE_DIR=${{ github.workspace }}/.sccache" >> "$GITHUB_ENV" + echo "Using sccache local disk + actions/cache fallback" + fi + + - name: Enable sccache wrapper + if: ${{ env.USE_SCCACHE == 'true' }} + shell: bash + run: echo "RUSTC_WRAPPER=sccache" >> "$GITHUB_ENV" + + - name: Restore sccache cache (fallback) + if: ${{ env.USE_SCCACHE == 'true' && env.SCCACHE_GHA_ENABLED != 'true' }} + id: cache_sccache_restore + uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: ${{ github.workspace }}/.sccache/ + key: sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ github.run_id }} + restore-keys: | + sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}- + sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}- + + - uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2 + with: + tool: nextest + version: 0.9.103 + + - name: Enable unprivileged user namespaces (Linux) + if: runner.os == 'Linux' + run: | + # Required for bubblewrap to work on Linux CI runners. + sudo sysctl -w kernel.unprivileged_userns_clone=1 + # Ubuntu 24.04+ can additionally gate unprivileged user namespaces + # behind AppArmor. + if sudo sysctl -a 2>/dev/null | grep -q '^kernel.apparmor_restrict_unprivileged_userns'; then + sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 + fi + + - name: Set up remote test env (Docker) + if: ${{ runner.os == 'Linux' && matrix.remote_env == 'true' }} + shell: bash + run: | + set -euo pipefail + export CODEX_TEST_REMOTE_ENV_CONTAINER_NAME=codex-remote-test-env + source "${GITHUB_WORKSPACE}/scripts/test-remote-env.sh" + echo "CODEX_TEST_REMOTE_ENV=${CODEX_TEST_REMOTE_ENV}" >> "$GITHUB_ENV" + + - name: tests + id: test + run: cargo nextest run --all-features --no-fail-fast --target ${{ matrix.target }} --cargo-profile ci-test --timings + env: + RUST_BACKTRACE: 1 + NEXTEST_STATUS_LEVEL: leak + + - name: Upload Cargo timings (nextest) + if: always() + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 + with: + name: cargo-timings-rust-ci-nextest-${{ matrix.target }}-${{ matrix.profile }} + path: codex-rs/target/**/cargo-timings/cargo-timing.html + if-no-files-found: warn + + - name: Save cargo home cache + if: always() && !cancelled() && steps.cache_cargo_home_restore.outputs.cache-hit != 'true' + continue-on-error: true + uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + key: cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ steps.lockhash.outputs.toolchain_hash }} + + - name: Save sccache cache (fallback) + if: always() && !cancelled() && env.USE_SCCACHE == 'true' && env.SCCACHE_GHA_ENABLED != 'true' + continue-on-error: true + uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + with: + path: ${{ github.workspace }}/.sccache/ + key: sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ github.run_id }} + + - name: sccache stats + if: always() && env.USE_SCCACHE == 'true' + continue-on-error: true + run: sccache --show-stats || true + + - name: sccache summary + if: always() && env.USE_SCCACHE == 'true' + shell: bash + run: | + { + echo "### sccache stats — ${{ matrix.target }} (tests)"; + echo; + echo '```'; + sccache --show-stats || true; + echo '```'; + } >> "$GITHUB_STEP_SUMMARY" + + - name: Tear down remote test env + if: ${{ always() && runner.os == 'Linux' && matrix.remote_env == 'true' }} + shell: bash + run: | + set +e + if [[ "${{ steps.test.outcome }}" != "success" ]]; then + docker logs codex-remote-test-env || true + fi + docker rm -f codex-remote-test-env >/dev/null 2>&1 || true + + - name: verify tests passed + if: steps.test.outcome == 'failure' + run: | + echo "Tests failed. See logs for details." + exit 1 + + # --- Gatherer job for the full post-merge workflow -------------------------- + results: + name: Full CI results + needs: + [ + general, + cargo_shear, + argument_comment_lint_package, + argument_comment_lint_prebuilt, + lint_build, + tests, + ] + if: always() + runs-on: ubuntu-24.04 + steps: + - name: Summarize + shell: bash + run: | + echo "argpkg : ${{ needs.argument_comment_lint_package.result }}" + echo "arglint: ${{ needs.argument_comment_lint_prebuilt.result }}" + echo "general: ${{ needs.general.result }}" + echo "shear : ${{ needs.cargo_shear.result }}" + echo "lint : ${{ needs.lint_build.result }}" + echo "tests : ${{ needs.tests.result }}" + [[ '${{ needs.argument_comment_lint_package.result }}' == 'success' ]] || { echo 'argument_comment_lint_package failed'; exit 1; } + [[ '${{ needs.argument_comment_lint_prebuilt.result }}' == 'success' ]] || { echo 'argument_comment_lint_prebuilt failed'; exit 1; } + [[ '${{ needs.general.result }}' == 'success' ]] || { echo 'general failed'; exit 1; } + [[ '${{ needs.cargo_shear.result }}' == 'success' ]] || { echo 'cargo_shear failed'; exit 1; } + [[ '${{ needs.lint_build.result }}' == 'success' ]] || { echo 'lint_build failed'; exit 1; } + [[ '${{ needs.tests.result }}' == 'success' ]] || { echo 'tests failed'; exit 1; } + + - name: sccache summary note + if: always() + run: | + echo "Per-job sccache stats are attached to each matrix job's Step Summary." diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 345c9f9d1e..ad4bac1689 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -1,15 +1,10 @@ name: rust-ci on: pull_request: {} - push: - branches: - - main workflow_dispatch: -# CI builds in debug (dev) for faster signal. - jobs: - # --- Detect what changed to detect which tests to run (always runs) ------------------------------------- + # --- Detect what changed so the fast PR workflow only runs relevant jobs ---- changed: name: Detect changed areas runs-on: ubuntu-24.04 @@ -33,11 +28,10 @@ jobs: HEAD_SHA='${{ github.event.pull_request.head.sha }}' echo "Base SHA: $BASE_SHA" echo "Head SHA: $HEAD_SHA" - # List files changed between base and PR head mapfile -t files < <(git diff --name-only --no-renames "$BASE_SHA" "$HEAD_SHA") else - # On push / manual runs, default to running everything - files=("codex-rs/force" ".github/force") + # On manual runs, default to the full fast-PR bundle. + files=("codex-rs/force" "tools/argument-comment-lint/force" ".github/force") fi codex=false @@ -47,7 +41,7 @@ jobs: for f in "${files[@]}"; do [[ $f == codex-rs/* ]] && codex=true [[ $f == codex-rs/* || $f == tools/argument-comment-lint/* || $f == justfile ]] && argument_comment_lint=true - [[ $f == tools/argument-comment-lint/* || $f == .github/workflows/rust-ci.yml ]] && argument_comment_lint_package=true + [[ $f == tools/argument-comment-lint/* || $f == .github/workflows/rust-ci.yml || $f == .github/workflows/rust-ci-full.yml ]] && argument_comment_lint_package=true [[ $f == .github/* ]] && workflows=true done @@ -56,12 +50,12 @@ jobs: echo "codex=$codex" >> "$GITHUB_OUTPUT" echo "workflows=$workflows" >> "$GITHUB_OUTPUT" - # --- CI that doesn't need specific targets --------------------------------- + # --- Fast Cargo-native PR checks ------------------------------------------- general: name: Format / etc runs-on: ubuntu-24.04 needs: changed - if: ${{ needs.changed.outputs.codex == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }} + if: ${{ needs.changed.outputs.codex == 'true' || needs.changed.outputs.workflows == 'true' }} defaults: run: working-directory: codex-rs @@ -77,7 +71,7 @@ jobs: name: cargo shear runs-on: ubuntu-24.04 needs: changed - if: ${{ needs.changed.outputs.codex == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }} + if: ${{ needs.changed.outputs.codex == 'true' || needs.changed.outputs.workflows == 'true' }} defaults: run: working-directory: codex-rs @@ -95,7 +89,7 @@ jobs: name: Argument comment lint package runs-on: ubuntu-24.04 needs: changed - if: ${{ needs.changed.outputs.argument_comment_lint_package == 'true' || github.event_name == 'push' }} + if: ${{ needs.changed.outputs.argument_comment_lint_package == 'true' }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 @@ -112,7 +106,7 @@ jobs: ~/.cargo/registry/index ~/.cargo/registry/cache ~/.cargo/git/db - key: argument-comment-lint-${{ runner.os }}-${{ hashFiles('tools/argument-comment-lint/Cargo.lock', 'tools/argument-comment-lint/rust-toolchain', '.github/workflows/rust-ci.yml') }} + key: argument-comment-lint-${{ runner.os }}-${{ hashFiles('tools/argument-comment-lint/Cargo.lock', 'tools/argument-comment-lint/rust-toolchain', '.github/workflows/rust-ci.yml', '.github/workflows/rust-ci-full.yml') }} - name: Install cargo-dylint tooling if: ${{ steps.cargo_dylint_cache.outputs.cache-hit != 'true' }} run: cargo install --locked cargo-dylint dylint-link @@ -125,27 +119,13 @@ jobs: run: cargo test argument_comment_lint_prebuilt: - name: Argument comment lint - ${{ matrix.name }} - runs-on: ${{ matrix.runs_on || matrix.runner }} + name: Argument comment lint + runs-on: ubuntu-24.04 needs: changed - if: ${{ needs.changed.outputs.argument_comment_lint == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }} - strategy: - fail-fast: false - matrix: - include: - - name: Linux - runner: ubuntu-24.04 - - name: macOS - runner: macos-15-xlarge - - name: Windows - runner: windows-x64 - runs_on: - group: codex-runners - labels: codex-windows-x64 + if: ${{ needs.changed.outputs.argument_comment_lint == 'true' || needs.changed.outputs.workflows == 'true' }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install Linux sandbox build dependencies - if: ${{ runner.os == 'Linux' }} shell: bash run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update @@ -155,635 +135,11 @@ jobs: toolchain: nightly-2025-09-18 components: llvm-tools-preview, rustc-dev, rust-src - uses: facebook/install-dotslash@1e4e7b3e07eaca387acb98f1d4720e0bee8dbb6a # v2 - - name: Run argument comment lint on codex-rs - if: ${{ runner.os == 'macOS' }} - shell: bash - run: python3 ./tools/argument-comment-lint/run-prebuilt-linter.py + # Keep the PR path on one host so Bazel owns most of the latency budget. + # Cross-platform wrapper coverage still runs post-merge in rust-ci-full.yml. - name: Run argument comment lint on codex-rs (default targets only) - if: ${{ runner.os == 'Linux' }} shell: bash run: python3 ./tools/argument-comment-lint/run-prebuilt-linter.py -- --lib --bins - - name: Run argument comment lint on codex-rs - if: ${{ runner.os == 'Windows' }} - shell: bash - run: python ./tools/argument-comment-lint/run-prebuilt-linter.py - - # --- CI to validate on different os/targets -------------------------------- - lint_build: - name: Lint/Build — ${{ matrix.runner }} - ${{ matrix.target }}${{ matrix.profile == 'release' && ' (release)' || '' }} - runs-on: ${{ matrix.runs_on || matrix.runner }} - timeout-minutes: 30 - needs: changed - # Keep job-level if to avoid spinning up runners when not needed - if: ${{ needs.changed.outputs.codex == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }} - defaults: - run: - working-directory: codex-rs - env: - # Speed up repeated builds across CI runs by caching compiled objects, except on - # arm64 macOS runners cross-targeting x86_64 where ring/cc-rs can produce - # mixed-architecture archives under sccache. - USE_SCCACHE: ${{ (startsWith(matrix.runner, 'windows') || (matrix.runner == 'macos-15-xlarge' && matrix.target == 'x86_64-apple-darwin')) && 'false' || 'true' }} - CARGO_INCREMENTAL: "0" - SCCACHE_CACHE_SIZE: 10G - # In rust-ci, representative release-profile checks use thin LTO for faster feedback. - CARGO_PROFILE_RELEASE_LTO: ${{ matrix.profile == 'release' && 'thin' || 'fat' }} - - strategy: - fail-fast: false - matrix: - include: - - runner: macos-15-xlarge - target: aarch64-apple-darwin - profile: dev - - runner: macos-15-xlarge - target: x86_64-apple-darwin - profile: dev - - runner: ubuntu-24.04 - target: x86_64-unknown-linux-musl - profile: dev - runs_on: - group: codex-runners - labels: codex-linux-x64 - - runner: ubuntu-24.04 - target: x86_64-unknown-linux-gnu - profile: dev - runs_on: - group: codex-runners - labels: codex-linux-x64 - - runner: ubuntu-24.04-arm - target: aarch64-unknown-linux-musl - profile: dev - runs_on: - group: codex-runners - labels: codex-linux-arm64 - - runner: ubuntu-24.04-arm - target: aarch64-unknown-linux-gnu - profile: dev - runs_on: - group: codex-runners - labels: codex-linux-arm64 - - runner: windows-x64 - target: x86_64-pc-windows-msvc - profile: dev - runs_on: - group: codex-runners - labels: codex-windows-x64 - - runner: windows-arm64 - target: aarch64-pc-windows-msvc - profile: dev - runs_on: - group: codex-runners - labels: codex-windows-arm64 - - # Also run representative release builds on Mac and Linux because - # there could be release-only build errors we want to catch. - # Hopefully this also pre-populates the build cache to speed up - # releases. - - runner: macos-15-xlarge - target: aarch64-apple-darwin - profile: release - - runner: ubuntu-24.04 - target: x86_64-unknown-linux-musl - profile: release - runs_on: - group: codex-runners - labels: codex-linux-x64 - - runner: ubuntu-24.04-arm - target: aarch64-unknown-linux-musl - profile: release - runs_on: - group: codex-runners - labels: codex-linux-arm64 - - runner: windows-x64 - target: x86_64-pc-windows-msvc - profile: release - runs_on: - group: codex-runners - labels: codex-windows-x64 - - runner: windows-arm64 - target: aarch64-pc-windows-msvc - profile: release - runs_on: - group: codex-runners - labels: codex-windows-arm64 - - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - name: Install Linux build dependencies - if: ${{ runner.os == 'Linux' }} - shell: bash - run: | - set -euo pipefail - if command -v apt-get >/dev/null 2>&1; then - sudo apt-get update -y - packages=(pkg-config libcap-dev) - if [[ "${{ matrix.target }}" == 'x86_64-unknown-linux-musl' || "${{ matrix.target }}" == 'aarch64-unknown-linux-musl' ]]; then - packages+=(libubsan1) - fi - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "${packages[@]}" - fi - - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 - with: - targets: ${{ matrix.target }} - components: clippy - - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} - name: Use hermetic Cargo home (musl) - shell: bash - run: | - set -euo pipefail - cargo_home="${GITHUB_WORKSPACE}/.cargo-home" - mkdir -p "${cargo_home}/bin" - echo "CARGO_HOME=${cargo_home}" >> "$GITHUB_ENV" - echo "${cargo_home}/bin" >> "$GITHUB_PATH" - : > "${cargo_home}/config.toml" - - - name: Compute lockfile hash - id: lockhash - working-directory: codex-rs - shell: bash - run: | - set -euo pipefail - echo "hash=$(sha256sum Cargo.lock | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" - echo "toolchain_hash=$(sha256sum rust-toolchain.toml | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" - - # Explicit cache restore: split cargo home vs target, so we can - # avoid caching the large target dir on the gnu-dev job. - - name: Restore cargo home cache - id: cache_cargo_home_restore - uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - ${{ github.workspace }}/.cargo-home/bin/ - ${{ github.workspace }}/.cargo-home/registry/index/ - ${{ github.workspace }}/.cargo-home/registry/cache/ - ${{ github.workspace }}/.cargo-home/git/db/ - key: cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ steps.lockhash.outputs.toolchain_hash }} - restore-keys: | - cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}- - - # Install and restore sccache cache - - name: Install sccache - if: ${{ env.USE_SCCACHE == 'true' }} - uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2 - with: - tool: sccache - version: 0.7.5 - - - name: Configure sccache backend - if: ${{ env.USE_SCCACHE == 'true' }} - shell: bash - run: | - set -euo pipefail - if [[ -n "${ACTIONS_CACHE_URL:-}" && -n "${ACTIONS_RUNTIME_TOKEN:-}" ]]; then - echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV" - echo "Using sccache GitHub backend" - else - echo "SCCACHE_GHA_ENABLED=false" >> "$GITHUB_ENV" - echo "SCCACHE_DIR=${{ github.workspace }}/.sccache" >> "$GITHUB_ENV" - echo "Using sccache local disk + actions/cache fallback" - fi - - - name: Enable sccache wrapper - if: ${{ env.USE_SCCACHE == 'true' }} - shell: bash - run: echo "RUSTC_WRAPPER=sccache" >> "$GITHUB_ENV" - - - name: Restore sccache cache (fallback) - if: ${{ env.USE_SCCACHE == 'true' && env.SCCACHE_GHA_ENABLED != 'true' }} - id: cache_sccache_restore - uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 - with: - path: ${{ github.workspace }}/.sccache/ - key: sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ github.run_id }} - restore-keys: | - sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}- - sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}- - - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} - name: Disable sccache wrapper (musl) - shell: bash - run: | - set -euo pipefail - echo "RUSTC_WRAPPER=" >> "$GITHUB_ENV" - echo "RUSTC_WORKSPACE_WRAPPER=" >> "$GITHUB_ENV" - - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} - name: Prepare APT cache directories (musl) - shell: bash - run: | - set -euo pipefail - sudo mkdir -p /var/cache/apt/archives /var/lib/apt/lists - sudo chown -R "$USER:$USER" /var/cache/apt /var/lib/apt/lists - - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} - name: Restore APT cache (musl) - id: cache_apt_restore - uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 - with: - path: | - /var/cache/apt - key: apt-${{ matrix.runner }}-${{ matrix.target }}-v1 - - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} - name: Install Zig - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 - with: - version: 0.14.0 - - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} - name: Install musl build tools - env: - DEBIAN_FRONTEND: noninteractive - TARGET: ${{ matrix.target }} - APT_UPDATE_ARGS: -o Acquire::Retries=3 - APT_INSTALL_ARGS: --no-install-recommends - shell: bash - run: bash "${GITHUB_WORKSPACE}/.github/scripts/install-musl-build-tools.sh" - - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} - name: Configure rustc UBSan wrapper (musl host) - shell: bash - run: | - set -euo pipefail - ubsan="" - if command -v ldconfig >/dev/null 2>&1; then - ubsan="$(ldconfig -p | grep -m1 'libubsan\.so\.1' | sed -E 's/.*=> (.*)$/\1/')" - fi - wrapper_root="${RUNNER_TEMP:-/tmp}" - wrapper="${wrapper_root}/rustc-ubsan-wrapper" - cat > "${wrapper}" <> "$GITHUB_ENV" - echo "RUSTC_WORKSPACE_WRAPPER=" >> "$GITHUB_ENV" - - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} - name: Clear sanitizer flags (musl) - shell: bash - run: | - set -euo pipefail - # Clear global Rust flags so host/proc-macro builds don't pull in UBSan. - echo "RUSTFLAGS=" >> "$GITHUB_ENV" - echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV" - echo "RUSTDOCFLAGS=" >> "$GITHUB_ENV" - # Override any runner-level Cargo config rustflags as well. - echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV" - echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV" - echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV" - echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV" - echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV" - - sanitize_flags() { - local input="$1" - input="${input//-fsanitize=undefined/}" - input="${input//-fno-sanitize-recover=undefined/}" - input="${input//-fno-sanitize-trap=undefined/}" - echo "$input" - } - - cflags="$(sanitize_flags "${CFLAGS-}")" - cxxflags="$(sanitize_flags "${CXXFLAGS-}")" - echo "CFLAGS=${cflags}" >> "$GITHUB_ENV" - echo "CXXFLAGS=${cxxflags}" >> "$GITHUB_ENV" - - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl' }} - name: Configure musl rusty_v8 artifact overrides - env: - TARGET: ${{ matrix.target }} - shell: bash - run: | - set -euo pipefail - version="$(python3 "${GITHUB_WORKSPACE}/.github/scripts/rusty_v8_bazel.py" resolved-v8-crate-version)" - release_tag="rusty-v8-v${version}" - base_url="https://github.com/openai/codex/releases/download/${release_tag}" - archive="https://github.com/openai/codex/releases/download/rusty-v8-v${version}/librusty_v8_release_${TARGET}.a.gz" - binding_dir="${RUNNER_TEMP}/rusty_v8" - binding_path="${binding_dir}/src_binding_release_${TARGET}.rs" - mkdir -p "${binding_dir}" - curl -fsSL "${base_url}/src_binding_release_${TARGET}.rs" -o "${binding_path}" - echo "RUSTY_V8_ARCHIVE=${archive}" >> "$GITHUB_ENV" - echo "RUSTY_V8_SRC_BINDING_PATH=${binding_path}" >> "$GITHUB_ENV" - - - name: Install cargo-chef - if: ${{ matrix.profile == 'release' }} - uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2 - with: - tool: cargo-chef - version: 0.1.71 - - - name: Pre-warm dependency cache (cargo-chef) - if: ${{ matrix.profile == 'release' }} - shell: bash - run: | - set -euo pipefail - RECIPE="${RUNNER_TEMP}/chef-recipe.json" - cargo chef prepare --recipe-path "$RECIPE" - cargo chef cook --recipe-path "$RECIPE" --target ${{ matrix.target }} --release --all-features - - - name: cargo clippy - run: cargo clippy --target ${{ matrix.target }} --all-features --tests --profile ${{ matrix.profile }} --timings -- -D warnings - - - name: Upload Cargo timings (clippy) - if: always() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 - with: - name: cargo-timings-rust-ci-clippy-${{ matrix.target }}-${{ matrix.profile }} - path: codex-rs/target/**/cargo-timings/cargo-timing.html - if-no-files-found: warn - - # Save caches explicitly; make non-fatal so cache packaging - # never fails the overall job. Only save when key wasn't hit. - - name: Save cargo home cache - if: always() && !cancelled() && steps.cache_cargo_home_restore.outputs.cache-hit != 'true' - continue-on-error: true - uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - ${{ github.workspace }}/.cargo-home/bin/ - ${{ github.workspace }}/.cargo-home/registry/index/ - ${{ github.workspace }}/.cargo-home/registry/cache/ - ${{ github.workspace }}/.cargo-home/git/db/ - key: cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ steps.lockhash.outputs.toolchain_hash }} - - - name: Save sccache cache (fallback) - if: always() && !cancelled() && env.USE_SCCACHE == 'true' && env.SCCACHE_GHA_ENABLED != 'true' - continue-on-error: true - uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 - with: - path: ${{ github.workspace }}/.sccache/ - key: sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ github.run_id }} - - - name: sccache stats - if: always() && env.USE_SCCACHE == 'true' - continue-on-error: true - run: sccache --show-stats || true - - - name: sccache summary - if: always() && env.USE_SCCACHE == 'true' - shell: bash - run: | - { - echo "### sccache stats — ${{ matrix.target }} (${{ matrix.profile }})"; - echo; - echo '```'; - sccache --show-stats || true; - echo '```'; - } >> "$GITHUB_STEP_SUMMARY" - - - name: Save APT cache (musl) - if: always() && !cancelled() && (matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl') && steps.cache_apt_restore.outputs.cache-hit != 'true' - continue-on-error: true - uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 - with: - path: | - /var/cache/apt - key: apt-${{ matrix.runner }}-${{ matrix.target }}-v1 - - tests: - name: Tests — ${{ matrix.runner }} - ${{ matrix.target }}${{ matrix.remote_env == 'true' && ' (remote)' || '' }} - runs-on: ${{ matrix.runs_on || matrix.runner }} - # Perhaps we can bring this back down to 30m once we finish the cutover - # from tui_app_server/ to tui/. Incidentally, windows-arm64 was the main - # offender for exceeding the timeout. - timeout-minutes: 45 - needs: changed - if: ${{ needs.changed.outputs.codex == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }} - defaults: - run: - working-directory: codex-rs - env: - # Speed up repeated builds across CI runs by caching compiled objects, except on - # arm64 macOS runners cross-targeting x86_64 where ring/cc-rs can produce - # mixed-architecture archives under sccache. - USE_SCCACHE: ${{ (startsWith(matrix.runner, 'windows') || (matrix.runner == 'macos-15-xlarge' && matrix.target == 'x86_64-apple-darwin')) && 'false' || 'true' }} - CARGO_INCREMENTAL: "0" - SCCACHE_CACHE_SIZE: 10G - - strategy: - fail-fast: false - matrix: - include: - - runner: macos-15-xlarge - target: aarch64-apple-darwin - profile: dev - - runner: ubuntu-24.04 - target: x86_64-unknown-linux-gnu - profile: dev - remote_env: "true" - runs_on: - group: codex-runners - labels: codex-linux-x64 - - runner: ubuntu-24.04-arm - target: aarch64-unknown-linux-gnu - profile: dev - runs_on: - group: codex-runners - labels: codex-linux-arm64 - - runner: windows-x64 - target: x86_64-pc-windows-msvc - profile: dev - runs_on: - group: codex-runners - labels: codex-windows-x64 - - runner: windows-arm64 - target: aarch64-pc-windows-msvc - profile: dev - runs_on: - group: codex-runners - labels: codex-windows-arm64 - - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - name: Set up Node.js for js_repl tests - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 - with: - node-version-file: codex-rs/node-version.txt - - name: Install Linux build dependencies - if: ${{ runner.os == 'Linux' }} - shell: bash - run: | - set -euo pipefail - if command -v apt-get >/dev/null 2>&1; then - sudo apt-get update -y - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev - fi - - # Some integration tests rely on DotSlash being installed. - # See https://github.com/openai/codex/pull/7617. - - name: Install DotSlash - uses: facebook/install-dotslash@1e4e7b3e07eaca387acb98f1d4720e0bee8dbb6a # v2 - - - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0 - with: - targets: ${{ matrix.target }} - - - name: Compute lockfile hash - id: lockhash - working-directory: codex-rs - shell: bash - run: | - set -euo pipefail - echo "hash=$(sha256sum Cargo.lock | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" - echo "toolchain_hash=$(sha256sum rust-toolchain.toml | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" - - - name: Restore cargo home cache - id: cache_cargo_home_restore - uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ steps.lockhash.outputs.toolchain_hash }} - restore-keys: | - cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}- - - - name: Install sccache - if: ${{ env.USE_SCCACHE == 'true' }} - uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2 - with: - tool: sccache - version: 0.7.5 - - - name: Configure sccache backend - if: ${{ env.USE_SCCACHE == 'true' }} - shell: bash - run: | - set -euo pipefail - if [[ -n "${ACTIONS_CACHE_URL:-}" && -n "${ACTIONS_RUNTIME_TOKEN:-}" ]]; then - echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV" - echo "Using sccache GitHub backend" - else - echo "SCCACHE_GHA_ENABLED=false" >> "$GITHUB_ENV" - echo "SCCACHE_DIR=${{ github.workspace }}/.sccache" >> "$GITHUB_ENV" - echo "Using sccache local disk + actions/cache fallback" - fi - - - name: Enable sccache wrapper - if: ${{ env.USE_SCCACHE == 'true' }} - shell: bash - run: echo "RUSTC_WRAPPER=sccache" >> "$GITHUB_ENV" - - - name: Restore sccache cache (fallback) - if: ${{ env.USE_SCCACHE == 'true' && env.SCCACHE_GHA_ENABLED != 'true' }} - id: cache_sccache_restore - uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 - with: - path: ${{ github.workspace }}/.sccache/ - key: sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ github.run_id }} - restore-keys: | - sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}- - sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}- - - - uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2 - with: - tool: nextest - version: 0.9.103 - - - name: Enable unprivileged user namespaces (Linux) - if: runner.os == 'Linux' - run: | - # Required for bubblewrap to work on Linux CI runners. - sudo sysctl -w kernel.unprivileged_userns_clone=1 - # Ubuntu 24.04+ can additionally gate unprivileged user namespaces - # behind AppArmor. - if sudo sysctl -a 2>/dev/null | grep -q '^kernel.apparmor_restrict_unprivileged_userns'; then - sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 - fi - - - name: Set up remote test env (Docker) - if: ${{ runner.os == 'Linux' && matrix.remote_env == 'true' }} - shell: bash - run: | - set -euo pipefail - export CODEX_TEST_REMOTE_ENV_CONTAINER_NAME=codex-remote-test-env - source "${GITHUB_WORKSPACE}/scripts/test-remote-env.sh" - echo "CODEX_TEST_REMOTE_ENV=${CODEX_TEST_REMOTE_ENV}" >> "$GITHUB_ENV" - - - name: tests - id: test - run: cargo nextest run --all-features --no-fail-fast --target ${{ matrix.target }} --cargo-profile ci-test --timings - env: - RUST_BACKTRACE: 1 - NEXTEST_STATUS_LEVEL: leak - - - name: Upload Cargo timings (nextest) - if: always() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 - with: - name: cargo-timings-rust-ci-nextest-${{ matrix.target }}-${{ matrix.profile }} - path: codex-rs/target/**/cargo-timings/cargo-timing.html - if-no-files-found: warn - - - name: Save cargo home cache - if: always() && !cancelled() && steps.cache_cargo_home_restore.outputs.cache-hit != 'true' - continue-on-error: true - uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: cargo-home-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ steps.lockhash.outputs.toolchain_hash }} - - - name: Save sccache cache (fallback) - if: always() && !cancelled() && env.USE_SCCACHE == 'true' && env.SCCACHE_GHA_ENABLED != 'true' - continue-on-error: true - uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 - with: - path: ${{ github.workspace }}/.sccache/ - key: sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-${{ github.run_id }} - - - name: sccache stats - if: always() && env.USE_SCCACHE == 'true' - continue-on-error: true - run: sccache --show-stats || true - - - name: sccache summary - if: always() && env.USE_SCCACHE == 'true' - shell: bash - run: | - { - echo "### sccache stats — ${{ matrix.target }} (tests)"; - echo; - echo '```'; - sccache --show-stats || true; - echo '```'; - } >> "$GITHUB_STEP_SUMMARY" - - - name: Tear down remote test env - if: ${{ always() && runner.os == 'Linux' && matrix.remote_env == 'true' }} - shell: bash - run: | - set +e - if [[ "${{ steps.test.outcome }}" != "success" ]]; then - docker logs codex-remote-test-env || true - fi - docker rm -f codex-remote-test-env >/dev/null 2>&1 || true - - - name: verify tests passed - if: steps.test.outcome == 'failure' - run: | - echo "Tests failed. See logs for details." - exit 1 # --- Gatherer job that you mark as the ONLY required status ----------------- results: @@ -795,8 +151,6 @@ jobs: cargo_shear, argument_comment_lint_package, argument_comment_lint_prebuilt, - lint_build, - tests, ] if: always() runs-on: ubuntu-24.04 @@ -808,32 +162,23 @@ jobs: echo "arglint: ${{ needs.argument_comment_lint_prebuilt.result }}" echo "general: ${{ needs.general.result }}" echo "shear : ${{ needs.cargo_shear.result }}" - echo "lint : ${{ needs.lint_build.result }}" - echo "tests : ${{ needs.tests.result }}" # If nothing relevant changed (PR touching only root README, etc.), # declare success regardless of other jobs. - if [[ '${{ needs.changed.outputs.argument_comment_lint }}' != 'true' && '${{ needs.changed.outputs.codex }}' != 'true' && '${{ needs.changed.outputs.workflows }}' != 'true' && '${{ github.event_name }}' != 'push' ]]; then + if [[ '${{ needs.changed.outputs.argument_comment_lint }}' != 'true' && '${{ needs.changed.outputs.codex }}' != 'true' && '${{ needs.changed.outputs.workflows }}' != 'true' ]]; then echo 'No relevant changes -> CI not required.' exit 0 fi - if [[ '${{ needs.changed.outputs.argument_comment_lint_package }}' == 'true' || '${{ github.event_name }}' == 'push' ]]; then + if [[ '${{ needs.changed.outputs.argument_comment_lint_package }}' == 'true' ]]; then [[ '${{ needs.argument_comment_lint_package.result }}' == 'success' ]] || { echo 'argument_comment_lint_package failed'; exit 1; } fi - if [[ '${{ needs.changed.outputs.argument_comment_lint }}' == 'true' || '${{ needs.changed.outputs.workflows }}' == 'true' || '${{ github.event_name }}' == 'push' ]]; then + if [[ '${{ needs.changed.outputs.argument_comment_lint }}' == 'true' || '${{ needs.changed.outputs.workflows }}' == 'true' ]]; then [[ '${{ needs.argument_comment_lint_prebuilt.result }}' == 'success' ]] || { echo 'argument_comment_lint_prebuilt failed'; exit 1; } fi - if [[ '${{ needs.changed.outputs.codex }}' == 'true' || '${{ needs.changed.outputs.workflows }}' == 'true' || '${{ github.event_name }}' == 'push' ]]; then + if [[ '${{ needs.changed.outputs.codex }}' == 'true' || '${{ needs.changed.outputs.workflows }}' == 'true' ]]; then [[ '${{ needs.general.result }}' == 'success' ]] || { echo 'general failed'; exit 1; } [[ '${{ needs.cargo_shear.result }}' == 'success' ]] || { echo 'cargo_shear failed'; exit 1; } - [[ '${{ needs.lint_build.result }}' == 'success' ]] || { echo 'lint_build failed'; exit 1; } - [[ '${{ needs.tests.result }}' == 'success' ]] || { echo 'tests failed'; exit 1; } fi - - - name: sccache summary note - if: always() - run: | - echo "Per-job sccache stats are attached to each matrix job's Step Summary."