Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 268 additions & 0 deletions .claude/skills/roll-playwright/SKILL.md

Large diffs are not rendered by default.

84 changes: 84 additions & 0 deletions .claude/skills/roll-playwright/find-changes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/bin/bash
# find-changes.sh — Discover everything that changed for a Playwright version roll.
#
# Usage: bash .claude/skills/roll-playwright/find-changes.sh <NEW_VERSION> [OLD_VERSION]
# Example: bash .claude/skills/roll-playwright/find-changes.sh 1.61.0
#
# Prints, for the target version:
# 1. The upstream release notes link + whether the tag exists.
# 2. The exact upstream docs/src/api/*.md files that changed between OLD and NEW.
# 3. Every NEW API block (`* since: vNEW`) and its current `* langs:` line — these
# are the candidates that may need `go` added in patches/main.patch.
# 4. The sibling roll PRs (python / java / dotnet) to read for parity.
#
# Requires: gh (authenticated), jq. Read-only — makes no changes to the repo.
set -euo pipefail

NEW="${1:?usage: find-changes.sh <NEW_VERSION> [OLD_VERSION] e.g. 1.61.0}"
NEW="${NEW#v}" # tolerate a leading v

# Derive OLD from run.go (the currently-pinned version) unless explicitly given.
if [ -n "${2:-}" ]; then
OLD="${2#v}"
else
OLD="$(grep -oE 'playwrightCliVersion = "[0-9.]+"' run.go | grep -oE '[0-9.]+')"
fi
MINOR="$(echo "$NEW" | grep -oE '^[0-9]+\.[0-9]+')"

hr() { printf '\n=== %s ===\n' "$1"; }

hr "Rolling: v$OLD -> v$NEW (minor $MINOR)"

hr "1. Upstream release"
if gh api "repos/microsoft/playwright/git/refs/tags/v$NEW" >/dev/null 2>&1; then
echo "tag v$NEW exists."
gh release view "v$NEW" --repo microsoft/playwright --json tagName,name,publishedAt --jq '" \(.tagName) published \(.publishedAt)"' 2>/dev/null || true
echo " release notes: https://github.com/microsoft/playwright/releases/tag/v$NEW"
else
echo "WARNING: tag v$NEW does not exist upstream yet. Available recent tags:"
gh release list --repo microsoft/playwright --limit 8 2>/dev/null | sed 's/^/ /'
fi

hr "2. Changed upstream API docs + protocol (v$OLD...v$NEW)"
CMP="repos/microsoft/playwright/compare/v$OLD...v$NEW"
CHANGED="$(gh api "$CMP" --jq '.files[].filename' 2>/dev/null | grep -E '^docs/src/api/|^packages/protocol/spec/|release-notes' || true)"
if [ -z "$CHANGED" ]; then
echo "(no docs/api/protocol files changed, or compare failed — check both tags exist)"
else
echo "$CHANGED" | sed 's/^/ /'
fi

hr "3. NEW API blocks gated to other languages (candidates for adding 'go')"
echo "For each changed class-*.md, lines added in this version with their langs line."
echo "Look for '* langs:' WITHOUT 'go' — those are not yet exposed to the Go client."
for f in $(echo "$CHANGED" | grep '^docs/src/api/class-' || true); do
PATCH="$(gh api "$CMP" --jq ".files[] | select(.filename==\"$f\") | .patch" 2>/dev/null || true)"
# Surface added method/property/option headers + their since/langs context.
HITS="$(echo "$PATCH" | grep -E '^\+' | grep -iE 'method:|property:|## |### |since: v'"$MINOR"'|langs:' || true)"
if [ -n "$HITS" ]; then
printf '\n --- %s ---\n' "$f"
echo "$HITS" | sed 's/^/ /'
fi
done

