From d666238b4058e5f77c5b8925c25929e3ceae55a6 Mon Sep 17 00:00:00 2001 From: starr-openai Date: Wed, 13 May 2026 12:46:51 -0700 Subject: [PATCH] Shard Bazel Windows tests across jobs (#22408) ## Summary - split the single PR-blocking Bazel Windows test leg into four Windows shard jobs - preserve the existing required Windows Bazel check name with a lightweight aggregate gate - keep Linux/macOS Bazel test jobs and the separate Windows clippy/release jobs unchanged ## Why The ordinary PR Windows Bazel test leg was one GitHub Actions job, so Bazel only had in-job parallelism. This gives that lane real job-level fanout across separate Windows hosts while keeping the target set disjoint via stable label hashing. ## Evidence - final pre-rebase green run: `25774733562` - Windows shard target counts: `61/212`, `48/212`, `52/212`, `51/212` - Windows test fanout completed in about 7m29s versus a recent monolithic median around 22m26s ## Notes - this is scoped to the Bazel Windows test leg only - each shard keeps the existing Windows cross-compile/RBE path and restores the former monolithic Windows test cache - shard jobs do not upload duplicate repository caches after test work, keeping cache cleanup off the PR-blocking shard path - no local validation run; relying on GitHub Actions for the workflow-shaped check Co-authored-by: Codex --- .github/workflows/bazel.yml | 133 +++++++++++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 17 deletions(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index cc3968d30..11c0988ce 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -17,10 +17,10 @@ concurrency: cancel-in-progress: ${{ github.ref_name != 'main' }} jobs: test: - # PRs use a fast Windows cross-compiled test leg for pre-merge signal. - # Post-merge pushes to main also run the native Windows test job below for - # broader Windows signal without putting PR latency back on the critical - # path. Cargo CI owns V8/code-mode test coverage for now. + # PRs use the sharded Windows cross-compiled test jobs below. Post-merge + # pushes to main also run the native Windows test job for broader Windows + # signal without putting PR latency back on the critical path. Cargo CI + # owns V8/code-mode test coverage for now. timeout-minutes: 30 strategy: fail-fast: false @@ -44,12 +44,6 @@ jobs: # - os: ubuntu-24.04-arm # target: aarch64-unknown-linux-gnu - # Windows fast path: build the windows-gnullvm binaries with Linux - # RBE, then run the resulting Windows tests on the Windows runner. - # Cargo CI preserves V8/code-mode coverage while Bazel CI keeps broad - # non-code-mode signal. - - os: windows-latest - target: x86_64-pc-windows-gnullvm runs-on: ${{ matrix.os }} # Configure a human readable name for each job @@ -108,13 +102,6 @@ jobs: --test_verbose_timeout_warnings --build_metadata=COMMIT_SHA=${GITHUB_SHA} ) - if [[ "${RUNNER_OS}" == "Windows" ]]; then - bazel_wrapper_args+=( - --windows-cross-compile - --remote-download-toplevel - ) - fi - ./.github/scripts/run-bazel-ci.sh \ "${bazel_wrapper_args[@]}" \ -- \ @@ -141,6 +128,118 @@ jobs: path: ${{ steps.prepare_bazel.outputs.repository-cache-path }} key: ${{ steps.prepare_bazel.outputs.repository-cache-key }} + test-windows-shard: + # Split the Windows Bazel test leg across separate Windows + # hosts. Each shard still uses Linux RBE for build actions, but the test + # execution itself happens on its own Windows runner. + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + shard: + - 1 + - 2 + - 3 + - 4 + runs-on: windows-latest + name: Bazel test on windows-latest for x86_64-pc-windows-gnullvm shard ${{ matrix.shard }}/4 + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + persist-credentials: false + + - name: Prepare Bazel CI + id: prepare_bazel + uses: ./.github/actions/prepare-bazel-ci + with: + target: x86_64-pc-windows-gnullvm + # Reuse the former monolithic Windows test cache for restores. Do + # not save it from every shard below; duplicate uploads would sit on + # the PR-blocking critical path after the useful test work is done. + cache-scope: bazel-test + install-test-prereqs: "true" + + - 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 //codex-rs/code-mode:code-mode-unit-tests except //codex-rs/v8-poc:v8-poc-unit-tests except attr(tags, "manual", tests(//...))' + mapfile -t bazel_targets < <( + MSYS2_ARG_CONV_EXCL='*' bazel query --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 [[ ${#selected_targets[@]} -eq 0 ]]; then + 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 # v7.0.0 + 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 + + test-windows: + # Preserve the existing required-check surface while the real work happens + # in the sharded Windows jobs above. + 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: # Native Windows Bazel tests are slower and frequently approach the # 30-minute PR budget. Run this only for post-merge commits to main and give