Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
changeKind: feature
packages:
- "@azure-tools/typespec-azure-resource-manager"
- "@azure-tools/typespec-azure-rulesets"
---

Add an ARM lint rule that warns when services select or emit older ARM common-types versions instead of the latest available common-types version.
1 change: 1 addition & 0 deletions packages/typespec-azure-resource-manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Available ruleSets:
| [`@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb`](https://azure.github.io/typespec-azure/docs/libraries/azure-resource-manager/rules/arm-resource-invalid-action-verb) | Actions must be HTTP Post or Get operations. |
| [`@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation`](https://azure.github.io/typespec-azure/docs/libraries/azure-resource-manager/rules/improper-subscription-list-operation) | Tenant and Extension resources should not define a list by subscription operation. |
| [`@azure-tools/typespec-azure-resource-manager/lro-location-header`](https://azure.github.io/typespec-azure/docs/libraries/azure-resource-manager/rules/lro-location-header) | A 202 response should include a Location response header. |
| [`@azure-tools/typespec-azure-resource-manager/use-latest-version-of-common-types`](https://azure.github.io/typespec-azure/docs/libraries/azure-resource-manager/rules/use-latest-version-of-common-types) | ARM services must use the latest available ARM common-types version. |
| [`@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers`](https://azure.github.io/typespec-azure/docs/libraries/azure-resource-manager/rules/missing-x-ms-identifiers) | Array properties should describe their identifying properties with x-ms-identifiers. Decorate the property with @OpenAPI.extension("x-ms-identifiers", #[id-prop]) where "id-prop" is a list of the names of identifying properties in the item type. |
| [`@azure-tools/typespec-azure-resource-manager/no-response-body`](https://azure.github.io/typespec-azure/docs/libraries/azure-resource-manager/rules/no-response-body) | Check that the body is empty for 202 and 204 responses, and not empty for other success (2xx) responses. |
| [`@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint`](https://azure.github.io/typespec-azure/docs/libraries/azure-resource-manager/rules/missing-operations-endpoint) | Check for missing Operations interface. |
Expand Down
2 changes: 2 additions & 0 deletions packages/typespec-azure-resource-manager/src/linter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { secretProprule } from "./rules/secret-prop.js";
import { unsupportedTypeRule } from "./rules/unsupported-type.js";
import { useApiVersionRule } from "./rules/use-api-version.js";
import { useInterfaceRule } from "./rules/use-interface.js";
import { useLatestVersionOfCommonTypesRule } from "./rules/use-latest-version-of-common-types.js";
import { useOperationDecoratorRule } from "./rules/use-operation-decorator.js";
import { useRelationshipRequiredPropertiesRule } from "./rules/use-relationship-required-properties.js";
import { versionProgressionRule } from "./rules/version-progression.js";
Expand Down Expand Up @@ -78,6 +79,7 @@ const rules = [
armResourceInvalidActionVerbRule,
improperSubscriptionListOperationRule,
lroLocationHeaderRule,
useLatestVersionOfCommonTypesRule,
missingXmsIdentifiersRule,
noResponseBodyRule,
operationsInterfaceMissingRule,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
title: "use-latest-version-of-common-types"
---

```text title="Full name"
@azure-tools/typespec-azure-resource-manager/use-latest-version-of-common-types
```

ARM services should use the latest ARM common-types version available in
Comment thread
msyyc marked this conversation as resolved.
`Azure.ResourceManager.CommonTypes.Versions`. This keeps TypeSpec services,
generated SDKs, and Azure tooling aligned with the current ARM common schemas.

The rule checks the effective `@armCommonTypesVersion` on each ARM service or
service version. When the selected version is current, it also checks common
types reachable from HTTP operation parameters and payloads so older legacy
symbols are not emitted through an otherwise current API version.

## Impact

- **Area:** API, SDK

Older ARM common-types versions can expose stale shared schemas or parameters in
generated API surfaces and SDKs even when newer definitions are available.

## Incorrect

```tsp
@armProviderNamespace
@service(#{ title: "Contoso" })
@versioned(Versions)
@armCommonTypesVersion(Azure.ResourceManager.CommonTypes.Versions.v3)
namespace Microsoft.Contoso;

enum Versions {
@useDependency(Azure.ResourceManager.CommonTypes.Versions.v3)
v2024_01_01: "2024-01-01",
}
```

## Correct

```tsp
@armProviderNamespace
@service(#{ title: "Contoso" })
@versioned(Versions)
@armCommonTypesVersion(Azure.ResourceManager.CommonTypes.Versions.v6)

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.

This line might become outdated if a new version of common types is added. So maybe we should add a note in the docs to say something like: As of August 2026 'v6' was the latest version of common types, but newer versions may exist so check for the latest version in the Azure.ResourceManager.CommonTypes.Versions enum.

namespace Microsoft.Contoso;

enum Versions {
@useDependency(Azure.ResourceManager.CommonTypes.Versions.v6)
v2024_01_01: "2024-01-01",
}
```

## Incorrect

This service selects the latest common-types version but still uses a legacy
common type that resolves to an older common-types file.

```tsp
@armProviderNamespace
@service(#{ title: "Contoso" })
@versioned(Versions)
@armCommonTypesVersion(Azure.ResourceManager.CommonTypes.Versions.v6)
namespace Microsoft.Contoso;

enum Versions {
@useDependency(Azure.ResourceManager.CommonTypes.Versions.v6)
v2024_01_01: "2024-01-01",
}

@route("/identity")
@get
op getIdentity(): Azure.ResourceManager.Legacy.ManagedServiceIdentityV4;
```

## Correct

Use a common type supported by the selected latest common-types version, or
remove the legacy reference when the API shape no longer needs it.

```tsp
@armProviderNamespace
@service(#{ title: "Contoso" })
@versioned(Versions)
@armCommonTypesVersion(Azure.ResourceManager.CommonTypes.Versions.v6)
namespace Microsoft.Contoso;

enum Versions {
@useDependency(Azure.ResourceManager.CommonTypes.Versions.v6)
v2024_01_01: "2024-01-01",
}

model Widget is TrackedResource<WidgetProperties> {
...ManagedServiceIdentityProperty;

@key("widgetName")
@segment("widgets")
@path
name: string;
}

model WidgetProperties {
description?: string;
}

@route("/identity")
@get
op getIdentity(): Widget;
Comment on lines +94 to +109

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.

This example seems much longer than the incorrect example, isnt there an equivalent ManagedServiceIdentity you can return from the latest common types?

```

## LintDiff Equivalent

This rule corresponds to the LintDiff rule
[LatestVersionOfCommonTypesMustBeUsed](https://github.com/Azure/azure-openapi-validator/blob/main/docs/latest-version-of-common-types-must-be-used.md).

## Suppression

Suppress only when an API must intentionally emit an older ARM common-types
schema for compatibility and the service team has accepted the API and SDK
impact.
Loading
Loading