.NET: add public API analyzers - #7935
Conversation
Add PublicAPI analyzer coverage for released .NET packages, including nullable-aware shipped baselines and unshipped API publish validation. Add automation to promote unshipped API entries into shipped baselines after release branches move forward. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds public API tracking and release safeguards for released .NET packages.
Changes:
- Adds nullable-aware shipped/unshipped API baselines per target framework.
- Integrates
Microsoft.CodeAnalysis.PublicApiAnalyzersand publish validation. - Adds API-promotion tooling, automation, and contributor guidance.
Reviewed changes
Copilot reviewed 74 out of 84 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/promote-shipped-apis.yml |
Automates API-baseline promotion PRs. |
CONTRIBUTING.md |
Documents API-baseline workflow. |
dotnet/Directory.Packages.props |
Pins the analyzer package. |
dotnet/nuget/nuget-package.props |
Wires analyzers and publish validation. |
dotnet/eng/scripts/promote-shipped-apis.ps1 |
Promotes unshipped API entries. |
dotnet/eng/scripts/test-unshipped-public-apis.ps1 |
Rejects unshipped APIs during publishing. |
dotnet/src/Microsoft.Agents.AI/PublicAPI/net8.0/PublicAPI.Shipped.txt |
Records net8.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI/PublicAPI/net8.0/PublicAPI.Unshipped.txt |
Initializes net8.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI/PublicAPI/net9.0/PublicAPI.Shipped.txt |
Records net9.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI/PublicAPI/net9.0/PublicAPI.Unshipped.txt |
Initializes net9.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI/PublicAPI/net10.0/PublicAPI.Shipped.txt |
Records net10.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI/PublicAPI/net10.0/PublicAPI.Unshipped.txt |
Initializes net10.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI/PublicAPI/net472/PublicAPI.Shipped.txt |
Records net472 shipped APIs. |
dotnet/src/Microsoft.Agents.AI/PublicAPI/net472/PublicAPI.Unshipped.txt |
Initializes net472 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt |
Records netstandard2.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt |
Initializes netstandard2.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Abstractions/PublicAPI/net8.0/PublicAPI.Shipped.txt |
Records net8.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Abstractions/PublicAPI/net8.0/PublicAPI.Unshipped.txt |
Initializes net8.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Abstractions/PublicAPI/net9.0/PublicAPI.Shipped.txt |
Records net9.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Abstractions/PublicAPI/net9.0/PublicAPI.Unshipped.txt |
Initializes net9.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Abstractions/PublicAPI/net10.0/PublicAPI.Shipped.txt |
Records net10.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Abstractions/PublicAPI/net10.0/PublicAPI.Unshipped.txt |
Initializes net10.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Abstractions/PublicAPI/net472/PublicAPI.Shipped.txt |
Records net472 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Abstractions/PublicAPI/net472/PublicAPI.Unshipped.txt |
Initializes net472 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Abstractions/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt |
Records netstandard2.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Abstractions/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt |
Initializes netstandard2.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Harness/PublicAPI/net8.0/PublicAPI.Shipped.txt |
Records net8.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Harness/PublicAPI/net8.0/PublicAPI.Unshipped.txt |
Initializes net8.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Harness/PublicAPI/net9.0/PublicAPI.Shipped.txt |
Records net9.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Harness/PublicAPI/net9.0/PublicAPI.Unshipped.txt |
Initializes net9.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Harness/PublicAPI/net10.0/PublicAPI.Shipped.txt |
Records net10.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Harness/PublicAPI/net10.0/PublicAPI.Unshipped.txt |
Initializes net10.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Harness/PublicAPI/net472/PublicAPI.Shipped.txt |
Records net472 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Harness/PublicAPI/net472/PublicAPI.Unshipped.txt |
Initializes net472 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Harness/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt |
Records netstandard2.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Harness/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt |
Initializes netstandard2.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.OpenAI/PublicAPI/net8.0/PublicAPI.Shipped.txt |
Records net8.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.OpenAI/PublicAPI/net8.0/PublicAPI.Unshipped.txt |
Initializes net8.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.OpenAI/PublicAPI/net9.0/PublicAPI.Shipped.txt |
Records net9.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.OpenAI/PublicAPI/net9.0/PublicAPI.Unshipped.txt |
Initializes net9.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.OpenAI/PublicAPI/net10.0/PublicAPI.Shipped.txt |
Records net10.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.OpenAI/PublicAPI/net10.0/PublicAPI.Unshipped.txt |
Initializes net10.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.OpenAI/PublicAPI/net472/PublicAPI.Shipped.txt |
Records net472 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.OpenAI/PublicAPI/net472/PublicAPI.Unshipped.txt |
Initializes net472 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.OpenAI/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt |
Records netstandard2.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.OpenAI/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt |
Initializes netstandard2.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows/PublicAPI/net8.0/PublicAPI.Shipped.txt |
Records net8.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows/PublicAPI/net8.0/PublicAPI.Unshipped.txt |
Initializes net8.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows/PublicAPI/net9.0/PublicAPI.Shipped.txt |
Records net9.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows/PublicAPI/net9.0/PublicAPI.Unshipped.txt |
Initializes net9.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows/PublicAPI/net10.0/PublicAPI.Shipped.txt |
Records net10.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows/PublicAPI/net10.0/PublicAPI.Unshipped.txt |
Initializes net10.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows/PublicAPI/net472/PublicAPI.Shipped.txt |
Records net472 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows/PublicAPI/net472/PublicAPI.Unshipped.txt |
Initializes net472 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt |
Records netstandard2.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt |
Initializes netstandard2.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PublicAPI/net8.0/PublicAPI.Shipped.txt |
Records net8.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PublicAPI/net8.0/PublicAPI.Unshipped.txt |
Initializes net8.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PublicAPI/net9.0/PublicAPI.Shipped.txt |
Records net9.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PublicAPI/net9.0/PublicAPI.Unshipped.txt |
Initializes net9.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PublicAPI/net10.0/PublicAPI.Shipped.txt |
Records net10.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PublicAPI/net10.0/PublicAPI.Unshipped.txt |
Initializes net10.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PublicAPI/net472/PublicAPI.Shipped.txt |
Records net472 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PublicAPI/net472/PublicAPI.Unshipped.txt |
Initializes net472 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt |
Records netstandard2.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt |
Initializes netstandard2.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/PublicAPI/net8.0/PublicAPI.Shipped.txt |
Records net8.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/PublicAPI/net8.0/PublicAPI.Unshipped.txt |
Initializes net8.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/PublicAPI/net9.0/PublicAPI.Shipped.txt |
Records net9.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/PublicAPI/net9.0/PublicAPI.Unshipped.txt |
Initializes net9.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/PublicAPI/net10.0/PublicAPI.Shipped.txt |
Records net10.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/PublicAPI/net10.0/PublicAPI.Unshipped.txt |
Initializes net10.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/PublicAPI/net472/PublicAPI.Shipped.txt |
Records net472 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/PublicAPI/net472/PublicAPI.Unshipped.txt |
Initializes net472 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt |
Records netstandard2.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt |
Initializes netstandard2.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/PublicAPI/net8.0/PublicAPI.Shipped.txt |
Records net8.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/PublicAPI/net8.0/PublicAPI.Unshipped.txt |
Initializes net8.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/PublicAPI/net9.0/PublicAPI.Shipped.txt |
Records net9.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/PublicAPI/net9.0/PublicAPI.Unshipped.txt |
Initializes net9.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/PublicAPI/net10.0/PublicAPI.Shipped.txt |
Records net10.0 shipped APIs. |
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/PublicAPI/net10.0/PublicAPI.Unshipped.txt |
Initializes net10.0 unshipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Generators/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt |
Records generator shipped APIs. |
dotnet/src/Microsoft.Agents.AI.Workflows.Generators/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt |
Initializes generator unshipped APIs. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
MAF Automated Review — Iteration 1
Result: Findings reported
Scope: full PR (1 commit(s)): 6e37574ced15
Model: gpt-5.6-sol
Overview
The PR consistently enables nullable-aware public API analysis for released packages, supplies per-TFM baselines, and adds automated validation and promotion scripts with scoped staging and lease-protected pushes. The analyzer is centrally pinned and private, while publish validation rejects populated unshipped files. Two baseline lifecycle gaps remain: the initial shipped snapshots include an API added after the latest release, and missing per-TFM baseline files silently disable both analysis and publish validation.
Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
2 verified findings remained after source verification (2 medium) across 2 files. Details are attached to the affected lines below.
Affected areas: dotnet/nuget/nuget-package.props, dotnet/src/Microsoft.Agents.AI/PublicAPI/net8.0/PublicAPI.Shipped.txt
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* .NET: expose OpenTelemetryAgent.DefaultSourceName The default ActivitySource name lives on the internal OpenTelemetryConsts class, so consumers cannot reference it when configuring a TracerProvider and must hardcode the literal "Experimental.Microsoft.Agents.AI" instead. ADR 0003 documents AgentOpenTelemetryConsts.DefaultSourceName for this, a type that no longer exists after the rename in microsoft#356. Expose the source name as a public const on OpenTelemetryAgent, the type that emits the spans, rather than making the whole constants class public. That keeps the gen_ai.* attribute keys internal, matching the Microsoft.Extensions.AI precedent, while making the documented AddSource call compile. Update the ADR snippet to the constant that now exists. * .NET: read DefaultSourceName at run time instead of inlining it A public const is baked into each consumer assembly at compile time, so a consumer built against one package version would keep subscribing to the old literal after upgrading to a version that changed the source name, and would silently stop receiving spans. That is the exact failure this API is meant to remove, so expose the value as a static property that is read at run time. Rename the test to describe what it actually asserts and point at the test that verifies emitted activities use the same source name. * .NET: document that AddSource and the agent source name must match The tracing pipeline only receives agent spans when the name registered with TracerProviderBuilder.AddSource matches the source name the agent emits under; a mismatch fails silently. Spell that pairing out in the sourceName XML docs on UseOpenTelemetry and the OpenTelemetryAgent constructors, and in the ADR usage example, which now also shows the custom-source case and uses the AsBuilder().UseOpenTelemetry() API that actually exists. * .NET: mark OpenTelemetryAgent.DefaultSourceName experimental DefaultSourceName is a new public API, so gate it behind MAAI001 and graduate it later if it proves useful. The ADR usage section notes that the diagnostic has to be suppressed to use the property. * .NET: declare DefaultSourceName in the public API baseline The public API analyzers added in microsoft#7935 require every public member of a released package to be listed in that package's PublicAPI baseline for each target framework. DefaultSourceName was added before those analyzers landed, so this branch built clean on its own but failed RS0016 once merged with main. Add the entry to all five Microsoft.Agents.AI baselines. Unshipped rather than Shipped, since the member has not been released yet; the promotion workflow moves it across after a release. --------- Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
Motivation & Context
The released .NET packages need build-time public API tracking so accidental public surface changes, source-breaking changes, and nullability changes are visible during review instead of only during packaging or release validation.
This change sets up Public API Analyzers for released .NET packages and adds shipped baselines for the APIs already released.
Description & Review Guide
Adds
Microsoft.CodeAnalysis.PublicApiAnalyzers5.6.0 to released .NET packages, introduces nullable-enabled per-target-frameworkPublicAPI.Shipped.txtandPublicAPI.Unshipped.txtbaselines, adds scripts to promote and validate unshipped API entries, and adds a workflow that opens or updates promotion PRs.Builds for released packages now fail when public API additions, removals, or nullability changes are not represented in the API baseline files. Publish packaging also fails if any unshipped API entries remain.
Please focus on the analyzer wiring in
dotnet/nuget/nuget-package.props, the per-TFM baseline layout, and the shipped API promotion workflow.Related Issue
Fixes #7933
No other open PR was found for this issue.
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.