Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions .github/agents/release-manager.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ every gate.

## Starting a session

When a new release-manager session begins and a release activity is in scope, first present a compact
process overview as a tree that shows the active track and all stages/sub-stages (monthly vs
servicing), then state which stage is current.

When the user asks where the release process stands, assess the current release state without relying
on this session's history: inspect the available branch, commit, pull-request, and build information;
identify what is complete and what remains; and state any missing context. Earlier stages may have
Expand Down Expand Up @@ -84,10 +88,20 @@ verification script lives at `release-manager/validate-release/scripts/Test-Sour
into sub-stages); complete them strictly in order. Pause for the user to review and approve before
each commit, and before every push, pipeline queue, publish, channel promotion, or merge-commit
completion. **Never push until the user explicitly instructs it.**
- **Progress visibility.** At each gating prompt, include a concise progress rail that shows completed
stages, the current stage/sub-step, and remaining stages. Keep it compact and update it every time
stage state changes.
- **Concrete next-step guidance.** After completing each stage/sub-stage, tell the user the exact next
action to advance (for example, a specific approval cue or command handoff) so they do not need to
guess or repeatedly send generic "proceed" prompts.
- **Irreversibility.** Publishing to nuget.org, promoting a build to a public channel (its symbols
and packages flow to msdl and downstream consumers), and pushing tags cannot be cleanly undone.
Prepare and review first, then act only on explicit user confirmation. Never run `dotnet nuget
push` yourself and never handle nuget.org API keys.
- **Run-location discipline.** Orchestrate in-session, but for privileged/auth-sensitive operational
commands (for example AzDO artifact access, `dotnet nuget push`, and BAR promotion checks), prefer
explicit terminal handoff blocks for the user to run outside the session, then continue based on
their reported output.
- **Commit hygiene.** Every stage and every sub-stage is its own commit -- never combine them.
Commits that land in public `dotnet/extensions` history keep the `Co-authored-by: Copilot`
trailer but **omit** the `Copilot-Session` trailer. Write commit subjects that describe what
Expand All @@ -97,6 +111,13 @@ verification script lives at `release-manager/validate-release/scripts/Test-Sour
branches. Resolve each by its **URL**, not by remote name -- names vary by machine. Do not rely on
absolute on-disk clone paths.
- **Release notes** are never published to a GitHub release without explicit user confirmation.
- **Release wrap-up.** When the full release process is complete (GitHub release published, any
required branch reconciliation done), present a short celebratory closing message that:
- Confirms the release version and packages shipped.
- Includes a timing summary: wall-clock elapsed time for each stage completed this session, total
elapsed time for the session, and an estimate of active user-interaction time (time the user
spent responding to prompts, as distinct from wait time while the agent or CI worked).
- Track stage start/end times throughout the session so this summary is accurate.

## Release process at a glance

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,60 @@ Then stop for merge/approval before publish steps.
2. Confirm the target patch version (`<major>.<minor>.<patch>`).
3. Create a working branch from `origin/release/<major>.<minor>`.

## Step 2: Build the candidate backport list from `main`
## Step 2: Survey the release branch for existing backport activity

Before building the full candidate list, check for evidence of existing backport work targeting this
release. This step is informational -- it seeds the candidate list and reminds the user that the release-manager agent can efficiently
cherry-pick from `main` as part of the servicing release process.

### 2a) Identify backport PRs

1. **Open PRs** targeting `release/<major>.<minor>`: find any with titles starting with
`[release/<major>.<minor>]` or bodies containing `Backport of #NNNN` / `backport of #NNNN`.
2. **Recently merged PRs** into `release/<major>.<minor>` since the previous release tag: apply the
same pattern match.
3. For each backport PR found, extract the source `main` PR number from its title or body.

### 2b) Classify backport PRs by release status

For each source `main` PR number identified, check whether it already shipped in a previous release:

- Run `git merge-base --is-ancestor <pr-merge-commit> <previous-tag>` to check ancestry.
- Or check whether the PR number appears in a prior release's release notes body.

