diff --git a/.github/linters/.markdownlintignore b/.github/linters/.markdownlintignore index abd6eaa869..97aba0cfce 100644 --- a/.github/linters/.markdownlintignore +++ b/.github/linters/.markdownlintignore @@ -2,3 +2,4 @@ **/api-diff/** **/prompts/** +**/.github/** diff --git a/.github/skills/libraries-release-notes/SKILL.md b/.github/skills/libraries-release-notes/SKILL.md new file mode 100644 index 0000000000..94f76ca385 --- /dev/null +++ b/.github/skills/libraries-release-notes/SKILL.md @@ -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. diff --git a/.github/skills/libraries-release-notes/references/author-1-entries.md b/.github/skills/libraries-release-notes/references/author-1-entries.md new file mode 100644 index 0000000000..c2a7404731 --- /dev/null +++ b/.github/skills/libraries-release-notes/references/author-1-entries.md @@ -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` diff --git a/.github/skills/libraries-release-notes/references/author-2-format.md b/.github/skills/libraries-release-notes/references/author-2-format.md new file mode 100644 index 0000000000..b826724e1f --- /dev/null +++ b/.github/skills/libraries-release-notes/references/author-2-format.md @@ -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 - Release Notes + +.NET includes new .NET Libraries features & enhancements: + +- [Feature Name](#anchor) +- [Feature Name](#anchor) +... + +.NET Libraries updates in .NET : + +- [What's new in .NET ](https://learn.microsoft.com/dotnet/core/whats-new/dotnet-/overview) documentation + +## Feature Name + +[/ #NNNNN](https://github.com///pull/NNNNN) . + +```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 + +[/ #NNNNN](https://github.com///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(); +\``` +``` diff --git a/.github/skills/libraries-release-notes/references/author-3-editorial.md b/.github/skills/libraries-release-notes/references/author-3-editorial.md new file mode 100644 index 0000000000..e176e026f6 --- /dev/null +++ b/.github/skills/libraries-release-notes/references/author-3-editorial.md @@ -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 diff --git a/.github/skills/libraries-release-notes/references/data-1-apidiff-review.md b/.github/skills/libraries-release-notes/references/data-1-apidiff-review.md new file mode 100644 index 0000000000..fe594a59c0 --- /dev/null +++ b/.github/skills/libraries-release-notes/references/data-1-apidiff-review.md @@ -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. diff --git a/.github/skills/libraries-release-notes/references/data-2-collect-prs.md b/.github/skills/libraries-release-notes/references/data-2-collect-prs.md new file mode 100644 index 0000000000..9cb21d6fa7 --- /dev/null +++ b/.github/skills/libraries-release-notes/references/data-2-collect-prs.md @@ -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 " +) +``` + +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 " +) +``` + +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 +## + +**TODO:** The API diff shows new surface area for `` 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`). diff --git a/.github/skills/libraries-release-notes/references/data-3-enrich.md b/.github/skills/libraries-release-notes/references/data-3-enrich.md new file mode 100644 index 0000000000..17caeee4e1 --- /dev/null +++ b/.github/skills/libraries-release-notes/references/data-3-enrich.md @@ -0,0 +1,126 @@ +# Step 4: Enrich — Fetch PR and Issue Details + +For each library PR, fetch the full body (description) which contains benchmark data, API signatures, and motivation. Building on the PR data, fetch the details for issues referenced by or linked to the pull request — especially any issues resolved by the PR. Issues labeled `api-approved` represent new APIs being added and should be represented in the API diff if it was loaded. The issue often has a more detailed description than the PR, including API usage examples and a statement of impact/value. The final API shape (and usage example) might be somewhat out of date compared to what was approved and merged in the pull request, so usage examples may need to be revised. + +## 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 PR details — GitHub MCP server (primary) + +Use `pull_request_read` with method `get` to fetch each PR's full details: + +``` +pull_request_read( + method: "get", + owner: "dotnet", + repo: "runtime", + pullNumber: +) +``` + +Multiple independent PR reads can be issued in parallel for efficiency. The PR response includes a `reactions` object with counts for each reaction type (e.g. `+1`, `heart`, `rocket`). Record the **total reaction count** for each PR as a popularity signal — PRs with high reaction counts indicate strong community interest. + +After fetching PR details, also fetch the PR's comments to look for **Copilot-generated summaries**. Copilot often posts a comment on PRs that summarizes the changes, intent, and impact — this can provide a concise understanding of the PR that complements the (sometimes lengthy or template-heavy) PR description. + +``` +pull_request_read( + method: "get_comments", + owner: "dotnet", + repo: "runtime", + pullNumber: +) +``` + +Look for comments authored by `copilot[bot]` or `github-actions[bot]` that contain a summary of the PR. These summaries are especially useful for large PRs where the description is auto-generated or sparse. Use this information to better understand the PR's purpose, but always cross-reference with the actual code changes and PR description for accuracy. + +## Discover related issues from the PR + +There are two complementary ways to find issues that a PR resolves or references. Use both to build a complete picture. + +### Parse the PR description for issue links + +Scan the PR body text for issue references. Common patterns include: + +- **Closing keywords**: `Fixes #1234`, `Closes #1234`, `Resolves #1234` (GitHub auto-links these) +- **Full URL links**: `https://github.com/dotnet/runtime/issues/1234` +- **Cross-repo references**: `dotnet/runtime#1234` +- **Bare hash references**: `#1234` (relative to the PR's repository) + +Extract all unique issue numbers from these patterns. For Copilot-authored PRs, also look in the `
` / `Original prompt` collapsed section, which typically contains the original issue title, description, and a `Fixes` link at the bottom of the PR body. + +### Use the GitHub MCP server to find linked issues + +Use `search_issues` to find issues that reference the PR or that the PR resolves: + +``` +search_issues( + owner: "dotnet", + repo: "runtime", + query: "is:closed linked:pr reason:completed " +) +``` + +This can surface issues that were closed by the PR even if the PR description does not contain an explicit `Fixes` reference (e.g. when the link was added via the GitHub sidebar rather than the PR body). + +You can also search by API name or type to find the backing issue directly: + +``` +search_issues( + owner: "dotnet", + repo: "runtime", + query: "is:closed " +) +``` + +If any discovered issue carries the `api-approved` label, pay extra attention to both that issue and its associated PR. The `api-approved` issue typically contains the approved API shape, usage examples, motivation, and discussion from the API review — all of which are valuable background for writing compelling release notes. + +## Fetch issue details + +For each discovered issue number, use `issue_read` with method `get`: + +``` +issue_read( + method: "get", + owner: "dotnet", + repo: "runtime", + issue_number: +) +``` + +Multiple independent issue reads can be issued in parallel for efficiency. The issue response includes a `reactions` object — record the **total reaction count** for each issue. Combine the PR and issue reaction counts to form an overall **popularity score** for each feature (sum of all `+1`, `heart`, `rocket`, and other positive reactions across the PR and its linked issues). Prioritize fetching issues that are: + +- Referenced by a `Fixes`/`Closes`/`Resolves` keyword (these are the resolved issues) +- Labeled `api-approved` (these contain the approved API shape and usage examples) +- Labeled `enhancement` with high reaction counts (these indicate community demand) + +The issue body often contains richer context than the PR, including: +- **API proposals** with `### API Proposal` and `### API Usage` sections +- **Motivation** explaining why the feature was requested +- **Upvote counts** (via reactions) that indicate community demand +- **Discussion comments** that may contain approved API shapes from API review + +## Fallback — GitHub CLI + +If the GitHub MCP server is not available, use the `gh` CLI: + +```bash +gh pr view --repo "$REPO" \ + --json number,title,body,labels,author,assignees,mergedAt,url + +gh issue view --repo "$REPO" \ + --json number,title,body,labels,author,assignees,url +``` + +To find issues closed by a PR via the CLI: + +```bash +# Search for closed issues linked to the PR +gh search issues --repo "$REPO" --state closed "linked:pr " +``` + +Store all fetched details using the **SQL tool** (update `body` and `reactions` columns in the `prs` table; insert into the `issues` table). Do **not** write intermediate files to disk. diff --git a/.github/skills/libraries-release-notes/references/process-inputs.md b/.github/skills/libraries-release-notes/references/process-inputs.md new file mode 100644 index 0000000000..9ef520200e --- /dev/null +++ b/.github/skills/libraries-release-notes/references/process-inputs.md @@ -0,0 +1,29 @@ +# Process Inputs and Validate Readiness + +Collect all required inputs from the user and verify that prerequisite data is available before starting the data pipeline. + +## Inputs + +If `$ARGUMENTS` is provided, use `$0` as the repository. Otherwise ask the user for the **repository** (`owner/repo`, e.g. `dotnet/runtime`). + +Collect inputs **one at a time** — ask a single question, wait for the answer, then ask the next. After each response, acknowledge what has been collected so far and ask for the next missing input: + +1. **Preview name** (e.g. ".NET 11 Preview 2") +2. **Start date** — ask: *"What was the Code Complete date for the previous release, ``?"* (ISO 8601). For **Preview 1**, this is the prior major version's RC1 Code Complete date (the vNext fork point); anything already covered in RC1/RC2/GA release notes will be de-duplicated in the [verify scope](verify-1-dedupe.md) step. +3. **End date** — ask: *"What was the Code Complete date for ``? (If it hasn't occurred yet, provide the expected date.)"* (ISO 8601) +4. **Output file** — path for the release notes markdown (default: `release-notes//preview//libraries.md`) + +## Early API Diff Check + +Before starting the data pipeline, verify that the required API diffs are present in the local repository clone. Check for both: + +1. **Current release API diff** — e.g. `release-notes//preview//api-diff/Microsoft.NETCore.App/` +2. **Previous release API diff** — e.g. `release-notes//preview//api-diff/Microsoft.NETCore.App/` (used during [deduplication](verify-1-dedupe.md) and cross-referencing) + +If **either** API diff directory is missing or empty: + +- **Warn the user immediately**, specifying which diff is missing and the expected path. +- Explain that the API diff significantly improves the quality of the release notes by enabling accurate cross-referencing of new APIs with implementing PRs. +- Ask whether to proceed without it or wait until the API diff is available. + +Do not defer this check to the data pipeline — surface the warning as soon as inputs are collected so the user can decide early whether to generate the API diff first. diff --git a/.github/skills/libraries-release-notes/references/verify-1-dedupe.md b/.github/skills/libraries-release-notes/references/verify-1-dedupe.md new file mode 100644 index 0000000000..ce713645f8 --- /dev/null +++ b/.github/skills/libraries-release-notes/references/verify-1-dedupe.md @@ -0,0 +1,44 @@ +# Verify: Deduplicate Against Previous Release Notes + +Before authoring content, check that candidate features have not already been covered in an earlier preview's release notes for the same major version. + +## Load prior release notes + +Load the `libraries.md` file from the immediately preceding release within the same major version. For example, when generating Preview 3, load Preview 2's notes; when generating RC1, load Preview 7's notes. + +When generating **Preview 1** release notes for a new major version, there are no prior previews to check. Instead, look back at the prior major version's late-cycle release notes — specifically RC1, RC2, and GA — since features that landed late in the previous release cycle may overlap with early work in the new version. For example, when generating .NET 12 Preview 1 notes, check: + +``` +release-notes/11.0/preview/rc1/libraries.md +release-notes/11.0/preview/rc2/libraries.md +release-notes/11.0/preview/ga/libraries.md +``` + +These files are in the local repository clone under `release-notes//preview/`. + +## Check for overlap + +For each candidate PR, check whether it (or its feature) already appears in a prior release's notes by looking for: + +- **PR number references** — search for `#` or the full PR URL in prior files +- **Feature names** — search for the API name, type name, or feature title (e.g. `IdnMapping`, `File.OpenNullHandle`, `Zstandard`) + +Remove any PR from the candidate list whose feature is already covered. A PR that was merged in the date range of a prior preview but was not included in that preview's release notes may still be included — only exclude PRs whose features were actually written up. + +## Flag earlier PRs that survived dedup + +If any PRs were removed during dedup, review the remaining candidate PRs that were merged **before** the previous release's Code Complete date (i.e. PRs whose merge date falls in the earlier portion of the date range). These PRs were not found in the prior release notes but their merge dates suggest they *could* have been covered elsewhere. Present these PRs to the user and ask whether each should be included or excluded. For example: + +> The following PRs were merged before the .NET 11 Preview 1 Code Complete date but were **not** found in any prior release notes. They may have been intentionally omitted or covered in a different document. Please confirm whether to include them: +> +> - #12345 — `Add Foo.Bar overload` (merged 2025-11-15) +> - #12400 — `Optimize Baz serialization` (merged 2025-12-03) + +If no PRs were removed during dedup (i.e. nothing overlapped with prior notes), skip this sub-step — the earlier merge dates are expected given the date range and do not need user confirmation. + +## Handle cross-preview features + +Some features span multiple PRs across previews (e.g. a Preview 1 PR adds the core API and a Preview 2 PR extends it). In these cases: + +- If the Preview 2 PR is a **substantial extension** (new overloads, new scenarios, significant perf improvement on top of the original, or breaking changes to the API shape), include it as an update referencing the earlier work. +- If the Preview 2 PR is a **minor follow-up** (bug fix, test addition, doc comment), skip it. diff --git a/.github/skills/libraries-release-notes/references/verify-2-release.md b/.github/skills/libraries-release-notes/references/verify-2-release.md new file mode 100644 index 0000000000..d2bd8f5a60 --- /dev/null +++ b/.github/skills/libraries-release-notes/references/verify-2-release.md @@ -0,0 +1,58 @@ +# Verify: Confirm Inclusion in Release Branch + +After collecting and enriching candidates (including any manually added PRs), verify that candidate changes actually shipped in the target release by checking the `dotnet/dotnet` Virtual Monolithic Repository (VMR). The VMR contains all .NET source code — including `dotnet/runtime` under `src/runtime/` — and its release branches represent what ships in each preview. + +## Determine the release branch name + +The expected branch name pattern is: + +``` +release/.0.1xx- +``` + +For example: +- .NET 11 Preview 1 → `release/11.0.1xx-preview1` +- .NET 11 Preview 2 → `release/11.0.1xx-preview2` +- .NET 11 RC 1 → `release/11.0.1xx-rc1` + +Use the GitHub MCP server (or CLI fallback) to verify the branch exists: + +``` +list_branches( + owner: "dotnet", + repo: "dotnet" +) +``` + +If the expected branch is **not found**, search for branches matching `release/.0*` and present the user with the matching branch names so they can select the correct one. + +## Spot-check that the newest changes are included + +Start from the most recently merged PRs in the candidate list and work backward. For each PR, verify its changes are present in the VMR release branch by either: + +1. **Searching for code** introduced by the PR in the `dotnet/dotnet` repo: + + ``` + search_code( + query: "repo:dotnet/dotnet path:src/runtime " + ) + ``` + +2. **Checking commit history** on the release branch for runtime source code updates that post-date the PR merge: + + ``` + list_commits( + owner: "dotnet", + repo: "dotnet", + sha: "release/.0.1xx-", + perPage: 30 + ) + ``` + + Look for commits with messages like `"Source code updates from dotnet/runtime"` dated after the PR's merge date. The dotnet-maestro bot regularly syncs changes from `dotnet/runtime` into the VMR. + +Stop checking after **2 consecutive PRs are confirmed present** — if the two newest changes made it into the release branch, older changes are also included. + +If any change is **not found** in the release branch, inform the user that the feature may not have been included in this preview release. Suggest either: +- Moving that feature to the **next preview's** release notes +- Confirming with the release team whether a late sync occurred diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml index daa49a74b3..6e8a9bb339 100644 --- a/.github/workflows/super-linter.yml +++ b/.github/workflows/super-linter.yml @@ -10,7 +10,7 @@ on: push: branches: [main] pull_request: - branches: '**' + branches: "**" permissions: contents: read @@ -35,5 +35,6 @@ jobs: VALIDATE_NATURAL_LANGUAGE: false VALIDATE_MARKDOWN_PRETTIER: false VALIDATE_JSON_PRETTIER: false + FILTER_REGEX_EXCLUDE: .github/skills/.* DEFAULT_BRANCH: main GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/release-notes/11.0/README.md b/release-notes/11.0/README.md index f3ca6a7fc7..f9d9fd8e03 100644 --- a/release-notes/11.0/README.md +++ b/release-notes/11.0/README.md @@ -1,14 +1,10 @@ # .NET 11 -.NET 11 is a [Short Term Support (STS)](../../release-policies.md) release and will be supported on [multiple operating systems](supported-os.md) for three years from November 10, 2026 to November 14, 2028. +[.NET 11](https://aka.ms/dotnet/11/preview1) is a [Standard Term Support (STS)](../../release-policies.md) release and will be supported for two years, from November 10, 2026 to November 9, 2028, on multiple operating systems. - [Downloads](https://dotnet.microsoft.com/download/dotnet/11.0) - [Linux Package Managers](https://learn.microsoft.com/dotnet/core/install/linux) - [Containers](https://hub.docker.com/_/microsoft-dotnet) -- [Supported OSes](supported-os.md) -- [OS packages](./os-packages.md) -- [Known Issues](known-issues.md) -- [Installation instructions](install.md) ## Release notes @@ -18,45 +14,59 @@ ### .NET Libraries -- [What's new in .NET 11 libraries](https://learn.microsoft.com/dotnet/core/whats-new/dotnet-11/overview#net-libraries) - [Preview 1](preview/preview1/libraries.md) ### .NET Runtime -- [What's new in the .NET 11 runtime](https://learn.microsoft.com/dotnet/core/whats-new/dotnet-11/runtime) - [Preview 1](preview/preview1/runtime.md) ### .NET SDK -- [What's new in the SDK for .NET 11](https://learn.microsoft.com/dotnet/core/whats-new/dotnet-11/sdk) - [Preview 1](preview/preview1/sdk.md) +### MSBuild + +- [Preview 1](preview/preview1/msbuild.md) + ### C\# -- [What's new in C# 14](https://learn.microsoft.com/dotnet/csharp/whats-new/csharp-14) +- [What's new in C#](https://learn.microsoft.com/dotnet/csharp/whats-new/) - [Preview 1](preview/preview1/csharp.md) +### F\# + +- [What's new in F#](https://learn.microsoft.com/dotnet/fsharp/whats-new/) +- [Preview 1](preview/preview1/fsharp.md) + +### Visual Basic + +- [What's new in Visual Basic](https://learn.microsoft.com/dotnet/visual-basic/whats-new/) +- [Preview 1](preview/preview1/visualbasic.md) + ### ASP.NET Core -- [What's new in ASP.NET Core 11.0](https://learn.microsoft.com/aspnet/core/release-notes/aspnetcore-11.0) - [Preview 1](preview/preview1/aspnetcore.md) ### .NET MAUI -- [What's new in .NET MAUI for .NET 11](https://learn.microsoft.com/dotnet/maui/whats-new/dotnet-11) +- [What's new in .NET MAUI](https://learn.microsoft.com/dotnet/maui/whats-new/) - [Preview 1](preview/preview1/dotnetmaui.md) ### Entity Framework Core -- [What's new in EF Core 11](https://learn.microsoft.com/ef/core/what-is-new/ef-core-11.0/whatsnew) +- [What's new in EF Core](https://learn.microsoft.com/ef/core/what-is-new/) - [Preview 1](preview/preview1/efcore.md) ### Windows Forms -- [What's new in Windows Forms for .NET 11](https://learn.microsoft.com/dotnet/desktop/winforms/whats-new/net110) +- [What's new in Windows Forms](https://learn.microsoft.com/dotnet/desktop/winforms/whats-new/) - [Preview 1](preview/preview1/winforms.md) ### Windows Presentation Foundation (WPF) -- [What's new in WPF for .NET 11](https://learn.microsoft.com/dotnet/desktop/wpf/whats-new/net110) +- [What's new in WPF](https://learn.microsoft.com/dotnet/desktop/wpf/whats-new/) - [Preview 1](preview/preview1/wpf.md) + +### Container images + +- [Preview 1](preview/preview1/containers.md) diff --git a/release-notes/11.0/known-issues.md b/release-notes/11.0/known-issues.md index 672b84cb59..e38777f1aa 100644 --- a/release-notes/11.0/known-issues.md +++ b/release-notes/11.0/known-issues.md @@ -4,4 +4,4 @@ You may encounter some known issues, which may include workarounds, mitigations, ## Covariant overrides of `Task`/`Task` causes TypeLoadException -Refactoring for the [Runtime-Async](https://github.com/dotnet/runtime/issues/109632) feature caused a bug in Task-returning methods with covariant returns. The bug has been fixed for Preview 2, but the fix did not make Preview 1. +Refactoring for the [Runtime-Async](https://github.com/dotnet/runtime/issues/109632) feature caused a bug in Task-returning methods with covariant returns. The bug has been fixed for Preview 2, but the fix did not make Preview 1. diff --git a/release-notes/11.0/preview/preview1/README.md b/release-notes/11.0/preview/preview1/README.md index 828cab8493..353e76fb98 100644 --- a/release-notes/11.0/preview/preview1/README.md +++ b/release-notes/11.0/preview/preview1/README.md @@ -1,35 +1,39 @@ # .NET 11 Preview 1 - Release Notes -Welcome to .NET 11! We're happy to deliver the first preview of .NET 11, released February 13th, 2024, and share in-depth release notes that provide varied and impressive improvements for the first preview out of the gate. We also published [Our Vision for .NET 11](https://aka.ms/dotnet/11/vision), which describes some of the broad areas we intend to deliver on by the final November 2024 release. +.NET 11 Preview 1 release notes. Find more information on new features released in .NET 11 Preview 1 by browsing through the release notes below: -Find more information on new features released in .NET 11 Preview 1 by browsing through the release notes below: +- [Libraries](./libraries.md) +- [Runtime](./runtime.md) +- [SDK](./sdk.md) +- [MSBuild](./msbuild.md) -* [Libraries](./libraries.md) -* [Runtime](./runtime.md) -* [SDK](./sdk.md) -* [.NET Data and EF Core](./efcoreanddata.md) -* [.NET MAUI](./dotnetmaui.md) -* [ASP.NET Core](./aspnetcore.md) -* [API diff](./api-diff/README.md) +## Languages -## Get Started +- [C#](./csharp.md) +- [F#](./fsharp.md) +- [Visual Basic](./visualbasic.md) -Instructions on getting started with .NET 11 can be found in the [getting started guide](../../get-started.md). Installers and binaries for .NET 11 Preview 1 can be found [here on GitHub](./11.0.0-preview.1.md). +## Workloads, Libraries, & More -## Announcements & Discussions +- [.NET MAUI](./dotnetmaui.md) +- [ASP.NET Core](./aspnetcore.md) +- [Container images](./containers.md) +- [EF Core & Data](./efcore.md) +- [Windows Forms](./winforms.md) +- [WPF](./wpf.md) -Discuss this release with the product teams on GitHub through the announcements for this release. +## Get Started -* [.NET 11 Preview 1 Announcement](https://aka.ms/dotnet/11/preview1) -* [.NET Data and EF Core](https://github.com/dotnet/efcore/issues/33030) -* [.NET MAUI](https://github.com/dotnet/maui/discussions/20558) -* [ASP.NET Core](https://github.com/dotnet/aspnetcore/discussions/54007) -* [Containers](https://github.com/dotnet/dotnet-docker/discussions/51118) -* [Libraries and Runtime](https://github.com/dotnet/runtime/discussions/118372) -* [Source-build](https://github.com/dotnet/source-build/discussions/4132) +Instructions on getting started with .NET 11 can be found in the [getting started guide](../../get-started.md). Installers and binaries for .NET 11 Preview 1 can be found [here on GitHub](./11.0.0-preview.1.md). ## Stay up-to-date -You can find a detailed overview of all new features in .NET 11 in the [What's new in .NET 11](https://learn.microsoft.com/dotnet/core/whats-new/dotnet-11/overview) documentation. +You can find a detailed overview of all new features in .NET 11: + +- [What's new in C#](https://learn.microsoft.com/dotnet/csharp/whats-new/) +- [What's new in .NET MAUI](https://learn.microsoft.com/dotnet/maui/whats-new/) +- [What's new in Entity Framework Core](https://learn.microsoft.com/ef/core/what-is-new/) +- [What's new in Windows Forms](https://learn.microsoft.com/dotnet/desktop/winforms/whats-new/) +- [What's new in WPF](https://learn.microsoft.com/dotnet/desktop/wpf/whats-new/) The latest .NET 11 release is always available at [dotnet.microsoft.com](https://dotnet.microsoft.com/download/dotnet/11.0) and [.NET 11 Releases](../../README.md). diff --git a/release-notes/11.0/preview/preview1/aspnetcore.md b/release-notes/11.0/preview/preview1/aspnetcore.md new file mode 100644 index 0000000000..32c9708d43 --- /dev/null +++ b/release-notes/11.0/preview/preview1/aspnetcore.md @@ -0,0 +1,523 @@ +# ASP.NET Core in .NET 11 Preview 1 - Release Notes + +Here's a summary of what's new in ASP.NET Core in this preview release: + +- [EnvironmentBoundary component](#environmentboundary-component) +- [Label component for forms](#label-component-for-forms) +- [DisplayName component](#displayname-component) +- [QuickGrid `OnRowClick` event](#quickgrid-onrowclick-event) +- [Relative navigation with `RelativeToCurrentUri`](#relative-navigation-with-relativetocurrenturi) +- [`GetUriWithHash()` extension method](#geturiwithhash-extension-method) +- [BasePath component](#basepath-component) +- [MathML namespace support](#mathml-namespace-support) +- [`InvokeVoidAsync()` analyzer](#invokevoidasync-analyzer) +- [`IComponentPropertyActivator`](#icomponentpropertyactivator) +- [SignalR `ConfigureConnection` for Interactive Server components](#signalr-configureconnection-for-interactive-server-components) +- [Unified startup options format for Blazor scripts](#unified-startup-options-format-for-blazor-scripts) +- [`IHostedService` support in Blazor WebAssembly](#ihostedservice-support-in-blazor-webassembly) +- [Environment variables in Blazor WebAssembly configuration](#environment-variables-in-blazor-webassembly-configuration) +- [Blazor WebAssembly component metrics and tracing](#blazor-webassembly-component-metrics-and-tracing) +- [Enable container support in Blazor Web App template](#enable-container-support-in-blazor-web-app-template) +- [OpenAPI schema support for binary file responses](#openapi-schema-support-for-binary-file-responses) +- [`IOutputCachePolicyProvider`](#ioutputcachepolicyprovider) +- [Auto-trust development certificates in WSL](#auto-trust-development-certificates-in-wsl) + +ASP.NET Core updates in .NET 11: + +- [What's new in ASP.NET Core in .NET 11](https://learn.microsoft.com/aspnet/core/release-notes/aspnetcore-11) documentation. +- [Roadmap](https://github.com/dotnet/aspnetcore/issues/64787) + +## EnvironmentBoundary component + +Blazor now includes a built-in `EnvironmentBoundary` component for conditional rendering based on the hosting environment. This component is similar to the MVC environment tag helper and provides a consistent way to render content based on the current environment across both server and WebAssembly hosting models. + +The `EnvironmentBoundary` component accepts `Include` and `Exclude` parameters for specifying environment names. The component performs case-insensitive matching and follows the same semantics as the MVC `EnvironmentTagHelper`. + +```razor +@using Microsoft.AspNetCore.Components.Web + + +
+ Debug mode enabled +
+
+ + +

Pre-production environment

+
+ + +

@DateTime.Now

+
+``` + +The component works consistently in both Blazor Server and Blazor WebAssembly scenarios by injecting `IHostEnvironment`, eliminating the need for manual environment checks and conditional logic. + +## Label component for forms + +A new `Label` component has been added to Blazor forms that renders accessible labels with support for both nested and non-nested patterns. The component automatically extracts display names from `[Display]` or `[DisplayName]` attributes, falling back to the property name if no attributes are present. + +The `Label` component supports two common label-input association patterns: + +**Nested pattern** (implicit association): + +```razor + +``` + +Renders: + +```html + +``` + +**Non-nested pattern** (for/id association): + +```razor +