diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 71fa7455798f0..38988f465681f 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -192,25 +192,24 @@ jobs: MSYS2_ARG_CONV_EXCL: "*" run: | mkdir -p build - ${{ inputs.run }} 2>&1 | tee build/bazel-console.log - - name: Parse Bazel log for failures + { + ${{ inputs.run }} + } 2>&1 | tee build/bazel-console.log + - name: Rerun failures with debug if: always() shell: bash - run: | - awk ' - /PASSED in/ {n=0; delete a; next} - /FAILED in/ {a[++n]=$1} - END {for (i=1; i<=n; i++) print a[i]} - ' build/bazel-console.log > build/bazel-failures.txt - - name: Rerun failures with debug - if: failure() && inputs.rerun-with-debug + run: ./scripts/github-actions/rerun-failures.sh '${{ inputs.run }}' '${{ inputs.rerun-with-debug }}' + - name: Collect failed test logs + if: failure() shell: bash - run: | - if [ -s build/bazel-failures.txt ]; then - base_cmd=$(echo "${{ inputs.run }}" | sed 's| //[^ ]*||g') - targets=$(cat build/bazel-failures.txt | tr '\n' ' ') - $base_cmd --test_env=SE_DEBUG=true --flaky_test_attempts=1 $targets - fi + run: ./scripts/github-actions/collect-test-logs.sh + - name: Upload failed test logs + if: failure() + uses: actions/upload-artifact@v5 + with: + name: test-logs-${{ inputs.os }}-${{ inputs.name }}-${{ inputs.browser }} + retention-days: 7 + path: build/failures/** - name: Start SSH session if: failure() && runner.debug == '1' uses: mxschmitt/action-tmate@v3 @@ -229,15 +228,6 @@ jobs: if: ${{ always() && inputs.artifact-name != 'ignore-artifacts' }} run: | git diff > changes.patch - - name: "Upload test logs" - if: failure() - uses: actions/upload-artifact@v5 - with: - name: test-logs-${{ inputs.os }}-${{ inputs.name }}-${{ inputs.browser }} - retention-days: 7 - path: | - bazel-testlogs/**/*.log - build/bazel-failures.txt - name: "Upload changes" if: ${{ always() && inputs.artifact-name != 'ignore-artifacts' }} uses: actions/upload-artifact@v4 diff --git a/.github/workflows/ci-ruby.yml b/.github/workflows/ci-ruby.yml index 168456bddeb88..3fd864a925470 100644 --- a/.github/workflows/ci-ruby.yml +++ b/.github/workflows/ci-ruby.yml @@ -30,21 +30,21 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - + - name: Install system dependencies run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev - + - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: 3.2.8 bundler-cache: true working-directory: rb - + - name: Install RBS collection working-directory: rb run: bundle exec rbs collection install - + - name: Run Steep type check working-directory: rb run: bundle exec rake steep 2>/dev/null || (bundle exec rake steep && exit 1) @@ -73,6 +73,7 @@ jobs: name: Unit Tests (${{ matrix.ruby-version }}, ${{ matrix.os }}) os: ${{ matrix.os }} ruby-version: ${{ matrix.ruby-version }} + rerun-with-debug: true run: > bazel test --keep_going @@ -101,11 +102,12 @@ jobs: name: Local Tests (${{ matrix.browser }}, ${{ matrix.os }}) browser: ${{ matrix.browser }} os: ${{ matrix.os }} + rerun-with-debug: true run: > bazel test --keep_going --build_tests_only - --flaky_test_attempts 3 + --flaky_test_attempts 2 --local_test_jobs 1 --test_size_filters large --test_tag_filters ${{ matrix.browser }} @@ -126,12 +128,13 @@ jobs: browser: ${{ matrix.browser }} os: ${{ matrix.os }} java-version: 17 + rerun-with-debug: true run: > bazel test --keep_going --build_tests_only - --flaky_test_attempts 3 --local_test_jobs 1 + --flaky_test_attempts 2 --test_size_filters large --test_tag_filters ${{ matrix.browser }}-remote //rb/spec/... diff --git a/scripts/github-actions/collect-test-logs.sh b/scripts/github-actions/collect-test-logs.sh new file mode 100755 index 0000000000000..4a35360f0164a --- /dev/null +++ b/scripts/github-actions/collect-test-logs.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Collects failed test logs from Bazel testlogs directory +# Reads targets from build/failures/_run2.txt if present, otherwise _run1.txt + +set -euxo pipefail + +TESTLOGS_ROOT=$(bazel info bazel-testlogs) + +LIST_FILE="" +if [ -s build/failures/_run2.txt ]; then + LIST_FILE="build/failures/_run2.txt" +elif [ -s build/failures/_run1.txt ]; then + LIST_FILE="build/failures/_run1.txt" +else + exit 0 +fi + +echo "Failures to collect from $LIST_FILE:" +cat "$LIST_FILE" + +while IFS= read -r target; do + [ -z "$target" ] && continue + + # Convert //path/to:target to path/to/target + rel_path=$(tr ':' '/' <<< "${target#//}") + + log_source="$TESTLOGS_ROOT/${rel_path}/test.log" + + if [ -f "$log_source" ]; then + # Convert path separators to underscores for safe filename + safe_name="${target#//}" + safe_name="${safe_name//[\/:]/_}" + echo "Copying log for $target..." + cp "$log_source" "build/failures/${safe_name}.log" + else + echo "Warning: No log found for $target at $log_source" >&2 + fi +done < "$LIST_FILE" diff --git a/scripts/github-actions/rerun-failures.sh b/scripts/github-actions/rerun-failures.sh new file mode 100755 index 0000000000000..685b5eba4119a --- /dev/null +++ b/scripts/github-actions/rerun-failures.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Parse Bazel console log for failures and optionally rerun with debug. + +set -euo pipefail + +RUN_CMD="${1:-}" +RERUN_WITH_DEBUG="${2:-false}" + +mkdir -p build/failures +awk '$1 ~ /^\/\// && $2 ~ /(FAILED|TIMEOUT|INCOMPLETE)/ && $3 == "in" { print $1 }' build/bazel-console.log > build/failures/_run1.txt + +if [ "$RERUN_WITH_DEBUG" != "true" ]; then + exit 0 +fi + +if [ ! -s build/failures/_run1.txt ]; then + echo "No failed tests to rerun." + exit 0 +fi + +base_cmd=$(echo "$RUN_CMD" | sed 's| //[^ ]*||g') +targets=$(tr '\n' ' ' < build/failures/_run1.txt) +echo "Rerunning tests: $base_cmd --test_env=SE_DEBUG=true --flaky_test_attempts=1 $targets" +set +e +{ + $base_cmd --test_env=SE_DEBUG=true --flaky_test_attempts=1 $targets +} 2>&1 | tee build/bazel-console2.log +status=$? +set -e +awk '$1 ~ /^\/\// && $2 ~ /FAILED/ && $3 == "in" { print $1 }' build/bazel-console2.log > build/failures/_run2.txt +exit $status