Classify each backport PR as either:

- **Already released** -- source PR shipped in a prior release tag; carry this into Step 3d for the
already-released grounding table (do not present it as a selectable candidate or comment on it).
- **Not yet released** -- source PR has not shipped; carry it into the Step 3 candidate list as a
pre-highlighted row.

### 2c) Inform the user if open or unshipped backport PRs exist

If any open or recently-merged (but not yet incorporated) backport PRs remain after filtering:

> "I see backport PRs already open/merged targeting `release/<major>.<minor>`. The release manager
> can cherry-pick those changes directly from `main` -- this is typically more efficient than
> managing individual backport PRs. I'll include the corresponding `main` PRs as pre-highlighted
> candidates in the selection below."

Carry the source `main` PR numbers into the Step 3 candidate list as pre-highlighted rows.

If no relevant backport activity is found, proceed directly to Step 3 without comment.

---

## Step 3: Build the candidate backport list from `main`

The user needs a clear **selection list** of commits from `main` that are not yet included in `release/<major>.<minor>`.

For grounding, also present a separate view of what is already merged into `release/<major>.<minor>` (whether those merges happened before or after the target patch-version bump point).

### 2a) Gather candidate PRs/commits
### 3a) Gather candidate PRs/commits

Build candidates from commits in `main` that are not in `release/<major>.<minor>`, then map them to PR numbers where possible.

### 2b) Build grounding for already-merged release-branch items
### 3b) Build grounding for already-merged release-branch items

Identify items that already shipped on the release branch by checking merged PRs into `release/<major>.<minor>` and harvesting referenced `#NNNN` slugs from their titles/bodies.

Expand All @@ -41,41 +84,49 @@ Present these as **grounding only** (not selectable candidates). If a patch-bump

If no patch-bump commit exists yet on the release branch, label rows as `before planned patch bump`.

### 2c) Enrich each candidate with affected libraries
### 3c) Enrich each candidate with affected libraries

For each candidate PR:

1. Read changed files.
2. Derive affected libraries from touched paths (for example, `src/Libraries/<LibraryName>/...`).
3. Keep the list unique and sorted.

### 2d) Present the selection table
### 3d) Present the selection table

Show a selection table with one row per **selectable** candidate item:
Show a selection table with one row per **selectable** candidate item. Pre-highlight any rows
seeded from Step 2 (existing backport PRs), so the user can quickly confirm or adjust those:

| SHA (short) | Title | PR | Libraries affected |
|---|---|---|---|
| `abc1234` | Commit/PR title | `#1234` link | `Microsoft.Extensions.AI`, ... |
| SHA (short) | Title | PR | Libraries affected | Pre-selected? |
|---|---|---|---|---|
| `abc1234` | Commit/PR title | `#1234` link | `Microsoft.Extensions.AI`, ... | ✔ (backport PR open) |

Then show a separate grounding table for already-merged release-branch items:
Then show a separate grounding table for items already merged into the release branch for this
release cycle:

| Timing vs patch bump | SHA (short) | Title | PR | Libraries affected |
|---|---|---|---|---|
| before patch bump / after patch bump / before planned patch bump | `def5678` | Commit/PR title | `#5678` link | `Microsoft.Extensions.AI.Abstractions`, ... |

Then show a third table for items identified in Step 2 as already shipped in a **prior** release:

| Prior release tag | Source PR | Title | Libraries affected |
|---|---|---|---|
| `v10.8.1` | `#5432` link | Commit/PR title | `Microsoft.Extensions.AI`, ... |

Requirements:

- Keep already-merged release-branch rows out of the selectable table.
- Prefer PR-number rows when available.
- If a commit has no PR number, mark it and ask the user whether to include it explicitly.

## Step 3: Ask the user to choose items (multi-select)
## Step 4: Ask the user to choose items (multi-select)

Prompt the user to select rows from the **selectable candidate table only** (for example by PR numbers or row numbers, comma-separated).