hr "4. Sibling roll PRs to read for parity"
# Match the minor as a literal substring (contains), NOT test() — test() is a regex
# where `.` is a wildcard, which produces false positives like "1.3.0-next.106133".
echo "# python (heaviest changes are usually in the -beta roll, not the final .0):"
gh pr list --repo microsoft/playwright-python --state merged --search "in:title roll" --limit 60 \
--json number,title,url --jq ".[] | select(.title | contains(\"$MINOR\")) | \" #\(.number) \(.title)\"" 2>/dev/null || true
echo "# java:"
gh pr list --repo microsoft/playwright-java --state all --search "in:title roll" --limit 60 \
--json number,title,url --jq ".[] | select(.title | contains(\"$MINOR\")) | \" #\(.number) \(.title)\"" 2>/dev/null || true
echo "# dotnet:"
gh pr list --repo microsoft/playwright-dotnet --state all --search "roll in:title" --limit 60 \
--json number,title --jq ".[] | select(.title | contains(\"$MINOR\")) | \" #\(.number) \(.title)\"" 2>/dev/null || true

hr "Next"
cat <<EOF
Read the roll PRs above (prefer the -beta/-alpha one — it carries the real API port;
the bare X.Y.0 PR is often just a version bump):
gh pr view <num> --repo microsoft/playwright-python # body lists every ported API
gh pr diff <num> --repo microsoft/playwright-python
Then follow SKILL.md to bump run.go, edit patches/main.patch langs, and regenerate.
EOF
142 changes: 142 additions & 0 deletions .claude/skills/roll-playwright/references/finding-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Finding the changes for a roll

Four sources tell you what changed. All commands below are verified against live data
(example: rolling `v1.60.0` → `v1.61.0`). `find-changes.sh` automates most of this; this
file is the manual fallback and the per-source detail.

The discovery flow across all three sibling clients is the same: **the PR _title_ carries the
target version, branch names don't** (they're inconsistent and sometimes disagree with the
title). GitHub full-text search tokenizes a dotted version oddly — a bare minor like `1.61`
matches nothing, but the full `1.61.0` matches. The robust move is to list all `roll` PRs and
filter locally on the version.

> **Read the `-beta`/`-alpha` roll, not just the `.0`.** Each minor typically gets 2–3 roll
> PRs (alpha → beta → stable). The stable `X.Y.0` PR is frequently a one-line driver-version
> bump; the **API port lands in the preceding beta/alpha PR**. Verified: python `1.60.0` final
> roll #3079 was +1/−1 (one line), while the beta roll #3069 was +2194/−226 across 36 files.

---

## 1. microsoft/playwright (upstream monorepo) — the diff

Upstream has no roll PRs; it ships `vX.Y.Z` tags + GitHub Releases. `docs/src/api/*.md` is the
source of truth every client generates from.

```bash
# Confirm the tag/release exists and read notes
gh release list --repo microsoft/playwright --limit 10
gh release view v1.61.0 --repo microsoft/playwright --json tagName,name,publishedAt,body

# Currently-pinned version (the OLD side of the diff)
grep playwrightCliVersion run.go

# Changed API docs + protocol between OLD and NEW
gh api repos/microsoft/playwright/compare/v1.60.0...v1.61.0 --jq '.files[].filename' \
| grep -E '^docs/src/api/|^packages/protocol/spec/|release-notes'

# Pull the hunk for one changed file and find newly-added APIs
gh api 'repos/microsoft/playwright/compare/v1.60.0...v1.61.0' \
--jq '.files[] | select(.filename=="docs/src/api/class-apiresponse.md") | .patch'
```

**Reading langs annotations.** Each method/option/property block carries:
- `* since: vX.Y` — version it appeared.
- `* langs: js, python, csharp` — which clients expose it (comma+space separated).

A new API gated to other languages (e.g. `* langs: js, python`) is **not** in Go until you add
`go`. Look in each hunk for added blocks containing `* since: v<NEW>` and inspect their
`* langs:` line — those are the candidates. Variants:
- sub-list form for per-language naming: `* langs:\n - alias-python: and_`
- Go-only block: `* langs: go`

**Protocol** lives under `packages/protocol/spec/*.yml` (`api.yml`, `page.yml`, `network.yml`,
…). There is **no** `packages/protocol/src/protocol.yml` (the `CONTRIBUTING.md` reference is
stale). Protocol rarely changes between minors.

**zsh gotcha:** single-quote any `gh api` URL containing `?` (e.g. `'...?ref=v1.61.0'`).

