test: auto-rerun failed Playwright Regression jobs (#12953)

## What

Adds **Playwright Regression Tests** to the auto-rerun workflow
(`playwright-auto-rerun.yml`), so a failed regression run automatically
re-runs only its failed jobs once — matching the existing behavior for
UI tests.

## Why

Until now `playwright-auto-rerun.yml` only watched **Playwright UI
Tests**. Regression failures (often flakes) required manual re-runs.

## Change

- Added `"Playwright Regression Tests"` to the `workflow_run`
`workflows` list.

The existing `if` (`run_attempt == 1`) and `gh run rerun --failed` step
are workflow-name-agnostic, so no other changes are needed — regression
gets exactly 1 auto-retry.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Shrinath Rao
2026-06-30 14:11:55 +00:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 96e8dcd5c1
commit 34646a9cfa
3 changed files with 50 additions and 3 deletions
+3 -1
View File
@@ -4,7 +4,9 @@ run-name: "Playwright Auto-Rerun - ${{ github.event.workflow_run.head_branch ||
on:
workflow_run:
workflows: ["Playwright UI Tests"]
workflows:
- "Playwright UI Tests"
- "Playwright Regression Tests"
types:
- completed
branches:
+7 -1
View File
@@ -1067,6 +1067,11 @@ jobs:
TESTS: ${{ needs.ui_integration_tests.result }}
MERGE_STATS: ${{ needs.merge_reports.outputs.stats }}
MERGE_FLAKY: ${{ needs.merge_reports.outputs.flaky }}
# Branch + PR for per-test rows so the dashboard needs no cross-stream JOIN.
# head_ref is set on pull_request (the source branch); ref_name covers push +
# merge_group (gh-readonly-queue/main/pr-<n>-<sha>). PR empty on merge_group/push.
REPORT_BRANCH: ${{ github.head_ref || github.ref_name }}
REPORT_PR: ${{ github.event.pull_request.number }}
run: |
# This job runs only when tests actually ran (merge `if:` gates on !cancelled &&
# ui != skipped), so TESTS is success|failure here.
@@ -1085,7 +1090,8 @@ jobs:
FLAKY_FILE=$(mktemp "${TMPDIR:-/tmp}/flaky.XXXXXX")
trap 'rm -f "$FLAKY_FILE"' EXIT
printf '%s' "$FLAKY" | jq -c --arg run_id "$GITHUB_RUN_ID" --arg repo "$GITHUB_REPOSITORY" \
'[.[] | {run_id:$run_id, repo:$repo, suite:"ui", workflow:"test", ingest_source:"live", status:.status, module:.module, test_title:.title, test_file:.file}]' \
--arg branch "${REPORT_BRANCH:-}" --arg pr "${REPORT_PR:-}" \
'[.[] | {run_id:$run_id, repo:$repo, suite:"ui", workflow:"test", ingest_source:"live", status:.status, module:.module, test_title:.title, test_file:.file, branch:(if $branch=="" then null else $branch end), pr_number:(if $pr=="" then null else ($pr|tonumber) end)}]' \
> "$FLAKY_FILE" 2>/dev/null || echo '[]' > "$FLAKY_FILE"
if [ "$(jq 'length' "$FLAKY_FILE" 2>/dev/null || echo 0)" -gt 0 ]; then
bash .github/scripts/o2-report.sh ci_test_results "$FLAKY_FILE"
+40 -1
View File
@@ -554,6 +554,9 @@ jobs:
# Compact Playwright stats (expected/unexpected/flaky/skipped/duration) from the merged
# report.json — consumed by the report_openobserve job to record reliability metrics.
stats: ${{ steps.report_stats.outputs.stats }}
# One JSON array of flaky+failed tests (per-test rows) for the ci_test_results stream,
# so the unified UI+Regression dashboard's Latest-failures / Flakiest panels cover regression.
flaky: ${{ steps.report_flaky.outputs.flaky }}
steps:
- name: Clone the current repo
@@ -658,6 +661,16 @@ jobs:
echo "stats=$STATS" >> "$GITHUB_OUTPUT"
echo "report stats: $STATS"
- name: Extract flaky/failed tests for OpenObserve
id: report_flaky
if: always()
run: |
# One JSON array of flaky+failed tests for the ci_test_results stream (per-test rows).
# Logic + schema live in extract-flaky.js; prints "[]" if the report is missing/clean.
FLAKY=$(node .github/scripts/extract-flaky.js tests/ui-testing/playwright-results/report.json)
printf 'flaky=%s\n' "$FLAKY" >> "$GITHUB_OUTPUT"
echo "report flaky count: $(printf '%s' "$FLAKY" | jq 'length' 2>/dev/null || echo '?')"
- name: Upload merged report
if: always()
uses: actions/upload-artifact@v4
@@ -805,6 +818,10 @@ jobs:
UI_RESULT: ${{ needs.ui_integration_tests.result }}
MERGE_RESULT: ${{ needs.merge_reports.result }}
MERGE_STATS: ${{ needs.merge_reports.outputs.stats }}
MERGE_FLAKY: ${{ needs.merge_reports.outputs.flaky }}
# Branch + PR for per-test rows (ci_test_results), matching the UI workflow.
REPORT_BRANCH: ${{ github.head_ref || github.ref_name }}
REPORT_PR: ${{ github.event.pull_request.number }}
run: |
set -uo pipefail
# Forks / unconfigured repos: skip entirely (no API call, no rate-limit spend).
@@ -916,6 +933,10 @@ jobs:
" > payload.json || { echo "::warning::payload build failed"; echo '{}' > payload.json; }
bash .github/scripts/o2-report.sh ci_regression payload.json
# Also write the same run-level doc to ci_test_runs (already tagged suite=regression) so
# the unified UI+Regression dashboard drives one panel set off a `suite` variable. Additive:
# ci_regression keeps receiving the doc, so existing dashboards/crons are untouched.
bash .github/scripts/o2-report.sh ci_test_runs payload.json
# Also emit one row per shard to the ci_regression_shards stream, flattened from
# payload.shards (each = {name, conclusion, duration_sec}). Powers per-shard duration /
@@ -927,17 +948,35 @@ jobs:
# doc above (which also leaves it unset), keeping the two streams time-aligned.
shards_json=$(jq -c --arg repo "$GITHUB_REPOSITORY" --arg run_id "$GITHUB_RUN_ID" \
'[.shards[]? | {
run_id: $run_id, repo: $repo, workflow: "regression", ingest_source: "live",
run_id: $run_id, repo: $repo, suite: "regression", workflow: "regression", ingest_source: "live",
shard_name: .name,
module: (.name | sub("^e2e / ";"") | sub("-Regression$";"") | if . == "" then "unknown" else . end),
conclusion: .conclusion, duration_sec: .duration_sec
}]' payload.json 2>/dev/null) && printf '%s' "$shards_json" > shards.json || echo '[]' > shards.json
if [ "$(jq 'length' shards.json 2>/dev/null || echo 0)" -gt 0 ]; then
bash .github/scripts/o2-report.sh ci_regression_shards shards.json
# Dual-write per-shard rows to the unified stream (now tagged suite=regression).
bash .github/scripts/o2-report.sh ci_test_runs_shards shards.json
else
echo "::notice::no shard rows to emit"
fi
# Per-test flaky/failed rows -> ci_test_results (suite=regression), so the unified
# dashboard's Latest-failures / Flakiest panels cover regression too. Non-fatal; mirrors
# the UI workflow's block. branch + pr_number stamped so no cross-stream JOIN is needed.
FLAKY="${MERGE_FLAKY:-[]}"
if printf '%s' "$FLAKY" | jq -e 'type=="array" and length>0' >/dev/null 2>&1; then
FLAKY_FILE=$(mktemp "${TMPDIR:-/tmp}/flaky.XXXXXX")
trap 'rm -f "$FLAKY_FILE"' EXIT
printf '%s' "$FLAKY" | jq -c --arg run_id "$GITHUB_RUN_ID" --arg repo "$GITHUB_REPOSITORY" \
--arg branch "${REPORT_BRANCH:-}" --arg pr "${REPORT_PR:-}" \
'[.[] | {run_id:$run_id, repo:$repo, suite:"regression", workflow:"regression", ingest_source:"live", status:.status, module:.module, test_title:.title, test_file:.file, branch:(if $branch=="" then null else $branch end), pr_number:(if $pr=="" then null else ($pr|tonumber) end)}]' \
> "$FLAKY_FILE" 2>/dev/null || echo '[]' > "$FLAKY_FILE"
if [ "$(jq 'length' "$FLAKY_FILE" 2>/dev/null || echo 0)" -gt 0 ]; then
bash .github/scripts/o2-report.sh ci_test_results "$FLAKY_FILE"
fi
fi
playwright_summary:
timeout-minutes: 5
runs-on: