Wire native voice dependencies into full Rust CI (#58719)

## What changed

- Build native voice SDK and runtime artifacts with Bazel for Linux GNU, macOS, and Windows on x64 and ARM64, then configure Cargo jobs to consume them. Keep musl builds in a separate job without these inputs.
- Validate artifact receipts against the target, source commit, and source manifest; verify SDK file hashes and relocate pkg-config metadata. Package the runtime and plugins with nextest archives and restore `CODEX_TEST_VOICE_RUNTIME` when running shards.
- Prepare native Windows voice tools for argument-comment linting and install ARM64 DotSlash on Windows ARM64. Reduce archive disk usage, bound Linux ARM64 build concurrency, and correct the JUnit artifact path.
- Recognize TLS errors wrapped directly in `io::Error`. Make TLS fallback fixtures select the native backend explicitly, allow the MCP test server's non-loopback address, and isolate skill-root tests from ancestor Git markers. Install `git` in remote test containers and filter MCP discovery assertions to POST requests.

## Testing

Add tests for relocated voice inputs, Windows ARM64 import libraries with host-native pkgconf, and rejection of mismatched receipts or corrupt SDK files. Extend untrusted-certificate coverage to an explicitly selected rustls backend.

GitOrigin-RevId: da3ff690b94906edc1f8f60a3c7feda1bf66134a
This commit is contained in:
Benjamin Carlsson
2026-11-01 15:50:50 +00:00
committed by copyberry
parent 8c811e8d93
commit e02a32cd51
17 changed files with 748 additions and 47 deletions
@@ -65,6 +65,8 @@ jobs:
CODEX_CI_PROFILE: ${{ inputs.profile }}
CODEX_CI_TARGET: ${{ inputs.target }}
CARGO_INCREMENTAL: "0"
# Debug symbols for hundreds of test binaries can exhaust the archive runner's disk.
CARGO_PROFILE_CI_TEST_DEBUG: "0"
SCCACHE_CACHE_SIZE: 10G
NEXTEST_ARCHIVE_FILE: nextest-${{ inputs.artifact_id }}.tar.zst
TEST_HELPERS_ARTIFACT: nextest-test-helpers-${{ inputs.artifact_id }}
@@ -73,6 +75,15 @@ jobs:
with:
persist-credentials: false
- name: Free disk space for the macOS test archive
if: ${{ runner.os == 'macOS' && runner.arch == 'ARM64' && runner.environment == 'github-hosted' }}
shell: bash
run: |
# The macOS build does not use the hosted image's Android SDK or NDKs.
df -h "$RUNNER_TEMP"
sudo rm -rf /Users/runner/Library/Android/sdk
df -h "$RUNNER_TEMP"
- uses: ./.github/actions/setup-ci
- name: Install Linux build dependencies
@@ -165,13 +176,25 @@ jobs:
tool: nextest
version: 0.9.103
- name: Set up native voice dependencies
uses: ./third_party/voice/cargo-ci/setup
with:
target: ${{ inputs.target }}
- name: Build nextest archive
shell: bash
run: |
set -euo pipefail
archive_dir="${RUNNER_TEMP}/nextest-archive"
mkdir -p "${archive_dir}"
cargo nextest archive \
if [[ "${RUNNER_OS}" == "Linux" && "${RUNNER_ARCH}" == "ARM64" && "${CODEX_CI_TARGET}" == "aarch64-unknown-linux-gnu" ]]; then
# Bound concurrency for full GNU ARM archives on native Linux runners.
nproc
free -h
export CARGO_BUILD_JOBS=4
fi
printf '%s\n' "$CODEX_VOICE_RUNTIME_RELATIVE" > "$archive_dir/voice-runtime-path.txt"
cargo nextest --tool-config-file "codex-voice:$CODEX_VOICE_NEXTEST_CONFIG" archive \
--target "${CODEX_CI_TARGET}" \
--cargo-profile "${CODEX_CI_PROFILE}" \
--timings \
@@ -215,7 +238,7 @@ jobs:
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: nextest-archive-${{ inputs.artifact_id }}
path: ${{ runner.temp }}/nextest-archive/${{ env.NEXTEST_ARCHIVE_FILE }}
path: ${{ runner.temp }}/nextest-archive/
if-no-files-found: error
retention-days: 1
@@ -341,10 +364,16 @@ jobs:
set -euo pipefail
archive_file="${RUNNER_TEMP}/nextest-archive/${NEXTEST_ARCHIVE_FILE}"
workspace_root="$(pwd)"
extract_dir="${RUNNER_TEMP}/nextest-extracted"
mkdir -p "$extract_dir"
runtime_relative="$(cat "${RUNNER_TEMP}/nextest-archive/voice-runtime-path.txt")"
export CODEX_TEST_VOICE_RUNTIME="$extract_dir/target/$runtime_relative"
if [[ "${RUNNER_OS}" == "Windows" ]]; then
archive_file="$(cygpath -w "${archive_file}")"
workspace_root="$(cygpath -w "${workspace_root}")"
extract_dir="$(cygpath -w "$extract_dir")"
CODEX_TEST_VOICE_RUNTIME="$(cygpath -w "$CODEX_TEST_VOICE_RUNTIME")"
fi
if [[ "${RUNNER_OS}" == "Linux" ]]; then
@@ -365,6 +394,7 @@ jobs:
run
--no-fail-fast
--archive-file "${archive_file}"
--extract-to "$extract_dir"
--workspace-remap "${workspace_root}"
--partition "hash:${{ matrix.shard }}/4"
)
@@ -395,6 +425,8 @@ jobs:
"${test_command[@]}"
env:
RUST_BACKTRACE: 1
# Keep panic backtraces without changing the CLI errors asserted by tests.
RUST_LIB_BACKTRACE: "0"
RUST_MIN_STACK: "8388608" # 8 MiB
NEXTEST_STATUS_LEVEL: leak
@@ -403,7 +435,7 @@ jobs:
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: nextest-junit-rust-ci-${{ inputs.artifact_id }}-shard-${{ matrix.shard }}
path: ${{ env.CARGO_TARGET_DIR }}/nextest/default/junit.xml
path: codex-rs/target/nextest/default/junit.xml
if-no-files-found: warn
- name: Tear down remote test env
+100 -32
View File
@@ -92,7 +92,7 @@ jobs:
argument_comment_lint_prebuilt:
name: Argument comment lint - ${{ matrix.name }}
runs-on: ${{ matrix.runs_on || matrix.runner }}
timeout-minutes: 30
timeout-minutes: 120
environment:
name: bazel
deployment: false
@@ -117,17 +117,51 @@ jobs:
uses: ./.github/actions/run-argument-comment-lint
with:
target: ${{ runner.os }}
buildbuddy-api-key: ${{ secrets.BUILDBUDDY_API_KEY }}
# --- CI to validate on different os/targets --------------------------------
cargo_voice_inputs:
name: Cargo voice inputs - ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
environment:
name: bazel
deployment: false
permissions:
contents: read
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
include:
- { target: x86_64-unknown-linux-gnu, runner: ubuntu-24.04 }
- { target: aarch64-unknown-linux-gnu, runner: ubuntu-24.04-arm }
- { target: x86_64-apple-darwin, runner: macos-15-intel }
- { target: aarch64-apple-darwin, runner: macos-15 }
- target: x86_64-pc-windows-msvc
runner:
group: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-windows-x64
- target: aarch64-pc-windows-msvc
runner:
group: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-windows-arm64
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: ./third_party/voice/cargo-ci/produce
with:
target: ${{ matrix.target }}
lint_build:
name: Lint/Build — ${{ matrix.runner }} - ${{ matrix.target }}${{ matrix.profile == 'release' && ' (release)' || '' }}
runs-on: ${{ matrix.runs_on || matrix.runner }}
timeout-minutes: 30
defaults:
needs: cargo_voice_inputs
if: &lint_build_if ${{ !cancelled() }}
name: &lint_build_name Lint/Build — ${{ matrix.runner }} - ${{ matrix.target }}${{ matrix.profile == 'release' && ' (release)' || '' }}
runs-on: &lint_build_runner ${{ matrix.runs_on || matrix.runner }}
timeout-minutes: &lint_build_timeout 30
defaults: &lint_build_defaults
run:
working-directory: codex-rs
env:
env: &lint_build_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.
@@ -145,24 +179,12 @@ jobs:
- 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: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-linux-x64
- runner: ubuntu-24.04
target: x86_64-unknown-linux-gnu
profile: dev
runs_on:
group: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-linux-x64
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
profile: dev
runs_on:
group: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-linux-arm64
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
profile: dev
@@ -189,18 +211,6 @@ jobs:
- 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: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-linux-x64
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
profile: release
runs_on:
group: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-linux-arm64
- runner: windows-x64
target: x86_64-pc-windows-msvc
profile: release
@@ -214,7 +224,7 @@ jobs:
group: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-windows-arm64
steps:
steps: &lint_build_steps
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
@@ -348,6 +358,12 @@ jobs:
with:
target: ${{ matrix.target }}
- name: Set up native voice dependencies
if: ${{ !endsWith(matrix.target, '-musl') }}
uses: ./third_party/voice/cargo-ci/setup
with:
target: ${{ matrix.target }}
- name: Install cargo-chef
if: ${{ matrix.profile == 'release' }}
uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
@@ -427,7 +443,46 @@ jobs:
/var/cache/apt
key: apt-${{ matrix.runner }}-${{ matrix.target }}-v1
lint_build_musl:
if: *lint_build_if
name: *lint_build_name
runs-on: *lint_build_runner
timeout-minutes: *lint_build_timeout
defaults: *lint_build_defaults
env: *lint_build_env
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-24.04
target: x86_64-unknown-linux-musl
profile: dev
runs_on:
group: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-linux-x64
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
profile: dev
runs_on:
group: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-linux-arm64
- runner: ubuntu-24.04
target: x86_64-unknown-linux-musl
profile: release
runs_on:
group: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-linux-x64
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
profile: release
runs_on:
group: ${{ github.event.repository.name }}-runners
labels: ${{ github.event.repository.name }}-linux-arm64
steps: *lint_build_steps
tests_macos_aarch64:
needs: cargo_voice_inputs
if: ${{ !cancelled() }}
name: Tests — macos-15-xlarge - aarch64-apple-darwin
uses: ./.github/workflows/rust-ci-full-nextest-platform.yml
with:
@@ -439,6 +494,8 @@ jobs:
secrets: inherit
tests_linux_x64_remote:
needs: cargo_voice_inputs
if: ${{ !cancelled() }}
name: Tests — ubuntu-24.04 - x86_64-unknown-linux-gnu (remote)
uses: ./.github/workflows/rust-ci-full-nextest-platform.yml
with:
@@ -453,6 +510,8 @@ jobs:
secrets: inherit
tests_linux_arm64:
needs: cargo_voice_inputs
if: ${{ !cancelled() }}
name: Tests — ubuntu-24.04-arm - aarch64-unknown-linux-gnu
uses: ./.github/workflows/rust-ci-full-nextest-platform.yml
with:
@@ -466,6 +525,8 @@ jobs:
secrets: inherit
tests_windows_x64:
needs: cargo_voice_inputs
if: ${{ !cancelled() }}
name: Tests — windows-x64 - x86_64-pc-windows-msvc
uses: ./.github/workflows/rust-ci-full-nextest-platform.yml
with:
@@ -479,6 +540,8 @@ jobs:
secrets: inherit
tests_windows_arm64:
needs: cargo_voice_inputs
if: ${{ !cancelled() }}
name: Tests — windows-arm64 - aarch64-pc-windows-msvc
uses: ./.github/workflows/rust-ci-full-nextest-platform.yml
with:
@@ -504,7 +567,9 @@ jobs:
cargo_shear,
argument_comment_lint_package,
argument_comment_lint_prebuilt,
cargo_voice_inputs,
lint_build,
lint_build_musl,
tests_macos_aarch64,
tests_linux_x64_remote,
tests_linux_arm64,
@@ -522,6 +587,7 @@ jobs:
echo "general: ${{ needs.general.result }}"
echo "shear : ${{ needs.cargo_shear.result }}"
echo "lint : ${{ needs.lint_build.result }}"
echo "musl : ${{ needs.lint_build_musl.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 }}"
@@ -531,7 +597,9 @@ jobs:
[[ '${{ 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.cargo_voice_inputs.result }}' == 'success' ]] || { echo 'cargo_voice_inputs failed'; exit 1; }
[[ '${{ needs.lint_build.result }}' == 'success' ]] || { echo 'lint_build failed'; exit 1; }
[[ '${{ needs.lint_build_musl.result }}' == 'success' ]] || { echo 'lint_build_musl 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; }