---

## 2. microsoft/playwright-python

Closest in shape to Go — use it as the primary parity reference.

```bash
# Robust: list roll PRs, filter on the version locally
gh pr list --repo microsoft/playwright-python --state merged \
--search "in:title roll" --limit 60 --json number,title,url \
--jq '.[] | select(.title | test("1\\.61\\.")) | "#\(.number)\t\(.title)\t\(.url)"'

# Read it — the body enumerates ported APIs
gh pr view <num> --repo microsoft/playwright-python
gh pr view <num> --repo microsoft/playwright-python --json files --jq '.files[].path'
gh pr diff <num> --repo microsoft/playwright-python
```

- **Title:** `chore: roll to X.Y.Z` / `chore: roll driver to X.Y.Z` / `chore(roll): vX.Y.Z`;
beta rolls carry `-beta-<epochms>`.
- **Extract:** PR body; new files under `playwright/_impl/` (new classes); diffs of `_impl/*.py`
and the regenerated `async_api/_generated.py` / `sync_api/_generated.py` for exact method
names, param names/types, defaults, optionality, and removed/deprecated params.

---

## 3. microsoft/playwright-java

Best for a per-upstream-PR breakdown — java roll bodies link each `microsoft/playwright` PR
ported and note which needed no client change / were skipped.

```bash
# Most robust: list all roll PRs, grep the minor locally (surfaces alpha/beta/stable)
gh pr list --repo microsoft/playwright-java --state merged --search "roll" --limit 100 | grep '1.61'

# Exact-match shortcut — must use the FULL version incl. patch
gh search prs --repo microsoft/playwright-java "1.61.0" --limit 10

gh pr view <num> --repo microsoft/playwright-java
gh pr diff <num> --repo microsoft/playwright-java
```

- **Title:** `chore: roll driver to X.Y.Z` / `chore: roll X.Y.Z`; occasionally `feat:` for big
feature rolls. Version marker file: `scripts/DRIVER_VERSION`.
- **Extract:** PR body (per-PR port list); new public interfaces under
`playwright/src/main/java/com/microsoft/playwright/` and option/enum types under `.../options/`
map ~1:1 to Go bindings.

---

## 4. microsoft/playwright-dotnet

```bash
# Search by title + version token (drop the patch to the minor if patch-level is empty)
gh pr list --repo microsoft/playwright-dotnet --state all \
--search "roll in:title 1.61.0" --json number,title,headRefName,state,mergedAt

# List all roll PRs and eyeball
gh pr list --repo microsoft/playwright-dotnet --state all --search "roll in:title" \
--limit 50 --json number,title,state,mergedAt

# Confirm a candidate actually bumps the driver (some "roll"-matching PRs aren't rolls)
gh pr diff <num> --repo microsoft/playwright-dotnet | grep DriverVersion
```

- **Title:** `chore: roll driver to X.Y.Z` / `chore(roll): roll Playwright to vX.Y.Z`; pre-release
rolls embed `-alpha-<ts>`/`-beta-<ts>`. **Match on title, not branch.**
- **Version marker:** `src/Common/Version.props` `<DriverVersion>` (changed in every roll).
- **Extract:** ported API surface in `src/Playwright/API/Generated/**` (new `I*.cs` members,
`Options/*Options.cs`, `Types/`, `Enums/`); wire changes in
`src/Playwright/Transport/Protocol/Generated/**`. PR body is the best changelog.

---

## How these map to the Go patch

- The upstream `v<OLD>...v<NEW>` docs diff tells you **which API/option blocks gained
`* since: v<NEW>`** and whether their `* langs:` already reaches Go.
- The **sibling PRs tell you which of those are real client surface** (names, types, defaults,
optionality, what was skipped). Use python/java for parity decisions.
- The **Go roll mirrors this by adding `go` to the `* langs:`** of each desired new API in
`docs/src/api/*.md`, recorded as one-line edits in `patches/main.patch`. Then regenerate.

The three sibling repos also keep their own roll runbooks at `.claude/skills/playwright-roll/SKILL.md`
— worth cross-referencing if a roll gets hairy.
Loading
Loading