diff --git a/.github/scripts/pw-triage-comment.js b/.github/scripts/pw-triage-comment.js new file mode 100644 index 0000000000..0edba012c5 --- /dev/null +++ b/.github/scripts/pw-triage-comment.js @@ -0,0 +1,65 @@ +#!/usr/bin/env node +// Render the sticky PR shard-triage comment from $MATRIX + the select log (argv[2]) to stdout. +const fs = require("fs"); + +function readLog(path) { + if (!path) return ""; + try { + return fs.readFileSync(path, "utf8").trim(); + } catch { + return ""; + } +} + +const marker = process.env.MARKER || ""; +const smokeActive = process.env.SMOKE_ACTIVE === "true"; +const headSha = (process.env.HEAD_SHA || "").slice(0, 9); +const attempt = process.env.ATTEMPT || "1"; +const log = readLog(process.argv[2]); + +let matrix; +try { + matrix = JSON.parse(process.env.MATRIX || "{}"); +} catch { + matrix = {}; +} +const shards = Array.isArray(matrix.include) ? matrix.include : []; + +// smoke_active only says selection ran; a global_paths hit still returns the full +// matrix, so infer the real mode from the log rather than the flag alone. +const fellBackToFull = /falling back to full matrix|full matrix:/.test(log); +const mode = smokeActive && !fellBackToFull ? "smoke (changed-path)" : "full matrix"; + +const specsOf = (s) => (Array.isArray(s.run_files) ? s.run_files.length : 0); +const totalSpecs = shards.reduce((n, s) => n + specsOf(s), 0); +const shardList = shards + .map((s) => `${s.testfolder} (${specsOf(s)})`) + .join(" 路 "); + +const lines = [ + marker, + "### 馃幆 Playwright shard selection", + `Mode: **${mode}** 路 **${shards.length} shard${shards.length === 1 ? "" : "s"}** 路 **${totalSpecs} spec${totalSpecs === 1 ? "" : "s"}**`, + "", + shardList || "_no shards selected_", +]; + +if (log) { + lines.push( + "", + "
Why these shards", + "", + "```", + log, + "```", + "", + "
" + ); +} + +lines.push( + "", + `Updated for \`${headSha}\` 路 attempt ${attempt} 路 updates in place on every push.` +); + +process.stdout.write(lines.join("\n") + "\n"); diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 71ebd2433b..f0e140742c 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -322,6 +322,30 @@ jobs: echo '```' } >> "$GITHUB_STEP_SUMMARY" + # One sticky comment per PR (found by the hidden marker) so the triage result updates + # in place on every push instead of spamming a fresh comment. Same idiom as Kinora below. + - name: Upsert shard-selection comment on PR + if: ${{ github.event_name == 'pull_request' }} + continue-on-error: true + env: + GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }} # PAT: comment as a human, not github-actions[bot] + REPO: ${{ github.repository }} + PR_NUMBER: ${{ github.event.pull_request.number }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + MATRIX: ${{ steps.gen.outputs.matrix }} + SMOKE_ACTIVE: ${{ steps.gen.outputs.smoke_active }} + ATTEMPT: ${{ github.run_attempt }} + run: | + MARKER="" + BODY=$(MARKER="$MARKER" node .github/scripts/pw-triage-comment.js /tmp/pw-select-log.txt) + CID=$(gh api "repos/$REPO/issues/$PR_NUMBER/comments" --paginate \ + -q ".[] | select(.body | contains(\"$MARKER\")) | .id" | head -1) + if [ -n "$CID" ]; then + gh api -X PATCH "repos/$REPO/issues/comments/$CID" -f body="$BODY" >/dev/null && echo "Updated triage comment ($CID)." + else + gh api -X POST "repos/$REPO/issues/$PR_NUMBER/comments" -f body="$BODY" >/dev/null && echo "Posted triage comment." + fi + ui_integration_tests: timeout-minutes: 45 name: e2e / ${{ matrix.testfolder }}