Anchor ARM resource identity to read and create operations#4851
Draft
ArcturusZhang wants to merge 8 commits into
Draft
Anchor ARM resource identity to read and create operations#4851ArcturusZhang wants to merge 8 commits into
ArcturusZhang wants to merge 8 commits into
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
commit: |
Contributor
|
All changed packages have been documented.
Show changes
|
Contributor
|
You can try these changes here
|
Contributor
⚡ Benchmark Results
Full details – comparing
|
| Metric | Baseline | Current | Change |
|---|---|---|---|
| total | 🔴 1.01s | 🔴 1.05s | +3.4% |
| loader | 🟡 307.6ms | 🟡 318.5ms | +3.5% |
| resolver | 🟢 40.5ms | 🟢 41.2ms | +1.8% |
| checker | 🟡 365.7ms | 🟡 379.9ms | +3.9% |
| validation | 🟢 85.1ms | 🟢 86.9ms | +2.1% |
| ↳ validation/@azure-tools/typespec-azure-core | 🟡 12.6ms | 🟡 13.3ms | +5.3% |
| ↳ validation/@typespec/http | 🟡 15.5ms | 🟡 16.3ms | +4.7% |
| ↳ validation/@typespec/rest | 🟢 1.6ms | 🟢 1.7ms | +2.7% |
| ↳ validation/@typespec/versioning | 🔴 51.4ms | 🔴 51.6ms | +0.4% |
| ↳ validation/compiler | 🟢 3.9ms | 🟢 3.9ms | +1.7% |
| linter | 🟡 215.3ms | 🟡 222.6ms | +3.4% |
| ↳ linter/@azure-tools/typespec-azure-core/auth-required | 🟢 0.1ms | 🟢 0.1ms | +7.4% |
| ↳ linter/@azure-tools/typespec-azure-core/bad-record-type | 🟢 0.6ms | 🟢 0.6ms | +1.7% |
| ↳ linter/@azure-tools/typespec-azure-core/byos | 🟢 8.4ms | 🟢 8.6ms | +2.8% |
| ↳ linter/@azure-tools/typespec-azure-core/casing-style | 🟢 1.5ms | 🟢 1.5ms | +0.9% |
| ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance | 🟢 0.2ms | 🟢 0.2ms | +1.6% |
| ↳ linter/@azure-tools/typespec-azure-core/documentation-required | 🟢 1.9ms | 🟢 2.0ms | +2.2% |
| ↳ linter/@azure-tools/typespec-azure-core/friendly-name | 🟢 1.4ms | 🟢 1.4ms | +2.0% |
| ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required | 🟢 0.4ms | 🟢 0.4ms | +3.2% |
| ↳ linter/@azure-tools/typespec-azure-core/known-encoding | 🟢 0.5ms | 🟢 0.5ms | +3.0% |
| ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required | 🟢 0.8ms | 🟢 0.8ms | +3.4% |
| ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch | 🟢 0.7ms | 🟢 0.7ms | +2.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union | 🟢 1.0ms | 🟢 1.0ms | +0.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-enum | 🟢 0.2ms | 🟢 0.3ms | +2.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes | 🟢 0.3ms | 🟢 0.3ms | +0.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops | 🟢 0.2ms | 🟢 0.2ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-format | 🟢 0.8ms | 🟢 0.8ms | +2.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric | 🟢 0.8ms | 🟢 0.9ms | +2.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-header-explode | 🔴 26.7ms | 🔴 28.2ms | +5.3% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage | 🟢 2.1ms | 🟢 2.1ms | +1.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator | 🟢 0.2ms | 🟢 0.2ms | +5.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-nullable | 🟢 0.4ms | 🟢 0.4ms | +4.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime | 🟢 2.0ms | 🟢 2.0ms | +1.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-openapi | 🟢 2.3ms | 🟢 2.4ms | +1.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-private-usage | 🟢 3.2ms | 🟢 3.2ms | +1.0% |
| ↳ linter/@azure-tools/typespec-azure-core/no-query-explode | 🔴 27.8ms | 🔴 29.5ms | +6.0% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-response-body | 🔴 33.4ms | 🔴 35.0ms | +4.7% |
| ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces | 🟢 0.1ms | 🟢 0.1ms | +1.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch | 🟢 7.7ms | 🟢 8.1ms | +5.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params | 🟢 0.4ms | 🟢 0.4ms | +2.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator | 🟢 0.1ms | 🟢 0.2ms | +5.7% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unknown | 🟢 0.4ms | 🟢 0.4ms | +3.2% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union | 🟢 0.8ms | 🟢 0.8ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version | 🟢 0.4ms | 🟢 0.4ms | -0.4% |
| ↳ linter/@azure-tools/typespec-azure-core/request-body-problem | 🟢 0.5ms | 🟢 0.5ms | +0.8% |
| ↳ linter/@azure-tools/typespec-azure-core/require-versioned | 🟢 0.1ms | 🟢 0.1ms | +2.6% |
| ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem | 🔴 32.6ms | 🔴 33.6ms | +2.9% |
| ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body | 🟢 0.7ms | 🟢 0.7ms | +4.9% |
| ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model | 🟢 0.5ms | 🟢 0.5ms | +0.7% |
| ↳ linter/@azure-tools/typespec-azure-core/use-standard-names | 🟢 7.6ms | 🟢 8.0ms | +5.3% |
| ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations | 🟢 0.3ms | 🟢 0.3ms | +1.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources | 🔴 21.0ms | 🔴 22.0ms | +4.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-lifecycle-operations | 🟢 0.3ms | 🟢 0.3ms | +9.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version | 🟡 12.1ms | 🟡 12.5ms | +3.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key | 🟢 0.2ms | 🟢 0.2ms | -0.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage | 🟢 0.1ms | 🟢 0.1ms | +1.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes | 🟢 5.0ms | 🟢 4.6ms | -6.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-feature-file-usage-discourage | 🟢 0.1ms | 🟢 0.1ms | -4.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts | 🟡 17.1ms | 🟡 17.0ms | -0.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record | 🟢 0.6ms | 🟢 0.6ms | -1.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes | 🟢 1.4ms | 🟢 1.4ms | +2.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes | 🟢 0.2ms | 🟢 0.2ms | -4.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment | 🟢 0.4ms | 🟢 0.4ms | -3.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property | 🟢 0.4ms | 🟢 0.4ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator | 🟢 0.1ms | 🟢 0.1ms | -0.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb | 🟢 0.2ms | 🟢 0.2ms | -4.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property | 🟢 0.3ms | 🟢 0.3ms | +4.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format | 🟢 0.2ms | 🟢 0.2ms | +0.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars | 🟢 0.5ms | 🟢 0.5ms | +1.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern | 🟢 0.1ms | 🟢 0.1ms | +3.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation | 🟢 0.5ms | 🟢 0.6ms | +2.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response | 🟢 9.0ms | 🟢 9.1ms | +1.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch | 🟢 0.8ms | 🟢 0.8ms | -4.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars | 🟢 0.4ms | 🟢 0.4ms | +0.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state | 🟢 0.4ms | 🟢 0.4ms | +2.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels | 🟢 0.2ms | 🟢 0.2ms | +2.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties | 🟢 0.4ms | 🟢 0.4ms | +0.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation | 🟢 0.1ms | 🟢 0.1ms | +13.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header | 🟡 19.7ms | 🔴 20.6ms | +5.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint | 🟢 0.1ms | 🟢 0.1ms | +1.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers | 🟢 1.0ms | 🟢 1.0ms | -1.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model | 🟢 0.3ms | 🟢 0.3ms | +2.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-override-props | 🟢 0.3ms | 🟢 0.3ms | -1.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-reserved-resource-property | 🟢 0.2ms | 🟢 0.2ms | -0.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation | 🟢 0.5ms | 🟢 0.5ms | -0.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body | 🔴 29.8ms | 🔴 30.7ms | +3.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope | 🟢 0.4ms | 🟢 0.4ms | +1.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name | 🟢 0.4ms | 🟢 0.4ms | -1.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop | 🟢 5.4ms | 🟢 5.1ms | -6.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type | 🟢 0.7ms | 🟢 0.7ms | -2.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression | 🟢 0.3ms | 🟢 0.3ms | -2.1% |
| ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict | 🟢 2.3ms | 🟢 2.3ms | +0.8% |
| ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix | 🟢 1.7ms | 🟢 1.7ms | +1.4% |
| emit | 🔴 6.04s | 🔴 6.28s | +3.9% |
| ↳ emit/@Azure-Tools | 🟢 0.0ms | 🟢 0.0ms | +0.0% |
| ↳ emit/@azure-tools/typespec-autorest | 🟢 125.4ms | 🟢 129.9ms | +3.6% |
| ↳ emit/@azure-tools/typespec-python | 🔴 2.25s | 🔴 2.35s | +4.1% |
| ↳ emit/@typespec | 🟢 0.0ms | 🟢 0.0ms | +0.0% |
| ↳ emit/@typespec/http-client-js | 🔴 571.9ms | 🔴 587.6ms | +2.7% |
| ↳ emit/@typespec/openapi3 | 🟢 107.9ms | 🟢 112.4ms | +4.1% |
| ↳ emit/@typespec/openapi3/compute | 🟢 93.8ms | 🟢 97.7ms | +4.2% |
| ↳ emit/@typespec/openapi3/write | 🟢 13.9ms | 🟢 14.4ms | +3.7% |
Averaged across 3 specs (azure-arm-resource-manager, azure-core-dataplane, azure-full).
Threshold: changes > ±5% are highlighted.
🟢 Fast · 🟡 Moderate (stages >200ms, rules >10ms) · 🔴 Slow (stages >400ms, rules >20ms)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…resource-identity
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…resource-identity
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
resolveArmResourcesdesign proposal and related linter candidatesDesigned resource detection flow
Collect candidate resource model details from
listArmResources(program). These are registered TypeSpec resource models, not yet concrete ARM resources.Find identity operations for each candidate model:
readandcreateOrUpdate.list,action,update,delete, andcheckExistence.readandcreateOrUpdate.Use identity operation paths as candidate resource instance paths. The resolver should trust the registered ARM operation kind; HTTP verb/response-shape correctness should be enforced by linters.
read/createOrUpdatepaths can establish resource identity.Parse and validate each candidate path as an ARM resource instance path.
getResourcePathElementswas removed and replaced with strictparseArmResourceInstancePath, which requires a literal/providers/{namespace}segment except for known providerless exceptions such as tenant, subscription, resource group, and explicit generic resource-id parameter paths.Group candidates by normalized resource identity: provider namespace, resource type segments, literal path segments case-insensitively, and variable path segments by position while ignoring variable names.
Create one concrete
ResolvedResourceper identity group.read+createOrUpdateon the same normalized path become one resource; different valid paths become separate resources;createOrUpdatealone can create a resource;list/actionalone cannot.listandactionoperations could create aResolvedResource.Derive stable resource facts from the canonical instance path:
resourceInstancePath,resourceType, provider namespace, scope, resource name parameter or singleton key, and parent candidate information.resourceInstancePath/resourceTypenow come from strict identity paths. Path-based singleton cleanup remains future work.Append remaining operations only to already-detected resources: lifecycle operations by matching normalized instance path, list operations by detected-resource-ID prefix, and action operations under the detected resource instance or collection path.
Leave unmatched operations for provider/non-resource handling. They should not invent new resources.
providerOperations.Resolve parent and scope relationships after the full resource set is known, using normalized path comparison. Missing parents should be skipped rather than synthesized as empty resources.
ExternalResourcefor ambiguous external scopes.Validation
pnpm --filter @azure-tools/typespec-azure-resource-manager exec tsc -p tsconfig.build.json --noEmitpnpm --filter @azure-tools/typespec-azure-resource-manager exec vitest run test/resource-resolution.test.ts --testNamePattern "parseArmResourceInstancePath"pnpm --filter @azure-tools/typespec-azure-resource-manager exec vitest run test/resource-resolution.test.tsis currently blocked by baselineexperimental-featurewarnings from compiler/agent TypeSpec files