Do not cherry-pick until selection is explicit.

## Step 4: Confirm package scope and template inclusion
## Step 5: Confirm package scope and template inclusion

Before committing:

Expand All @@ -85,7 +136,7 @@ Before committing:

Record this confirmed scope; it is the source of truth for publish/validate/release-notes stages.

## Step 5: Apply commits in servicing order
## Step 6: Apply commits in servicing order

Apply commits in this exact order:

Expand All @@ -104,7 +155,7 @@ For each cherry-pick, record whether it was:
- Commit message format: `Bump version to <major>.<minor>.<patch>`.
- This matches recent 10.* servicing examples (`10.4.1`, `10.5.1`, `10.5.2`, `10.8.1`).

## Step 6: Create the servicing-prep PR
## Step 7: Create the servicing-prep PR

Do not push or open the PR until the user explicitly says to do so.

Expand Down Expand Up @@ -139,7 +190,7 @@ Notes:
- Keep the `DO-NOT-SQUASH` label on the PR from creation through merge.
- For the merge method into `release/<major>.<minor>`, prefer **Rebase and merge** (never squash).

## Step 7: Preserve scope for downstream stages
## Step 8: Preserve scope for downstream stages

After PR creation, treat the merged servicing-prep PR description as authoritative for:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,28 @@ This stage is operational and produces no commit. Both actions are **irreversibl

For servicing releases, also require the merged servicing-prep PR description; it is the source of truth for package scope.

## Execution context check

Before running artifact/publish operations, confirm whether this session can access AzDO/BAR with the
required auth context. If access is limited in-session, switch to a terminal handoff flow: provide
exact commands for the user to run outside the session, then continue based on their output.

## Sub-stage 1 - Prepare and publish packages

Publishing is irreversible (a published version cannot be overwritten or truly deleted) and requires nuget.org API keys, so the agent only prepares the set; the user runs the push.

1. Download and extract the `PackageArtifacts` from the official build.
- If in-session artifact download/auth fails, hand off this step to the user's terminal and ask
them to return the local extracted package folder path.
2. Stage the packages to publish into a clean folder:
- Always exclude `Microsoft.Internal.*`.
- For **servicing releases**, start from the package list in the merged servicing-prep PR description; treat that list as canonical unless the user explicitly changes it.
- For **monthly releases**, include all release packages except those the user explicitly holds back.
- In both tracks, flag template/tooling packages (for example `*.ProjectTemplates`) for an explicit include/exclude decision.
3. Present the excluded and to-publish lists for the user to review.
4. Two nuget.org accounts are involved: almost all packages publish from the **dotnetframework** account; **`Microsoft.Agents.AI.ProjectTemplates`** publishes from the **MicrosoftAgentFramework** account, so it must be pushed separately with that account's key.
5. The **user** runs `dotnet nuget push` with the appropriate API key(s). Never run the push, and never handle the API keys.
5. The **user** runs `dotnet nuget push` with the appropriate API key(s) in their terminal (outside
the agent session). Never run the push, and never handle the API keys.

### Secure API key entry (user-run helper)

Expand Down Expand Up @@ -102,6 +111,15 @@ Notes:

