From 93e367039d288bd138e2bc5c84984c115d2c1fc5 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Tue, 20 Oct 2026 14:05:08 -0700 Subject: [PATCH 1/3] chore: describe porting release notes to Java in playwright-java-release skill --- .../skills/playwright-java-release/SKILL.md | 108 ++++++++++++++++-- 1 file changed, 97 insertions(+), 11 deletions(-) diff --git a/.claude/skills/playwright-java-release/SKILL.md b/.claude/skills/playwright-java-release/SKILL.md index 93b6450fb..d4a0082e3 100644 --- a/.claude/skills/playwright-java-release/SKILL.md +++ b/.claude/skills/playwright-java-release/SKILL.md @@ -1,6 +1,6 @@ --- name: playwright-java-release -description: Prepare a Playwright Java release after the rolling PR has merged — cut the release branch, mark the Maven version, draft the GitHub release, and tick the Java boxes in the internal checklist. +description: Prepare a Playwright Java release after the rolling PR has merged — cut the release branch, mark the Maven version, port the Node.js release notes to Java, draft the GitHub release, and tick the Java boxes in the internal checklist. --- Use this skill once the `chore: roll driver to 1.X.0` PR has merged into `main` and the upstream JS `v1.X.0` is published. The rolling work itself is covered by the [[playwright-roll]] skill. @@ -31,23 +31,109 @@ git fetch upstream main git push upstream upstream/main:refs/heads/release-1.X ``` -## 2. Draft the GitHub release +## 2. Release notes -Generate the release notes from the upstream docs: +There are two pieces of text, both written by hand: +- the `## Version 1.X` section of `docs/src/release-notes-java.md` in the upstream `playwright` repo. playwright.dev renders it. +- the body of the GitHub release, which is written from that section. + +### 2a. Port the Node.js notes to `docs/src/release-notes-java.md` + +Check whether the section is already upstream: ```bash -cd ~/playwright -node utils/render_release_notes.mjs java 1.X > /tmp/v1.X.0-release-notes.md +cd ~/playwright && git fetch upstream main release-1.X +git show upstream/release-1.X:docs/src/release-notes-java.md | grep -n '^## Version 1.X$' ``` -The renderer leaves JS-isms that need fixing for Java. Apply these substitutions — the list is not exhaustive, eyeball the diff before publishing: +If it's missing, write it by porting the `## Version 1.X` section of `docs/src/release-notes-js.md`. Do the work in a worktree off `upstream/main` so the local checkout stays untouched. If someone else already wrote it, still review it against the rules below. For example, the 1.63 Java notes went out saying "accepts an array of credentials". + +Go through the JS section top to bottom and decide what to do with each item: + +- **Keep** library features (Page, Frame, Locator, BrowserContext, APIRequestContext, Tracing, Screencast, assertions, …). Also keep breaking changes that affect the library, announcements about OS support and browser builds, and the Browser Versions list as is. +- **Drop** whatever exists only in the Node.js test runner or JS tooling: + - `@playwright/test`, `playwright.config.ts`, and `npx playwright test` flags + - `TestOptions`, `TestConfig`, `TestProject`, `FullConfig`, `TestStep` and `Fixtures` + - reporters, the HTML report and UI mode + - component testing + - TypeScript-only features (generics, JSX, `tsconfig`) + - `devices` descriptors and npm packages +- **Check `langs:`** of every linked member in `docs/src/api/` (`grep -n -A4 'method: Page.foo$' docs/src/api/class-page.md`). A member whose `langs:` doesn't include `java` doesn't exist in Java, so drop the item or reword it around the Java API. +- **Describe the Java shape** when the Java API differs from the JS one, using the names in the generated interfaces of this repo (`playwright/src/main/java/com/microsoft/playwright/`): + - 1.63: the JS `trace.snapshots: { aria, screen }` object became the `ariaSnapshots` and `screenSnapshots` options of `Tracing.start`. + - 1.64: the JS `recordVideo.fps` became the `recordVideoFps` option. +- **Replace config examples.** When a JS example shows a library feature through `playwright.config.ts`, show the equivalent API call instead. In 1.64, the video config became `page.screencast().start(...)` plus `showActions(...)`. +- **Add Java-only highlights**, such as 1.63's JSpecify nullability annotations. List the user-visible changes in this repo since the previous release branch was cut: + ```bash + git log --oneline --no-merges $(git merge-base upstream/release-1. upstream/main)..upstream/main | grep -E '^\w+ (feat|fix)' + ``` + +Write code samples and prose in Java style: + +| Node.js | Java | +|---|---| +| `await page.goto('...')` | `page.navigate("...");`: no `await`, double quotes, semicolons, typed locals (`Locator dialog = ...`) | +| `page.getByRole('button', { name: 'Save' })` | `page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Save"))` | +| options object `{ path: 'video.webm', fps: 60 }` | options builder `new Screencast.StartOptions().setPath(Paths.get("video.webm")).setFps(60)` | +| object literal `{ name: 'session-id', value: '42', url }` | value class `new Cookie("session-id", "42").setUrl(url)` | +| `['a', 'b']`, `{ a: 2 }` | `Arrays.asList("a", "b")`, `Map.of("a", 2)`; `new String[] {"a", "b"}` for assertion arguments | +| property `page.webmcp`, `context.tracing` | getter `page.webmcp()`, `context.tracing()` | +| event `page.on('dialogclosed', handler)` | `page.onDialogClosed(handler)` | +| `expect(locator).toHaveText(...)` | `assertThat(locator).hasText(...)`. Likewise `toBeX` → `isX`, `toHaveX` → `hasX`, `toContainX` → `containsX`, `toMatchX` → `matchesX` | +| `route.continue()` and other members with `alias-java:` | the alias, e.g. `route.resume()` (`grep -rn 'alias-java' docs/src/api/`) | +| `npx playwright install --no-remove` | `mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --no-remove"` | +| "array", `undefined`, `'ai'` in prose | "list", `null`, `"ai"` | + +In the markdown, keep API references as links in the docs format (``[`method: Locator.within`]``, ``[`property: Page.webmcp`]``, ``[`option: Browser.newContext.recordVideoFps`]``, `[Locator]`) instead of writing out names. playwright.dev renders them with the Java names. Use ```` ```java ```` code fences. Every API a sample uses must exist in the generated Java interfaces, so grep for each method and option setter. + +Send the change as an upstream PR titled `docs: release notes for v1.X Java`. The upstream `infra` workflow checks the syntax of `java` snippets, so make sure it passes. Once the PR merges, ask the user to get it cherry-picked to `release-1.X`: upstream maintainers push `cherry-pick(#NNNN): ...` commits straight to the release branch. Then tick the Java "write release notes" box and set its PR link. + +### 2b. Write the GitHub release body + +Write `/tmp/v1.X.0-release-notes.md` by hand from the `## Version 1.X` section of `upstream/release-1.X:docs/src/release-notes-java.md`: + +- Drop the `## Version 1.X` heading and move every other heading up one level (`###` → `##`, `####` → `###`). +- Replace each docs-format link with a playwright.dev link whose text is the Java name from the table above: + +| Markdown | GitHub release | +|---|---| +| `[Locator]` | `[Locator](https://playwright.dev/java/docs/api/class-locator)` | +| ``[`method: Locator.within`]`` | `[locator.within()](https://playwright.dev/java/docs/api/class-locator#locator-within)` | +| ``[`property: Page.webmcp`]`` | `[page.webmcp()](https://playwright.dev/java/docs/api/class-page#page-webmcp)` | +| ``[`event: Page.dialogClosed`]`` | `[page.onDialogClosed()](https://playwright.dev/java/docs/api/class-page#page-event-dialog-closed)` | +| ``[`method: LocatorAssertions.toBeVisible`]`` | `[assertThat(locator).isVisible()](https://playwright.dev/java/docs/api/class-locatorassertions#locator-assertions-to-be-visible)` | +| ``[`option: Screencast.start.fps`]`` | ``[`fps`](https://playwright.dev/java/docs/api/class-screencast#screencast-start-option-fps)`` | +| `[Playwright MCP](./getting-started-mcp.md)` | `[Playwright MCP](https://playwright.dev/java/docs/getting-started-mcp)` | +| `![alt](./images/foo.png)` | `![alt](https://github.com/microsoft/playwright/blob/main/docs/src/images/foo.png?raw=true)` | + +How to build the links: +- **Link text:** start with the class name in lower camel case (`page`, `browserContext`, `apiRequestContext`). Methods and properties get `()` with no arguments, events become `on()`, and assertions start with `assertThat(locator).`, `assertThat(page).` or `assertThat(response).`. +- **Page path:** `class-`. +- **Anchor:** built from the names in the docs, not the Java names: `-`. Insert `-event-` for events and append `-option-` for options. kebab-case splits at every case change, so `APIRequestContext.addCookies` → `class-apirequestcontext#api-request-context-add-cookies`. + +Then check that every link resolves. The GitHub draft is written after the JS release, so playwright.dev already documents the new APIs. playwright.dev serves minified HTML, so the anchor may appear without quotes (`id=page-webmcp>`): + +```bash +grep -oE 'https://playwright\.dev/[^) ]+' /tmp/v1.X.0-release-notes.md | sort -u | while read -r url; do + page=${url%%#*} + html=$(curl -sfL "$page") || { echo "MISSING PAGE $url"; continue; } + if [[ "$url" == *"#"* ]]; then + anchor=${url#*#} + grep -qE "id=\"?${anchor}[\" >]" <<<"$html" || echo "MISSING ANCHOR $url" + fi +done +``` + +Scan for anything that wasn't converted. Both commands should print nothing: + +```bash +grep -nE '\[`(method|property|event|option|param): |\]\(\./|\[[A-Z][A-Za-z]*\]([^(]|$)' /tmp/v1.X.0-release-notes.md +grep -nE "\.on\('|\b(toBe|toHave|toContain|toMatch)[A-Z]|\bawait\b|\barray\b|\bundefined\b|\[[a-z][A-Za-z]*\.[a-z][A-Za-z]*\]\(" /tmp/v1.X.0-release-notes.md +``` -- `toMatchAriaSnapshot()` → `matchesAriaSnapshot()` -- `toHaveCSS()` → `hasCSS()` (and other `toHaveX` matchers → `hasX`) -- `browser.on('context')` → `browser.onContext()` -- `browserContext.on('download' | 'frameattached' | ...)` → `browserContext.onDownload()` / `onFrameAttached()` / … +If the body exposes a problem in the markdown itself, such as a JS-only feature or a JS-style sample, fix it upstream as well (2a). Otherwise playwright.dev keeps the problem. -Create the draft directly against `release-1.X` — drafting against `main` and retargeting later is fragile because every `gh release edit` rotates the `untagged-` ID: +Create the draft directly against `release-1.X`. Drafting against `main` and retargeting later is fragile, because every `gh release edit` rotates the `untagged-` ID: ```bash gh release create v1.X.0 --repo microsoft/playwright-java --draft \ From c032571e091a764f34a8415dd4f295ea78104b1b Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Tue, 20 Oct 2026 14:22:55 -0700 Subject: [PATCH 2/3] chore: rely on upstream release notes in playwright-java-release skill --- .../skills/playwright-java-release/SKILL.md | 101 +++--------------- 1 file changed, 13 insertions(+), 88 deletions(-) diff --git a/.claude/skills/playwright-java-release/SKILL.md b/.claude/skills/playwright-java-release/SKILL.md index d4a0082e3..865238cf1 100644 --- a/.claude/skills/playwright-java-release/SKILL.md +++ b/.claude/skills/playwright-java-release/SKILL.md @@ -1,6 +1,6 @@ --- name: playwright-java-release -description: Prepare a Playwright Java release after the rolling PR has merged — cut the release branch, mark the Maven version, port the Node.js release notes to Java, draft the GitHub release, and tick the Java boxes in the internal checklist. +description: Prepare a Playwright Java release after the rolling PR has merged — cut the release branch, mark the Maven version, add Java-specific changes to the release notes, draft the GitHub release, and tick the Java boxes in the internal checklist. --- Use this skill once the `chore: roll driver to 1.X.0` PR has merged into `main` and the upstream JS `v1.X.0` is published. The rolling work itself is covered by the [[playwright-roll]] skill. @@ -33,105 +33,30 @@ git push upstream upstream/main:refs/heads/release-1.X ## 2. Release notes -There are two pieces of text, both written by hand: -- the `## Version 1.X` section of `docs/src/release-notes-java.md` in the upstream `playwright` repo. playwright.dev renders it. -- the body of the GitHub release, which is written from that section. - -### 2a. Port the Node.js notes to `docs/src/release-notes-java.md` - -Check whether the section is already upstream: +The Java notes in `docs/src/release-notes-java.md` are written upstream, together with the Node.js notes. The `playwright-release-notes` skill in `../playwright/.claude/skills/playwright-release-notes/SKILL.md` covers that, including the Java code style. Check that the `## Version 1.X` section is on the release branch: ```bash -cd ~/playwright && git fetch upstream main release-1.X -git show upstream/release-1.X:docs/src/release-notes-java.md | grep -n '^## Version 1.X$' +git -C ../playwright fetch upstream release-1.X +git -C ../playwright show upstream/release-1.X:docs/src/release-notes-java.md | grep -n '^## Version 1.X$' ``` -If it's missing, write it by porting the `## Version 1.X` section of `docs/src/release-notes-js.md`. Do the work in a worktree off `upstream/main` so the local checkout stays untouched. If someone else already wrote it, still review it against the rules below. For example, the 1.63 Java notes went out saying "accepts an array of credentials". - -Go through the JS section top to bottom and decide what to do with each item: - -- **Keep** library features (Page, Frame, Locator, BrowserContext, APIRequestContext, Tracing, Screencast, assertions, …). Also keep breaking changes that affect the library, announcements about OS support and browser builds, and the Browser Versions list as is. -- **Drop** whatever exists only in the Node.js test runner or JS tooling: - - `@playwright/test`, `playwright.config.ts`, and `npx playwright test` flags - - `TestOptions`, `TestConfig`, `TestProject`, `FullConfig`, `TestStep` and `Fixtures` - - reporters, the HTML report and UI mode - - component testing - - TypeScript-only features (generics, JSX, `tsconfig`) - - `devices` descriptors and npm packages -- **Check `langs:`** of every linked member in `docs/src/api/` (`grep -n -A4 'method: Page.foo$' docs/src/api/class-page.md`). A member whose `langs:` doesn't include `java` doesn't exist in Java, so drop the item or reword it around the Java API. -- **Describe the Java shape** when the Java API differs from the JS one, using the names in the generated interfaces of this repo (`playwright/src/main/java/com/microsoft/playwright/`): - - 1.63: the JS `trace.snapshots: { aria, screen }` object became the `ariaSnapshots` and `screenSnapshots` options of `Tracing.start`. - - 1.64: the JS `recordVideo.fps` became the `recordVideoFps` option. -- **Replace config examples.** When a JS example shows a library feature through `playwright.config.ts`, show the equivalent API call instead. In 1.64, the video config became `page.screencast().start(...)` plus `showActions(...)`. -- **Add Java-only highlights**, such as 1.63's JSpecify nullability annotations. List the user-visible changes in this repo since the previous release branch was cut: - ```bash - git log --oneline --no-merges $(git merge-base upstream/release-1. upstream/main)..upstream/main | grep -E '^\w+ (feat|fix)' - ``` - -Write code samples and prose in Java style: - -| Node.js | Java | -|---|---| -| `await page.goto('...')` | `page.navigate("...");`: no `await`, double quotes, semicolons, typed locals (`Locator dialog = ...`) | -| `page.getByRole('button', { name: 'Save' })` | `page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Save"))` | -| options object `{ path: 'video.webm', fps: 60 }` | options builder `new Screencast.StartOptions().setPath(Paths.get("video.webm")).setFps(60)` | -| object literal `{ name: 'session-id', value: '42', url }` | value class `new Cookie("session-id", "42").setUrl(url)` | -| `['a', 'b']`, `{ a: 2 }` | `Arrays.asList("a", "b")`, `Map.of("a", 2)`; `new String[] {"a", "b"}` for assertion arguments | -| property `page.webmcp`, `context.tracing` | getter `page.webmcp()`, `context.tracing()` | -| event `page.on('dialogclosed', handler)` | `page.onDialogClosed(handler)` | -| `expect(locator).toHaveText(...)` | `assertThat(locator).hasText(...)`. Likewise `toBeX` → `isX`, `toHaveX` → `hasX`, `toContainX` → `containsX`, `toMatchX` → `matchesX` | -| `route.continue()` and other members with `alias-java:` | the alias, e.g. `route.resume()` (`grep -rn 'alias-java' docs/src/api/`) | -| `npx playwright install --no-remove` | `mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --no-remove"` | -| "array", `undefined`, `'ai'` in prose | "list", `null`, `"ai"` | - -In the markdown, keep API references as links in the docs format (``[`method: Locator.within`]``, ``[`property: Page.webmcp`]``, ``[`option: Browser.newContext.recordVideoFps`]``, `[Locator]`) instead of writing out names. playwright.dev renders them with the Java names. Use ```` ```java ```` code fences. Every API a sample uses must exist in the generated Java interfaces, so grep for each method and option setter. - -Send the change as an upstream PR titled `docs: release notes for v1.X Java`. The upstream `infra` workflow checks the syntax of `java` snippets, so make sure it passes. Once the PR merges, ask the user to get it cherry-picked to `release-1.X`: upstream maintainers push `cherry-pick(#NNNN): ...` commits straight to the release branch. Then tick the Java "write release notes" box and set its PR link. - -### 2b. Write the GitHub release body - -Write `/tmp/v1.X.0-release-notes.md` by hand from the `## Version 1.X` section of `upstream/release-1.X:docs/src/release-notes-java.md`: - -- Drop the `## Version 1.X` heading and move every other heading up one level (`###` → `##`, `####` → `###`). -- Replace each docs-format link with a playwright.dev link whose text is the Java name from the table above: +If it's missing, tell the user: it should have landed with the Node.js notes. -| Markdown | GitHub release | -|---|---| -| `[Locator]` | `[Locator](https://playwright.dev/java/docs/api/class-locator)` | -| ``[`method: Locator.within`]`` | `[locator.within()](https://playwright.dev/java/docs/api/class-locator#locator-within)` | -| ``[`property: Page.webmcp`]`` | `[page.webmcp()](https://playwright.dev/java/docs/api/class-page#page-webmcp)` | -| ``[`event: Page.dialogClosed`]`` | `[page.onDialogClosed()](https://playwright.dev/java/docs/api/class-page#page-event-dialog-closed)` | -| ``[`method: LocatorAssertions.toBeVisible`]`` | `[assertThat(locator).isVisible()](https://playwright.dev/java/docs/api/class-locatorassertions#locator-assertions-to-be-visible)` | -| ``[`option: Screencast.start.fps`]`` | ``[`fps`](https://playwright.dev/java/docs/api/class-screencast#screencast-start-option-fps)`` | -| `[Playwright MCP](./getting-started-mcp.md)` | `[Playwright MCP](https://playwright.dev/java/docs/getting-started-mcp)` | -| `![alt](./images/foo.png)` | `![alt](https://github.com/microsoft/playwright/blob/main/docs/src/images/foo.png?raw=true)` | +### 2a. Add Java-specific changes -How to build the links: -- **Link text:** start with the class name in lower camel case (`page`, `browserContext`, `apiRequestContext`). Methods and properties get `()` with no arguments, events become `on()`, and assertions start with `assertThat(locator).`, `assertThat(page).` or `assertThat(response).`. -- **Page path:** `class-`. -- **Anchor:** built from the names in the docs, not the Java names: `-`. Insert `-event-` for events and append `-option-` for options. kebab-case splits at every case change, so `APIRequestContext.addCookies` → `class-apirequestcontext#api-request-context-add-cookies`. - -Then check that every link resolves. The GitHub draft is written after the JS release, so playwright.dev already documents the new APIs. playwright.dev serves minified HTML, so the anchor may appear without quotes (`id=page-webmcp>`): +List the user-visible changes in this repo since the previous release branch was cut: ```bash -grep -oE 'https://playwright\.dev/[^) ]+' /tmp/v1.X.0-release-notes.md | sort -u | while read -r url; do - page=${url%%#*} - html=$(curl -sfL "$page") || { echo "MISSING PAGE $url"; continue; } - if [[ "$url" == *"#"* ]]; then - anchor=${url#*#} - grep -qE "id=\"?${anchor}[\" >]" <<<"$html" || echo "MISSING ANCHOR $url" - fi -done +git log --oneline --no-merges $(git merge-base upstream/release-1. upstream/main)..upstream/main | grep -E '^\w+ (feat|fix)' ``` -Scan for anything that wasn't converted. Both commands should print nothing: +Pick only significant changes that the Java port alone has, such as a new JUnit fixture or option, a Java-only API, or changed Java requirements. Leave out minor bug fixes, internal changes and anything the notes already cover. If nothing is significant, leave the notes as they are and move on. -```bash -grep -nE '\[`(method|property|event|option|param): |\]\(\./|\[[A-Z][A-Za-z]*\]([^(]|$)' /tmp/v1.X.0-release-notes.md -grep -nE "\.on\('|\b(toBe|toHave|toContain|toMatch)[A-Z]|\bawait\b|\barray\b|\bundefined\b|\[[a-z][A-Za-z]*\.[a-z][A-Za-z]*\]\(" /tmp/v1.X.0-release-notes.md -``` +List the candidates for the user and ask which to add. Add them to the section in the style of the existing notes. Then send an upstream PR titled `docs: release notes for v1.X Java`. Once it merges, it needs a cherry-pick to `release-1.X` (the upstream `playwright-cherry-pick` skill). Tick the Java "write release notes" box with the PR link, or with the PR that added the section when there was nothing to add. + +### 2b. Write the GitHub release body -If the body exposes a problem in the markdown itself, such as a JS-only feature or a JS-style sample, fix it upstream as well (2a). Otherwise playwright.dev keeps the problem. +Convert the `## Version 1.X` section of `upstream/release-1.X:docs/src/release-notes-java.md` to GitHub markdown with Java link text, and save it as `/tmp/v1.X.0-release-notes.md`. Follow step 3 of the upstream `playwright-release-notes` skill, including its link check and the Java scan. If the conversion shows a problem in the notes themselves, fix them upstream as well. Create the draft directly against `release-1.X`. Drafting against `main` and retargeting later is fragile, because every `gh release edit` rotates the `untagged-` ID: From 9da506dfb22c4ea41fe719ff020858369fd4e71b Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Tue, 20 Oct 2026 14:29:54 -0700 Subject: [PATCH 3/3] chore: reference upstream release notes skill in playwright-java-release skill --- .../skills/playwright-java-release/SKILL.md | 23 +++---------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/.claude/skills/playwright-java-release/SKILL.md b/.claude/skills/playwright-java-release/SKILL.md index 865238cf1..d5a02d16c 100644 --- a/.claude/skills/playwright-java-release/SKILL.md +++ b/.claude/skills/playwright-java-release/SKILL.md @@ -33,32 +33,15 @@ git push upstream upstream/main:refs/heads/release-1.X ## 2. Release notes -The Java notes in `docs/src/release-notes-java.md` are written upstream, together with the Node.js notes. The `playwright-release-notes` skill in `../playwright/.claude/skills/playwright-release-notes/SKILL.md` covers that, including the Java code style. Check that the `## Version 1.X` section is on the release branch: - -```bash -git -C ../playwright fetch upstream release-1.X -git -C ../playwright show upstream/release-1.X:docs/src/release-notes-java.md | grep -n '^## Version 1.X$' -``` - -If it's missing, tell the user: it should have landed with the Node.js notes. - -### 2a. Add Java-specific changes - -List the user-visible changes in this repo since the previous release branch was cut: +The Java notes in `docs/src/release-notes-java.md` are written upstream together with the Node.js notes, following the `playwright-release-notes` skill (`../playwright/.claude/skills/playwright-release-notes/SKILL.md`). Assume the `## Version 1.X` section is already on `release-1.X`, and only add what's missing: significant changes that only the Java port has, such as a new JUnit fixture or a Java-only API. Leave out minor bug fixes. To find candidates, list this repo's changes since the previous release branch was cut: ```bash git log --oneline --no-merges $(git merge-base upstream/release-1. upstream/main)..upstream/main | grep -E '^\w+ (feat|fix)' ``` -Pick only significant changes that the Java port alone has, such as a new JUnit fixture or option, a Java-only API, or changed Java requirements. Leave out minor bug fixes, internal changes and anything the notes already cover. If nothing is significant, leave the notes as they are and move on. - -List the candidates for the user and ask which to add. Add them to the section in the style of the existing notes. Then send an upstream PR titled `docs: release notes for v1.X Java`. Once it merges, it needs a cherry-pick to `release-1.X` (the upstream `playwright-cherry-pick` skill). Tick the Java "write release notes" box with the PR link, or with the PR that added the section when there was nothing to add. - -### 2b. Write the GitHub release body - -Convert the `## Version 1.X` section of `upstream/release-1.X:docs/src/release-notes-java.md` to GitHub markdown with Java link text, and save it as `/tmp/v1.X.0-release-notes.md`. Follow step 3 of the upstream `playwright-release-notes` skill, including its link check and the Java scan. If the conversion shows a problem in the notes themselves, fix them upstream as well. +Ask the user before adding anything. Send additions upstream as `docs: release notes for v1.X Java`, and cherry-pick them to `release-1.X`. -Create the draft directly against `release-1.X`. Drafting against `main` and retargeting later is fragile, because every `gh release edit` rotates the `untagged-` ID: +Write the GitHub release body from the section as step 3 of the upstream skill describes, and save it as `/tmp/v1.X.0-release-notes.md`. Create the draft directly against `release-1.X`. Drafting against `main` and retargeting later is fragile, because every `gh release edit` rotates the `untagged-` ID: ```bash gh release create v1.X.0 --repo microsoft/playwright-java --draft \