<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Release note generation skill add support for quoting co-authors <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #xxx <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Result may vary because of uncertainty of LLM, while I can get this result during my tests <img width="696" height="147" alt="image" src="https://github.com/user-attachments/assets/9d20670f-b9fb-4630-b6b4-f94c2a5d2284" />
6.3 KiB
Step 1: Collection and Milestones
1.0 To-do
- 1.0.0 Verify GitHub CLI authentication (REQUIRED)
- 1.0.1 Generate MemberList.md (REQUIRED)
- 1.1 Collect PRs
- 1.2 Assign Milestones (REQUIRED)
Required Variables
⚠️ Before starting, confirm these values with the user:
| Variable | Description | Example |
|---|---|---|
{{ReleaseVersion}} |
Target release version | 0.97 |
{{PreviousReleaseTag}} |
Previous release tag from releases page | v0.96.1 |
If user hasn't specified {{ReleaseVersion}}, ASK: "What release version are we generating notes for? (e.g., 0.97)"
{{PreviousReleaseTag}} is derived from the releases page, not user input. Use the latest published release tag (top of the page). You will use its tag name and tag commit SHA in Step 1.
1.0.0 Verify GitHub CLI Authentication (REQUIRED)
⚠️ BLOCKING: The collection script requires an authenticated gh CLI to fetch PR metadata and co-author information via GitHub's GraphQL API. Without authentication, PR data and NeedThanks attribution will be incomplete.
Check authentication status
gh auth status
If authenticated: You'll see Logged in to github.com account <username>. Proceed to 1.0.1.
If NOT authenticated: Run the login flow before continuing:
# Interactive login (opens browser for OAuth)
gh auth login --hostname github.com --web
# Or use a personal access token
gh auth login --with-token <<< "YOUR_GITHUB_TOKEN"
Required scopes: repo (for reading PR data and assigning milestones)
After login, verify again with gh auth status and confirm exit code 0.
1.0.1 Generate MemberList.md (REQUIRED)
Create Generated Files/ReleaseNotes/MemberList.md from the PowerToys core team section in COMMUNITY.md.
Rules:
- One GitHub username per line, no
@prefix. - Use the usernames exactly as listed in the core team section.
- Do not include former team members or other sections.
Example (format only):
example-user
another-user
1.1 Collect PRs
1.1.1 Get the previous release commit
- Open the PowerToys releases page
- Find the latest release (e.g., v0.96.1, which should be at the top)
- Set
{{PreviousReleaseTag}}to that tag name (e.g.,v0.96.1) - Copy the full tag commit SHA as
{{SHALastRelease}}
If the release SHA is not in your branch history: Use the helper script to find an equivalent commit on the target branch by matching the commit title:
pwsh ./.github/skills/release-note-generation/scripts/find-commit-by-title.ps1 `
-Commit '{{SHALastRelease}}' `
-Branch 'stable'
1.1.2 Run collection script against stable branch
# Collect PRs from previous release to current HEAD of stable branch
pwsh ./.github/skills/release-note-generation/scripts/dump-prs-since-commit.ps1 `
-StartCommit '{{SHALastRelease}}' `
-Branch 'stable' `
-OutputDir 'Generated Files/ReleaseNotes'
Parameters:
-StartCommit- Previous release tag or commit SHA (exclusive)-Branch- Always usestablebranch, notmain(script usesorigin/stableas the end ref)-EndCommit- Optional override if you need a custom end ref-OutputDir- Output directory for generated files
Reliability check: If the script reports “No commits found”, the stable branch has not moved since the last release. In that case, either:
- Confirm this is expected and stop (no new release notes), or
- Re-run against
mainto gather pending changes for the next release cycle.
The script detects both merge commits (Merge pull request #12345) and squash commits (Feature (#12345)).
Output (in Generated Files/ReleaseNotes/):
milestone_prs.json- raw PR datasorted_prs.csv- sorted PR list with columns: Id, Title, Labels, Author, Url, Body, CopilotSummary, NeedThanksAuthor: Comma-separated list of all contributors (PR opener + co-authors from commit trailers)NeedThanks: Comma-separated list of external contributors to thank (excludes core team members from MemberList.md). Empty string means no thanks needed.
1.2 Assign Milestones (REQUIRED)
Before generating release notes, ensure all collected PRs have the correct milestone assigned.
⚠️ CRITICAL: Do NOT proceed to labeling until all PRs have milestones assigned.
1.2.1 Check current milestone status (dry run)
# Dry run first to see what would be changed:
pwsh ./.github/skills/release-note-generation/scripts/collect-or-apply-milestones.ps1 `
-InputCsv 'Generated Files/ReleaseNotes/sorted_prs.csv' `
-OutputCsv 'Generated Files/ReleaseNotes/prs_with_milestone.csv' `
-DefaultMilestone 'PowerToys {{ReleaseVersion}}' `
-ApplyMissing -WhatIf
This queries GitHub for each PR's current milestone and shows which PRs would be updated.
1.2.2 Apply milestones to PRs missing them
# Apply for real:
pwsh ./.github/skills/release-note-generation/scripts/collect-or-apply-milestones.ps1 `
-InputCsv 'Generated Files/ReleaseNotes/sorted_prs.csv' `
-OutputCsv 'Generated Files/ReleaseNotes/prs_with_milestone.csv' `
-DefaultMilestone 'PowerToys {{ReleaseVersion}}' `
-ApplyMissing
Script Behavior:
- Queries each PR's current milestone from GitHub
- PRs that already have a milestone are skipped (not overwritten)
- PRs missing a milestone get the default milestone applied
- Outputs
prs_with_milestone.csvwith (Id, Milestone) columns - Produces summary:
Updated=X Skipped=Y Failed=Z
Validation: After assignment, all PRs in prs_with_milestone.csv should have the target milestone.
Additional Commands
Collect milestones only (no changes to GitHub)
pwsh ./.github/skills/release-note-generation/scripts/collect-or-apply-milestones.ps1 `
-InputCsv 'Generated Files/ReleaseNotes/sorted_prs.csv' `
-OutputCsv 'Generated Files/ReleaseNotes/prs_with_milestone.csv'
Local assignment only (fill blanks in CSV, no GitHub changes)
pwsh ./.github/skills/release-note-generation/scripts/collect-or-apply-milestones.ps1 `
-InputCsv 'Generated Files/ReleaseNotes/sorted_prs.csv' `
-OutputCsv 'Generated Files/ReleaseNotes/prs_with_milestone.csv' `
-DefaultMilestone 'PowerToys {{ReleaseVersion}}' `
-LocalAssign