Skip to main content

triage-ci-flake

Use when CI tests fail on main branch after PR merge, when investigating flaky test failures, or when user provides a PR URL/number to aggregate all failing tests

Source facts

Repository
payloadcms/payload
Last source activity
September 22, 2026 at 17:53
Detected SKILL.md language
English
Stars
45,280
Forks
4,298

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
triage-ci-flake
description
Use when CI tests fail on main branch after PR merge, when investigating flaky test failures, or when user provides a PR URL/number to aggregate all failing tests
allowed-tools
Write, Bash(date:*), Bash(mkdir -p *)
# Triage CI Failure ## Overview Systematic workflow designed specifically for triaging and fixing end-to-end (e2e) test failures in CI, especially flaky Playwright tests that pass locally but fail in CI. E2E tests that made it to `main` are usually flaky due to timing, bundling, or environment differences. **CRITICAL RULE: You MUST run the reproduction workflow before proposing any fixes. No exceptions.** ## When to Use - CI test fails on `main` branch after PR was merged - Test passes locally but fails in CI - Test failure labeled as "flaky" or intermittent - E2E test timing out in CI only - User provides a PR URL/number with failing checks ## PR-Based Workflow (When PR URL/Number Provided) When the user provides a PR URL (e.g., `https://github.com/payloadcms/payload/pull/16701`) or PR number: ### Step 1: Fetch PR Status Checks First, use `tool_search` with query "github pull request status checks" to load the GitHub tools. Then use the `github-pull-request_pullRequestStatusChecks` tool to get all failing checks: ``` Tool: github-pull-request_pullRequestStatusChecks Parameters: pullRequestNumber: <extracted from URL or provided> repo: { owner: "payloadcms", name: "payload" } ``` ### Step 2: Aggregate Failing Tests Parse the status checks response and create a summary table: | Suite | Check Status | Target URL | | --------------------- | ------------ | ---------- | | admin**e2e**list-view | failed | [link] | | plugin-import-export | failed | [link] | For each failing check, the `context` field contains the test suite name (e.g., `admin__e2e__list-view`). ### Step 3: Extract Failure Details from Each Check For each failing check: 1. Visit the `targetUrl` to get detailed failure logs 2. Extract the specific test name and error message 3. Add to the aggregated failure list Present a consolidated summary: ```markdown ## Failing Tests Summary ### 1. admin**e2e**list-view (3/4) - **Test**: "should use custom pagination limit" - **Error**: Locator `.per-page__button` not found - **File**: test/admin/e2e/list-view/e2e.spec.ts:1495 ### 2. plugin-import-export - **Test**: "should inherit limit from list view URL" - **Error**: Locator `.per-page__button` not found - **File**: test/plugin-import-export/e2e.spec.ts:150 ``` ### Step 4: Identify Common Patterns Look for patterns across failures: - Same selector errors → likely a component change needing test updates - Same test file → localized issue - Different errors in same suite → may be test pollution ### Step 5: Proceed with Triage For each unique failure, follow the standard reproduction workflow below. ## MANDATORY First Steps **YOU MUST EXECUTE THESE COMMANDS. Reading code or analyzing logs does NOT count as reproduction.** 1. **Extract** suite name, test name, and error from CI logs 2. **EXECUTE**: Kill port 3000 to avoid conflicts 3. **EXECUTE**: `pnpm dev $SUITE_NAME` (use run_in_background=true) 4. **EXECUTE**: Wait for server to be ready (check with curl or sleep) 5. **EXECUTE**: Run the specific failing test with Playwright directly (npx playwright test test/TEST_SUITE_NAME/e2e.spec.ts:31:3 --headed -g "TEST_DESCRIPTION_TARGET_GOES_HERE") 6. **If test passes**, **EXECUTE**: `pnpm prepare-run-test-against-prod` 7. **EXECUTE**: `pnpm dev:prod $SUITE_NAME` and run test again **Only after EXECUTING these commands and seeing their output** can you proceed to analysis and fixes. **"Analysis from logs" is NOT reproduction. You must RUN the commands.** ## Core Workflow ```dot digraph triage_ci { "CI failure reported" [shape=box]; "Extract details from CI logs" [shape=box]; "Identify suite and test name" [shape=box]; "Run dev server: pnpm dev $SUITE" [shape=box]; "Run specific test by name" [shape=box]; "Did test fail?" [shape=diamond]; "Debug with dev code" [shape=box]; "Run prepare-run-test-against-prod" [shape=box]; "Run: pnpm dev:prod $SUITE" [shape=box]; "Run specific test again" [shape=box]; "Did test fail now?" [shape=diamond]; "Debug bundling issue" [shape=box]; "Unable to reproduce - check logs" [shape=box]; "Fix and verify" [shape=box]; "CI failure reported" -> "Extract details from CI logs"; "Extract details from CI logs" -> "Identify suite and test name"; "Identify suite and test name" -> "Run dev server: pnpm dev $SUITE"; "Run dev server: pnpm dev $SUITE" -> "Run specific test by name"; "Run specific test by name" -> "Did test fail?"; "Did test fail?" -> "Debug with dev code" [label="yes"]; "Did test fail?" -> "Run prepare-run-test-against-prod" [label="no"]; "Run prepare-run-test-against-prod" -> "Run: pnpm dev:prod $SUITE"; "Run: pnpm dev:prod $SUITE" -> "Run specific test again"; "Run specific test again" -> "Did test fail now?"; "Did test fail now?" -> "Debug bundling issue" [label="yes"]; "Did test fail now?" -> "Unable to reproduce - check logs" [label="no"]; "Debug with dev code" -> "Fix and verify"; "Debug bundling issue" -> "Fix and verify"; } ``` ## Step-by-Step Process ### 1. Extract CI Details From CI logs or GitHub Actions URL, identify: - **Suite name**: Directory name (e.g., `i18n`, `fields`, `lexical`) - **Test file**: Full path (e.g., `test/i18n/e2e.spec.ts`) - **Test name**: Exact test description - **Error message**: Full stack trace - **Test type**: E2E (Playwright) ### 2. Reproduce with Dev Code **CRITICAL: Always run the specific test by name, not the full suite.** **SERVER MANAGEMENT RULES:** 1. **ALWAYS kill all servers before starting a new one** 2. **NEVER assume ports are free** 3. **ALWAYS wait for server ready confirmation before running tests** ```bash # ======================================== # STEP 2A: STOP ALL SERVERS # ======================================== lsof -ti:3000 | xargs kill -9 2>/dev/null || echo "Port 3000 clear" # ======================================== # STEP 2B: START DEV SERVER # ======================================== # Start dev server with the suite (in background with run_in_background=true) pnpm dev $SUITE_NAME # ======================================== # STEP 2C: WAIT FOR SERVER READY # ======================================== # Wait for server to be ready (REQUIRED - do not skip) until curl -s http://localhost:3000/admin > /dev/null 2>&1; do sleep 1; done && echo "Server ready" # ======================================== # STEP 2D: RUN SPECIFIC TEST # ======================================== # Run ONLY the specific failing test using Playwright directly # For E2E tests (DO NOT use pnpm test:e2e as it spawns its own server): pnpm exec playwright test test/$SUITE_NAME/e2e.spec.ts -g "exact test name" ``` **Did the test fail?** - ✅ **YES**: You reproduced it! Proceed to debug with dev code. - ❌ **NO**: Continue to step 3 (bundled code test). ### 3. Reproduce with Bundled Code If test passed with dev code, the issue is likely in bundled/production code. **IMPORTANT: You MUST stop the dev server before starting prod server.** ```bash # ======================================== # STEP 3A: STOP ALL SERVERS (INCLUDING DEV SERVER FROM STEP 2) # ======================================== lsof -ti:3000 | xargs kill -9 2>/dev/null || echo "Port 3000 clear" # ======================================== # STEP 3B: BUILD AND PACK FOR PROD # ======================================== # Build all packages and pack them (this takes time - be patient) pnpm prepare-run-test-against-prod # ======================================== # STEP 3C: START PROD SERVER # ======================================== # Start prod dev server (in background with run_in_background=true) pnpm dev:prod $SUITE_NAME # ======================================== # STEP 3D: WAIT FOR SERVER READY # ======================================== # Wait for server to be ready (REQUIRED - do not skip) until curl -s http://localhost:3000/admin > /dev/null 2>&1; do sleep 1; done && echo "Server ready" # ======================================== # STEP 3E: RUN SPECIFIC TEST # ======================================== # Run the specific test again using Playwright directly pnpm exec playwright test test/$SUITE_NAME/e2e.spec.ts -g "exact test name" ``` **Did the test fail now?** - ✅ **YES**: Bundling or production build issue. Look for: - Missing exports in package.json - Build configuration problems - Code that behaves differently when bundled - ❌ **NO**: Unable to reproduce locally. Proceed to step 4. ### 4. Unable to Reproduce If you cannot reproduce locally after both attempts: - Review CI logs more carefully for environment differences - Check for race conditions (run test multiple times: `for i in {1..10}; do pnpm test:e2e...; done`) - Look for CI-specific constraints (memory, CPU, timing) - Consider if it's a true race condition that's highly timing-dependent ## Common Flaky Test Patterns ### Race Conditions - Page navigating while assertions run - Network requests not settled before assertions - State updates not completed
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub