Generate Release Notes
This skill describes how to generate release notes for a stable release of the C# VS Code extension.
Background
Versioning Scheme
The extension uses a tiered versioning scheme: 2.<minor>.x.
- Release versions have a minor version ending in
0(e.g.,2.120.x,2.130.x). - Prerelease versions have a minor version that does not end in
0(e.g.,2.121.x,2.122.x, ...,2.129.x). - When a new stable release is created, the minor version increments to the next ten (e.g.,
2.120→2.130).
So for a release at version 2.130, the prerelease entries are 2.121.x through 2.129.x. For 2.140, they are 2.131.x through 2.139.x.
Branch Structure
main— Active development.prerelease— Published prerelease builds; CHANGELOG here is the canonical source for prerelease entries.release— Published stable builds.
Always use the CHANGELOG from the prerelease branch as the source of truth for changes since the last release.
Input Required
- Target release version (optional): The stable version being released (e.g.,
2.130). If not provided, determine it from the currentversion.jsononprereleaseby rounding up the minor version to the next ten.
Process
Step 1: Determine the version range
- Identify the target release version. If not given, read
version.jsononprereleaseto get the current minor version, and round up to the next ten (e.g., if current is2.131, the next release is2.140). - Calculate the previous release version by subtracting 10 from the target minor (e.g., target
2.140→ previous2.130). - The prerelease sections to gather are all minor versions after the previous release and before the target release. For example, for target
2.140: sections2.131.x,2.132.x, ...,2.139.x.
Step 2: Fetch the CHANGELOG from the prerelease branch
The prerelease entries are in the prerelease branch. The prerelease branch is the canonical source.
Fetch the prerelease branch and retrieve its CHANGELOG:
git fetch origin prerelease
git show origin/prerelease:CHANGELOG.md
Extract sections for the prerelease versions identified in Step 1.
Step 3: Follow PR and issue links to gather details
For each entry in the extracted CHANGELOG sections:
- Follow the PR link (e.g.,
https://github.com/dotnet/vscode-csharp/pull/8954) to read the PR description for additional context about the change. - If the PR has a linked issue, follow that link too to understand the user-facing problem being solved.
This additional context is critical for writing meaningful, user-facing release notes rather than just echoing commit messages.
Step 4: Generate the release notes
Write a markdown document in the style of VS Code release notes (see https://code.visualstudio.com/updates/v1_106 for an example of the format and tone).
Content rules
Apply these rules strictly when deciding what to include and how to organize it:
- Do not mention version bumps directly — instead, describe the improvements and fixes they bring.
- PRs from
dotnet/razorshould only appear under a Razor section. xamlToolsfixes should only appear under a MAUI section.- Do not mention documentation-only changes.
- Do not mention infrastructure-only changes (CI/CD, pipeline, packaging).
- Do not mention unit test or integration test changes.
- Do not mention the specific prerelease version a change was made in.
- Do not mention these instructions in the output document.
Organizing sections
Group changes into logical sections. The sections below are listed in the required order — always present them in this order (use only those that have relevant entries):
- C# Language Support — General C# language features, completions, diagnostics, refactorings, code fixes, etc. Changes from
dotnet/roslynthat are not Razor-specific go here. - Performance — Notable performance improvements from any component.
- Razor — All changes from
dotnet/razorPRs and Razor-related features. - Debugging — Debugger improvements and fixes.
- MAUI — Changes related to
xamlToolsor MAUI features. - Editor Experience — UX improvements in the extension itself (project context, settings, commands, etc.).
Within each section, lead with new features and improvements, then list fixes.
Writing style
- Write in a user-facing tone: describe what changed for the user, not internal implementation details.
- Be concise but informative. Each item should be 1-2 sentences.
- Where a change fixes a user-visible bug, describe the symptom that was fixed.
- Where a change adds a new feature, describe what users can now do.
- Use present tense (e.g., "The extension now supports..." not "Added support for...").
- Link to the relevant PR from
dotnet/vscode-csharpfor each item (not the upstream Roslyn/Razor PR).
Step 5: Create a PR against the release branch
The release notes are delivered as a PR that modifies CHANGELOG.md on the release branch. This inserts the generated notes as a new version section at the top of the changelog.
Prerequisites: Install and authenticate the GitHub CLI
If gh is not installed, install it first:
# macOS
brew install gh
# Windows
winget install --id GitHub.cli
# Linux (Debian/Ubuntu)
sudo apt install gh
Verify installation and authenticate if needed:
gh --version
gh auth status || gh auth login
Create the branch, commit, and PR
Stash any local changes to avoid conflicts:
git stash --include-untrackedCreate a new branch directly from the remote
releasebranch:git fetch origin release git checkout -b changelog/v2.<VERSION> origin/releaseIf a conflicting branch name exists (e.g., a stale
changelogbranch), delete it first withgit branch -D <conflicting-branch>.Edit
CHANGELOG.md— insert the generated release notes as a new# 2.<VERSION>.xsection immediately after the## Known Issuesblock and before the previous release section. The format should be:# 2.<VERSION>.x <generated release notes content> # 2.<PREVIOUS_VERSION>.xCommit and push:
git add CHANGELOG.md git commit -m "Release notes for version 2.<VERSION>.x" git push -u origin changelog/v2.<VERSION>Create the PR targeting the
releasebranch. Write the PR body to a temp file first to avoid shell quoting issues with markdown content:# Write PR body to a temp file (markdown with backticks, angle brackets, etc.) cat > /tmp/pr-body.md << 'PRBODY' <PR body content here> PRBODY gh pr create \ --repo dotnet/vscode-csharp \ --base release \ --title "Release notes for version 2.<VERSION>.x" \ --body-file /tmp/pr-body.md rm /tmp/pr-body.mdImportant: Use
--body-fileinstead of--bodybecause the PR body contains markdown with backticks, angle brackets, and other characters that break shell quoting. Also use--repo dotnet/vscode-csharpto ensure the PR is created on the correct repository even if the git remote uses an older URL.Return to the original branch and restore stashed changes:
git checkout main git stash pop
PR conventions
- Target branch:
release(notmain) - Title:
Release notes for version 2.<VERSION>.x - Body: A brief summary of the key themes (e.g., "This update includes improvements to reliability, diagnostics tooling, language server performance, and Razor editing."). Always use
--body-fileto avoid shell quoting issues. - Only
CHANGELOG.mdshould be modified in the PR.
Example
For a release at version 2.130, using CHANGELOG sections 2.121.x, 2.122.x, and 2.123.x, the PR would insert a section like this into CHANGELOG.md on the release branch:
# 2.130.x
This update brings significant improvements to reliability, diagnostics tooling,
language server performance, and Razor editing.
## Reliability
### Improved error reporting when the language server encounters an error
The experience when the language server crashes has been significantly improved.
Now, a single consolidated notification is shown with a "Report Issue" button
that opens the issue reporter with logs pre-filled. Server crashes can also
trigger an automatic restart. ([vscode-csharp#8982](https://github.com/dotnet/vscode-csharp/pull/8982))
## Performance
### Balanced source generator execution (default)
Source generator execution now defaults to **Balanced** mode, running only on
file save, build, or explicit command rather than every keystroke. Use the
`dotnet.server.sourceGeneratorExecution` setting to switch back to `Automatic`
if needed. ([vscode-csharp#8970](https://github.com/dotnet/vscode-csharp/pull/8970))
## Razor
### Formatting fixes
- Fixed formatting of multiline `@if` statements, ternary expressions, and
wrapped CSS. ([razor#12786](https://github.com/dotnet/razor/pull/12786))
- Fixed indentation after complete tags. ([razor#12784](https://github.com/dotnet/razor/pull/12784))
Notes
- This skill works best with a model that can follow links and synthesize information from PRs and issues (e.g., Claude Opus).
- If the CHANGELOG on the prerelease branch is not yet up to date, the agent should note this and work with whatever is available.
- The agent should use
fetch_webpageto follow GitHub PR links and gather details. - If
ghauthentication fails or the user doesn't have push access, fall back to creating the branch locally and instruct the user to open the PR manually.
Source: dotnet/vscode-csharp — distributed by TomeVault.