Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
cf3df5e
Add release notes for .NET 11 Preview 1 across various components
jamesmontemagno Feb 5, 2026
d369426
Update sdk.md for Preview 1 (#10230)
jamesmontemagno Feb 9, 2026
ff62d39
Update visualbasic.md for Preview 1 (#10231)
jamesmontemagno Feb 9, 2026
5f88a94
Update csharp.md for Preview 1 (#10224)
jamesmontemagno Feb 9, 2026
fcbbdb3
Update efcore.md for Preview 1 (#10226)
jamesmontemagno Feb 10, 2026
08f661a
Update libraries.md for Preview 1 (#10228)
jamesmontemagno Feb 10, 2026
0dee912
Update aspnetcore.md for .NET 11 Preview 1 (#10222)
jamesmontemagno Feb 10, 2026
4c6611d
Update fsharp.md for Preview 1 (#10227)
jamesmontemagno Feb 10, 2026
46ee44c
Add libraries release-notes-generator Copilot skill (#10244)
artl93 Feb 10, 2026
69d9373
Update wpf.md for Preview 1 (#10233)
jamesmontemagno Feb 10, 2026
eab7be3
Update dotnetmaui.md for Preview 1 (#10225)
jamesmontemagno Feb 10, 2026
5161671
Update runtime.md for Preview 1 (#10229)
jamesmontemagno Feb 10, 2026
17d812e
Update release notes for .NET 11 Preview 1, including content adjustm…
jamesmontemagno Feb 10, 2026
51b05bf
Fix formatting issues in release notes for .NET 11 Preview 1
jamesmontemagno Feb 10, 2026
9d6e543
Merge branch 'main' into dotnet-11-preview1
jamesmontemagno Feb 10, 2026
c1af8ed
Fix formatting issue in known issues section of release notes for .NE…
jamesmontemagno Feb 10, 2026
4a1cad4
Add .github directory to markdownlintignore for improved linting control
jamesmontemagno Feb 10, 2026
7c98a43
Add runtime.md
richlander Feb 10, 2026
babf06f
Clean up runtime-async
agocke Feb 10, 2026
e64e43a
Merge branch 'main' into dotnet-11-preview1
rbhanda Feb 10, 2026
221591e
Include .github/skills in exclude for super-linter
jongalloway Feb 10, 2026
465ad47
markdownlint fix
jongalloway Feb 10, 2026
d33fdb6
Merge branch 'main' into dotnet-11-preview1
jongalloway Feb 10, 2026
f28d903
Fix ASP.NET Core roadmap link for .NET 11
danroth27 Feb 10, 2026
0c9534e
Update release-notes/11.0/preview/preview1/runtime.md
jongalloway Feb 10, 2026
2cf9b30
Merge branch 'main' into dotnet-11-preview1
jongalloway Feb 10, 2026
b5e93cb
Fix EF learn links
jongalloway Feb 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/linters/.markdownlintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

**/api-diff/**
**/prompts/**
**/.github/**
32 changes: 32 additions & 0 deletions .github/skills/libraries-release-notes/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: libraries-release-notes
description: Generate .NET Libraries release notes by evaluating the release's API diff, fetching merged PRs from a GitHub repository, categorizing by area or theme, and producing formatted markdown with exact benchmark data and code examples.
disable-model-invocation: true
argument-hint: "[owner/repo]"
---

# Release Notes Generator

Generate .NET Libraries release notes for a given release.

## Execution guidelines

- **Do not write intermediate files to disk.** Use the **SQL tool** for structured storage and querying (see [data-2-collect-prs.md](references/data-2-collect-prs.md) for schema).
- **Do not run linters, formatters, or validators.** Do not run markdownlint, prettier, link checkers, or any other validation tool on the output. The only output of this skill is the release notes markdown file itself.
- **Maximize parallel tool calls.** Fetch multiple PR and issue details in a single response to minimize round trips.

## Process

1. **[Process Inputs and Validate Readiness](references/process-inputs.md)** — collect inputs and verify API diffs are available.
2. **Data pipeline** — gather the changes included in the release:
1. [Analyze the API diff](references/data-1-apidiff-review.md)
2. [Collect and filter PRs](references/data-2-collect-prs.md)
3. [Enrich — fetch PR and issue details](references/data-3-enrich.md)
3. **Verify scope** — validate the candidate list:
1. [Deduplicate from previous release notes](references/verify-1-dedupe.md)
2. [Confirm inclusion in release branch](references/verify-2-release.md)
4. **Author content** — write the release notes:
1. [Categorize entries by area, theme, and impact](references/author-1-entries.md)
2. [Apply formatting rules](references/author-2-format.md)
3. [Apply editorial rules](references/author-3-editorial.md)
5. Confirm feature list with the user before finalizing.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Author: Categorize by Area, Theme, and Impact

Group PRs into tiers:
- **Headline features**: New namespaces or types, implementations of new industry trends/algorithms, major new API surfaces
- **Quality**: PRs or groups of PRs that improve quality across an area (recognizing `area-*` labels on the PRs and issues)
- **Performance**: PRs with benchmark data showing measurable improvements
- **API additions**: New methods/overloads on existing types
- **Small improvements**: Single-mapping additions, minor fixes with public API changes
- **Community contributions**: Large PRs labeled as `community-contribution` or collections of such PRs by the same author

**Multi-faceted PRs.** A single PR may span multiple categories — for example, a PR that rewrites an implementation may improve correctness, fix bugs, simplify the codebase, *and* deliver performance gains. Do not reduce such PRs to a single category. When writing the release notes entry, describe the full scope of the improvement. A PR that fixes correctness bugs and improves performance should lead with the quality/reliability story and include performance data as supporting evidence — not be categorized as "Performance" alone. Read the full PR description, not just benchmark tables.

Only Headline, Quality, Performance, and significant API additions go into the release notes. Use judgment — a 2-line dictionary entry addition is less noteworthy than a new numeric type. The early previews (preview1 through preview5) tend to include more features, and the later previews (preview6, preview7, and rc1) tend to have fewer headline features and more quality improvements and small additions. The RC2 and GA releases typically have fewer changes so quality and performance improvements can be emphasized more.

For community contributions, if a community contributor has provided valuable features or quality improvements for popular libraries, give those entries more consideration for mentioning in the release notes.

Some example sets of release notes to use for reference and inspiration:
* `release-notes/11.0/preview/preview1/libraries.md`
* `release-notes/10.0/preview/preview1/libraries.md`
* `release-notes/9.0/preview/rc1/libraries.md`
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Release Notes Format Template

The release notes must mirror the style of the official .NET Preview release notes (e.g. `.NET 10 Preview 1`).

## Document Structure

```markdown
# .NET Libraries in .NET <VERSION> <PREVIEW> - Release Notes

.NET <VERSION> <PREVIEW> includes new .NET Libraries features & enhancements:

- [Feature Name](#anchor)
- [Feature Name](#anchor)
...

.NET Libraries updates in .NET <VERSION>:

- [What's new in .NET <VERSION>](https://learn.microsoft.com/dotnet/core/whats-new/dotnet-<version>/overview) documentation

## Feature Name

[<owner>/<repo> #NNNNN](https://github.com/<owner>/<repo>/pull/NNNNN) <one-paragraph description>.

```csharp
// Code example or API signature
```
```

## Section Rules

1. **TOC at top** — Every feature gets a linked entry in the table of contents.
2. **PR link first** — Each section opens with a link to the PR.
3. **One paragraph of context** — What the feature does and why it matters.
4. **API signature** — Show the new public API surface in a `csharp` code block.
5. **Usage example** — A short, runnable code snippet showing the feature in action.
6. **Benchmark summary** (if applicable) — State what was measured and the speedup range. Do NOT embed full BenchmarkDotNet tables.

## Example Section

```markdown
## Finding Certificates By Thumbprints Other Than SHA-1

[<owner>/<repo> #NNNNN](https://github.com/<owner>/<repo>/pull/NNNNN) introduces a new method
that accepts the name of the hash algorithm to use for matching, since SHA-2-256 and SHA-3-256
have the same lengths and making the Find method match any vaguely matching thumbprint was not ideal.

\```csharp
X509Certificate2Collection coll = store.Certificates.FindByThumbprint(
HashAlgorithmName.SHA256, thumbprint);
return coll.SingleOrDefault();
\```
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Editorial Rules

## Benchmarks

- Use **exact data** from PR descriptions — never round, approximate, or paraphrase performance numbers.
- State the benchmark scenarios (what was measured, what hardware, what workloads).
- Report speedup ranges (e.g. "2.4–3.9x faster on Windows, 1.6–4.7x on Linux").
- Include specific before/after measurements when they tell a compelling story (e.g. "dropped from 48.0 ns to 12.2 ns").
- Do **not** embed full BenchmarkDotNet tables in the release notes — summarize in prose.
- If the user asks for exact tables, pull them verbatim from the PR body. Never reconstruct or approximate.

## Attribution

- **Community contributors**: If the PR author is not a Microsoft employee or a bot, cite them: `contributed by community member @handle`.
- **Copilot-authored PRs**: The PR author will be `Copilot` (bot). Do not credit Copilot. Cite the assignee who merged it if attribution is needed.
- **Microsoft employees**: No special attribution needed — they are implied.
- When in doubt, check the PR author's GitHub profile or the `author_association` field (`MEMBER` = Microsoft, `CONTRIBUTOR`/`NONE` = community).

## Entry Naming

- Prefer a **brief description** of what the feature does over simply stating the API name. The heading should help a reader understand the value at a glance.
-`## Support for Zstandard compression`
-`## Faster time zone conversions`
-`## Dictionary expression support for immutable and frozen collections`
-`## ZstandardStream`
-`## TimeZoneInfo performance`
-`## ImmutableDictionary.CreateRange`
- Keep headings concise — aim for 3–8 words.
- Include the API or type name in the body text, not necessarily in the heading.

## Feature Ranking

Order features by **customer impact**, using both qualitative "wow" factor and quantitative popularity signals. Promote entries that affect popular, widely-used libraries; move niche or specialized scenarios lower.

**Primary ordering criteria** (biggest impact first):
1. Major new capabilities for popular libraries (new types, new compression algorithms, new protocol support) — especially those with high reaction counts on the backing issue or PR
2. Performance improvements with dramatic numbers in widely-used APIs (e.g. `DateTime.Now`, `HttpClient`, `JsonSerializer`)
3. New API surfaces on popular existing types, prioritized by combined PR + issue reaction count
4. Improvements to less-common or specialized libraries (e.g. `System.Reflection.Emit`, `System.Formats.Tar`)
5. Small additions and fixes

**Popularity signals** (gathered in Step 5):
- **Reaction counts**: PRs and issues with many 👍, ❤️, or 🚀 reactions indicate strong community demand. Use the combined reaction count across the PR and its linked issues as a tiebreaker within each tier.
- **Linked issue upvotes**: An `api-approved` issue with 50+ reactions is a stronger signal than one with 2.
- **Library popularity**: Changes to `System.Text.Json`, `System.Net.Http`, `System.Collections`, `System.IO`, and `System.Threading` affect more users than changes to narrower namespaces. When two entries are otherwise similar in impact, prefer the one in the more widely-used library.

## Inclusion Criteria

Include a feature if it meets ANY of:
- Introduces a new public type or namespace
- Adds significant new API surface (3+ new methods) to an existing type
- Has benchmark data showing ≥20% improvement in a common scenario
- Enables a scenario that was previously impossible or required workarounds
- Was a highly-requested community feature (check linked issues for upvote counts)

Exclude:
- Internal refactoring with no public API change
- Test-only changes
- Build/infrastructure changes
- Backports from servicing branches
- Single-line fixes unless they unblock a major scenario
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Step 1: Analyze API Diff

> **Note:** The [early API diff check](../SKILL.md#early-api-diff-check) in SKILL.md verifies that both the current and previous release API diffs exist *before* the data pipeline starts. By the time this step executes, the user has already been warned about any missing diffs and has chosen to proceed. If a diff is missing, skip the corresponding load step below but continue with the rest of the pipeline.

## Locate the API diff

Locate and load the `Microsoft.NETCore.App` API diff for the target release. The API diff provides context about which APIs were added or changed and significantly improves the quality of the generated release notes.

The API diff lives under the `release-notes` folder within an `api-diff` subfolder for the target release. For example:
* .NET 10 RC 2: `release-notes/10.0/preview/rc2/api-diff/Microsoft.NETCore.App/10.0-RC2.md`
* .NET 10 GA: `release-notes/10.0/preview/ga/api-diff/Microsoft.NETCore.App/10.0-ga.md`
* .NET 11 Preview 1: `release-notes/11.0/preview/preview1/api-diff/Microsoft.NETCore.App/11.0-preview1.md`

## Load the API diff

Once the `api-diff` folder is located, load all of the API difference files under the `Microsoft.NETCore.App` subfolder:

```
api-diff/Microsoft.NETCore.App/
```

For example:

```
release-notes/11.0/preview/preview1/api-diff/Microsoft.NETCore.App/
```

Read every diff file in this folder to understand the full set of APIs that have been added or changed in the release. This information is used later to cross-reference with merged PRs and ensure the release notes accurately cover all API surface changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Step 2: Collect and Filter PRs

## MCP response size

GitHub MCP search tools that return large payloads get saved to temporary files on disk — reading those files back requires PowerShell commands that trigger approval prompts. Prevent this by keeping individual search result sets small:

- Use **label-scoped searches** (e.g. `label:area-System.Text.Json`) instead of fetching all merged PRs at once.
- Use `perPage: 30` or less for search queries. Only use `perPage: 100` for targeted queries that are expected to return few results.
- If a search response is saved to a temp file anyway, use the `view` tool (with `view_range` for large files) to read it — **never** use PowerShell/shell commands to read or parse these files.

## Fetch Merged PRs

Pull merged PRs in the date range from the specified repository, filtered to library areas. The primary method is the **GitHub MCP server** tools; fall back to the **GitHub CLI (`gh`)** if the MCP server is unavailable.

### Primary — GitHub MCP server

Use `search_pull_requests` with **label-scoped queries** to keep result sets small and avoid large responses being saved to temp files on disk (which then require shell commands to read — triggering approval prompts).

Search for merged PRs one area label at a time. The most common library area labels are listed below, but also search with the broader `label:area-System.` prefix to catch less-common areas:

```
# Search per area label — one query per label, small result sets
search_pull_requests(
owner: "dotnet",
repo: "runtime",
query: "is:merged merged:2026-01-26..2026-02-11 label:area-System.Text.Json",
perPage: 30
)
```

**Recommended area labels to search** (run these in parallel batches):

- `area-System.Text.Json`, `area-System.Net.Http`, `area-System.Collections`
- `area-System.IO`, `area-System.IO.Compression`, `area-System.Threading`
- `area-System.Numerics`, `area-System.Runtime`, `area-System.Memory`
- `area-System.Security`, `area-System.Diagnostics`, `area-System.Globalization`
- `area-System.Linq`, `area-System.Reflection`, `area-System.Reflection.Emit`
- `area-System.Formats.*`, `area-System.Net.*`, `area-System.Text.*`
- `area-Microsoft.Extensions.*`, `area-Extensions-*`

After the label-scoped searches, do a **catch-all search** for any remaining library PRs that may use uncommon area labels. Use a broad query but keep `perPage` small:

```
search_pull_requests(
owner: "dotnet",
repo: "runtime",
query: "is:merged merged:2026-01-26..2026-02-11 label:area-System",
perPage: 30
)
```

Page through results (incrementing `page`) until all PRs for each query are collected. Deduplicate by PR number across all queries before inserting into the database.

**PRs without area labels.** Some PRs lack an `area-*` label altogether. To catch these, also run a search without label filters but restricted to a short date range and `perPage: 30`. Check the title and description of unlabeled PRs for library-relevant content. If a PR references a library issue (via "Fixes #..." links), fetch the issue to check for `area-*` labels.

### Fallback — GitHub CLI

If the GitHub MCP server is not available, use the `gh` CLI instead. Verify availability with `gh --version` first.

```bash
REPO="dotnet/runtime" # Set from user input

# First batch (newer half of range)
gh pr list --repo "$REPO" --state merged \
--search "merged:2025-12-01..2026-02-01" \
--limit 1000 --json number,title,labels,author,mergedAt,url

# Second batch (older half of range)
gh pr list --repo "$REPO" --state merged \
--search "merged:2025-10-01..2025-12-01" \
--limit 1000 --json number,title,labels,author,mergedAt,url
```

### Data storage

Store all fetched PR data using the **SQL tool**. Do **not** write cache files to disk — disk I/O triggers approval prompts. Insert each PR into the `prs` table and use SQL queries for all subsequent filtering.

```sql
CREATE TABLE prs (
number INTEGER PRIMARY KEY,
title TEXT,
author TEXT,
author_association TEXT,
labels TEXT, -- comma-separated label names
merged_at TEXT,
body TEXT,
reactions INTEGER DEFAULT 0,
is_library INTEGER DEFAULT 0,
is_candidate INTEGER DEFAULT 0
);

CREATE TABLE issues (
number INTEGER PRIMARY KEY,
title TEXT,
body TEXT,
labels TEXT,
reactions INTEGER DEFAULT 0,
pr_number INTEGER -- the PR that references this issue
);
```

Additional PRs can be added to the candidate list manually by number. Use [Enrich](data-3-enrich.md) to fetch their details.

## Filter to Library PRs

Since the search queries above are already scoped to library area labels, most results will be relevant. Apply these additional filters before marking PRs as candidates:

### Exclusion filters
- Labels: `backport`, `servicing`, `NO-MERGE`
- PRs whose title starts with `[release/` or contains `backport`
- PRs that are purely test, CI, or documentation changes (no `src` changes)

### Cross-reference with API diff

If the API diff was loaded in [Step 1](data-1-apidiff-review.md), cross-reference the candidate PRs against the new APIs. For each new API or namespace in the diff, verify that at least one candidate PR covers it. If an API in the diff has **no matching PR**, search for the implementing PR explicitly:

```
search_pull_requests(
owner: "dotnet",
repo: "runtime",
query: "is:merged <API name or type name>"
)
```

This catches PRs that were missed by the date range (merged slightly after the Code Complete date but before the release branch was cut) or that lacked a recognized area label. Add any discovered PRs to the candidate list.

Also use the API diff to discover **issues** that drove new APIs. Many approved APIs originate from `api-approved` issues that may reference a broader feature story. Use `search_issues` to find related issues:

```
search_issues(
owner: "dotnet",
repo: "runtime",
query: "label:api-approved <API name or type name>"
)
```

If such issues exist, trace them to their implementing PRs and ensure those PRs are in the candidate list.

**Unmatched API surface area.** After cross-referencing, if any substantial new APIs in the diff still cannot be correlated to a PR or issue, include a placeholder section in the release notes for each unmatched API group. Use a `**TODO**` marker so the author can manually resolve it later. For example:

```markdown
## <New API or Feature Name>

**TODO:** The API diff shows new surface area for `<Namespace.TypeName>` but the implementing PR/issue could not be found. Investigate and fill in this section.
```

Mark matching PRs as candidates in the SQL `prs` table (`is_candidate = 1`).
Loading