After a successful push, **delete or regenerate the API key on nuget.org** ([nuget.org/account/apikeys](https://www.nuget.org/account/apikeys)) so the key used for this release is not left valid. The helper shreds the temporary key *file* locally, but only deleting/regenerating the key on nuget.org invalidates it server-side. Guide the user to do this as the final step of Sub-stage 1.

### Terminal handoff expectation

When handing off Sub-stage 1 commands, provide a copy/paste-ready command block and ask the user to
run it in terminal, then report:

- staged package path(s),
- push output summary,
- confirmation that the nuget.org API key was deleted/regenerated.

## Sub-stage 2 - Ensure the official release build is on the public channel

Determine whether manual promotion is required:
Expand Down
10 changes: 7 additions & 3 deletions .github/agents/release-manager/validate-release/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ Run this playbook after **publish-release**.

- Stage 5 is automated symbol verification.
- Stage 6 stages reconciliation merges when needed (pushing and PR completion are left to the user).
- Stage 7 confirms the support-page listing.
- Stage 7 handles support-page follow-up based on release type and package novelty.

For servicing releases prepared directly on public `release/<major>.<minor>`, Stage 6 is often unnecessary because commits were backported from `main` into the release branch up front. In that case, run Stage 5 and Stage 7, and run Stage 6 only if the user explicitly asks for additional branch-flow follow-up.
For servicing releases prepared directly on public `release/<major>.<minor>`, Stage 6 is often unnecessary because commits were backported from `main` into the release branch up front. In that case, run Stage 5 and run Stage 6 only if the user explicitly asks for additional branch-flow follow-up.

## Stage 5 - Verify Source Link and Symbols

Expand All @@ -24,7 +24,11 @@ Read and follow [references/stage-6-reconcile-branches.md](references/stage-6-re

## Stage 7 - Confirm the Support-Page Update

The .NET Platform Extensions support page is maintained by a partner team. Confirm that a pull request updating it has been opened for this release, review it, and flag any newly published or recently-stabilized packages that are missing from the list.
Stage 7 is conditional:

- **Monthly releases**: the support page is maintained by a partner team; review their PR and confirm completeness.
- **Servicing releases that only service existing packages**: Stage 7 can be skipped.
- **Servicing releases that introduce newly shipped packages**: the release manager must author and submit the `dotnet/website` PR that adds those packages to the support page.

Read and follow [references/stage-7-support-page.md](references/stage-7-support-page.md).

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
# Stage 7 - Confirm the Support-Page Update
# Stage 7 - Support-Page Follow-up

The [.NET Platform Extensions support policy page](https://dotnet.microsoft.com/en-us/platform/support/policy/extensions) lists the supported packages and their current versions. It is maintained by a **partner team**, so this stage is a **review**, not an edit: confirm their update lands and is complete.
The [.NET Platform Extensions support policy page](https://dotnet.microsoft.com/en-us/platform/support/policy/extensions)
lists supported packages and current versions. This stage differs by release type and package novelty.

## Decision gate

1. Determine whether the release is **monthly** or **servicing**.
2. Determine whether the shipped scope includes any **newly published packages**.

Then follow one path:

- **Monthly release** -> review partner-team PR (Path A).
- **Servicing release, existing packages only** -> skip Stage 7 (Path B).
- **Servicing release with new package(s)** -> release manager authors `dotnet/website` PR (Path C).

## Path A - Monthly release (review partner-team PR)

The support page is maintained by a partner team in the monthly flow; this path is a review.

## Steps

Expand All @@ -15,6 +31,26 @@ The [.NET Platform Extensions support policy page](https://dotnet.microsoft.com/
Exclude preview-only packages, which are not listed.
4. If the pull request is missing or incomplete, raise it with the partner team.

## Path B - Servicing release with existing packages only

No support-page PR is required. Record that Stage 7 is intentionally skipped because the servicing
release did not introduce new package entries.

## Path C - Servicing release with newly published package(s)

In servicing flow, the release manager owns the website update when a new package is introduced.

1. Create a PR in [`dotnet/website`](https://github.com/dotnet/website) updating
`website/src/netlandingpage/Pages/platform/support/policy/extensions.cshtml`.
2. Update:
- supported version and release date for this release,
- package list entries for newly published packages,
- any required out-of-support table changes.
3. Ensure preview-only packages are not listed.
4. Submit the PR and track it to completion as part of release sign-off.

## After the stage

This is the final validation step. The release is complete once its symbols are public (Stage 5), the branches are reconciled (Stage 6), and the support-page listing is confirmed.
This is the final validation step when applicable. The release is complete once symbols are public
(Stage 5), branch reconciliation is complete when required (Stage 6), and Stage 7 obligations for the
selected path are satisfied.
Loading