| name: Bazel |
|
|
| |
| |
|
|
| on: |
| workflow_call: |
| workflow_dispatch: |
|
|
| concurrency: |
| |
| |
| group: concurrency-group::${{ github.workflow }}::${{ github.event.pull_request.number > 0 && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}${{ github.ref_name == 'main' && format('::{0}', github.run_id) || ''}} |
| cancel-in-progress: ${{ github.ref_name != 'main' }} |
|
|
| jobs: |
| test: |
| |
| |
| |
| |
| |
| timeout-minutes: 30 |
| strategy: |
| fail-fast: false |
| matrix: |
| include: |
| |
| - os: macos-15-xlarge |
| target: aarch64-apple-darwin |
| - os: macos-15-xlarge |
| target: x86_64-apple-darwin |
|
|
| |
| - os: ubuntu-24.04 |
| target: x86_64-unknown-linux-gnu |
| - os: ubuntu-24.04 |
| target: x86_64-unknown-linux-musl |
| |
| |
| |
| |
| |
| |
|
|
| runs-on: ${{ matrix.os }} |
|
|
| |
| name: Bazel test on ${{ matrix.os }} for ${{ matrix.target }} |
| environment: |
| name: bazel |
| deployment: false |
|
|
| steps: |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd |
| with: |
| persist-credentials: false |
|
|
| - name: Prepare Bazel CI |
| id: prepare_bazel |
| uses: ./.github/actions/prepare-bazel-ci |
| with: |
| target: ${{ matrix.target }} |
| cache-scope: bazel-${{ github.job }} |
|
|
| - name: Check rusty_v8 MODULE.bazel checksums |
| if: matrix.os == 'ubuntu-24.04' && matrix.target == 'x86_64-unknown-linux-gnu' |
| shell: bash |
| run: | |
| python3 .github/scripts/rusty_v8_bazel.py check-module-bazel |
| just test-github-scripts |
| |
| - name: Check MODULE.bazel.lock is up to date |
| if: matrix.os == 'ubuntu-24.04' && matrix.target == 'x86_64-unknown-linux-gnu' |
| shell: bash |
| run: ./scripts/check-module-bazel-lock.sh |
|
|
| - name: bazel test //... |
| env: |
| BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} |
| shell: bash |
| run: | |
| bazel_targets=( |
| //... |
| # Keep standalone V8 library targets out of the ordinary Bazel CI |
| # path. V8 consumers under `//codex-rs/...` still participate |
| # transitively through `//...`. |
| -//third_party/v8:all |
| -//codex-rs/v8-poc:v8-poc-unit-tests |
| ) |
| |
| bazel_wrapper_args=( |
| --print-failed-action-summary |
| --print-failed-test-logs |
| ) |
| bazel_test_args=( |
| test |
| --test_tag_filters=-argument-comment-lint |
| --test_verbose_timeout_warnings |
| --build_metadata=COMMIT_SHA=${GITHUB_SHA} |
| ) |
| ./.github/scripts/run-bazel-ci.sh \ |
| "${bazel_wrapper_args[@]}" \ |
| -- \ |
| "${bazel_test_args[@]}" \ |
| -- \ |
| "${bazel_targets[@]}" |
|
|
| - name: Upload Bazel execution logs |
| if: always() && !cancelled() |
| continue-on-error: true |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f |
| with: |
| name: bazel-execution-logs-test-${{ matrix.target }} |
| path: ${{ runner.temp }}/bazel-execution-logs |
| if-no-files-found: ignore |
|
|
| |
| |
| - name: Save bazel repository cache |
| if: always() && !cancelled() && steps.prepare_bazel.outputs.repository-cache-hit != 'true' |
| continue-on-error: true |
| uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 |
| with: |
| path: ${{ steps.prepare_bazel.outputs.repository-cache-path }} |
| key: ${{ steps.prepare_bazel.outputs.repository-cache-key }} |
|
|
| - name: Check for a clean worktree |
| if: always() && !cancelled() |
| uses: ./.github/actions/check-clean-worktree |
|
|
| test-windows-shard: |
| |
| |
| |
| timeout-minutes: 30 |
| strategy: |
| fail-fast: false |
| matrix: |
| shard: |
| - 1 |
| - 2 |
| - 3 |
| - 4 |
| runs-on: |
| group: ${{ github.event.repository.name }}-runners |
| labels: ${{ github.event.repository.name }}-windows-x64 |
| name: Bazel test on windows-latest for x86_64-pc-windows-gnullvm shard ${{ matrix.shard }}/4 |
| environment: |
| name: bazel |
| deployment: false |
|
|
| steps: |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd |
| with: |
| persist-credentials: false |
|
|
| - name: Test BuildBuddy Bazel wrapper |
| if: matrix.shard == 1 |
| shell: pwsh |
| run: python .github/scripts/test_run_bazel_with_buildbuddy.py |
|
|
| - name: Prepare Bazel CI |
| id: prepare_bazel |
| uses: ./.github/actions/prepare-bazel-ci |
| with: |
| target: x86_64-pc-windows-gnullvm |
| |
| |
| |
| cache-scope: bazel-test |
|
|
| - name: bazel test shard |
| env: |
| BAZEL_TEST_SHARD: ${{ matrix.shard }} |
| BAZEL_TEST_SHARD_COUNT: 4 |
| BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} |
| shell: bash |
| run: | |
| set -euo pipefail |
| |
| bazel_test_query='tests(//...) except tests(//third_party/v8:all) except attr(tags, "manual", tests(//...))' |
| mapfile -t bazel_targets < <( |
| ./.github/scripts/run-bazel-query-ci.sh --output=label -- "${bazel_test_query}" \ |
| | LC_ALL=C sort |
| ) |
|
|
| selected_targets=() |
| for bazel_target in "${bazel_targets[@]}"; do |
| target_bucket="$( |
| printf '%s\n' "${bazel_target}" \ |
| | cksum \ |
| | awk -v shard_count="${BAZEL_TEST_SHARD_COUNT}" '{ print ($1 % shard_count) + 1 }' |
| )" |
| if [[ "${target_bucket}" == "${BAZEL_TEST_SHARD}" ]]; then |
| selected_targets+=("${bazel_target}") |
| fi |
| done |
|
|
| if [[ ${ |
| echo "No Bazel test targets selected for Windows shard ${BAZEL_TEST_SHARD}/${BAZEL_TEST_SHARD_COUNT}." >&2 |
| exit 1 |
| fi |
|
|
| echo "Selected ${#selected_targets[@]} of ${#bazel_targets[@]} Bazel test targets for Windows shard ${BAZEL_TEST_SHARD}/${BAZEL_TEST_SHARD_COUNT}." |
|
|
| bazel_test_args=( |
| test |
| --skip_incompatible_explicit_targets |
| --test_tag_filters=-argument-comment-lint |
| --test_verbose_timeout_warnings |
| --build_metadata=COMMIT_SHA=${GITHUB_SHA} |
| --build_metadata=TAG_windows_test_shard=${BAZEL_TEST_SHARD} |
| ) |
|
|
| ./.github/scripts/run-bazel-ci.sh \ |
| --print-failed-action-summary \ |
| --print-failed-test-logs \ |
| --windows-cross-compile \ |
| --remote-download-toplevel \ |
| -- \ |
| "${bazel_test_args[@]}" \ |
| -- \ |
| "${selected_targets[@]}" |
|
|
| - name: Upload Bazel execution logs |
| if: always() && !cancelled() |
| continue-on-error: true |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f |
| with: |
| name: bazel-execution-logs-test-x86_64-pc-windows-gnullvm-shard-${{ matrix.shard }} |
| path: ${{ runner.temp }}/bazel-execution-logs |
| if-no-files-found: ignore |
|
|
| - name: Check for a clean worktree |
| if: always() && !cancelled() |
| uses: ./.github/actions/check-clean-worktree |
|
|
| test-windows: |
| |
| |
| if: always() |
| needs: test-windows-shard |
| runs-on: ubuntu-24.04 |
| name: Bazel test on windows-latest for x86_64-pc-windows-gnullvm |
|
|
| steps: |
| - name: Confirm Windows Bazel test shards passed |
| shell: bash |
| run: | |
| if [[ "${{ needs.test-windows-shard.result }}" != "success" ]]; then |
| echo "Windows Bazel test shards finished with result: ${{ needs.test-windows-shard.result }}" >&2 |
| exit 1 |
| fi |
| |
| test-windows-native-main: |
| |
| |
| |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' |
| timeout-minutes: 40 |
| runs-on: |
| group: ${{ github.event.repository.name }}-runners |
| labels: ${{ github.event.repository.name }}-windows-x64 |
| name: Bazel test on windows-latest for x86_64-pc-windows-msvc (native main) |
| environment: |
| name: bazel |
| deployment: false |
|
|
| steps: |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd |
| with: |
| persist-credentials: false |
|
|
| - name: Prepare Bazel CI |
| id: prepare_bazel |
| uses: ./.github/actions/prepare-bazel-ci |
| with: |
| target: x86_64-pc-windows-msvc |
| cache-scope: bazel-${{ github.job }} |
|
|
| - name: bazel test //... |
| env: |
| BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} |
| shell: bash |
| run: | |
| bazel_targets=( |
| //... |
| # Keep standalone V8 library targets out of the ordinary Bazel CI |
| # path. V8 consumers under `//codex-rs/...` still participate |
| # transitively through `//...`. |
| -//third_party/v8:all |
| -//codex-rs/v8-poc:v8-poc-unit-tests |
| ) |
| |
| bazel_test_args=( |
| test |
| --platforms=//:windows_x86_64_msvc |
| --test_tag_filters=-argument-comment-lint |
| --test_verbose_timeout_warnings |
| --build_metadata=COMMIT_SHA=${GITHUB_SHA} |
| --build_metadata=TAG_windows_native_main=true |
| ) |
|
|
| ./.github/scripts/run-bazel-ci.sh \ |
| --print-failed-action-summary \ |
| --print-failed-test-logs \ |
| --windows-msvc-host-platform \ |
| -- \ |
| "${bazel_test_args[@]}" \ |
| -- \ |
| "${bazel_targets[@]}" |
|
|
| - name: Upload Bazel execution logs |
| if: always() && !cancelled() |
| continue-on-error: true |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f |
| with: |
| name: bazel-execution-logs-test-windows-native-x86_64-pc-windows-msvc |
| path: ${{ runner.temp }}/bazel-execution-logs |
| if-no-files-found: ignore |
|
|
| |
| |
| - name: Save bazel repository cache |
| if: always() && !cancelled() && steps.prepare_bazel.outputs.repository-cache-hit != 'true' |
| continue-on-error: true |
| uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 |
| with: |
| path: ${{ steps.prepare_bazel.outputs.repository-cache-path }} |
| key: ${{ steps.prepare_bazel.outputs.repository-cache-key }} |
|
|
| - name: Check for a clean worktree |
| if: always() && !cancelled() |
| uses: ./.github/actions/check-clean-worktree |
|
|
| clippy: |
| timeout-minutes: 30 |
| strategy: |
| fail-fast: false |
| matrix: |
| include: |
| |
| |
| |
| |
| - 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: |
| group: ${{ github.event.repository.name }}-runners |
| labels: ${{ github.event.repository.name }}-windows-x64 |
| runs-on: ${{ matrix.runs_on || matrix.os }} |
| name: Bazel clippy on ${{ matrix.os }} for ${{ matrix.target }} |
| environment: |
| name: bazel |
| deployment: false |
|
|
| steps: |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd |
| with: |
| persist-credentials: false |
|
|
| - name: Prepare Bazel CI |
| id: prepare_bazel |
| uses: ./.github/actions/prepare-bazel-ci |
| with: |
| target: ${{ matrix.target }} |
| cache-scope: bazel-${{ github.job }} |
|
|
| - name: bazel build --config=clippy lint targets |
| env: |
| BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} |
| shell: bash |
| run: | |
| bazel_clippy_args=( |
| --config=clippy |
| --build_metadata=COMMIT_SHA=${GITHUB_SHA} |
| --build_metadata=TAG_job=clippy |
| ) |
| bazel_wrapper_args=() |
| bazel_target_list_args=() |
| if [[ "${RUNNER_OS}" == "Windows" ]]; then |
| # Keep this aligned with the fast Windows Bazel test job: use |
| # Linux RBE for clippy build actions while targeting Windows |
| # gnullvm. Fork/community PRs without the BuildBuddy secret fall |
| # back inside `run-bazel-ci.sh` to the previous local Windows MSVC |
| # host-platform shape. |
| bazel_wrapper_args+=(--windows-cross-compile) |
| bazel_target_list_args+=(--windows-cross-compile) |
| if [[ -z "${BUILDBUDDY_API_KEY:-}" ]]; then |
| # The fork fallback can see incompatible explicit Windows-cross |
| # internal test binaries in the generated target list. Preserve |
| # the old local-fallback behavior there. |
| bazel_clippy_args+=(--skip_incompatible_explicit_targets) |
| fi |
| fi |
| |
| bazel_target_lines="$(./scripts/list-bazel-clippy-targets.sh "${bazel_target_list_args[@]}")" |
| bazel_targets=() |
| while IFS= read -r target; do |
| bazel_targets+=("${target}") |
| done <<< "${bazel_target_lines}" |
| |
| ./.github/scripts/run-bazel-ci.sh \ |
| --print-failed-action-summary \ |
| "${bazel_wrapper_args[@]}" \ |
| -- \ |
| build \ |
| "${bazel_clippy_args[@]}" \ |
| -- \ |
| "${bazel_targets[@]}" |
| |
| - name: Upload Bazel execution logs |
| if: always() && !cancelled() |
| continue-on-error: true |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 |
| with: |
| name: bazel-execution-logs-clippy-${{ matrix.target }} |
| path: ${{ runner.temp }}/bazel-execution-logs |
| if-no-files-found: ignore |
| |
| # Save the job-scoped Bazel repository cache after cache misses. Keep the |
| # upload non-fatal so cache service issues never fail the job itself. |
| - name: Save bazel repository cache |
| if: always() && !cancelled() && steps.prepare_bazel.outputs.repository-cache-hit != 'true' |
| continue-on-error: true |
| uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 |
| with: |
| path: ${{ steps.prepare_bazel.outputs.repository-cache-path }} |
| key: ${{ steps.prepare_bazel.outputs.repository-cache-key }} |
| |
| - name: Check for a clean worktree |
| if: always() && !cancelled() |
| uses: ./.github/actions/check-clean-worktree |
| |
| verify-release-build: |
| timeout-minutes: 30 |
| strategy: |
| fail-fast: false |
| matrix: |
| include: |
| - 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: |
| group: ${{ github.event.repository.name }}-runners |
| labels: ${{ github.event.repository.name }}-windows-x64 |
| runs-on: ${{ matrix.runs_on || matrix.os }} |
| name: Verify release build on ${{ matrix.os }} for ${{ matrix.target }} |
| environment: |
| name: bazel |
| deployment: false |
| |
| steps: |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 |
| with: |
| persist-credentials: false |
| |
| - name: Prepare Bazel CI |
| id: prepare_bazel |
| uses: ./.github/actions/prepare-bazel-ci |
| with: |
| target: ${{ matrix.target }} |
| cache-scope: bazel-${{ github.job }} |
| |
| - name: bazel build verify-release-build targets |
| env: |
| BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} |
| shell: bash |
| run: | |
| # This job exists to compile Rust code behind |
| # `cfg(not(debug_assertions))` so PR CI catches failures that would |
| # otherwise show up only in a release build. We do not need the full |
| # optimizer and debug-info work that normally comes with a release |
| # build to get that signal, so keep Bazel in `fastbuild` and disable |
| # Rust debug assertions explicitly. |
| bazel_wrapper_args=() |
| if [[ "${RUNNER_OS}" == "Windows" ]]; then |
| |
| |
| |
| |
| |
| bazel_wrapper_args+=(--windows-cross-compile) |
| fi |
|
|
| bazel_build_args=( |
| --compilation_mode=fastbuild |
| --@rules_rust//rust/settings:extra_rustc_flag=-Cdebug-assertions=no |
| --@rules_rust//rust/settings:extra_exec_rustc_flag=-Cdebug-assertions=no |
| --build_metadata=COMMIT_SHA=${GITHUB_SHA} |
| --build_metadata=TAG_job=verify-release-build |
| --build_metadata=TAG_rust_debug_assertions=off |
| ) |
|
|
| bazel_target_lines="$(bash ./scripts/list-bazel-release-targets.sh)" |
| bazel_targets=() |
| while IFS= read -r target; do |
| bazel_targets+=("${target}") |
| done <<< "${bazel_target_lines}" |
| |
| ./.github/scripts/run-bazel-ci.sh \ |
| "${bazel_wrapper_args[@]}" \ |
| -- \ |
| build \ |
| "${bazel_build_args[@]}" \ |
| -- \ |
| "${bazel_targets[@]}" |
| |
| - name: Verify Bazel builds bwrap |
| if: runner.os == 'Linux' |
| env: |
| BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} |
| shell: bash |
| run: | |
| ./.github/scripts/run-bazel-ci.sh \ |
| --remote-download-toplevel \ |
| --print-failed-action-summary \ |
| -- \ |
| build \ |
| --build_metadata=COMMIT_SHA=${GITHUB_SHA} \ |
| --build_metadata=TAG_job=verify-bwrap \ |
| -- \ |
| //codex-rs/bwrap:bwrap |
| |
| - name: Upload Bazel execution logs |
| if: always() && !cancelled() |
| continue-on-error: true |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 |
| with: |
| name: bazel-execution-logs-verify-release-build-${{ matrix.target }} |
| path: ${{ runner.temp }}/bazel-execution-logs |
| if-no-files-found: ignore |
| |
| # Save the job-scoped Bazel repository cache after cache misses. Keep the |
| # upload non-fatal so cache service issues never fail the job itself. |
| - name: Save bazel repository cache |
| if: always() && !cancelled() && steps.prepare_bazel.outputs.repository-cache-hit != 'true' |
| continue-on-error: true |
| uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 |
| with: |
| path: ${{ steps.prepare_bazel.outputs.repository-cache-path }} |
| key: ${{ steps.prepare_bazel.outputs.repository-cache-key }} |
| |
| - name: Check for a clean worktree |
| if: always() && !cancelled() |
| uses: ./.github/actions/check-clean-worktree |
| |