Skip to content

Add arm-version-progression linter rule (Rule 7)#4347

Open
Copilot wants to merge 6 commits intomainfrom
copilot/implement-first-7-rules
Open

Add arm-version-progression linter rule (Rule 7)#4347
Copilot wants to merge 6 commits intomainfrom
copilot/implement-first-7-rules

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 29, 2026

Implementing Rule 7 from the plan: arm-version-progression linter rule for the @azure-tools/typespec-azure-resource-manager package.

  • Pull latest from main into the working branch
  • Create arm-version-progression.ts rule
  • Register rule in linter.ts and the azure-rulesets resource-manager ruleset
  • Add tests in arm-version-progression.test.ts
  • Add docs page arm-version-progression.md
  • Add Chronus changelog entry
  • Address review feedback: enforce unique dates across all api-versions
  • Run regen-docs to update generated linter rule listings
  • Update docs examples to follow best practices (preview is the last version in Versions; correct example uses a single preview as the last entry; added an edge-case valid example with stable second-to-last and preview one day later)
  • Run build, full test suite, lint, and pnpm format

@markcowl
Copy link
Copy Markdown
Member

@copilot There is one fundamental change here. No api-version is allowed to use the same date as any other api-version. That is, there can be no preview version and stable version that have the same date (i.e. 2026-04-28 and 2026-04-28-preview are *not allowed) The dates in api-versions must all be different, and they must be monotonically increasing from the top to the bottom of the Versions enum for a namespace.

Please add tests that ensure a violation in this case, please look over tests to see if they need to be updated, please make sure all tests pass, and that you are up to date with the main branch

@markcowl markcowl added the int:azure-specs Run integration tests against azure-rest-api-specs label Apr 29, 2026
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 29, 2026

@copilot There is one fundamental change here. No api-version is allowed to use the same date as any other api-version. That is, there can be no preview version and stable version that have the same...

Updated in 89d52fe. The rule now enforces that every api-version uses a unique YYYY-MM-DD date — preview and stable versions sharing a date (e.g. 2026-04-28 + 2026-04-28-preview) emits a duplicateDate diagnostic. Dates must still be strictly monotonically increasing top-to-bottom.

Test updates:

  • Replaced the old "preview before stable on same date is valid" test with one that asserts a duplicateDate diagnostic for that case.
  • Added an explicit test using 2026-04-28 + 2026-04-28-preview (the exact example from your comment).
  • Added a test for two preview versions sharing a date.
  • Existing "out of chronological order" test still asserts notMonotonic.

Branch is up to date with main. Full suite passes: 298/298 RM tests, 3/3 rulesets tests, eslint clean, pnpm format clean.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 29, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/typespec-azure-resource-manager@4347
npm i https://pkg.pr.new/@azure-tools/typespec-azure-rulesets@4347

commit: 797519c

@markcowl
Copy link
Copy Markdown
Member

@copilot It looks like there are changes to website docs in the ci build. Please ensure you have rebuilt docs from the typespec-azure-resource-manager directory, and ensure that all files are formatted correctly. Also, please pull the latest from main and ensure that only changes associated with this PR are in the PR diff

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 29, 2026

@copilot It looks like there are changes to website docs in the ci build. Please ensure you have rebuilt docs from the typespec-azure-resource-manager directory, and ensure that all files are format...

Addressed in fe563a0. Ran pnpm regen-docs from packages/typespec-azure-resource-manager, which added the arm-version-progression row to the auto-generated linter listings in packages/typespec-azure-resource-manager/README.md and website/src/content/docs/docs/libraries/azure-resource-manager/reference/linter.md. pnpm format reports no changes needed. Branch is up to date with main and the PR diff now contains only the 8 expected files for this rule.

Copy link
Copy Markdown
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As always, make sure to pull the latest from main, make the suggested changes, alter tests to match, ensure that all tests pass, that all files are formatted correctly and that only the changes that are part of this PR are in the PR diff

Copilot AI requested a review from markcowl May 1, 2026 22:01
@markcowl markcowl marked this pull request as ready for review May 5, 2026 01:53
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

⚡ Benchmark Results

Comparing [8a4c302] against baseline [ea64206]

