diff --git a/.github/workflows/blog-auditor.lock.yml b/.github/workflows/blog-auditor.lock.yml index a7c8ba3ca2a..1b2333bc6a3 100644 --- a/.github/workflows/blog-auditor.lock.yml +++ b/.github/workflows/blog-auditor.lock.yml @@ -556,7 +556,7 @@ jobs: - name: Install Claude Code CLI run: npm install -g @anthropic-ai/claude-code@2.1.195 - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 9a6c08fe8a6..016637ec32d 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -681,7 +681,7 @@ jobs: - name: Install Claude Code CLI run: npm install -g @anthropic-ai/claude-code@2.1.195 - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/daily-model-inventory.lock.yml b/.github/workflows/daily-model-inventory.lock.yml index b1bdbd6b750..66fb7553888 100644 --- a/.github/workflows/daily-model-inventory.lock.yml +++ b/.github/workflows/daily-model-inventory.lock.yml @@ -528,7 +528,7 @@ jobs: - name: Install GitHub Copilot SDK (Node.js) run: cd "${GITHUB_WORKSPACE}" && npm install --ignore-scripts --no-save @github/copilot-sdk@1.0.4 - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/daily-multi-device-docs-tester.lock.yml b/.github/workflows/daily-multi-device-docs-tester.lock.yml index 3affa42e544..5a4daf5909a 100644 --- a/.github/workflows/daily-multi-device-docs-tester.lock.yml +++ b/.github/workflows/daily-multi-device-docs-tester.lock.yml @@ -517,7 +517,7 @@ jobs: - name: Install Pi CLI run: npm install --ignore-scripts -g @earendil-works/pi-coding-agent@0.80.2 - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/docs-noob-tester.lock.yml b/.github/workflows/docs-noob-tester.lock.yml index 228dd60ee63..200843b20ba 100644 --- a/.github/workflows/docs-noob-tester.lock.yml +++ b/.github/workflows/docs-noob-tester.lock.yml @@ -511,7 +511,7 @@ jobs: - name: Install GitHub Copilot SDK (Node.js) run: cd "${GITHUB_WORKSPACE}" && npm install --ignore-scripts --no-save @github/copilot-sdk@1.0.4 - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/slide-deck-maintainer.lock.yml b/.github/workflows/slide-deck-maintainer.lock.yml index 94536440795..5a1fcef0502 100644 --- a/.github/workflows/slide-deck-maintainer.lock.yml +++ b/.github/workflows/slide-deck-maintainer.lock.yml @@ -563,7 +563,7 @@ jobs: - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.20 --rootless - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 8246cf6dd29..1434d67685b 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -814,7 +814,7 @@ jobs: - name: Install Claude Code CLI run: npm install -g @anthropic-ai/claude-code@2.1.195 - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index b075d7af731..8916d5dd87d 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -640,7 +640,7 @@ jobs: - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.20 --rootless - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/smoke-copilot-aoai-apikey.lock.yml b/.github/workflows/smoke-copilot-aoai-apikey.lock.yml index 3e5fdd0c01f..5c03cc4a89b 100644 --- a/.github/workflows/smoke-copilot-aoai-apikey.lock.yml +++ b/.github/workflows/smoke-copilot-aoai-apikey.lock.yml @@ -701,7 +701,7 @@ jobs: - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.20 --rootless - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/smoke-copilot-aoai-entra.lock.yml b/.github/workflows/smoke-copilot-aoai-entra.lock.yml index fb3e0751df3..afb5dc33fcb 100644 --- a/.github/workflows/smoke-copilot-aoai-entra.lock.yml +++ b/.github/workflows/smoke-copilot-aoai-entra.lock.yml @@ -702,7 +702,7 @@ jobs: - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.20 --rootless - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index 1a830537d1f..defe43506dc 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -646,7 +646,7 @@ jobs: - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.20 --rootless - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 686118986ed..6fc81de700f 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -717,7 +717,7 @@ jobs: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/visual-regression-checker.lock.yml b/.github/workflows/visual-regression-checker.lock.yml index fc85db57896..e16d3660111 100644 --- a/.github/workflows/visual-regression-checker.lock.yml +++ b/.github/workflows/visual-regression-checker.lock.yml @@ -562,7 +562,7 @@ jobs: - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.20 --rootless - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/.github/workflows/weekly-editors-health-check.lock.yml b/.github/workflows/weekly-editors-health-check.lock.yml index 9943f4cc92a..ae6fc03ff2d 100644 --- a/.github/workflows/weekly-editors-health-check.lock.yml +++ b/.github/workflows/weekly-editors-health-check.lock.yml @@ -504,7 +504,7 @@ jobs: - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.20 --rootless - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10 diff --git a/pkg/constants/version_constants.go b/pkg/constants/version_constants.go index 45d1153f354..882c8c5474c 100644 --- a/pkg/constants/version_constants.go +++ b/pkg/constants/version_constants.go @@ -132,9 +132,11 @@ const MCPGIntegrityReactionsMinVersion Version = "v0.2.18" // DefaultPlaywrightMCPVersion is the default version of the @playwright/mcp package const DefaultPlaywrightMCPVersion Version = "0.0.77" -// DefaultPlaywrightCLIVersion is the default version of the @playwright/cli package +// DefaultPlaywrightCLIVersion is the default version of the @playwright/cli package. // Used when tools.playwright.mode is "cli" to install the CLI tool instead of the MCP server. -const DefaultPlaywrightCLIVersion Version = "0.1.15" +// Keep this version outside the default 3-day npm release-age cooldown window enforced by +// generated Playwright CLI install steps. See TestDefaultPlaywrightCLIVersionOutsideCooldownWindow. +const DefaultPlaywrightCLIVersion Version = "0.1.14" // DefaultPlaywrightBrowserVersion is the default version of the Playwright browser Docker image const DefaultPlaywrightBrowserVersion Version = "v1.61.1" diff --git a/pkg/constants/version_constants_test.go b/pkg/constants/version_constants_test.go new file mode 100644 index 00000000000..a8af61d6960 --- /dev/null +++ b/pkg/constants/version_constants_test.go @@ -0,0 +1,30 @@ +//go:build !integration + +package constants + +import ( + "testing" + "time" +) + +func TestDefaultPlaywrightCLIVersionOutsideCooldownWindow(t *testing.T) { + const ( + expectedVersion Version = "0.1.14" + publishedAtRFC3339 = "2026-06-10T00:20:51.773Z" + minReleaseAge = 72 * time.Hour + ) + + if DefaultPlaywrightCLIVersion != expectedVersion { + t.Fatalf("DefaultPlaywrightCLIVersion = %q, want %q; update this test metadata when changing the pinned default", DefaultPlaywrightCLIVersion, expectedVersion) + } + + publishedAt, err := time.Parse(time.RFC3339Nano, publishedAtRFC3339) + if err != nil { + t.Fatalf("parse publishedAtRFC3339: %v", err) + } + + age := time.Since(publishedAt) + if age < minReleaseAge { + t.Fatalf("@playwright/cli@%s is only %s old, but Playwright CLI installs enforce a %s npm release-age cooldown", DefaultPlaywrightCLIVersion, age.Round(time.Second), minReleaseAge) + } +} diff --git a/pkg/workflow/playwright_cli_test.go b/pkg/workflow/playwright_cli_test.go new file mode 100644 index 00000000000..b9ce11ea2fc --- /dev/null +++ b/pkg/workflow/playwright_cli_test.go @@ -0,0 +1,33 @@ +//go:build !integration + +package workflow + +import ( + "strings" + "testing" + + "github.com/github/gh-aw/pkg/constants" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGeneratePlaywrightCLIInstallSteps_DefaultVersionUsesCooldown(t *testing.T) { + steps := generatePlaywrightCLIInstallSteps(&WorkflowData{ + Tools: map[string]any{ + "playwright": map[string]any{ + "mode": "cli", + }, + }, + }) + + require.Len(t, steps, 2, "expected npm install step plus skills install step") + + installStep := strings.Join(steps[0], "\n") + assert.Contains(t, installStep, "npm install -g @playwright/cli@"+string(constants.DefaultPlaywrightCLIVersion)) + assert.Contains(t, installStep, "NPM_CONFIG_MIN_RELEASE_AGE: '3'") + assert.Contains(t, installStep, "timeout-minutes: 10") + + skillsStep := strings.Join(steps[1], "\n") + assert.Contains(t, skillsStep, "playwright-cli install --skills") + assert.Contains(t, skillsStep, "PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'") +} diff --git a/pkg/workflow/testdata/TestWasmGolden_CompileFixtures/playwright-cli-mode.golden b/pkg/workflow/testdata/TestWasmGolden_CompileFixtures/playwright-cli-mode.golden index 714fca5dbc7..9faffdbab9e 100644 --- a/pkg/workflow/testdata/TestWasmGolden_CompileFixtures/playwright-cli-mode.golden +++ b/pkg/workflow/testdata/TestWasmGolden_CompileFixtures/playwright-cli-mode.golden @@ -406,7 +406,7 @@ jobs: - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.20 --rootless - name: Install Playwright CLI - run: npm install -g @playwright/cli@0.1.15 + run: npm install -g @playwright/cli@0.1.14 env: NPM_CONFIG_MIN_RELEASE_AGE: '3' timeout-minutes: 10