[Swagger Linter Migration] XmsPageableForListCalls - #5379
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…for-list-calls-to-arm
|
All changed packages have been documented.
Show changes
|
📦 Package size report✅ No notable package size changes compared to the base branch. 13 package(s) with no notable change
Packed = gzipped |
There was a problem hiding this comment.
🟢 Approval recommended
The rule implementation and coverage look consistent with existing ARM linter patterns, and the remaining feedback is non-blocking (documentation wording/maintainability).
Pull request overview
Promotes the Swagger validator rule XmsPageableForListCalls into the native ARM linter as list-operation-missing-pageable, ensuring ARM collection GET operations on list paths emit x-ms-pageable (or equivalent TypeSpec paging metadata), while keeping the rule disabled by default in the ARM ruleset.
Changes:
- Added the
list-operation-missing-pageablelinter rule (implementation + rule documentation) to@azure-tools/typespec-azure-resource-manager. - Added a dedicated Vitest suite covering ARM list-path classification, template/dynamic-path exclusions, and extension truthiness behavior.
- Registered the rule in docs/README and in the
resource-managerruleset with a default offalse.
File summaries
| File | Description |
|---|---|
| website/src/content/docs/docs/libraries/azure-resource-manager/reference/linter.md | Adds the new rule to the published ARM linter rule list. |
| packages/typespec-azure-rulesets/src/rulesets/resource-manager.ts | Registers the new rule in the ARM ruleset (disabled by default). |
| packages/typespec-azure-resource-manager/test/rules/list-operation-missing-pageable.test.ts | Adds native rule tests covering compliant/noncompliant list GET shapes and exclusions. |
| packages/typespec-azure-resource-manager/src/rules/list-operation-missing-pageable.ts | Implements the rule logic for detecting ARM collection GETs missing pageable metadata. |
| packages/typespec-azure-resource-manager/src/rules/list-operation-missing-pageable.md | Adds end-user rule documentation and examples. |
| packages/typespec-azure-resource-manager/src/linter.ts | Wires the new rule into the ARM package linter export. |
| packages/typespec-azure-resource-manager/README.md | Lists the new rule in the package README rule table. |
| .chronus/changes/promote-xms-pageable-for-list-calls-2026-09-02.md | Adds a changelog entry for the new rule promotion. |
Review details
- Files reviewed: 8/8 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
commit: |
Clarify the explicit extension remediation and share collection-path detection between ARM lint rules. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
You can try these changes here
|
There was a problem hiding this comment.
🟡 Changes recommended
The new rule’s diagnostic message omits the explicitly-authored truthy x-ms-pageable extension remediation path that the rule already accepts, which can mislead users.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 10/10 changed files
- Comments generated: 1
- Review effort level: Lite
Mention the explicitly authored x-ms-pageable extension accepted by the rule. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Approval recommended
The rule implementation, shared helper extraction, documentation, and targeted test coverage are consistent with existing patterns and appear complete.
Review details
- Files reviewed: 10/10 changed files
- Comments generated: 0 new
- Review effort level: Lite
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Original Swagger linter
The original rule checks that:
isListOperationPathclassification;}or/defaultremain excluded;x-ms-pageableexists with a truthy value; andx-ms-pageablevalues produce`x-ms-pageable` extension must be specified for LIST APIs..How the Swagger linter works
The ARM Spectral ruleset selects GET operations on ARM paths, excluding selector-boundary paths that end in
}or/default, and invokesxms-pageable-for-list-calls.tswith the OpenAPI operation object and its Spectral path. The function reads the path key frompaths.path[1], delegates collection classification toisListOperationPath, and then tests the operation'sx-ms-pageablevalue for truthiness. It reports against the selected GET operation path when that value is absent or falsy.The validator does not inspect response schemas or verify that a
nextLinkproperty exists. The migration therefore preserves the emitted-OpenAPI behavior rather than adding response-shape requirements. Raw validator results can contain repeated occurrences for emitted API-version/files; migration evidence compares stable operation identities and does not copy that emitted-file duplication into TypeSpec diagnostics.Source TypeSpec lintdiff rule
XmsPageableForListCallstsp-lintdiff-local-linter/xms-pageable-for-list-callsxms-pageable-for-list-callsfeature/lintdiff-xms-pageable-for-list-callseb284b1a7327f39dc75af49c314b7755bc2f2867C:\dev\worktrees\lintdiff-xms-pageable-for-list-callsThe source worktree had no uncommitted rule changes. The user-marked done lintdiff source was not modified during promotion.
Destination analysis
The rule is promoted to
@azure-tools/typespec-azure-resource-manager. Its source imports ARM provider helpers, limits diagnostics to ARM provider namespaces, and classifies ARM resource collection routes. Fixture metadata declaresApplies to: Resource Manager (ARM)and the migration report uses the resource-manager ruleset. Azure Core is not a viable alternative because preserving these semantics would require a prohibited dependency from Core to the ARM library or duplicating ARM provider behavior.The official name is shortened from the validator id to
list-operation-missing-pageable, following the subject-oriented TypeSpec lint naming convention. The rule is explicitly registered asfalsein the ARM ruleset so promotion makes it available without immediately adding diagnostics to existing service specifications.How the promoted TypeSpec linter works
The ARM rule visits emitted operations and skips uninstantiated operation/interface templates. It uses
getArmProviderNamespaceso operations in both the provider namespace and child namespaces are included, resolves HTTP metadata withgetHttpOperation, and applies the Swagger helper's dotted-provider-tail and segment-parity collection-path heuristic. Non-GET operations, dynamic provider paths, singleton paths, and/defaultpaths are ignored.For matching collection GETs, the rule accepts a truthy authored OpenAPI
x-ms-pageableextension. It also accepts TypeSpec list metadata only whengetPagingOperationresolves a next-link property, matching what AutoRest can emit asx-ms-pageable. Otherwise it emits one warning targeted at the TypeSpec operation. This intentionally avoids Swagger's repeated emitted-file occurrences while preserving one diagnostic per semantic operation.Fixture-to-native test mapping
compliant-with-template/main.tspit("allows a standard ARM list operation template")decorated-custom-list/main.tspit("reports a custom ARM list operation without pageable metadata")@armResourceListoperation remains non-pageable.nested-provider-namespace/main.tspit("reports an ARM collection GET in a child provider namespace")explicit-pageable-extension/main.tspit("allows an explicit truthy x-ms-pageable extension")falsy-pageable-extension/main.tspit("reports a falsy x-ms-pageable extension")list-without-next-link/main.tspit("reports a list operation with page items but no next link")@pageItemswithout@nextLinkcannot emit pageable metadata.list-without-pageable/main.tspit("reports raw ARM collection GETs but ignores point and default paths")operations-path/main.tspit("reports the ARM operations endpoint as a collection path")/operationsclassification.selector-boundaries/main.tspit("ignores dynamic provider paths and uninstantiated templates")Migration evidence
The checked-in migration.md records focused fixtures, real-service project comparison, the latest full-corpus counts, compile-failure exclusions, emitted-occurrence duplication, and remaining uncertainty.
Validation
validate:prpassed build, lint, format, spelling, and 3,225 tests; two unrelated playground sample tests (Tracked ResourceandTenant Resource) exceeded their existing 10-second timeout. Final affected-package docs regeneration and targeted tests were rerun after synchronizing withorigin/main.Promotion sync policy
If review finds a semantic gap in the done lintdiff rule, this promotion should be blocked until the user explicitly reopens lintdiff repair. Promotion-only adaptation issues can be fixed here without modifying the source rule.
NOTE: heavy