Metric Baseline Current Change
total 🔴 876.3ms 🔴 843.3ms -3.8%
loader 🟢 176.9ms 🟢 172.2ms -2.7%
resolver 🟢 21.1ms 🟢 17.8ms -16.0% 🟢
checker 🟡 215.8ms 🟡 201.6ms -6.6% 🟢
validation 🟢 43.9ms 🟢 42.5ms -3.2%
 ↳ validation/@azure-tools/typespec-azure-core 🟢 6.8ms 🟢 6.6ms -4.2%
 ↳ validation/@typespec/http 🟢 6.8ms 🟢 5.8ms -14.7% 🟢
 ↳ validation/@typespec/rest 🟢 0.6ms 🟢 0.5ms -17.6% 🟢
 ↳ validation/@typespec/versioning 🔴 27.9ms 🔴 28.1ms +0.6%
 ↳ validation/compiler 🟢 1.7ms 🟢 1.6ms -10.8% 🟢
linter 🟢 155.3ms 🟢 151.4ms -2.6%
 ↳ linter/@azure-tools/typespec-azure-core/auth-required 🟢 0.0ms 🟢 0.0ms +7.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/bad-record-type 🟢 0.2ms 🟢 0.2ms -8.7% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 7.5ms 🟢 6.3ms -15.8% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/casing-style 🟢 0.7ms 🟢 0.6ms -4.6%
 ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance 🟢 0.1ms 🟢 0.1ms +9.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/documentation-required 🟢 0.8ms 🟢 0.8ms -5.3% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/friendly-name 🟢 0.7ms 🟢 0.7ms -0.2%
 ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required 🟢 0.2ms 🟢 0.2ms -1.0%
 ↳ linter/@azure-tools/typespec-azure-core/known-encoding 🟢 0.2ms 🟢 0.3ms +13.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required 🟢 0.3ms 🟢 0.3ms -0.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch 🟢 0.2ms 🟢 0.2ms -10.9% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union 🟢 0.3ms 🟢 0.3ms -9.4% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-enum 🟢 0.0ms 🟢 0.0ms -5.2% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes 🟢 0.1ms 🟢 0.1ms -1.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops 🟢 0.1ms 🟢 0.1ms -2.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-format 🟢 0.5ms 🟢 0.5ms -5.6% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric 🟢 0.4ms 🟢 0.4ms -9.0% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 21.9ms 🔴 21.4ms -1.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage 🟢 1.1ms 🟢 1.1ms -1.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator 🟢 0.1ms 🟢 0.1ms +21.3% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-nullable 🟢 0.2ms 🟢 0.2ms -9.5% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime 🟢 1.3ms 🟢 1.3ms -4.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-openapi 🟢 2.1ms 🟢 1.9ms -11.1% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-private-usage 🟢 2.2ms 🟢 1.8ms -17.9% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🔴 25.9ms 🔴 21.1ms -18.4% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 24.1ms 🔴 23.6ms -1.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces 🟢 0.0ms 🟢 0.0ms -14.8% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 6.0ms 🟢 6.2ms +3.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params 🟢 0.2ms 🟢 0.2ms -8.9% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator 🟢 0.1ms 🟢 0.1ms -16.2% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-unknown 🟢 0.2ms 🟢 0.2ms -2.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union 🟢 0.3ms 🟢 0.3ms -6.5% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version 🟢 0.2ms 🟢 0.2ms -12.9% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/request-body-problem 🟢 0.2ms 🟢 0.2ms +3.1%
 ↳ linter/@azure-tools/typespec-azure-core/require-versioned 🟢 0.0ms 🟢 0.0ms -10.1% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🔴 24.1ms 🔴 30.4ms +26.3% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body 🟢 0.3ms 🟢 0.3ms -1.0%
 ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model 🟢 0.3ms 🟢 0.3ms -5.2% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 5.7ms 🟢 5.7ms -1.2%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations 🟢 0.1ms 🟢 0.1ms -10.6% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟢 6.3ms 🟢 6.1ms -2.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key 🟢 0.1ms 🟢 0.1ms -2.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage 🟢 0.1ms 🟢 0.1ms -1.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 7.4ms 🟢 7.2ms -2.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record 🟢 0.4ms 🟢 0.4ms -1.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes 🟢 0.7ms 🟢 0.7ms -1.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes 🟢 0.0ms 🟢 0.0ms -16.0% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment 🟢 0.3ms 🟢 0.2ms -4.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property 🟢 0.2ms 🟢 0.1ms -12.3% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator 🟢 0.0ms 🟢 0.0ms -33.3% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb 🟢 0.1ms 🟢 0.1ms -10.4% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property 🟢 0.1ms 🟢 0.1ms -15.7% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format 🟢 0.1ms 🟢 0.1ms -17.5% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars 🟢 0.3ms 🟢 0.3ms -5.4% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern 🟢 0.0ms 🟢 0.0ms -12.3% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation 🟢 0.2ms 🟢 0.2ms -5.8% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 8.9ms 🟢 6.1ms -31.3% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch 🟢 0.4ms 🟢 0.4ms -2.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars 🟢 0.2ms 🟢 0.2ms -9.1% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state 🟢 0.1ms 🟢 0.1ms -9.5% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-version-progression 🟢 0.0ms 🟢 0.0ms +100.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels 🟢 0.1ms 🟢 0.1ms +6.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties 🟢 0.2ms 🟢 0.2ms +6.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation 🟢 0.0ms 🟢 0.0ms -3.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🔴 21.6ms 🟡 18.5ms -14.5% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint 🟢 0.0ms 🟢 0.0ms -15.4% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers 🟢 0.3ms 🟢 0.3ms -3.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model 🟢 0.2ms 🟢 0.1ms -12.3% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation 🟢 0.2ms 🟢 0.2ms -5.0% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🔴 28.2ms 🔴 28.6ms +1.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope 🟢 0.2ms 🟢 0.1ms -6.2% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name 🟢 0.2ms 🟢 0.2ms -4.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop 🟢 2.7ms 🟢 2.5ms -7.4% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type 🟢 0.4ms 🟢 0.4ms -0.1%
 ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict 🟢 1.1ms 🟢 1.1ms -2.0%
 ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix 🟢 0.2ms 🟢 0.2ms -7.7% 🟢
