> Auto-generate release notes from a list of PRs for Azure Functions Python Worker components (worker, runtime v1, or runtime v2). Analyzes PR file changes to determine component relevance, groups by category/prefix, and outputs organized release notes. Use when the user asks to "generate release notes", "create release notes from PRs", "format these PRs for release", or provides a list of PRs to organize.
npx skills add https://github.com/Azure/azure-functions-python-worker --skill generate-release-notes
Auto-generate organized release notes from a list of PRs for Azure Functions Python Worker components.
Accept:
fix:, feat:, build:, etc.)#number)worker - Python Worker componentruntime v1 - Runtime V1 componentruntime v2 - Runtime V2 componentExample input format:
## What's Changed
* fix: fix protobuf import for V2 by @hallvictoria in https://github.com/Azure/azure-functions-python-worker/pull/1736
* feat: allow event loop to be uvloop by @EvanR-Dev in https://github.com/Azure/azure-functions-python-worker/pull/1697
...
For each PR in the list, extract:
#number)Store this information for later use.
For each PR, determine which files were changed:
Using GitHub CLI:
gh pr view <number> --json files | ConvertFrom-Json
This returns the list of changed files in the PR.
For each PR, analyze the changed files and classify based on paths:
| Path Pattern | Component | Rule |
|-------------|-----------|------|
| runtimes/v1/** | runtime v1 | Any file inside runtimes/v1/ directory |
| runtimes/v2/** | runtime v2 | Any file inside runtimes/v2/ directory |
| workers/** | worker | Any file inside workers/ directory |
| Other paths | all | Changes outside these directories affect all components |
Component matching logic:
runtimes/v1/ files changed → runtime v1 onlyruntimes/v2/ files changed → runtime v2 onlyworkers/ files changed → worker onlyWorker-specific exclusions:
Some PRs should ONLY appear in worker releases, even if they change root-level files:
azure-functions package version in workers/pyproject.tomlworkers/pyproject.toml (dependency update)workers/*/version.pyworkers/azure_functions_worker/version.py or similarDetection logic for worker-specific PRs:
If PR title matches "Update Python SDK Version" OR "Update version to":
Check if files changed include:
- workers/pyproject.toml (for SDK updates)
- workers/*/version.py (for worker version updates)
If yes:
- Include in worker release ONLY
- Exclude from runtime v1 and runtime v2 releases
Filter PRs based on the user-specified component:
Parse the PR title prefix to determine the category:
| Prefix | Category | Description |
|--------|----------|-------------|
| feat: | Features | New features or capabilities |
| fix: | Bug Fixes | Bug fixes and corrections |
| build: | Build & Dependencies | Version updates, dependency changes, build configuration |
| refactor: | Refactoring | Code restructuring without behavior changes |
| test: | Tests | Test additions or modifications |
| chore: | Chores | Maintenance tasks, cleanup |
| docs: | Documentation | Documentation updates |
| perf: | Performance | Performance improvements |
| ci: | CI/CD | Continuous integration/deployment changes |
| style: | Style | Code style, formatting |
| revert: | Reverts | Reverting previous changes |
If no recognized prefix is found, use the first word or classify as "Other".
For worker component releases only, read the current versions from workers/pyproject.toml:
Extract the versions of these packages:
azure-functions-runtimeazure-functions-runtime-v1azure-functions (with Python version conditions)Important: The azure-functions SDK has different versions for different Python version ranges. Extract all variants.
Using PowerShell:
$pyprojectContent = Get-Content workers/pyproject.toml -Raw
# Extract runtime versions (single version each)
$runtimeMatch = [regex]::Match($pyprojectContent, 'azure-functions-runtime==([^;"\s]+)')
$runtimeV1Match = [regex]::Match($pyprojectContent, 'azure-functions-runtime-v1==([^;"\s]+)')
# Extract all azure-functions SDK versions with their Python version conditions
$sdkMatches = [regex]::Matches($pyprojectContent, '"azure-functions==([^;"]+);\s*([^"]+)"')
$sdkVersions = @()
foreach ($match in $sdkMatches) {
$version = $match.Groups[1].Value
$condition = $match.Groups[2].Value
$sdkVersions += @{Version=$version; Condition=$condition}
}
Using Python:
import re
with open('workers/pyproject.toml', 'r') as f:
content = f.read()
# Extract runtime versions
runtime = re.search(r'azure-functions-runtime==([^;"\s]+)', content)
runtime_v1 = re.search(r'azure-functions-runtime-v1==([^;"\s]+)', content)
# Extract all azure-functions versions with Python conditions
sdk_pattern = r'"azure-functions==([^;"]+);\s*([^"]+)"'
sdk_matches = re.findall(sdk_pattern, content)
# sdk_matches = [(version, condition), ...]
# Example: [('1.24.0', "python_version < '3.10'"), ('1.25.0b4', "python_version >= '3.10' and python_version < '3.13'")]
Format for output:
Store these versions for inclusion in the output.
Note: Skip this step for runtime v1 and runtime v2 releases.
For worker component releases only, classify each PR by which Python versions it affects:
Python version classification rules:
workers/ directory → General/Build sectionworkers/azure_functions_worker/workers/proxy_worker/workers/ that affect both (e.g., workers/pyproject.toml, workers/README.md)workers/pyproject.toml to determine which Python version range uses this versionazure-functions==2.0.0; python_version >= '3.13', then this PR is Python 3.13+ onlyazure-functions==1.25.0b4; python_version >= '3.10' and python_version < '3.13', then this PR is Python <= 3.12 onlyClassification logic:
for pr in filtered_prs:
files = get_pr_files(pr.number)
# Check if it's a worker version update
if re.match(r'[Uu]pdate\s+version\s+to\s+4\.\d+\.\d+', pr.title):
pr.section = 'worker_version'
continue
# Check if PR touches workers/ directory at all
touches_workers = any(f.startswith('workers/') for f in files)
if not touches_workers:
# General/build changes that don't touch worker code
pr.section = 'general'
continue
# Check if it's an SDK version update
if 'Update Python SDK Version' in pr.title:
version = extract_version_from_title(pr.title)
pyproject = read_pyproject()
python_range = find_python_range_for_sdk_version(pyproject, version)
if '3.13' in python_range and '3.10' not in python_range:
pr.python_versions = ['3.13+']
elif '3.10' in python_range or '3.12' in python_range:
pr.python_versions = ['<=3.12']
else:
pr.python_versions = ['<=3.12', '3.13+']
else:
# Regular file-based classification for worker code
affects_legacy = any(f.startswith('workers/azure_functions_worker/') for f in files)
affects_proxy = any(f.startswith('workers/proxy_worker/') for f in files)
affects_workers_general = any(
f.startswith('workers/') and
not f.startswith('workers/azure_functions_worker/') and
not f.startswith('workers/proxy_worker/')
for f in files
)
if affects_legacy and not affects_proxy and not affects_workers_general:
pr.python_versions = ['<=3.12']
elif affects_proxy and not affects_legacy and not affects_workers_general:
pr.python_versions = ['3.13+']
else:
# Both directories or workers/ general files
pr.python_versions = ['<=3.12', '3.13+']
Notes:
workers/ general files (e.g., workers/pyproject.toml) appear in both Python sectionsworkers/ at all go in the "General" sectionOrganize filtered PRs into categories based on their prefix.
Recommended category order for output:
For Build & Dependencies category only, deduplicate PRs that update the same package multiple times:
Package patterns to check:
Update Python SDK Version to X.Y.Z → package: azure-functionsUpdate Python Runtime Version to X.Y.Z → package: azure-functions-runtimeUpdate version to X.Y.Z (runtime v1) → package: azure-functions-runtime-v1Update azurefunctions-extensions-<name> version to X.Y.Z → package: azurefunctions-extensions-<name>Update <package-name> version to X.Y.Z → package: <package-name>Deduplication logic:
azure-functionsazure-functions-runtimeazure-functions-runtime-v1azurefunctions-extensions-<name>Example:
Input PRs (Build & Dependencies):
- Update Python SDK Version to 1.24.0b4 (#1755)
- Update Python SDK Version to 1.25.0b2 (#1798)
- Update Python SDK Version to 1.25.0b3 (#1822)
- Update azurefunctions-extensions-blob version to 1.1.1 (#1762)
- Update azurefunctions-extensions-blob version to 1.1.2 (#1821)
After deduplication:
- Update Python SDK Version to 1.25.0b3 (#1822) ✓ (highest PR for azure-functions)
- Update azurefunctions-extensions-blob version to 1.1.2 (#1821) ✓ (highest PR for extensions-blob)
Removed:
- #1755, #1798 (older azure-functions updates)
- #1762 (older extensions-blob update)
Implementation approach:
# Pseudocode
package_updates = {}
for pr in build_dependency_prs:
package_name = extract_package_name(pr.title)
if package_name:
if package_name not in package_updates or pr.number > package_updates[package_name].number:
package_updates[package_name] = pr
# Keep only the deduplicated PRs
deduplicated_prs = list(package_updates.values())
Note: Only apply deduplication to PRs that match version update patterns. Keep other build/dependency PRs as-is.
Generate clean, human-readable release notes in Markdown format.
For worker releases:
# Release Notes
## General
### Features
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Bug Fixes
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Build & Dependencies
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
[... other categories ...]
## Worker Version
* <title without prefix> ([#<number>](<link>)) - @<author>
## Python <= 3.12
### Features
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Bug Fixes
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Build & Dependencies
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Refactoring
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Tests
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Chores
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
## Python 3.13+
### Features
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Bug Fixes
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Build & Dependencies
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Refactoring
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Tests
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
### Chores
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
## Runtime and SDK Versions
azure-functions-runtime==<version>
azure-functions-runtime-v1==<version>
azure-functions==<version> (Python < 3.10)
azure-functions==<version> (Python 3.10-3.12)
azure-functions==<version> (Python 3.13+)
For runtime v1/v2 releases:
# Release Notes
## Features
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
## Bug Fixes
* <title without prefix> ([#<number>](<link>)) - @<author>
* ...
[... other categories ...]
Formatting rules:
workers/ directory (optional - only if PRs exist)azure_functions_worker/proxy_worker/fix: → )#number@usernameSave the formatted release notes to a temporary markdown file for easy copying:
File location:
$env:TEMP\release-notes-<component>.md/tmp/release-notes-<component>.mdExample:
release-notes-worker.mdrelease-notes-runtime-v1.mdrelease-notes-runtime-v2.mdUsing PowerShell:
$component = "worker" # or "runtime-v1" or "runtime-v2"
$outputPath = Join-Path $env:TEMP "release-notes-$component.md"
$releaseNotes | Out-File -FilePath $outputPath -Encoding utf8
Write-Host "Release notes saved to: $outputPath"
Using Python:
import tempfile
import os
component = "worker" # or "runtime-v1" or "runtime-v2"
temp_dir = tempfile.gettempdir()
output_path = os.path.join(temp_dir, f"release-notes-{component}.md")
with open(output_path, 'w', encoding='utf-8') as f:
f.write(release_notes)
print(f"Release notes saved to: {output_path}")
After saving:
PR without recognizable prefix:
PR affects multiple components:
Large PR lists (>30 PRs):
Authentication errors:
gh auth statusPR not found:
User provides:
Component: worker
PRs:
* fix: fix protobuf import by @user1 in https://github.com/org/repo/pull/100
* feat: add new feature for proxy worker by @user2 in https://github.com/org/repo/pull/101
* fix: legacy worker bug fix by @user3 in https://github.com/org/repo/pull/105
* build: update version to 4.40.0 by @user4 in https://github.com/org/repo/pull/102
* build: update Python SDK Version to 1.24.0b4 by @user5 in https://github.com/org/repo/pull/103
* build: update Python SDK Version to 1.25.0b2 by @user6 in https://github.com/org/repo/pull/150
* build: update Python SDK Version to 1.25.0b3 by @user7 in https://github.com/org/repo/pull/160
* build: update pyproject for azure-functions 2.x structure by @user8 in https://github.com/org/repo/pull/200
Agent:
setup.cfg (root level, not in workers/) → General sectionworkers/proxy_worker/handler.py → Python 3.13+ onlyworkers/azure_functions_worker/version.py + title matches \"Update version to 4.X.X\" → Worker Version sectionworkers/pyproject.toml (SDK updates) → Check version in pyprojectworkers/azure_functions_worker/dispatcher.py → Python <= 3.12 only.github/workflows/ci.yml (not in workers/) → General sectionproxy_worker/ → Python 3.13+ only\n - PR #102: Title \"Update version to 4.40.0\" → Worker Version section\n - PR #103, #150, #160: SDK updates - check pyproject.toml:\n - If version 1.25.0b3 is for Python 3.10-3.12 → Python <= 3.12 only\n - PR #105: Only azure_functions_worker/ → Python <= 3.12 only\n - PR #200: CI file, not in workers/ → General section\n10. Deduplicates version updates:\n - Package azure-functions: PRs #103, #150, #160\n - Keeps only #160 (highest PR number)\n - Removes #103 and #150\n11. Reads workers/pyproject.toml to extract versions:\n - azure-functions-runtime==1.1.0\n - azure-functions-runtime-v1==1.1.0\n - azure-functions==1.24.0 (Python < 3.10)\n - azure-functions==1.25.0b4 (Python 3.10-3.12)\n - azure-functions==2.0.0 (Python 3.13+)\n12. Groups by section and category, then outputs:\n\nmarkdown\n# Release Notes\n\n## General\n\n### Bug Fixes\n* Fix protobuf import (#100) - @user1\n\n### Build & Dependencies\n* Update pyproject for azure-functions 2.x structure (#200) - @user8\n\n## Worker Version\n* Update version to 4.40.0 (#102) - @user4\n\n## Python <= 3.12\n\n### Bug Fixes\n* Legacy worker bug fix (#105) - @user3\n\n### Build & Dependencies\n* Update Python SDK Version to 1.25.0b3 (#160) - @user7\n\n## Python 3.13+\n\n### Features\n* Add new feature for proxy worker (#101) - @user2\n\n## Runtime and SDK Versions\nazure-functions-runtime==1.1.0\nazure-functions-runtime-v1==1.1.0\nazure-functions==1.24.0 (Python < 3.10)\nazure-functions==1.25.0b4 (Python 3.10-3.12)\nazure-functions==2.0.0 (Python 3.13+)\n\n\nNote: \n- PR #100 and #200 in General section (don't touch workers/ directory)\n- PR #102 in Worker Version section (matches \"Update version to 4.X.X\")\n- PR #105 only in Python <= 3.12 (only affects azure_functions_worker/)\n- PR #101 only in Python 3.13+ (only affects proxy_worker/)\n- PR #160 only in Python <= 3.12 (SDK version 1.25.0b3 is for Python 3.10-3.12)\n- PRs #103 and #150 were excluded due to deduplication\n- Runtime and SDK Versions section is at the ENDUser provides:
Component: runtime v2
PRs:
* fix: fix protobuf import by @user1 in https://github.com/org/repo/pull/100
* feat: add new feature by @user2 in https://github.com/org/repo/pull/101
* build: update version to 1.0.0b1 by @user3 in https://github.com/org/repo/pull/110
* build: update version to 1.0.0b2 by @user4 in https://github.com/org/repo/pull/120
* build: update version to 1.1.0b1 by @user5 in https://github.com/org/repo/pull/130
* build: update azurefunctions-extensions-blob version to 1.1.1 by @user6 in https://github.com/org/repo/pull/140
* build: update azurefunctions-extensions-blob version to 1.1.2 by @user7 in https://github.com/org/repo/pull/145
* build: update Python SDK Version to 1.24.0 by @user8 in https://github.com/org/repo/pull/150
Agent:
setup.cfg (root level) → all components ✓runtimes/v2/handler.py → runtime v2 ✓runtimes/v2/version.py → runtime v2 ✓runtimes/v2/pyproject.toml (extensions-blob) → runtime v2 ✓workers/pyproject.toml (azure-functions) → worker-specific only ✗ (exclude)azure-functions-runtime-v2: PRs #110, #120, #130 → Keeps only #130azurefunctions-extensions-blob: PRs #140, #145 → Keeps only #145# Release Notes
## Features
* Add new feature ([#101](link)) - @user2
## Bug Fixes
* Fix protobuf import ([#100](link)) - @user1
## Build & Dependencies
* Update version to 1.1.0b1 ([#130](link)) - @user5
* Update azurefunctions-extensions-blob version to 1.1.2 ([#145](link)) - @user7
Notes:
azure-functions-runtime-v2 updates)azurefunctions-extensions-blob update)azure-functions SDK update)gh auth login)worker, runtime v1, or runtime v2)$env:TEMP\release-notes-<component>.md (Windows) or /tmp/release-notes-<component>.md (Linux/Mac)Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
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.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling
Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification
Take azure/generate-release-notes from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.