Release v1.1.0 (#1411)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
123f9728ff
commit
ca040d77ec
4 changed files with 888 additions and 235 deletions
307
.github/skills/prepare-release/SKILL.md
vendored
Normal file
307
.github/skills/prepare-release/SKILL.md
vendored
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
---
|
||||
name: prepare-release
|
||||
description: Prepare a new release for the C# MCP SDK. Assesses Semantic Versioning level (PATCH/MINOR/MAJOR), bumps the version, runs ApiCompat and ApiDiff, reviews documentation, updates changelogs, drafts release notes, and creates a pull request with all release artifacts. Use when asked to prepare a release, start a release, create a release PR, or assess what the next release should be.
|
||||
compatibility: Requires gh CLI with repo access, GitHub API access for PR details and timeline events, dotnet CLI for building and packing, and git for branch management.
|
||||
---
|
||||
|
||||
# Prepare Release
|
||||
|
||||
Prepare a new release for the `modelcontextprotocol/csharp-sdk` repository. This skill assesses the appropriate [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html) level based on queued changes, bumps the version, runs API compatibility and diff tools, reviews documentation, drafts release notes, and creates a pull request containing all release artifacts.
|
||||
|
||||
> **Safety: This skill creates a local branch and PR. It must never create a GitHub release.** Release creation is handled by the **publish-release** skill after this PR is merged.
|
||||
|
||||
> **User confirmation required: This skill NEVER pushes a branch or creates a pull request without explicit user confirmation.** The user must review and approve all details before any remote operations occur.
|
||||
|
||||
## Process
|
||||
|
||||
Work through each step sequentially. Present findings at each step and get user confirmation before proceeding. Skip any step that has no applicable items.
|
||||
|
||||
### Step 1: Determine Target and Gather PRs
|
||||
|
||||
The user may provide:
|
||||
- **A git ref** (commit SHA, branch, or tag) — use as the target commit
|
||||
- **No context** — show the last 5 commits on `main` (noting HEAD) and offer the option to enter a branch or tag name instead
|
||||
|
||||
Once the target is established:
|
||||
1. Determine the previous release tag from `gh release list` (most recent **published** release — exclude drafts with `--exclude-drafts`).
|
||||
2. Get the full list of PRs merged between the previous release tag and the target commit.
|
||||
3. Read `src/Directory.Build.props` **at the target commit**. Extract `<VersionPrefix>` as the **candidate version**.
|
||||
|
||||
### Step 2: Categorize and Attribute
|
||||
|
||||
Sort every PR into one of four categories. See [references/categorization.md](references/categorization.md) for detailed guidance.
|
||||
|
||||
| Category | Content |
|
||||
|----------|---------|
|
||||
| **What's Changed** | Features, bug fixes, improvements, breaking changes |
|
||||
| **Documentation Updates** | PRs whose sole purpose is documentation |
|
||||
| **Test Improvements** | Adding, fixing, or unskipping tests; flaky test repairs |
|
||||
| **Repository Infrastructure Updates** | CI/CD, dependency bumps, version bumps, build system |
|
||||
|
||||
**Entry format** — `* Description #PR by @author` with co-authors when present:
|
||||
```
|
||||
* Description #PR by @author
|
||||
* Description #PR by @author (co-authored by @user1 @Copilot)
|
||||
```
|
||||
|
||||
**Attribution rules:**
|
||||
- Harvest `Co-authored-by` trailers from all commits in each PR's merge commit
|
||||
- For Copilot-authored PRs, check the `copilot_work_started` timeline event to identify the triggering user. That person becomes the primary author; `@Copilot` becomes a co-author
|
||||
- Omit the co-author parenthetical when there are none
|
||||
- Sort entries within each section by merge date (chronological)
|
||||
|
||||
### Step 3: Breaking Change Audit
|
||||
|
||||
Invoke the **breaking-changes** skill with the commit range from the previous release tag to the target commit. Examine every PR, assess impact, reconcile labels (offering to add/remove labels and comment on PRs), and get user confirmation.
|
||||
|
||||
Use the results (confirmed breaking changes with impact ordering and detail bullets) in the remaining steps.
|
||||
|
||||
### Step 4: Assess Release Version
|
||||
|
||||
Using the categorized PRs from Step 2 and confirmed breaking changes from Step 3, assess the appropriate [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html) release level. Follow the [SemVer assessment guide](../bump-version/references/semver-assessment.md) (owned by the **bump-version** skill) for the full assessment criteria.
|
||||
|
||||
1. **Classify the release level**:
|
||||
- **MAJOR** — if any confirmed breaking changes are present (API or behavioral), excluding changes to `[Experimental]` APIs
|
||||
- **MINOR** — if no breaking changes but new public APIs, features, or obsoletion warnings are introduced
|
||||
- **PATCH** — otherwise
|
||||
2. **Compute the recommended version** from the previous release tag:
|
||||
- Increment the appropriate component (MAJOR resets MINOR.PATCH to 0; MINOR resets PATCH to 0)
|
||||
3. **Compare against the candidate version** from `src/Directory.Build.props`. Flag any discrepancy:
|
||||
- **Under-versioned**: The candidate is lower than the recommended level. This is a concern that should be resolved.
|
||||
- **Over-versioned**: The candidate is higher than strictly required. This is acceptable under SemVer but worth noting.
|
||||
4. **Present the assessment** with a summary table showing the previous release, change classification, recommended level, recommended version, and any discrepancy with the candidate. Include a brief rationale citing the most significant PRs.
|
||||
5. **Get user confirmation** of the release version before proceeding.
|
||||
|
||||
### Step 5: Create Release Branch and Bump Version
|
||||
|
||||
After the version is confirmed:
|
||||
|
||||
1. Create a local branch named `release-{version}` from the target commit (e.g., `release-1.1.0`).
|
||||
2. Update `src/Directory.Build.props`:
|
||||
- Set `<VersionPrefix>` to the confirmed version
|
||||
- Update `<PackageValidationBaselineVersion>` if the MAJOR version has changed (set to the previous release version)
|
||||
3. Build the solution to verify the version change compiles: `dotnet build`
|
||||
|
||||
This step creates local changes only — nothing is committed or pushed yet.
|
||||
|
||||
### Step 6: Run API Compatibility Check
|
||||
|
||||
Run API compatibility validation against the baseline version. Follow [references/apicompat-apidiff.md](references/apicompat-apidiff.md) for the full procedure.
|
||||
|
||||
1. Run `dotnet pack` to trigger package validation against `PackageValidationBaselineVersion`
|
||||
2. Capture the ApiCompat output (compatibility issues, warnings, suppressions)
|
||||
3. If there are unexpected compatibility breaks:
|
||||
- Cross-reference with the breaking change audit from Step 3
|
||||
- Present any unaccounted breaks to the user
|
||||
- If breaks are intentional, add appropriate entries to `CompatibilitySuppressions.xml` in the affected project directory
|
||||
4. Record the ApiCompat results for inclusion in the PR description
|
||||
|
||||
### Step 7: Generate API Diff Report
|
||||
|
||||
Generate a human-readable diff of the public API surface between the previous release and the new version. Follow [references/apicompat-apidiff.md](references/apicompat-apidiff.md) for the full procedure, including how to install the `Microsoft.DotNet.ApiDiff.Tool` from the .NET transport feed.
|
||||
|
||||
1. Install `Microsoft.DotNet.ApiDiff.Tool` from the transport feed if not already installed (requires `--prerelease` and `--add-source` pointing to `https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet{MAJOR}-transport/nuget/v3/index.json`)
|
||||
2. Download the baseline packages and build the current version in Release configuration
|
||||
3. Run `dotnet apidiff` comparing baseline vs. current assemblies for each SDK package
|
||||
4. Format the diff as markdown for inclusion in the PR description
|
||||
|
||||
> **If the ApiDiff tool cannot be installed or fails to produce output, STOP and inform the user.** Present the error and ask how to proceed. Do not fall back to a manual summary — the user must decide whether to troubleshoot, skip the API diff, or abort.
|
||||
|
||||
### Step 8: Review and Update Documentation
|
||||
|
||||
Review repository documentation for changes needed to compensate for or adapt to this release:
|
||||
|
||||
1. **NuGet package READMEs** — Validate that code samples in `README.md` and `src/PACKAGE.md` compile against the current SDK. Follow [references/readme-snippets.md](references/readme-snippets.md) for the validation procedure. Propose fixes for any API mismatches.
|
||||
2. **Conceptual documentation** — Review `docs/` for content affected by the changes in this release. Update references to changed APIs, new features, or removed functionality.
|
||||
3. **Versioning documentation** — If the release introduces new versioning-relevant policies (new experimental APIs, obsoletion changes), verify `docs/versioning.md` reflects them.
|
||||
4. **Changelogs** — If the repository contains changelog files (e.g., `CHANGELOG.md`), update them with the release information. If no changelogs exist, skip this sub-step and note it in the summary.
|
||||
|
||||
Stage all documentation changes for inclusion in the release commit.
|
||||
|
||||
### Step 9: Draft Release Notes
|
||||
|
||||
Compose the release notes that will appear in the PR description and serve as the foundation for the **publish-release** skill. This is a draft — the final release notes will be refreshed when the GitHub release is created.
|
||||
|
||||
1. **Preamble** — Draft a short paragraph summarizing the release theme. Present it to the user for review and editing. The preamble is **required**.
|
||||
2. **Breaking Changes** — sorted most → least impactful (from Step 3 results). Include the versioning docs link.
|
||||
3. **What's Changed** — chronological; includes breaking change PRs
|
||||
4. **Documentation Updates** — chronological
|
||||
5. **Test Improvements** — chronological
|
||||
6. **Repository Infrastructure Updates** — chronological
|
||||
7. **Acknowledgements**:
|
||||
- New contributors (first contribution in this release)
|
||||
- Issue reporters (cite resolving PRs)
|
||||
- PR reviewers (single bullet, sorted by review count, no count shown)
|
||||
8. **Full Changelog** link
|
||||
|
||||
Omit empty sections. Present each section for user review before proceeding.
|
||||
|
||||
### Step 10: Commit Changes
|
||||
|
||||
Commit all changes to the `release-{version}` branch:
|
||||
|
||||
1. Stage all modified files (version bump, compatibility suppressions, documentation updates, changelog updates)
|
||||
2. Commit with message: `Prepare release v{version}`
|
||||
3. Do **not** push yet
|
||||
|
||||
### Step 11: Present Release Summary
|
||||
|
||||
Present **all** of the following details to the user for review. The user must confirm every aspect before proceeding to Step 12.
|
||||
|
||||
1. **Version number** with brief rationale for why this SemVer level was selected
|
||||
2. **Branch name** (e.g., `release-1.1.0`)
|
||||
3. **Remote** the branch would be pushed to (show the configured remote, typically `origin`)
|
||||
4. **Files changed** — list every file modified in the commit with a one-line summary of what changed in each:
|
||||
```
|
||||
src/Directory.Build.props — Version bumped from 1.0.0 to 1.1.0
|
||||
src/ModelContextProtocol.Core/CompatibilitySuppressions.xml — Added 2 new suppressions
|
||||
README.md — Updated code sample for new API
|
||||
docs/experimental.md — Added new experimental API reference
|
||||
```
|
||||
5. **Draft release notes** — the complete release notes from Step 9
|
||||
6. **API Compatibility results** — the ApiCompat output from Step 6
|
||||
7. **API Diff report** — the API diff from Step 7
|
||||
8. **Proposed PR title** (e.g., `Release v1.1.0`)
|
||||
9. **Proposed PR description** — the assembled content combining release notes, ApiCompat, and ApiDiff
|
||||
|
||||
After presenting all details, explicitly ask the user:
|
||||
> Would you like to push the branch and create the pull request?
|
||||
|
||||
**Do not proceed without explicit "yes" confirmation.**
|
||||
|
||||
### Step 12: Push Branch and Create Pull Request
|
||||
|
||||
Only after explicit user confirmation in Step 11:
|
||||
|
||||
1. Push the `release-{version}` branch to the remote
|
||||
2. Create a pull request:
|
||||
- **Title**: `Release v{version}`
|
||||
- **Base**: default branch (typically `main`)
|
||||
- **Head**: `release-{version}`
|
||||
- **Description**: The assembled PR description (see PR Description Template below)
|
||||
- **Labels**: Apply appropriate labels (e.g., `release`)
|
||||
3. Present the PR URL to the user
|
||||
|
||||
**Important**: No draft GitHub release is created at this point. The **publish-release** skill handles release creation after this PR is merged.
|
||||
|
||||
## Edge Cases
|
||||
|
||||
- **PR spans categories**: categorize by primary intent
|
||||
- **Copilot timeline missing**: fall back to `Co-authored-by` trailers; if still unclear, use `@Copilot` as primary author
|
||||
- **No breaking changes**: omit the Breaking Changes section from release notes entirely
|
||||
- **Single breaking change**: use the same numbered format as multiple
|
||||
- **No user-facing changes**: if all PRs are documentation, tests, or infrastructure, flag that a release may not be warranted and ask the user whether to proceed
|
||||
- **Version discrepancy**: if the candidate version from `Directory.Build.props` doesn't match the SemVer assessment, present the discrepancy and let the user decide the final version
|
||||
- **No previous release**: if this is the first release, there is no previous tag; gather all PRs merged to the target
|
||||
- **ApiCompat tooling unavailable**: fall back to `dotnet pack` output; note in the PR description that full ApiCompat was run via package validation only
|
||||
- **API diff tool installation fails**: do not fall back to a manual summary; pause and present the installation error to the user, offering options to troubleshoot, skip the API diff section, or abort the release preparation
|
||||
- **No changelogs in repo**: skip changelog updates; note in the summary
|
||||
- **Branch already exists**: if `release-{version}` already exists locally or remotely, ask the user whether to reuse it, delete and recreate, or choose a different name
|
||||
- **PackageValidationBaselineVersion update**: when bumping MAJOR version, update the baseline to the previous release version; when bumping MINOR or PATCH, keep the existing baseline
|
||||
- **CompatibilitySuppressions.xml**: when intentional breaks are found, add suppression entries and include the file in the commit; existing suppressions should be preserved
|
||||
- **User declines PR creation**: if the user declines at Step 11, leave the local branch intact so they can review, modify, or push manually
|
||||
|
||||
## PR Description Template
|
||||
|
||||
The PR description combines release notes, ApiCompat, and ApiDiff into a single document. Omit empty sections.
|
||||
|
||||
```markdown
|
||||
# Release v{version}
|
||||
|
||||
[Preamble — summarize the release theme]
|
||||
|
||||
## Release Notes
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
Refer to the [C# SDK Versioning](https://modelcontextprotocol.github.io/csharp-sdk/versioning.html) documentation for details on versioning and breaking change policies.
|
||||
|
||||
1. **Description #PR**
|
||||
* Detail of the break
|
||||
* Migration guidance
|
||||
|
||||
### What's Changed
|
||||
|
||||
* Description #PR by @author (co-authored by @user1 @Copilot)
|
||||
|
||||
### Documentation Updates
|
||||
|
||||
* Description #PR by @author
|
||||
|
||||
### Test Improvements
|
||||
|
||||
* Description #PR by @author
|
||||
|
||||
### Repository Infrastructure Updates
|
||||
|
||||
* Description #PR by @author
|
||||
|
||||
### Acknowledgements
|
||||
|
||||
* @user made their first contribution in #PR
|
||||
* @user1 @user2 @user3 reviewed pull requests
|
||||
|
||||
**Full Changelog**: https://github.com/modelcontextprotocol/csharp-sdk/compare/previous-tag...release-{version}
|
||||
|
||||
---
|
||||
|
||||
## API Compatibility Report
|
||||
|
||||
[ApiCompat output — pass/fail status per package and any issues or suppressions]
|
||||
|
||||
## API Diff Report
|
||||
|
||||
### ModelContextProtocol.Core
|
||||
|
||||
[API diff — additions, removals, changes]
|
||||
|
||||
### ModelContextProtocol
|
||||
|
||||
[API diff — additions, removals, changes]
|
||||
|
||||
### ModelContextProtocol.AspNetCore
|
||||
|
||||
[API diff — additions, removals, changes]
|
||||
```
|
||||
|
||||
## Release Notes Template
|
||||
|
||||
The release notes section within the PR description uses the same format as the final GitHub release notes (used by the **publish-release** skill). This ensures consistency between the PR and the published release.
|
||||
|
||||
Omit empty sections. The preamble is **always required** — it is not inside a section heading.
|
||||
|
||||
```markdown
|
||||
[Preamble — REQUIRED. Summarize the release theme.]
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
Refer to the [C# SDK Versioning](https://modelcontextprotocol.github.io/csharp-sdk/versioning.html) documentation for details on versioning and breaking change policies.
|
||||
|
||||
1. **Description #PR**
|
||||
* Detail of the break
|
||||
* Migration guidance
|
||||
|
||||
## What's Changed
|
||||
|
||||
* Description #PR by @author (co-authored by @user1 @Copilot)
|
||||
|
||||
## Documentation Updates
|
||||
|
||||
* Description #PR by @author (co-authored by @user1 @Copilot)
|
||||
|
||||
## Test Improvements
|
||||
|
||||
* Description #PR by @author (co-authored by @user1 @Copilot)
|
||||
|
||||
## Repository Infrastructure Updates
|
||||
|
||||
* Description #PR by @author (co-authored by @user1 @Copilot)
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
* @user made their first contribution in #PR
|
||||
* @user submitted issue #1234 (resolved by #5678)
|
||||
* @user1 @user2 @user3 reviewed pull requests
|
||||
|
||||
**Full Changelog**: https://github.com/modelcontextprotocol/csharp-sdk/compare/previous-tag...new-tag
|
||||
```
|
||||
204
.github/skills/prepare-release/references/apicompat-apidiff.md
vendored
Normal file
204
.github/skills/prepare-release/references/apicompat-apidiff.md
vendored
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
# API Compatibility and Diff Guide
|
||||
|
||||
This reference describes how to run API compatibility checks and generate API diff reports for the C# MCP SDK release process.
|
||||
|
||||
## API Compatibility Check (ApiCompat)
|
||||
|
||||
The SDK uses NuGet's [Package Validation](https://learn.microsoft.com/dotnet/fundamentals/package-validation/overview) to verify API compatibility between releases. This is configured in `src/Directory.Build.props`:
|
||||
|
||||
```xml
|
||||
<EnablePackageValidation>true</EnablePackageValidation>
|
||||
<PackageValidationBaselineVersion>1.0.0</PackageValidationBaselineVersion>
|
||||
```
|
||||
|
||||
### Running ApiCompat
|
||||
|
||||
1. **Pack the SDK packages** to trigger validation:
|
||||
```sh
|
||||
dotnet pack src/ModelContextProtocol.Core/ModelContextProtocol.Core.csproj
|
||||
dotnet pack src/ModelContextProtocol/ModelContextProtocol.csproj
|
||||
dotnet pack src/ModelContextProtocol.AspNetCore/ModelContextProtocol.AspNetCore.csproj
|
||||
```
|
||||
Or pack all at once:
|
||||
```sh
|
||||
dotnet pack
|
||||
```
|
||||
|
||||
2. **Capture the output.** Package validation compares the current public API against the baseline version downloaded from NuGet. Any compatibility issues appear as build warnings or errors.
|
||||
|
||||
3. **Interpret results:**
|
||||
- **No issues**: The API is backward-compatible with the baseline. This is the expected result for PATCH and MINOR releases.
|
||||
- **Compatibility errors**: The API has breaking changes relative to the baseline. These should align with the breaking change audit from Step 3 of the prepare-release skill.
|
||||
- **Suppressions needed**: If intentional breaking changes are confirmed, add entries to `CompatibilitySuppressions.xml` in the affected project directory.
|
||||
|
||||
### Updating the Baseline Version
|
||||
|
||||
- **MAJOR version bump**: Update `<PackageValidationBaselineVersion>` to the previous release version so that ApiCompat validates against the last stable release of the prior MAJOR version. After the new MAJOR release is published, the baseline stays at the new version for future comparisons.
|
||||
- **MINOR or PATCH version bump**: Keep `<PackageValidationBaselineVersion>` at the last MAJOR release version (e.g., keep `1.0.0` when releasing `1.1.0` or `1.0.1`).
|
||||
|
||||
### Compatibility Suppressions
|
||||
|
||||
When intentional breaking changes are confirmed, create or update `CompatibilitySuppressions.xml` in the affected project directory. The repo already uses this pattern — see `src/ModelContextProtocol.Core/CompatibilitySuppressions.xml` for examples.
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:ModelContextProtocol.SomeType.SomeMethod(System.String)</Target>
|
||||
<Left>lib/net10.0/ModelContextProtocol.Core.dll</Left>
|
||||
<Right>lib/net10.0/ModelContextProtocol.Core.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
</Suppressions>
|
||||
```
|
||||
|
||||
The exact suppression entries are generated by the pack command when it reports errors — copy the suggested suppression XML from the build output. Remember that suppressions are needed **per target framework** (net10.0, net9.0, net8.0, netstandard2.0).
|
||||
|
||||
### Common Diagnostic IDs
|
||||
|
||||
| ID | Meaning |
|
||||
|----|---------|
|
||||
| CP0001 | Type or member exists in left but not in right (removed) |
|
||||
| CP0002 | Member signature changed |
|
||||
| CP0005 | Virtual member removed from unsealed type |
|
||||
| CP0006 | Parameter or return type changed |
|
||||
| CP0008 | Sealed type was previously unsealed |
|
||||
|
||||
See the [full diagnostic list](https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids) for details.
|
||||
|
||||
## API Diff Report (ApiDiff)
|
||||
|
||||
The API diff report provides a human-readable summary of public API changes between the previous release and the new version. This is included in the release PR description alongside the ApiCompat results.
|
||||
|
||||
> **Important:** If the ApiDiff tool cannot be installed or fails to produce output, the release preparation process must **pause**. Do not fall back to a manual summary. Instead, present the error to the user and ask how to proceed. The user may choose to troubleshoot the tool, skip the API diff section, or abort the release preparation.
|
||||
|
||||
### Installing Microsoft.DotNet.ApiDiff.Tool
|
||||
|
||||
The `Microsoft.DotNet.ApiDiff.Tool` is published on the .NET **transport feed**, not on NuGet.org. The transport feed URL follows the pattern `https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet{MAJOR}-transport/nuget/v3/index.json`, where `{MAJOR}` is the major version of the .NET SDK from `global.json`.
|
||||
|
||||
1. **Determine the SDK major version** from `global.json`:
|
||||
```sh
|
||||
# Read the SDK version — e.g. "10.0.100" → MAJOR is 10
|
||||
cat global.json
|
||||
```
|
||||
|
||||
2. **Install the tool** globally with the `--prerelease` flag (required since the tool is only published as prerelease):
|
||||
```sh
|
||||
dotnet tool install --global Microsoft.DotNet.ApiDiff.Tool \
|
||||
--prerelease \
|
||||
--add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet{MAJOR}-transport/nuget/v3/index.json
|
||||
```
|
||||
For example, with .NET SDK 10.x:
|
||||
```sh
|
||||
dotnet tool install --global Microsoft.DotNet.ApiDiff.Tool \
|
||||
--prerelease \
|
||||
--add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10-transport/nuget/v3/index.json
|
||||
```
|
||||
|
||||
3. **Verify installation**:
|
||||
```sh
|
||||
dotnet apidiff --help
|
||||
```
|
||||
|
||||
If the tool is already installed, update it with `dotnet tool update` using the same flags.
|
||||
|
||||
> **Reference:** The dotnet/core repo's [RunApiDiff.md](https://github.com/dotnet/core/blob/main/release-notes/RunApiDiff.md) documents this same tool and transport feed approach for generating API diff reports between .NET releases.
|
||||
|
||||
### Generating the API Diff
|
||||
|
||||
1. **Build the current version** in Release configuration:
|
||||
```sh
|
||||
dotnet build -c Release
|
||||
```
|
||||
|
||||
2. **Download the baseline packages** from NuGet:
|
||||
```sh
|
||||
mkdir api-diff-temp && cd api-diff-temp
|
||||
dotnet new console
|
||||
dotnet add package ModelContextProtocol.Core --version {baseline-version}
|
||||
dotnet add package ModelContextProtocol --version {baseline-version}
|
||||
dotnet add package ModelContextProtocol.AspNetCore --version {baseline-version}
|
||||
dotnet restore
|
||||
```
|
||||
|
||||
3. **Run the diff** for each package, comparing the baseline assembly against the current build. Use `dotnet apidiff` with `-l` (left/baseline) and `-r` (right/current):
|
||||
```sh
|
||||
# ModelContextProtocol.Core
|
||||
dotnet apidiff \
|
||||
-l ~/.nuget/packages/modelcontextprotocol.core/{baseline-version}/lib/net10.0/ModelContextProtocol.Core.dll \
|
||||
-r ../artifacts/bin/ModelContextProtocol.Core/Release/net10.0/ModelContextProtocol.Core.dll
|
||||
|
||||
# ModelContextProtocol
|
||||
dotnet apidiff \
|
||||
-l ~/.nuget/packages/modelcontextprotocol/{baseline-version}/lib/net10.0/ModelContextProtocol.dll \
|
||||
-r ../artifacts/bin/ModelContextProtocol/Release/net10.0/ModelContextProtocol.dll
|
||||
|
||||
# ModelContextProtocol.AspNetCore
|
||||
dotnet apidiff \
|
||||
-l ~/.nuget/packages/modelcontextprotocol.aspnetcore/{baseline-version}/lib/net10.0/ModelContextProtocol.AspNetCore.dll \
|
||||
-r ../artifacts/bin/ModelContextProtocol.AspNetCore/Release/net10.0/ModelContextProtocol.AspNetCore.dll
|
||||
```
|
||||
|
||||
> **Note:** The exact CLI flags may vary by version. Run `dotnet apidiff --help` to confirm the available options. If the tool uses different argument names (e.g., `--left`/`--right`, `--before`/`--after`, or positional arguments), adapt accordingly.
|
||||
|
||||
4. **Capture the output** for each package and format as markdown fenced code blocks with `diff` syntax highlighting.
|
||||
|
||||
5. **Repeat for other target frameworks** if a more comprehensive report is desired (e.g., `net9.0`, `net8.0`, `netstandard2.0`). At minimum, diff the highest TFM (`net10.0`).
|
||||
|
||||
### Per-Package Reports
|
||||
|
||||
Generate separate reports for each SDK package:
|
||||
- **ModelContextProtocol.Core** — the core library with minimal dependencies
|
||||
- **ModelContextProtocol** — the main package with hosting and DI extensions
|
||||
- **ModelContextProtocol.AspNetCore** — HTTP-based server implementations
|
||||
|
||||
### Cleanup
|
||||
|
||||
After generating the reports, delete any temporary files (downloaded baseline packages, generated API files, temp projects). These must not be committed.
|
||||
|
||||
## Presenting Results
|
||||
|
||||
### In the PR Description
|
||||
|
||||
Include both reports in the PR description under dedicated sections:
|
||||
|
||||
```markdown
|
||||
---
|
||||
|
||||
## API Compatibility Report
|
||||
|
||||
✅ All packages pass API compatibility validation against v{baseline-version}.
|
||||
|
||||
_or_
|
||||
|
||||
⚠️ API compatibility issues detected (suppressions added for intentional breaks):
|
||||
|
||||
[Detailed ApiCompat output]
|
||||
|
||||
## API Diff Report
|
||||
|
||||
### ModelContextProtocol.Core
|
||||
|
||||
[Diff or table of changes]
|
||||
|
||||
### ModelContextProtocol
|
||||
|
||||
[Diff or table of changes]
|
||||
|
||||
### ModelContextProtocol.AspNetCore
|
||||
|
||||
[Diff or table of changes]
|
||||
```
|
||||
|
||||
### In the User Summary (Step 11)
|
||||
|
||||
Present a condensed version for the user review:
|
||||
|
||||
- **ApiCompat**: pass/fail with count of issues and suppressions per package
|
||||
- **ApiDiff**: count of additions, removals, and changes per package
|
||||
|
||||
```
|
||||
API Compatibility: ✅ All 3 packages pass (2 existing suppressions in Core)
|
||||
API Diff: +12 additions, -2 removals, ~3 changes across all packages
|
||||
```
|
||||
116
.github/skills/prepare-release/references/categorization.md
vendored
Normal file
116
.github/skills/prepare-release/references/categorization.md
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
# Categorization Guide
|
||||
|
||||
## Category Definitions
|
||||
|
||||
### What's Changed
|
||||
Feature work, bug fixes, API improvements, performance enhancements, and any other user-facing changes. This includes:
|
||||
- New API surface area (new types, methods, properties)
|
||||
- Bug fixes that affect runtime behavior
|
||||
- Performance improvements
|
||||
- Breaking changes (these appear in both "Breaking Changes" and "What's Changed")
|
||||
- Changes that span code + docs (categorize based on the primary intent)
|
||||
|
||||
### Documentation Updates
|
||||
PRs whose **sole purpose** is documentation. Examples:
|
||||
- Fixing typos in docs
|
||||
- Adding or improving XML doc comments (when not part of a functional change)
|
||||
- Updating conceptual documentation (e.g., files in `docs/`)
|
||||
- README updates
|
||||
- Adding CONTRIBUTING.md or similar guides
|
||||
|
||||
**Important**: A PR that changes code AND updates docs should go in "What's Changed" — only pure documentation PRs belong here. However, documentation PRs should still be studied during the breaking change audit, as they may document changes that were not properly flagged as breaking.
|
||||
|
||||
### Repository Infrastructure Updates
|
||||
PRs that maintain the development environment but don't affect the shipped product or test coverage. Examples:
|
||||
- Version bumps (`Bump version to X.Y.Z`)
|
||||
- CI/CD workflow changes (GitHub Actions updates)
|
||||
- Dependency updates from Dependabot
|
||||
- Build system changes
|
||||
- Dev container or codespace configuration
|
||||
- Copilot instructions updates
|
||||
- NuGet/package configuration changes
|
||||
|
||||
**Important**: PRs that touch the `tests/` folder should never be categorized as Infrastructure — they belong in either "Test Improvements" or "What's Changed" depending on whether product code was also modified.
|
||||
|
||||
### Test Improvements
|
||||
PRs focused on test quality, coverage, or reliability. Examples:
|
||||
- Adding new tests (unit, integration, regression, conformance)
|
||||
- Fixing broken or incorrect tests
|
||||
- Addressing flaky tests (timing, race conditions)
|
||||
- Unskipping or skipping tests
|
||||
- Test infrastructure improvements (new test helpers, test base classes)
|
||||
|
||||
**Important**: PRs that reference "MCP conformance tests" are not automatically test-only. Examine the PR body and file changes to determine whether product code was modified to achieve conformance — if so, the PR belongs in "What's Changed." Conformance PRs should never be placed in "Repository Infrastructure Updates."
|
||||
|
||||
## Entry Format
|
||||
|
||||
Use this simplified format (GitHub auto-links `#PR` and `@user`):
|
||||
```
|
||||
* Description #PR by @author
|
||||
```
|
||||
|
||||
For PRs with co-authors (harvested from `Co-authored-by` commit trailers):
|
||||
```
|
||||
* Description #PR by @author (co-authored by @user1 @user2)
|
||||
```
|
||||
|
||||
For Dependabot PRs, do not acknowledge @dependabot[bot]:
|
||||
```
|
||||
* Bump actions/checkout from 5.0.0 to 6.0.0 #1234
|
||||
```
|
||||
|
||||
For direct commits without an associated PR (e.g., version bumps merged directly to the branch), use the commit description and `by @author` but omit the `#PR` reference:
|
||||
```
|
||||
* Bump version to v0.1.0-preview.12 by @halter73
|
||||
```
|
||||
|
||||
For Copilot-authored PRs, identify who triggered Copilot using the `copilot_work_started` timeline event on the PR. That person becomes the primary author, and @Copilot becomes a co-author:
|
||||
```
|
||||
* Add trace-level logging for JSON-RPC payloads #1234 by @halter73 (co-authored by @Copilot)
|
||||
```
|
||||
|
||||
## Sorting
|
||||
|
||||
Sort entries within each section by **merge date** (chronological order, oldest first).
|
||||
|
||||
## Examples from Past Releases
|
||||
|
||||
### What's Changed (format example)
|
||||
```
|
||||
* Add Trace-level logging for JSON-RPC payloads in transports #1191 by @halter73 (co-authored by @Copilot)
|
||||
* Use Process.Kill(entireProcessTree: true) on .NET for faster process termination #1187 by @stephentoub
|
||||
* Include response body in HttpRequestException for transport client errors #1193 by @halter73 (co-authored by @Copilot)
|
||||
* Fix race condition in SSE GET request initialization #1212 by @stephentoub
|
||||
* Fix keyset pagination with monotonic UUIDv7-like task IDs #1215 by @halter73 (co-authored by @Copilot)
|
||||
* Add ILoggerFactory to StreamableHttpServerTransport #1213 by @halter73 (co-authored by @Copilot)
|
||||
* Add support for message-level filters to McpServer #1207 by @halter73
|
||||
* Add `DistributedCacheEventStreamStore` #1136 by @MackinnonBuck
|
||||
```
|
||||
|
||||
### Documentation Updates (format example)
|
||||
```
|
||||
* Fix typo in elicitation.md #1186 by @ruyut
|
||||
* Fix typo in progress.md #1189 by @ruyut
|
||||
* Clarify McpMetaAttribute documentation scope #1242 by @stephentoub (co-authored by @Copilot)
|
||||
```
|
||||
|
||||
### Repository Infrastructure Updates (format example)
|
||||
```
|
||||
* Bump version to 0.8.0-preview.1 #1181 by @stephentoub (co-authored by @Copilot)
|
||||
* Bump actions/checkout from 6.0.1 to 6.0.2 #1173
|
||||
* Bump the opentelemetry-testing group with 6 updates #1174
|
||||
```
|
||||
|
||||
### Test Improvements (format example)
|
||||
```
|
||||
* Remove 10 second wait from docker tests #1188 by @stephentoub
|
||||
* Fix Session_TracksActivities test #1200 by @stephentoub
|
||||
* Add serialization roundtrip tests for all Protocol namespace types #1289 by @stephentoub (co-authored by @Copilot)
|
||||
```
|
||||
|
||||
### Acknowledgements (format example)
|
||||
```
|
||||
* @ruyut made their first contribution in #1186
|
||||
* @user submitted issue #1234 (resolved by #5678)
|
||||
* @user1 @user2 @user3 reviewed pull requests
|
||||
```
|
||||
143
.github/skills/prepare-release/references/readme-snippets.md
vendored
Normal file
143
.github/skills/prepare-release/references/readme-snippets.md
vendored
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
# README Code Sample Validation
|
||||
|
||||
This reference describes how to validate that C# code samples in README files compile against the current SDK.
|
||||
|
||||
## Which READMEs to Validate
|
||||
|
||||
Validate code samples from the **package README** files — these are shipped with NuGet packages and are the primary documentation users see:
|
||||
|
||||
| README | Package |
|
||||
|--------|---------|
|
||||
| `README.md` (root) | ModelContextProtocol |
|
||||
| `src/ModelContextProtocol.Core/README.md` | ModelContextProtocol.Core |
|
||||
| `src/ModelContextProtocol.AspNetCore/README.md` | ModelContextProtocol.AspNetCore |
|
||||
|
||||
Sample README files (`samples/*/README.md`) are excluded — the samples themselves are buildable projects and are validated by CI.
|
||||
|
||||
## What to Extract
|
||||
|
||||
Extract only fenced code blocks tagged as `csharp` (` ```csharp `). Skip blocks tagged as plain ` ``` ` (shell commands, install instructions) or any other language.
|
||||
|
||||
### Handling Incomplete Snippets
|
||||
|
||||
README samples are often **incomplete** — they use `...` for placeholder values, omit `using` directives, or show only a method body. The validation wrapper must account for this:
|
||||
|
||||
- **Placeholder expressions** like `IChatClient chatClient = ...;` — replace `...` on the right-hand side of assignments with `null!`
|
||||
- **Missing usings** — the wrapper file supplies all common namespaces (see template below)
|
||||
- **Top-level statements** — wrap in an `async Task` method so `await` works
|
||||
- **Suppressed warnings** — disable CS1998 (async without await), CS8321 (unused local function), and similar non-substantive warnings
|
||||
|
||||
### Snippets That Cannot Be Validated
|
||||
|
||||
Some code blocks are illustrative fragments that cannot compile even with wrappers (e.g., partial class definitions shown in isolation, pseudo-code). If a snippet fails to compile after applying the standard fixups, examine the error:
|
||||
|
||||
- **API mismatch** (missing member, wrong type, wrong signature) → this is a **real bug** in the README that must be reported and fixed
|
||||
- **Structural issue** (missing context, incomplete fragment) → exclude this specific snippet from validation with a comment explaining why
|
||||
|
||||
## Test Project Approach
|
||||
|
||||
Create a **temporary** test project that references the SDK projects, wraps each README's code samples in compilable methods, and builds.
|
||||
|
||||
### Project File Template
|
||||
|
||||
```xml
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<NoWarn>CS1998;CS8321;CS0168;CS0219;CS1591;CS8602</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\ModelContextProtocol\ModelContextProtocol.csproj" />
|
||||
<ProjectReference Include="..\..\src\ModelContextProtocol.AspNetCore\ModelContextProtocol.AspNetCore.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
Place the project at `tests/ReadmeSnippetValidation/ReadmeSnippetValidation.csproj`.
|
||||
|
||||
### Source File Template
|
||||
|
||||
Create one `.cs` file per README. Each file wraps the README's code blocks in static methods inside a class. Use this pattern:
|
||||
|
||||
```csharp
|
||||
#pragma warning disable CS1998
|
||||
#pragma warning disable CS8321
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.AI;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ModelContextProtocol;
|
||||
using ModelContextProtocol.Client;
|
||||
using ModelContextProtocol.Protocol;
|
||||
using ModelContextProtocol.Server;
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ReadmeSnippetValidation;
|
||||
|
||||
public static class RootReadmeSamples
|
||||
{
|
||||
// Snippet 1: Client example
|
||||
public static async Task ClientExample()
|
||||
{
|
||||
// ... pasted snippet code ...
|
||||
}
|
||||
|
||||
// Snippet 2: Server example
|
||||
public static async Task ServerExample()
|
||||
{
|
||||
// ... pasted snippet code ...
|
||||
}
|
||||
|
||||
// Snippet with attributed types (tools, prompts) go as nested or sibling types
|
||||
[McpServerToolType]
|
||||
public static class EchoTool
|
||||
{
|
||||
[McpServerTool, Description("Echoes the message back to the client.")]
|
||||
public static string Echo(string message) => $"hello {message}";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Build Commands
|
||||
|
||||
```sh
|
||||
# Restore and build the validation project
|
||||
dotnet restore tests/ReadmeSnippetValidation/ReadmeSnippetValidation.csproj
|
||||
dotnet build tests/ReadmeSnippetValidation/ReadmeSnippetValidation.csproj
|
||||
|
||||
### Cleanup
|
||||
|
||||
After validation, **always delete** the `tests/ReadmeSnippetValidation/` directory. It must not be committed.
|
||||
|
||||
## Reporting Results
|
||||
|
||||
### All Snippets Compile
|
||||
|
||||
Report success and move to the next step:
|
||||
> ✅ All README code samples compile successfully against the current SDK.
|
||||
|
||||
### Compilation Failures
|
||||
|
||||
For each failure:
|
||||
1. Identify the README file and which code block failed
|
||||
2. Show the compiler error
|
||||
3. Classify the error:
|
||||
- **API mismatch**: The README uses an API that doesn't exist or has a different signature. This indicates the README is outdated and needs updating.
|
||||
- **Structural**: The snippet is a fragment that can't be wrapped. Note it for exclusion.
|
||||
4. For API mismatches, investigate the correct current API and propose a fix
|
||||
5. Present all findings to the user for confirmation before making any README edits
|
||||
|
||||
### Fixing Issues
|
||||
|
||||
If the user approves fixes:
|
||||
1. Edit the README files directly with minimal, surgical changes
|
||||
2. Re-run the validation build to confirm fixes compile
|
||||
3. Ensure the overall solution still builds: `dotnet build`
|
||||
4. Include the README fixes in the same release or as a prerequisite PR — the user decides
|
||||
Loading…
Reference in a new issue