-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Copilot Skill: Add skill for generate a release-change-log #44577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
vanzue
wants to merge
3
commits into
main
Choose a base branch
from
dev/vanzue/skill-for-release-generation
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+848
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| --- | ||
| name: changelog-generator | ||
| description: Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation. | ||
| --- | ||
|
|
||
| # Changelog Generator | ||
|
|
||
| This skill transforms technical git commits into polished, user-friendly changelogs that your customers and users will actually understand and appreciate. | ||
|
|
||
| ## When to Use This Skill | ||
|
|
||
| - Preparing release notes for a new version | ||
| - Generating changelog between two tags/commits | ||
| - Creating draft release notes from recent commits | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ``` | ||
| Create a changelog from commits since v0.96.1 | ||
| ``` | ||
|
|
||
| ``` | ||
| Create release notes for version 0.97.0 starting from tag v0.96.1 | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Workflow Overview | ||
|
|
||
| ``` | ||
| ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ | ||
| │ 1. Fetch │───▶│ 2. Filter │───▶│ 3. Categorize│───▶│ 4. Generate │ | ||
| │ Commits │ │ & Dedupe │ │ by Module │ │ Descriptions │ | ||
| └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ | ||
| │ │ │ │ | ||
| ▼ ▼ ▼ ▼ | ||
| 📄 github-api 📄 commit- 📄 module- 📄 user-facing- | ||
| reference.md filtering.md mapping.md description.md | ||
| ``` | ||
|
|
||
| ## Sub-Skills Reference | ||
|
|
||
| This skill is composed of the following sub-skills. | ||
|
|
||
| **⚠️ IMPORTANT: Do NOT read all sub-skills at once!** | ||
| - Only read a sub-skill when you reach that step in the workflow | ||
| - This saves context window and improves accuracy | ||
| - Use `read_file` to load a sub-skill only when needed | ||
|
|
||
| | Step | Sub-Skill | When to Read | | ||
| |------|-----------|--------------| | ||
| | Fetch data | [github-api-reference.md](sub-skills/github-api-reference.md) | When fetching commits/PRs | | ||
| | Filter commits | [commit-filtering.md](sub-skills/commit-filtering.md) | When checking if commit should be skipped | | ||
| | Categorize | [module-mapping.md](sub-skills/module-mapping.md) | When determining which module a PR belongs to | | ||
| | Generate text | [user-facing-description.md](sub-skills/user-facing-description.md) | When writing the changelog entry text | | ||
| | Attribution | [contributor-attribution.md](sub-skills/contributor-attribution.md) | When checking if author needs thanks | | ||
| | Large releases | [progress-tracking.md](sub-skills/progress-tracking.md) | Only if processing 50+ commits | | ||
|
|
||
| --- | ||
|
|
||
| ## Step-by-Step Summary | ||
|
|
||
| ### Step 1: Get Commit Range | ||
| ```powershell | ||
| # Count commits between tags | ||
| gh api repos/microsoft/PowerToys/compare/v0.96.0...v0.96.1 --jq '.commits | length' | ||
| ``` | ||
| 👉 Details: [github-api-reference.md](sub-skills/github-api-reference.md) | ||
|
|
||
| ### Step 2: Filter Commits | ||
| - Skip commits already in start tag | ||
| - Skip cherry-picks and backports | ||
| - Deduplicate by PR number | ||
|
|
||
| 👉 Details: [commit-filtering.md](sub-skills/commit-filtering.md) | ||
|
|
||
| ### Step 3: For Each PR, Generate Entry | ||
| 1. Get PR title, body, files, labels | ||
| 2. Determine module from file paths or labels | ||
| 3. Check if user-facing (skip internal changes) | ||
| 4. Transform to user-friendly description | ||
| 5. Add contributor attribution if needed | ||
|
|
||
| 👉 Details: [user-facing-description.md](sub-skills/user-facing-description.md), [module-mapping.md](sub-skills/module-mapping.md), [contributor-attribution.md](sub-skills/contributor-attribution.md) | ||
|
|
||
| ### Step 4: Checkpoint (if 50+ commits) | ||
| - Save progress after every 15-20 commits | ||
| - Track processed PRs for deduplication | ||
| - Enable resume from interruption | ||
|
|
||
| 👉 Details: [progress-tracking.md](sub-skills/progress-tracking.md) | ||
|
|
||
| ### Step 5: Format Output | ||
| ```markdown | ||
| ## ✨ What's new | ||
| **Version X.XX (Month Year)** | ||
|
|
||
| **✨ Highlights** | ||
| - [Most impactful change 1] | ||
| - [Most impactful change 2] | ||
|
|
||
| ### [Module Name - Alphabetical] | ||
| - [Description]. Thanks [@contributor](https://github.com/contributor)! | ||
|
|
||
| ### Development | ||
| - [Internal changes] | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Example Output | ||
|
|
||
| ```markdown | ||
| ## ✨ What's new | ||
| **Version 0.96.1 (December 2025)** | ||
|
|
||
| **✨ Highlights** | ||
| - Advanced Paste now supports multiple AI providers. | ||
| - PowerRename can extract photo metadata for renaming. | ||
|
|
||
| ### Advanced Paste | ||
| - Added support for Azure OpenAI, Google Gemini, Mistral, and more. | ||
|
|
||
| ### Awake | ||
| - The countdown timer now stays accurate over long periods. Thanks [@daverayment](https://github.com/daverayment)! | ||
|
|
||
| ### Development | ||
| - Resolved build warnings in Command Palette projects. | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Tips | ||
|
|
||
| 1. **Propose highlights** after all entries are generated | ||
| 2. **Check PR body** when title is unclear | ||
| 3. **Thank external contributors** - see [contributor-attribution.md](sub-skills/contributor-attribution.md) | ||
| 4. **Use progress tracking** for large releases - see [progress-tracking.md](sub-skills/progress-tracking.md) | ||
| 5. **Save output** to `release-change-note-draft.md` | ||
|
|
||
| --- | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| | Problem | Solution | | ||
| |---------|----------| | ||
| | Lost progress mid-generation | Read `release-notes-progress.md` to resume | | ||
| | Duplicate entries | Check processed PR list, dedupe by PR number | | ||
| | Commit already released | Use `git merge-base --is-ancestor` to verify | | ||
| | API rate limited | Check `gh api rate_limit`, wait or use token | | ||
|
|
||
| 👉 See sub-skills for detailed troubleshooting. |
107 changes: 107 additions & 0 deletions
107
.github/skills/changelog-generator/sub-skills/commit-filtering.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| # Commit Filtering Rules | ||
|
|
||
| This sub-skill defines rules for filtering commits to include in the changelog. | ||
|
|
||
| ## Understanding the Branch Model | ||
|
|
||
| PowerToys uses a release branch model where fixes are cherry-picked from main: | ||
|
|
||
| ``` | ||
| main: A---B---C---D---E---F---G---H (HEAD) | ||
| \ | ||
| release: X---Y---Z (v0.96.1 tag) | ||
| ↑ | ||
| (X, Y are cherry-picks of C, E from main) | ||
| ``` | ||
|
|
||
| **Key insight:** When comparing `v0.96.1...main`: | ||
| - The release tag (v0.96.1) is on a **different branch** than main | ||
| - GitHub compare finds the merge-base and returns commits on main after that point | ||
| - Commits C and E appear in the results even though they were cherry-picked to release as X and Y | ||
| - **The SHAs are different**, so SHA-based filtering won't work! | ||
|
|
||
| ## ⚠️ CRITICAL: Filter by PR Number, Not SHA | ||
|
|
||
| Since cherry-picks have different SHAs, you **MUST** check by PR number: | ||
|
|
||
| ```powershell | ||
| # Extract PR number from commit message and check if it exists in the release tag | ||
| $prNumber = "43785" | ||
| $startTag = "v0.96.1" | ||
|
|
||
| # Search the release branch for this PR number in commit messages | ||
| $cherryPicked = git log $startTag --oneline --grep="#$prNumber" | ||
| if ($cherryPicked) { | ||
| Write-Host "SKIP: PR #$prNumber was cherry-picked to $startTag" | ||
| } else { | ||
| Write-Host "INCLUDE: PR #$prNumber is new since $startTag" | ||
| } | ||
| ``` | ||
|
|
||
| ## Complete Filtering Workflow | ||
|
|
||
| ```powershell | ||
| $startTag = "v0.96.1" # Release tag (on release branch) | ||
| $endRef = "main" # Target (main branch) | ||
|
|
||
| # Step 1: Get all commits from main since the merge-base with release tag | ||
| $commits = gh api "repos/microsoft/PowerToys/compare/$startTag...$endRef" ` | ||
| --jq '.commits[] | {sha: .sha, message: .commit.message}' | ConvertFrom-Json | ||
|
|
||
| # Step 2: Build list of PR numbers already in the release tag | ||
| $releasePRs = git log $startTag --oneline | Select-String -Pattern '#(\d+)' -AllMatches | | ||
| ForEach-Object { $_.Matches.Groups[1].Value } | Sort-Object -Unique | ||
|
|
||
| Write-Host "PRs already in $startTag : $($releasePRs.Count)" | ||
|
|
||
| # Step 3: Filter commits - skip if PR was cherry-picked to release | ||
| $newCommits = @() | ||
| foreach ($commit in $commits) { | ||
| if ($commit.message -match '#(\d+)') { | ||
| $prNumber = $matches[1] | ||
| if ($releasePRs -contains $prNumber) { | ||
| Write-Host "SKIP: PR #$prNumber already in $startTag (cherry-picked)" | ||
| continue | ||
| } | ||
| } | ||
| $newCommits += $commit | ||
| } | ||
|
|
||
| Write-Host "New commits to process: $($newCommits.Count)" | ||
| ``` | ||
|
|
||
| ## Why SHA-Based Methods Don't Work Here | ||
|
|
||
| | Method | Works for same branch? | Works for cross-branch (cherry-picks)? | | ||
| |--------|------------------------|----------------------------------------| | ||
| | `git merge-base --is-ancestor` | ✅ Yes | ❌ No - different SHAs | | ||
| | `git tag --contains` | ✅ Yes | ❌ No - tag is on different branch | | ||
| | GitHub Compare API | ✅ Yes | ❌ No - returns commits by SHA | | ||
| | **PR number matching** | ✅ Yes | ✅ **Yes** | | ||
|
|
||
| ## Skip Rules Summary | ||
|
|
||
| | Priority | Condition | Action | | ||
| |----------|-----------|--------| | ||
| | 1 | PR number found in `git log $startTag --grep="#$prNumber"` | **SKIP** - cherry-picked | | ||
| | 2 | Same PR number already processed in this run | **SKIP** - duplicate | | ||
| | 3 | Bot author (dependabot, etc.) | **SKIP** - unless user-visible | | ||
| | 4 | Internal-only change (CI, tests, refactor) | Move to **Development** section | | ||
|
|
||
| ## User-Facing vs Non-User-Facing | ||
|
|
||
| **Include in changelog:** | ||
| - New features and capabilities | ||
| - Bug fixes that affect users | ||
| - UI/UX improvements | ||
| - Performance improvements users would notice | ||
| - Breaking changes or behavior modifications | ||
| - Security fixes | ||
|
|
||
| **Exclude from changelog (put in Development section):** | ||
| - Internal refactoring | ||
| - CI/CD changes | ||
| - Code style fixes | ||
| - Test additions/modifications | ||
| - Documentation-only changes | ||
| - Dependency updates (unless user-visible impact) |
110 changes: 110 additions & 0 deletions
110
.github/skills/changelog-generator/sub-skills/contributor-attribution.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| # Contributor Attribution Rules | ||
|
|
||
| This sub-skill defines when and how to credit contributors in changelog entries. | ||
|
|
||
| ## Attribution Rules | ||
|
|
||
| - Check [COMMUNITY.md](../../../COMMUNITY.md) for the "PowerToys core team" section | ||
| - If author is **NOT** in core team → Add `Thanks [@username](https://github.com/username)!` | ||
| - If author **IS** in core team → No attribution needed | ||
| - Microsoft employees working on PowerToys as their job → No attribution needed | ||
|
|
||
| ## Core Team Members | ||
|
|
||
| Current core team members (from COMMUNITY.md) - do NOT thank these: | ||
|
|
||
| ``` | ||
| @craigloewen-msft, @niels9001, @dhowett, @yeelam-gordon, @jamrobot, | ||
|
||
| @lei9444, @shuaiyuanxx, @moooyo, @haoliuu, @chenmy77, @chemwolf6922, | ||
|
||
| @yaqingmi, @zhaoqpcn, @urnotdfs, @zhaopy536, @wang563681252, @vanzue, | ||
|
||
| @zadjii-msft, @khmyznikov, @chatasweetie, @MichaelJolley, @Jaylyn-Barbee, | ||
|
||
| @zateutsch, @crutkas | ||
|
||
| ``` | ||
|
|
||
| ## Check Author Script | ||
|
|
||
| ```powershell | ||
| $coreTeam = @( | ||
| 'craigloewen-msft', 'niels9001', 'dhowett', 'yeelam-gordon', 'jamrobot', | ||
|
||
| 'lei9444', 'shuaiyuanxx', 'moooyo', 'haoliuu', 'chenmy77', 'chemwolf6922', | ||
|
||
| 'yaqingmi', 'zhaoqpcn', 'urnotdfs', 'zhaopy536', 'wang563681252', 'vanzue', | ||
|
||
| 'zadjii-msft', 'khmyznikov', 'chatasweetie', 'MichaelJolley', 'Jaylyn-Barbee', | ||
|
||
| 'zateutsch', 'crutkas' | ||
|
||
| ) | ||
|
|
||
| function Get-Attribution { | ||
| param([string]$author) | ||
|
|
||
| if ($coreTeam -contains $author) { | ||
| return $null # No attribution needed | ||
| } | ||
| return "Thanks [@$author](https://github.com/$author)!" | ||
| } | ||
|
|
||
| # Usage | ||
| $author = gh pr view 12345 --repo microsoft/PowerToys --json author --jq '.author.login' | ||
| $attribution = Get-Attribution $author | ||
| if ($attribution) { | ||
| Write-Host "Add: $attribution" | ||
| } else { | ||
| Write-Host "No attribution needed (core team member)" | ||
| } | ||
| ``` | ||
|
|
||
| ## Attribution Format | ||
|
|
||
| **With attribution:** | ||
| ```markdown | ||
| - The Awake countdown timer now stays accurate over long periods. Thanks [@daverayment](https://github.com/daverayment)! | ||
| ``` | ||
|
|
||
| **Without attribution (core team):** | ||
| ```markdown | ||
| - Added new feature to Command Palette for opening settings. | ||
| ``` | ||
|
|
||
| ## Special Cases | ||
|
|
||
| 1. **Co-authored commits**: Credit the primary author (first in list) | ||
| 2. **Bot accounts** (dependabot, etc.): No attribution | ||
| 3. **Former core team members**: Check if they were core team at time of PR | ||
| 4. **Multiple PRs by same external contributor**: Thank them on each entry | ||
|
|
||
| ## High-Impact Community Members | ||
|
|
||
| These contributors have made significant ongoing contributions and are recognized in COMMUNITY.md. | ||
| **ALWAYS thank these contributors** - they are NOT core team and deserve recognition: | ||
|
|
||
| ``` | ||
| @davidegiacometti, @htcfreek, @daverayment, @jiripolasek | ||
|
||
| ``` | ||
|
|
||
| Check COMMUNITY.md for the full up-to-date list under "High impact community members" section. | ||
|
|
||
| ## Updated Check Author Script | ||
|
|
||
| ```powershell | ||
| $coreTeam = @( | ||
| 'craigloewen-msft', 'niels9001', 'dhowett', 'yeelam-gordon', 'jamrobot', | ||
|
||
| 'lei9444', 'shuaiyuanxx', 'moooyo', 'haoliuu', 'chenmy77', 'chemwolf6922', | ||
|
||
| 'yaqingmi', 'zhaoqpcn', 'urnotdfs', 'zhaopy536', 'wang563681252', 'vanzue', | ||
|
||
| 'zadjii-msft', 'khmyznikov', 'chatasweetie', 'MichaelJolley', 'Jaylyn-Barbee', | ||
|
||
| 'zateutsch', 'crutkas' | ||
|
||
| ) | ||
|
|
||
| # High-impact community members - ALWAYS thank these! | ||
| $highImpactCommunity = @( | ||
| 'davidegiacometti', 'htcfreek', 'daverayment', 'jiripolasek' | ||
|
||
| ) | ||
|
|
||
| function Get-Attribution { | ||
| param([string]$author) | ||
|
|
||
| # Core team and bots don't need thanks | ||
| if ($coreTeam -contains $author -or $author -match '\[bot\]$') { | ||
| return $null | ||
| } | ||
| # Everyone else (including high-impact community) gets thanked | ||
| return "Thanks [@$author](https://github.com/$author)!" | ||
| } | ||
| ``` | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.