Skip to main content

playwright-release

Prepare a Playwright Python release. Checks open bugs, writes the Python release notes in microsoft/playwright, opens the release PR, cuts the release branch, and saves a draft GitHub release. Never publishes the release.

Source facts

Repository
microsoft/playwright-python
Last source activity
October 15, 2026 at 18:25
Detected SKILL.md language
English
Stars
15,044
Forks
1,250

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
playwright-release
description
Prepare a Playwright Python release. Checks open bugs, writes the Python release notes in microsoft/playwright, opens the release PR, cuts the release branch, and saves a draft GitHub release. Never publishes the release.
# Preparing a Playwright Python release In this skill, `1.xx` is the release (for example `1.64`), and `v1.xx.0` is its tag. `$PW_SRC_DIR` is the roll checkout of `microsoft/playwright` (see the `playwright-roll` skill, step 2). Remotes: find the remote for `microsoft/playwright-python` with `git remote -v`. The commands below call it `upstream`. What you may push: - The user's request to prepare the release is the instruction to open the two PRs in steps 2 and 3. - Cut the release branch (step 4) only when the user tells you to. - Never publish the release. ## 1. Preconditions Check that the bugs are closed. The bug and regression issue templates give these title prefixes: ```sh gh issue list --repo microsoft/playwright-python --state open \ --search 'in:title "[Bug]" OR in:title "[Regression]"' ``` If any are open, list them for the user and ask whether to continue. Do not close or comment on issues. Check that the driver is rolled. `DRIVER_VERSION` must be the driver for the release: a `1.xx.y` build, or a `1.xx.0-beta-…` build from `release-1.xx`, as the user says. If it is not, roll with the `playwright-roll` skill. This is often already done. The roll commit goes into the release commit PR (step 3). When the API roll for 1.xx is already on `main`, that PR only moves `DRIVER_VERSION`. ## 2. Release notes (microsoft/playwright) Write the notes in the roll checkout, on a branch from `origin/main`: ```sh git -C "$PW_SRC_DIR" fetch origin main git -C "$PW_SRC_DIR" checkout -b release-notes-1.xx-python origin/main ``` In `docs/src/release-notes-python.md`, add a `## Version 1.xx` section above the previous version. Translate it from the `## Version 1.xx` section of `docs/src/release-notes-js.md`. Compare the `Version 1.63` sections of the two files to see what a past translation dropped and changed. - Keep the structure: highlights with emoji headings, `### New APIs` with `####` groups, `### Announcements`, `### Browser Versions`. - Remove what Python does not have: the test runner (`@playwright/test`, `test.*`, config, fixtures, projects, reporters), UI mode, the HTML report, component testing, the VS Code extension, and `npx playwright test` options. Remove every API whose `langs` excludes Python. To check an API, look for it in `playwright/async_api/_generated.py`, or check `langs` in `api.json` (see "Verifying classifications" in the `playwright-roll` skill). - Rewrite code samples in Python, with the sync API: `page.get_by_role("button").click()`. Use snake_case names and Python values (`True`, `None`). - Keep API links as docs link macros: `` [`method: Page.frameLocator`] ``, `` [`option: Tracing.start.ariaSnapshots`] ``, `` [`event: Page.dialogClosed`] ``. The docs site shows them with Python names. In plain text, use Python names. - Commands: write `playwright install`, not `npx playwright install`. - Lean towards Python. List the playwright-python commits since the previous release branch: ```sh gh api repos/microsoft/playwright-python/compare/release-1.<xx-1>...main \ --jq '.commits[].commit.message | split("\n")[0]' ``` If some of them change what users see (for example, a different exception type), list them for the user and ask whether to add them to the notes. Commit, push to the user's fork of `microsoft/playwright`, and open the PR. If the checkout has no remote for the fork, add one. `gh api user --jq .login` gives the user's login. ```sh git -C "$PW_SRC_DIR" commit -am "docs: release notes for v1.xx Python" git -C "$PW_SRC_DIR" push <fork-remote> release-notes-1.xx-python gh pr create --repo microsoft/playwright --head <login>:release-notes-1.xx-python \ --title "docs: release notes for v1.xx Python" \ --body "- Add \`Version 1.xx\` to the Python release notes, translated from the Node.js notes" ``` Then put the roll checkout back on the release branch. `./scripts/update_api.sh` reads the docs from it. Run the checkout checks from step 2 of the `playwright-roll` skill. ```sh git -C "$PW_SRC_DIR" checkout release-1.xx ``` ## 3. Release commit (playwright-python) Open a PR from the branch with the roll commit: - Title: `chore: roll Playwright to v1.xx.y`, where `v1.xx.y` is the Python release version, even when `DRIVER_VERSION` is a beta build. - Description: the release notes from step 2, in GitHub markdown (see below). The user copies this description into the GitHub release, so for this PR it replaces the "keep PR descriptions short" rule in `AGENTS.md`. Convert the notes to GitHub markdown yourself: - Leave out the `## Version 1.xx` heading. Move every other heading up one level (`###` becomes `##`, `####` becomes `###`). - Replace each link macro with a full playwright.dev link. Use the Python name as the link text: | Macro | GitHub markdown | |---|---| | `` [`method: Page.frameLocator`] `` | `[page.frame_locator()](https://playwright.dev/python/docs/api/class-page#page-frame-locator)` | | `` [`method: Locator.visible`] `` (a property in Python) | `[locator.visible](https://playwright.dev/python/docs/api/class-locator#locator-visible)` | | `` [`option: Browser.newContext.httpCredentials`] `` | ``[`http_credentials`](https://playwright.dev/python/docs/api/class-browser#browser-new-context-option-http-credentials)`` | | `` [`event: BrowserContext.dialogClosed`] `` | `[browser_context.on("dialogclosed")](https://playwright.dev/python/docs/api/class-browsercontext#browser-context-event-dialog-closed)` | The page is `class-` and the class name in lower case. The anchor is the class and member names in kebab-case. Options add `-option-<name>`, and events add `-event-<name>`. A member is a property in Python if `_generated.py` declares it with `@property`. Wait for the user to review and merge the PR. Do not merge it yourself. ## 4. Release (only when the user tells you to) Cut `release-1.xx` from `main` and push it to `upstream`: ```sh git fetch upstream main git show FETCH_HEAD:DRIVER_VERSION # the release driver git log -1 --oneline FETCH_HEAD # the release commit from step 3 git ls-remote --exit-code upstream refs/heads/release-1.xx # must fail: the branch must not exist yet git push upstream FETCH_HEAD:refs/heads/release-1.xx ``` Save the release notes as a draft release that targets the branch. Take the notes from the merged PR description, so that edits from the review are included: ```sh gh pr view <release-pr> --repo microsoft/playwright-python --json body --jq .body > <notes-file> gh release create v1.xx.0 --repo microsoft/playwright-python --draft \ --target release-1.xx --title v1.xx.0 --notes-file <notes-file> gh release list --repo microsoft/playwright-python --limit 3 # v1.xx.0 shows as Draft ``` Give the user the URL of the draft. Your work ends here. Do not publish the release: never run `gh release create` without `--draft`, and never run `gh release edit --draft=false`. Publishing creates the tag and starts `.github/workflows/publish.yml`, which builds the wheels and uploads them to PyPI after a reviewer approves the `pypi` environment. Never run that workflow, and never approve the environment.
View on GitHub