Skip to main content

mpg-migration

Handles Azure SDK for .NET management-plane migrations from AutoRest/Swagger to TypeSpec; use for MPG, mgmt migration, or Azure.ResourceManager.* migration requests.

Informações da origem

Repositório
Azure/azure-sdk-for-net
Última atividade na origem
12 de junho de 2026 às 08:35
Idioma detectado do SKILL.md
inglês
Estrelas
6.034
Forks
5.179

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
mpg-migration
description
Handles Azure SDK for .NET management-plane migrations from AutoRest/Swagger to TypeSpec; use for MPG, mgmt migration, or Azure.ResourceManager.* migration requests.
# MPG Migration Workflow Use for Azure SDK for .NET management-plane migrations from AutoRest/Swagger to TypeSpec for packages named `Azure.ResourceManager.*`. ## Inputs - SDK package path: `sdk/<service>/Azure.ResourceManager.<Service>/` - Local `azure-rest-api-specs` path if not at `../azure-rest-api-specs` - Branches in both repos, normally `<service>-mpg-migration` from `main` ## Non-Negotiables - Never hand-edit `src/Generated/` or `metadata.json`. - Never add ApiCompat baselines or disable ApiCompat/package validation, except targeted `WirePathAttribute` removal entries in the centralized baseline file. - Prefer `client.tsp` decorators with `"csharp"` scope before SDK custom code. - Root-cause every ApiCompat/API diff before adding custom code. - SDK custom code is only for backward compatibility or cases decorators cannot express. - Do not overwrite dirty user work in either repo. Ask the user only when the spec repo path is missing, a fix requires files beyond `client.tsp`, or a generator bug has no safe workaround. ## Setup 1. If resuming, read the draft SDK PR description first and continue from its phase/blockers. 2. Check `git status` in SDK and spec repos, then sync both to latest `main` without disturbing unrelated dirty files. 3. Fresh migration only: inventory and remove old SDK custom code (`src/Custom/`, `src/Customization/`, `src/Customized/`, hand-written partials, old shims) before first generation. Re-add only proven-needed compatibility shims later. 4. Remove AutoRest config: delete `<IncludeAutorestDependency>true</IncludeAutorestDependency>` and remove/replace `src/autorest.md`. 5. Set `tsp-location.yaml` to `emitterPackageJsonPath: eng/azure-typespec-http-client-csharp-mgmt-emitter-package.json`. 6. Generate with saved inputs so `tspCodeModel.json` is preserved for hierarchy checks. `-Services` must be the exact package folder name, not service directory: ```pwsh pwsh eng/packages/http-client-csharp-mgmt/eng/scripts/RegenSdkLocal.ps1 -Services "Azure.ResourceManager.<Service>" -LocalSpecRepoPath <path> -SaveInputs ``` Alternative from the package `src/` directory: `dotnet build /t:GenerateCode /p:SaveInputs=true`. 7. Build after first generation. Errors are expected; classify them in the build-fix loop. ## Resource Hierarchy Gate Before the build-fix loop, compare the generated hierarchy with the previous GA SDK. The previous GA DLL is restored automatically by ApiCompat from `<ApiCompatVersion>`. Write JSON outputs to temp/package-local scratch and do not commit them. ```pwsh $scripts = "eng/packages/http-client-csharp-mgmt/eng/scripts" pwsh $scripts/Get-PreviousGaResourceHierarchy.ps1 -ProjectPath sdk/<svc>/Azure.ResourceManager.<Svc>/src -OutFile ga-hierarchy.json pwsh $scripts/Get-ResourceHierarchyFromTspCodeModel.ps1 -TspCodeModelPath sdk/<svc>/Azure.ResourceManager.<Svc>/src -GeneratedDir sdk/<svc>/Azure.ResourceManager.<Svc>/src/Generated -OutFile new-hierarchy.json pwsh $scripts/Compare-ResourceHierarchy.ps1 -GAJson ga-hierarchy.json -NewJson new-hierarchy.json ``` - Exit `0`: every GA resource exists in the new SDK with the same `ResourceType`, parent set, scope, and singleton flag; continue. - Exit `1`: structural drift. Fix TypeSpec resource shape first (`@parentResource`, `@singleton`, scopes/templates). Do not enter ApiCompat mitigation yet. - Exit `2`: class-name renames only. Continue, but record and handle during naming/API compatibility work. For C# base-model/base-type compatibility, do **not** use `@@hierarchyBuilding`; use SDK custom code after the generated surface is stable. ## Build-Fix Loop Repeat: build → classify → fix → regenerate if needed → rebuild. Always verify zero Swagger diff after spec changes. Keep a running status list grouped by issue category so real migration breaks, compatibility shims, and generator bugs stay distinct. Classify each issue before fixing: | Category | Preferred action | |---|---| | Spec shape: names, types, paging, visibility, grouping | Fix in `client.tsp` with scoped decorators | | SDK compatibility gap: missing/changed shipped API | Add minimal SDK shim only after root cause is known | | Customization drift | Remove stale custom code; re-add only proven shims | | Generated-code drift | Regenerate/export API; do not hand-edit generated files | | Generator bug | Stop, minimize repro, file/link issue | Common decorator fixes: | Problem | Decorator | |---|---| | Wrong property type | `@@alternateType(Model.prop, targetType, "csharp")` | | Wrong operation parameter type | `@@alternateType(Interface.op::parameters.param, targetType, "csharp")` | | Wrong name | `@@clientName(target, "NewName", "csharp")` | | Model should be input and output | `@@usage(Model, Usage.input, "csharp")`; decorator appends, so specify only the missing flag | | Needs pageable return type | `@@markAsPageable(Interface.op, "csharp")` | | Flatten properties envelope | `@@flattenProperty(Model.properties, "csharp")` | | Operation name collision | `@@clientLocation(Interface.op, "GroupName", "csharp")` | SDK custom code goes in the package's existing customization folder (`src/Custom/`, `src/Customization/`, or `src/Customized/`). Use MCP tools for deterministic edits when available, then hand-write only remaining shim logic. Useful MCP edits include `add_using_directive`, `remove_using_directive`, `regex_replacement`, `nullable_annotation_fix`, `rename_codegen_type`, and `add_codegen_suppress`. Regenerate when `CodeGen*` attributes change. Every customization file or significant custom member needs a root-cause comment explaining what generated differently and why SDK-side customization is required. Avoid vague comments like "for backward compatibility". Obsolete custom members do not need a separate justification comment when the `[Obsolete]` message already clearly explains the reason and replacement. Model factory compatibility overloads should translate renamed parameters or enum/value types, then delegate to generated public model-factory overloads. Do not construct generated models through internal constructors, internal `Properties` bags, or private `Core` helpers just to preserve an old factory signature. First look for a public generated factory overload or public model surface that can receive the same values. SDK-side fix patterns when decorators cannot help: | Problem | Fix | |---|---| | Base model/base type changed | Add a custom partial model declaring the intended base model; use `[CodeGenType]` only when the custom type name differs from the generated/TypeSpec name, then regenerate. Do not use `@@hierarchyBuilding`. | | Flattened properties lost on a polymorphic type | Shim properties delegating to the `Properties` bag | | Protected constructor missing on a discriminated base | Add a `protected` constructor in the partial class | | Property lost due to `@@alternateType` model swap | Add the property in a partial class | ## Breaking Changes And New APIs 1. Export API: `pwsh eng/scripts/Export-API.ps1 <service>`. 2. Diff against the previous stable API surface from `ApiCompatVersion` / latest stable package tag. Use `origin/main` only if it matches that baseline. 3. Fix each break using the same classify-first loop, then regenerate/export API/re-diff until clean. Never suppress with an ApiCompat baseline except for `WirePathAttribute` removal diffs. For every new public API, classify it before keeping it: | Category | Action | |---|---| | Real service/API-version addition | Keep and note source API version in PR status | | Rename of existing shipped API | Prefer `@@clientName`; otherwise suppress/add minimal shim. Do not keep both names without approval | | Generator convenience/drift | Investigate operation id, route, resource type, and prior API before keeping | Compare each new member against the previous GA public API listing or restored ApiCompat assembly, operation id and request path in generated XML docs/source, resource type/parent hierarchy, and the TypeSpec or Swagger API version where the operation/model first appears. If a new API is actually a rename of an existing API, fix the rename instead of documenting it as additive. ## Generator Bugs If generated code is structurally wrong after stale customizations are removed, stop and report a generator bug. Create a minimum TypeSpec repro, document any approved workaround in `client.tsp` or SDK custom code with an issue link, and pause migration if no safe workaround exists. ## Finalize 1. Review locally with `mpg-migration-pr-review` rules. 2. Ensure `CHANGELOG.md` has a short migration note and `ci.mgmt.yml` exists if needed. 3. Format TypeSpec before opening the spec PR. 4. Push spec changes to a fork and open draft spec PR titled `Add csharp customizations for <Service> migration`. 5. Update `tsp-location.yaml` to point to the fork spec commit, then push SDK changes to a fork and open draft SDK PR titled `[Mgmt] <PackageName>: Migrate to TypeSpec`. 6. Keep the SDK PR description as the status tracker: current phase, blockers, remaining breaks. If pausing before a draft PR exists, create one and use its description as the tracker. 7. Before final SDK review, point `tsp-location.yaml` to the final spec commit, regenerate once without `LocalSpecRepoPath`, run `pre-commit-checks`, and verify build. ## Done When - Build is clean. - ApiCompat is clean without baselines, except approved `WirePathAttribute` removal entries. - New APIs are triaged. - Required PR/status/review steps are complete. - `tsp-location.yaml` points to the final spec commit.
Ver no GitHub