# Generate Release Notes

> Generate release notes for a new stable release of the C# extension by gathering prerelease CHANGELOG entries and writing them in VS Code release notes style. Use this when asked to generate, draft, or write release notes. Use when this capability is needed.

- Skill: `tomevault-io/generate-release-notes-4` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/generate-release-notes-4`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/generate-release-notes-4/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/generate-release-notes-4

---


# 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 current `version.json` on `prerelease` by rounding up the minor version to the next ten.

## Process

### Step 1: Determine the version range

1. Identify the **target release version**. If not given, read `version.json` on `prerelease` to get the current minor version, and round up to the next ten (e.g., if current is `2.131`, the next release is `2.140`).
2. Calculate the **previous release version** by subtracting 10 from the target minor (e.g., target `2.140` → previous `2.130`).
3. The prerelease sections to gather are all minor versions **after** the previous release and **before** the target release. For example, for target `2.140`: sections `2.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:

```bash
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:

1. **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.
2. **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/razor`** should only appear under a **Razor** section.
- **`xamlTools` fixes** 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):

1. **C# Language Support** — General C# language features, completions, diagnostics, refactorings, code fixes, etc. Changes from `dotnet/roslyn` that are not Razor-specific go here.
2. **Performance** — Notable performance improvements from any component.
3. **Razor** — All changes from `dotnet/razor` PRs and Razor-related features.
4. **Debugging** — Debugger improvements and fixes.
5. **MAUI** — Changes related to `xamlTools` or MAUI features.
6. **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-csharp` for 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:

```bash
# macOS
brew install gh

# Windows
winget install --id GitHub.cli

# Linux (Debian/Ubuntu)
sudo apt install gh
```

Verify installation and authenticate if needed:

```bash
gh --version
gh auth status || gh auth login
```

#### Create the branch, commit, and PR

1. **Stash any local changes** to avoid conflicts:

   ```bash
   git stash --include-untracked
   ```

2. **Create a new branch** directly from the remote `release` branch:

   ```bash
   git fetch origin release
   git checkout -b changelog/v2.<VERSION> origin/release
   ```

   If a conflicting branch name exists (e.g., a stale `changelog` branch), delete it first with `git branch -D <conflicting-branch>`.

3. **Edit `CHANGELOG.md`** — insert the generated release notes as a new `# 2.<VERSION>.x` section immediately after the `## Known Issues` block and before the previous release section. The format should be:

   ```markdown
   # 2.<VERSION>.x

   <generated release notes content>

   # 2.<PREVIOUS_VERSION>.x
   ```

4. **Commit and push**:

   ```bash
   git add CHANGELOG.md
   git commit -m "Release notes for version 2.<VERSION>.x"
   git push -u origin changelog/v2.<VERSION>
   ```

5. **Create the PR** targeting the `release` branch. Write the PR body to a temp file first to avoid shell quoting issues with markdown content:

   ```bash
   # 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.md
   ```

   > **Important**: Use `--body-file` instead of `--body` because the PR body contains markdown with backticks, angle brackets, and other characters that break shell quoting. Also use `--repo dotnet/vscode-csharp` to ensure the PR is created on the correct repository even if the git remote uses an older URL.

6. **Return to the original branch** and restore stashed changes:

   ```bash
   git checkout main
   git stash pop
   ```

#### PR conventions

- **Target branch**: `release` (not `main`)
- **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-file` to avoid shell quoting issues.
- **Only `CHANGELOG.md` should 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:

```markdown
# 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_webpage` to follow GitHub PR links and gather details.
- If `gh` authentication 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](https://github.com/dotnet/vscode-csharp) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-06-18 -->