emit 🟡 263.3ms 🟡 257.8ms -2.1%
 ↳ emit/@azure-tools/typespec-autorest 🟢 166.0ms 🟢 164.1ms -1.1%
 ↳ emit/@typespec/openapi3 🟢 145.8ms 🟢 140.5ms -3.6%
 ↳ emit/@typespec/openapi3/compute 🟢 126.9ms 🟢 125.6ms -1.0%
 ↳ emit/@typespec/openapi3/write 🟢 18.8ms 🟢 14.8ms -21.3% 🟢

Averaged across 3 specs (azure-arm-resource-manager, azure-core-dataplane, azure-full).
Threshold: changes > ±5% are highlighted.

@azure-sdk
Copy link
Copy Markdown
Collaborator

azure-sdk commented May 5, 2026

All changed packages have been documented.

  • @azure-tools/typespec-azure-resource-manager
  • @azure-tools/typespec-azure-rulesets
Show changes

@azure-tools/typespec-azure-resource-manager - feature ✏️

Add new arm-version-progression linter rule that validates ARM service versions are declared in strictly increasing chronological order, with preview versions appearing before the stable version for the same date.

@azure-tools/typespec-azure-rulesets - feature ✏️

Add new arm-version-progression linter rule that validates ARM service versions are declared in strictly increasing chronological order, with preview versions appearing before the stable version for the same date.

@azure-sdk
Copy link
Copy Markdown
Collaborator

azure-sdk commented May 5, 2026

You can try these changes here

🛝 Playground 🌐 Website

Copy link
Copy Markdown
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to suppress the issues it found in existing specs

@markcowl
Copy link
Copy Markdown
Member

markcowl commented May 5, 2026

/azp run typespec-azure - PR Tools

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@markcowl
Copy link
Copy Markdown
Member

markcowl commented May 5, 2026

PR for suppressions: Azure/azure-rest-api-specs#42900

@@ -0,0 +1,70 @@
---
title: arm-version-progression
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to keep the arm- prefix when we already have the package on the left?

create(context) {
return {
namespace: (namespace: Namespace) => {
if (isInternalTypeSpec(context.program, namespace)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this check for new rules

@versioned(Versions)
@armProviderNamespace
namespace Microsoft.Contoso;

Copy link
Copy Markdown
Member

@haolingdong-msft haolingdong-msft May 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Mark for adding the versioning linters. May I know is it better to add this document in versioning section? https://azure.github.io/typespec-azure/docs/howtos/versioning/01-about-versioning/ so that it increase the chance of agent picking it up in versioning scenario.
Or could we at least refer this document in versioning section?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

int:azure-specs Run integration tests against azure-rest-api-specs lib:azure-resource-manager Issues for @azure-tools/typespec-azure-core library meta:website TypeSpec.io updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants