Review Azure SDK management-plane pull requests, check naming conventions, API compatibility, and code quality.
Review Azure SDK for .NET management library pull requests against the official API review guidelines.
The review is split into three sequential phases: Phase 1: Versioning Review (gate), Phase 2: API Review, and Phase 3: Breaking Change Detection. Each phase must pass before proceeding to the next.
This phase checks version-related rules that are simple and rule-based. If any violation is found in this phase, stop the review immediately, submit the review with "Request Changes", and do not proceed to Phase 2.
.csproj file and CHANGELOG.md for the rules below.1.x to 2.0.0), flag as Critical: "You must not bump the major version without the .NET architects' explicit requirement."ApiCompatVersion. If a PR removes the ApiCompatVersion property from the .csproj file, flag as Critical. This property enforces API compatibility checks against the last stable release and must not be deleted. Removing it would allow breaking changes to slip through undetected.ApiCompatBaseline.txt. If the PR adds new entries to the ApiCompatBaseline.txt file (which suppresses ApiCompat errors), flag as Critical. Suppressing API compatibility errors hides breaking changes from customers. The correct approach is to mitigate breaking changes through customization code, not to baseline them away.This phase reviews the API surface for naming conventions, type correctness, and adherence to design guidelines. It runs only after Phase 1 passes.
The review should focus only on new or changed API surface compared to the RP's latest released stable version. Types, properties, and methods that were already shipped in a prior stable release cannot be changed and should not be flagged.
To determine the review scope:
ApiCompatVersion property in the package's .csproj file — since Phase 1 passed, this property is guaranteed to be present if it existed before. If ApiCompatVersion is not present, assume there is no prior stable version — the entire API surface is in scope for review and no breaking changes are possible.ApiCompatVersion is present, retrieve that version's API surface file from the corresponding git tag (tag format: <PackageName>_<Version>, e.g., Azure.ResourceManager.Foo_1.0.0). The API file is at sdk/<service>/<PackageName>/api/<PackageName>.net10.0.cs (or earlier TFM variants like netstandard2.0.cs).pwsh .github/skills/azure-sdk-mgmt-pr-review/Check-MgmtNamingRules.ps1 -PackagePath <package-path>
The script checks all rules in the "API Review Checklist" below and outputs violations with rule IDs, line numbers, and suggested fixes. Include every violation from the script output as an inline review comment.
If ApiCompatVersion is present (i.e., a prior stable version exists), pass the baseline API surface file to the script using -BaselineApiFilePath so it can deterministically filter out violations on unchanged API surface:
pwsh .github/skills/azure-sdk-mgmt-pr-review/Check-MgmtNamingRules.ps1 -ApiFilePath <current-api-file> -BaselineApiFilePath <baseline-api-file>
When -BaselineApiFilePath is provided, the script automatically excludes violations on types/members that existed unchanged in the prior stable release.client.tsp, tspconfig.yaml).| Suffix | Replace With | Exception |
|---|---|---|
| Parameter(s) | Content/Patch | - |
| Request | Content | - |
| Options | Config | Unless ClientOptions |
| Response | Result | - |
| Data | - | Unless derives from ResourceData/TrackedResourceData |
| Definition | - | Unless removing it creates conflict with another resource |
| Operation | Data or Info | Unless derives from Operation<T> |
| Collection | Group/List | Unless domain-specific (e.g., MongoDBCollection) |
Data property of an ArmResource must not include "Resource" before the "Data" suffix — e.g., VirtualMachineResourceData is not allowed; use VirtualMachineData instead.ArmCollection types must not include "Resource" before "Collection" — e.g., VirtualMachineResourceCollection is not allowed; use VirtualMachineCollection instead.*PrivateLinkResourceData and *PrivateLinkResourceCollection are allowed because "PrivateLinkResource" is the established ARM resource name.[Model]Patch[Model]Content or [Model]DataIs, Can, Has, Does, Should, Allow, Enable, Disable, Use, SupportOn or At (e.g., CreatedOn, StartOn, ExpiresAt)MonitoringIntervalInSeconds)TimeToLiveIn<Unit>Aes, Tcp, HttpIO), except Id, VmPublicNetworkAccess, EncryptionStatus, PrivateEndpointConnection — these names lack context; a reader cannot tell which service they belong to without looking at the namespace.StorageAccountPublicNetworkAccess, CosmosDBEncryptionStatus, KeyVaultPrivateEndpointConnection — these names include the service or resource context.When flagging a naming issue, the recommended fix depends on whether the type is explicitly defined in the service's TypeSpec.
@@clientName decorator in client.tsp.
@@clientName(PublicNetworkAccess, "DurableTaskPublicNetworkAccess", "csharp");@@clientName cannot be used. Instead, recommend SDK-side custom code — create a customization file (e.g., src/Customize/Models/<NewName>.cs) using [CodeGenType("OriginalGeneratedName")] to rename the type.
[CodeGenType("OptionalPropertiesUpdateableProperties")] on a class named DurableTaskPrivateEndpointConnectionPatchProperties.To determine whether a type is defined in the service's TypeSpec, search all .tsp files under the spec folder for a model, union, or enum declaration with the same name.
Tls1_0, Ver5_6The following table applies to the generated C# API surface (public types/properties in api/*.cs).
| Property Pattern | Expected Type |
|---|---|
Ends with Id/Guid with UUID value | Guid |
Ends with Id with ARM resource ID | ResourceIdentifier |
Named ResourceType or ends with Type for resource types | ResourceType |
Named etag | ETag |
Contains location/locations | Consider AzureLocation |
Contains size | Consider int/long instead of string |
For TypeSpec, UUID-valued properties should use the uuid scalar and map to Guid in the generated .NET SDK.
duration scalar in TypeSpec@encode(DurationConstant) in TypeSpecCheck[Resource/RP name]NameAvailability[Resource/RP name]NameAvailabilityXXX[Resource/RP name]NameUnavailableReasonabstractListOperations methods (SDK exposes operations via public APIs)This phase runs after Phase 2. If ApiCompatVersion is present in the .csproj (i.e., a prior stable version exists), check for breaking changes by building the project. The ApiCompat tooling will report breaking changes as build errors automatically.
dotnet build (or the appropriate build command for the package).ApiCompat errors — these indicate breaking changes against the last stable version (removals, signature changes, etc.).ApiCompat errors, this phase passes.ApiCompat errors are found:
rename-mapping, custom properties, shim methods) to preserve backward compatibility. The mitigate-breaking-changes skill can be invoked to assist with this.If ApiCompatVersion is not present in the .csproj, skip this phase — there is no prior stable version to compare against.
Submit a single pull request review with all findings as inline comments attached to the relevant file and line. Do not post findings as general PR comments.
gh CLI:
gh api repos/{owner}/{repo}/pulls/{pull_number}/reviews \
--method POST \
--header "Accept: application/vnd.github+json" \
--input - << 'EOF'
{
"event": "REQUEST_CHANGES",
"body": "<overall summary>",
"comments": [
{
"path": "<file>",
"line": <line>,
"side": "RIGHT",
"body": "<comment>"
}
]
}
EOF
event: "REQUEST_CHANGES" if any phase fails or there are blocking issues that must be resolved before merge.event: "APPROVE" if all phases pass and there are no issues requiring changes.event: "COMMENT" if all phases pass and there are only non-blocking/minor suggestions.ApiCompatVersion exists, include Phase 3 (Breaking Change Detection) results:
ApiCompat errors.