Skip to content

Commit 8ef7331

Browse files
authored
Per-component release notes PRs in the release-notes skill (#10382) (#10383)
1 parent 20e72eb commit 8ef7331

6 files changed

Lines changed: 113 additions & 172 deletions

File tree

.github/prompts/createprs-for-preview.prompt.md

Lines changed: 0 additions & 132 deletions
This file was deleted.

.github/skills/release-notes/SKILL.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@ This skill is the **editorial writing stage** of the pipeline. It turns a scored
1818
4. `api-diff` / `dotnet-inspect` verifies public APIs and confirms suspect features still exist in the shipped build
1919
5. `release-notes` writes curated markdown using the higher-value entries from `features.json`
2020
6. `review-release-notes` runs a final multi-model editorial QA pass against the scoring rubric and examples
21-
7. Output is one PR per release milestone in dotnet/core, maintained incrementally
21+
7. Output is a set of pull requests per release milestone in dotnet/core: a base PR that holds shared metadata (`changes.json`, `features.json`, `README.md`, `build-metadata.json`) and one PR per component file. Each component PR targets the base branch so component teams review and edit their file in isolation. See [`pr-layout.md`](references/pr-layout.md) for the full layout and naming scheme.
22+
23+
## Local testing (no PRs)
24+
25+
To dry-run the skill against a milestone, only create the branch set locally. Don't push the branches or create the PRs.
2226

2327
## Existing-branch reruns
2428

25-
When the milestone branch already exists and contains drafted markdown, invoke
29+
When the milestone branch set already exists and contains drafted markdown, invoke
2630
[`update-existing-branch`](../update-existing-branch/SKILL.md). That shared
2731
skill is the canonical playbook for refreshing `changes.json`, merging the delta
2832
into `features.json`, integrating new material into existing sections, and
@@ -32,7 +36,8 @@ handling review comments without clobbering human edits.
3236

3337
- [quality-bar.md](references/quality-bar.md) — what good release notes look like
3438
- [vmr-structure.md](references/vmr-structure.md) — VMR branches, tags, source-manifest.json
35-
- [../update-existing-branch/SKILL.md](../update-existing-branch/SKILL.md) — how to refresh a populated milestone branch incrementally
39+
- [pr-layout.md](references/pr-layout.md) — base + per-component branch layout
40+
- [../update-existing-branch/SKILL.md](../update-existing-branch/SKILL.md) — how to refresh a populated milestone branch set incrementally
3641
- [changes-schema.md](references/changes-schema.md) — the shared `changes.json` / `features.json` schema
3742
- [../editorial-scoring/SKILL.md](../editorial-scoring/SKILL.md) — the reusable scoring rubric and cut guidance
3843
- [feature-scoring.md](references/feature-scoring.md) — how to score and cut features

.github/skills/release-notes/references/component-mapping.md

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,34 @@
44

55
Uses the `repo` field from `changes.json` (which matches `source-manifest.json` `path` values) to identify components.
66

7-
| Manifest Path | Component | Source Repo | Release Notes File |
8-
| ------------- | --------- | ----------- | ------------------ |
9-
| `runtime` | .NET Libraries | `dotnet/runtime` | `libraries.md` |
10-
| `runtime` | .NET Runtime | `dotnet/runtime` | `runtime.md` |
11-
| `aspnetcore` | ASP.NET Core | `dotnet/aspnetcore` | `aspnetcore.md` |
12-
| `razor` | ASP.NET Core (Razor) | `dotnet/razor` | `aspnetcore.md` |
13-
| `sdk` | .NET SDK | `dotnet/sdk` | `sdk.md` |
14-
| `templating` | .NET SDK (Templating) | `dotnet/templating` | `sdk.md` |
15-
| `msbuild` | MSBuild | `dotnet/msbuild` | `msbuild.md` |
16-
| `winforms` | Windows Forms | `dotnet/winforms` | `winforms.md` |
17-
| `wpf` | WPF | `dotnet/wpf` | `wpf.md` |
18-
| `efcore` | EF Core | `dotnet/efcore` | `efcore.md` |
19-
| `roslyn` | C# / Visual Basic | `dotnet/roslyn` | `csharp.md` |
20-
| `fsharp` | F# | `dotnet/fsharp` | `fsharp.md` |
21-
| `nuget-client` | NuGet | `nuget/nuget.client` | `nuget.md` |
7+
| Manifest Path | Component | Source Repo | Release Notes File | Default Assignee(s) |
8+
| ------------- | --------- | ----------- | ------------------ | ------------------- |
9+
| `runtime` | .NET Libraries | `dotnet/runtime` | `libraries.md` | @artl93 @jeffhandley @SamMonoRT @karelz |
10+
| `runtime` | .NET Runtime | `dotnet/runtime` | `runtime.md` | @richlander |
11+
| `aspnetcore` | ASP.NET Core | `dotnet/aspnetcore` | `aspnetcore.md` | @danroth27 |
12+
| `razor` | ASP.NET Core (Razor) | `dotnet/razor` | `aspnetcore.md` | @danroth27 |
13+
| `sdk` | .NET SDK | `dotnet/sdk` | `sdk.md` | @baronfel |
14+
| `templating` | .NET SDK (Templating) | `dotnet/templating` | `sdk.md` | @baronfel |
15+
| `msbuild` | MSBuild | `dotnet/msbuild` | `msbuild.md` | @baronfel |
16+
| `winforms` | Windows Forms | `dotnet/winforms` | `winforms.md` | @KlausLoeffelmann @merriemcgaw |
17+
| `wpf` | WPF | `dotnet/wpf` | `wpf.md` | @harshit7962 @adegeo |
18+
| `efcore` | EF Core | `dotnet/efcore` | `efcore.md` | @SamMonoRT @roji |
19+
| `roslyn` | C# / Visual Basic | `dotnet/roslyn` | `csharp.md` | @BillWagner |
20+
| `fsharp` | F# | `dotnet/fsharp` | `fsharp.md` | @T-Gro |
21+
| `nuget-client` | NuGet | `nuget/nuget.client` | `nuget.md` | @baronfel |
22+
23+
Each release notes file gets its own per-component branch named `release-notes/{version}-{milestone-slug}-{file-stem}`, where `{file-stem}` is the release notes filename without `.md` (for example, `aspnetcore.md``release-notes/11.0-preview4-aspnetcore`). See [`pr-layout.md`](pr-layout.md) for the full branching scheme.
24+
25+
The agent assigns each component PR to its default assignee(s) when opening the PR (`gh pr create --assignee ...`), so the right team sees it in their review queue.
26+
27+
### Components contributed out-of-band (not in the VMR)
28+
29+
These components ship with .NET but live outside the VMR, so `changes.json` won't contain entries for them. The agent still creates a stub PR for each so the component team can push their own content (or close the PR if there is nothing noteworthy this milestone).
30+
31+
| Component | Source Repo | Release Notes File | Default Assignee(s) |
32+
| --------- | ----------- | ------------------ | ------------------- |
33+
| .NET MAUI | `dotnet/maui` | `dotnetmaui.md` | @davidortinau |
34+
| Containers | `dotnet/dotnet-docker` | `containers.md` | @lbussell |
2235

2336
### Runtime sub-component classification
2437

@@ -77,5 +90,7 @@ winforms.md # Windows Forms
7790
wpf.md # WPF
7891
msbuild.md # MSBuild
7992
nuget.md # NuGet client
93+
dotnetmaui.md # .NET MAUI (team-authored, not in VMR)
94+
containers.md # Containers (team-authored, not in VMR)
8095
changes.json # Machine-readable change manifest
8196
```

.github/skills/release-notes/references/editorial-rules.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,15 @@ At the bottom of each component's notes, list ALL external contributors — not
9595

9696
**Vet the list** — the `community-contribution` label is sometimes wrong. Exclude usernames containing `-msft`, `-microsoft`, or other Microsoft suffixes. When in doubt about whether someone is a Microsoft employee, leave them out of the community list.
9797

98+
**Scope `dotnet/aspnetcore` links to the milestone.** That repo tags every PR with a release milestone (e.g. `11.0-preview4`), so the contributor link should append `+milestone%3A<slug>` to limit it to this milestone's contributions. Look up the exact slug with `gh pr view <pr> --repo dotnet/aspnetcore --json milestone`. Most other source repos don't apply milestones consistently — for those, omit the filter and link to the author's merged PRs without scope.
99+
98100
```markdown
99101
## Community contributors
100102

101103
Thank you contributors! ❤️
102104

103-
- [@username](https://github.com/<owner>/<repo>/pulls?q=is%3Apr+is%3Amerged+author%3Ausername)
105+
- [@username](https://github.com/dotnet/aspnetcore/pulls?q=is%3Apr+is%3Amerged+author%3Ausername+milestone%3A<slug>)
106+
- [@username](https://github.com/<other-owner>/<other-repo>/pulls?q=is%3Apr+is%3Amerged+author%3Ausername)
104107
```
105108

106109
## Bug fixes section
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# PR Layout
2+
3+
Each release-notes milestone produces a **set of pull requests** instead of one large PR, so each component team reviews its own file in isolation.
4+
5+
## Branch set per milestone
6+
7+
- **Base branch** `release-notes/{version}-{milestone-slug}` (e.g. `release-notes/11.0-preview4`) — holds the shared metadata for the milestone (`README.md`, `changes.json`, `features.json`, `build-metadata.json`). Its PR targets `main`.
8+
- **Component branch** `release-notes/{version}-{milestone-slug}-{file-stem}` (e.g. `release-notes/11.0-preview4-aspnetcore` for `aspnetcore.md`) — holds only that component's `{file-stem}.md`. Its PR targets the base branch.
9+
10+
The set of components and their release notes files is defined in [`component-mapping.md`](component-mapping.md). Components with no noteworthy changes still get a stub PR.
11+
12+
## Invariants
13+
14+
- `changes.json`, `features.json`, `build-metadata.json`, and `README.md` live on the **base branch only**. Component branches never modify them; they rebase or merge from the base branch to pick up refreshed metadata.
15+
- Each `{component}.md` lives on its **matching component branch only**. The agent never edits another component's file from the wrong branch.
16+
- The milestone landing page `{version}.md` (for example, `11.0.0-preview.4.md`) is **not produced by this skill**. The .NET release team generates it through separate artifacts-publishing automation, so the agent leaves it alone on every branch.
17+
18+
## Merge flow
19+
20+
Each component PR merges into the base branch. When all component PRs merge, the base PR's diff is the full milestone — there is no separate consolidation PR.
21+
22+
## PR title convention
23+
24+
- Base PR: `[release-notes] .NET {version} {milestone-label}` (e.g. `[release-notes] .NET 11 Preview 4`).
25+
- Component PR: `[release-notes] {Component name} in .NET {version} {milestone-label}` (e.g. `[release-notes] ASP.NET Core in .NET 11 Preview 4`).
26+
27+
## Draft state
28+
29+
Open both the base PR and every component PR as **drafts** (`gh pr create --draft`). Component teams promote their PR to ready-for-review once they've vetted the AI-authored content (including any `<!-- TODO -->` placeholders). The base PR stays a draft until the milestone ships.

0 commit comments

Comments
 (0)