name: rust-ci-full
on:
  push:
    branches:
      - main
      - "**full-ci**"
  workflow_dispatch:

# CI builds in debug (dev) for faster signal.
env:
  # Cargo's libgit2 transport has been flaky on macOS when fetching git
  # dependencies with nested submodules. Use the system git CLI, which has
  # better network/proxy behavior and matches Cargo's own suggested fallback.
  CARGO_NET_GIT_FETCH_WITH_CLI: "true"

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.0.2
        with:
          persist-credentials: false
      - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
        with:
          components: rustfmt
      - uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
        with:
          tool: just
      - name: cargo fmt
        run: cargo fmt -- --config imports_granularity=Item --check
      - name: Rust benchmark smoke test
        run: just bench-smoke

  cargo_shear:
    name: cargo shear
    runs-on: ubuntu-24.04
    defaults:
      run:
        working-directory: codex-rs
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
      - uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
        with:
          tool: cargo-shear@1.11.2
      - name: cargo shear
        run: cargo shear --deny-warnings

  argument_comment_lint_package:
    name: Argument comment lint package
    runs-on: ubuntu-24.04
    env:
      CARGO_DYLINT_VERSION: 5.0.0
      DYLINT_LINK_VERSION: 5.0.0
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - 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.0.4
        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 }}-${{ env.CARGO_DYLINT_VERSION }}-${{ env.DYLINT_LINK_VERSION }}-${{ 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' }}
        shell: bash
        run: |
          cargo install --locked cargo-dylint --version "$CARGO_DYLINT_VERSION"
          cargo install --locked dylint-link --version "$DYLINT_LINK_VERSION"
      - 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
        env:
          RUST_MIN_STACK: "8388608" # 8 MiB

  argument_comment_lint_prebuilt:
    name: Argument comment lint - ${{ matrix.name }}
    runs-on: ${{ matrix.runs_on || matrix.runner }}
    timeout-minutes: 30
    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.0.2
        with:
          persist-credentials: false
      - uses: ./.github/actions/setup-bazel-ci
        with:
          target: ${{ runner.os }}
          install-test-prereqs: true
      - 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
      - name: Run argument comment lint on codex-rs via Bazel
        if: ${{ runner.os != 'Windows' }}
        env:
          BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }}
        shell: bash
        run: |
          bazel_targets="$(./tools/argument-comment-lint/list-bazel-targets.sh)"
          ./.github/scripts/run-bazel-ci.sh \
            -- \
            build \
            --config=argument-comment-lint \
            --keep_going \
            --build_metadata=COMMIT_SHA=${GITHUB_SHA} \
            -- \
            ${bazel_targets}
      - name: Run argument comment lint on codex-rs via Bazel
        if: ${{ runner.os == 'Windows' }}
        env:
          BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }}
        shell: bash
        run: |
          ./.github/scripts/run-argument-comment-lint-bazel.sh \
            --config=argument-comment-lint \
            --platforms=//:local_windows \
            --keep_going \
            --build_metadata=COMMIT_SHA=${GITHUB_SHA}

  # --- 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.0.2
        with:
          persist-credentials: false
      - 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.0.4
        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.62.49
        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.0.4
        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.0.4
        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.2.1
        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}" <<EOF
          #!/usr/bin/env bash
          set -euo pipefail
          if [[ -n "${ubsan}" ]]; then
            export LD_PRELOAD="${ubsan}\${LD_PRELOAD:+:\${LD_PRELOAD}}"
          fi
          exec "\$1" "\${@:2}"
          EOF
          chmod +x "${wrapper}"
          echo "RUSTC_WRAPPER=${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: ${{ !contains(matrix.target, 'windows') }}
        name: Configure rusty_v8 artifact overrides and verify checksums
        uses: ./.github/actions/setup-rusty-v8
        with:
          target: ${{ matrix.target }}

      - name: Install cargo-chef
        if: ${{ matrix.profile == 'release' }}
        uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
        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

      - name: cargo clippy
        run: cargo clippy --target ${{ matrix.target }} --tests --profile ${{ matrix.profile }} --timings -- -D warnings

      - name: Upload Cargo timings (clippy)
        if: always()
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
        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.0.4
        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.0.4
        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.0.4
        with:
          path: |
            /var/cache/apt
          key: apt-${{ matrix.runner }}-${{ matrix.target }}-v1

  tests_macos_aarch64:
    name: Tests — macos-15-xlarge - aarch64-apple-darwin
    uses: ./.github/workflows/rust-ci-full-nextest-platform.yml
    with:
      runner: macos-15-xlarge
      target: aarch64-apple-darwin
      profile: ci-test
      artifact_id: macos-aarch64
      use_sccache: true
    secrets: inherit

  tests_linux_x64_remote:
    name: Tests — ubuntu-24.04 - x86_64-unknown-linux-gnu (remote)
    uses: ./.github/workflows/rust-ci-full-nextest-platform.yml
    with:
      runner: ubuntu-24.04
      runner_group: codex-runners
      runner_labels: codex-linux-x64
      target: x86_64-unknown-linux-gnu
      profile: ci-test
      artifact_id: linux-x64-remote
      remote_env: true
      use_sccache: true
    secrets: inherit

  tests_linux_arm64:
    name: Tests — ubuntu-24.04-arm - aarch64-unknown-linux-gnu
    uses: ./.github/workflows/rust-ci-full-nextest-platform.yml
    with:
      runner: ubuntu-24.04-arm
      runner_group: codex-runners
      runner_labels: codex-linux-arm64
      target: aarch64-unknown-linux-gnu
      profile: ci-test
      artifact_id: linux-arm64
      use_sccache: true
    secrets: inherit

  tests_windows_x64:
    name: Tests — windows-x64 - x86_64-pc-windows-msvc
    uses: ./.github/workflows/rust-ci-full-nextest-platform.yml
    with:
      runner: windows-x64
      runner_group: codex-runners
      runner_labels: codex-windows-x64
      target: x86_64-pc-windows-msvc
      profile: ci-test
      artifact_id: windows-x64
      test_threads: 8
    secrets: inherit

  tests_windows_arm64:
    name: Tests — windows-arm64 - aarch64-pc-windows-msvc
    uses: ./.github/workflows/rust-ci-full-nextest-platform.yml
    with:
      runner: windows-arm64
      runner_group: codex-runners
      runner_labels: codex-windows-arm64
      archive_runner: windows-x64
      archive_runner_group: codex-runners
      archive_runner_labels: codex-windows-x64
      target: aarch64-pc-windows-msvc
      profile: ci-test
      artifact_id: windows-arm64
      test_threads: 8
      use_sccache: true
    secrets: inherit

  # --- 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_macos_aarch64,
        tests_linux_x64_remote,
        tests_linux_arm64,
        tests_windows_x64,
        tests_windows_arm64,
      ]
    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 "test macos : ${{ needs.tests_macos_aarch64.result }}"
          echo "test linux : ${{ needs.tests_linux_x64_remote.result }}"
          echo "test arm64 : ${{ needs.tests_linux_arm64.result }}"
          echo "test winx64: ${{ needs.tests_windows_x64.result }}"
          echo "test winarm: ${{ needs.tests_windows_arm64.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_macos_aarch64.result }}' == 'success' ]] || { echo 'tests_macos_aarch64 failed'; exit 1; }
          [[ '${{ needs.tests_linux_x64_remote.result }}' == 'success' ]] || { echo 'tests_linux_x64_remote failed'; exit 1; }
          [[ '${{ needs.tests_linux_arm64.result }}' == 'success' ]] || { echo 'tests_linux_arm64 failed'; exit 1; }
          [[ '${{ needs.tests_windows_x64.result }}' == 'success' ]] || { echo 'tests_windows_x64 failed'; exit 1; }
          [[ '${{ needs.tests_windows_arm64.result }}' == 'success' ]] || { echo 'tests_windows_arm64 failed'; exit 1; }

      - name: sccache summary note
        if: always()
        run: |
          echo "Per-job sccache stats are attached to each matrix job's Step Summary."
