Skip to content

Added Linter rule to disallow reserved property presence in resource's property bag. - #4842

Merged
markcowl merged 5 commits into
Azure:mainfrom
vayada:vayada/billingDataLinterRule
Jul 9, 2026
Merged

Added Linter rule to disallow reserved property presence in resource's property bag.#4842
markcowl merged 5 commits into
Azure:mainfrom
vayada:vayada/billingDataLinterRule

Conversation

@vayada

@vayada vayada commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Added Linter rule to disallow reserved property presence in resource's property bag.
One such example is "BillingData" property which is reserved for Billing Feature through RP Platform and is being standardized through Common Types.

@microsoft-github-policy-service microsoft-github-policy-service Bot added 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 linter Issues related to linter rules labels Jul 6, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jul 6, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: e5b9fb5

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

⚡ Benchmark Results

⚠️ 3 metric(s) regressed above the +5% threshold:

Metric Baseline Current Change
loader 🟡 303.9ms 🟡 322.3ms +6.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 26.5ms 🔴 28.1ms +6.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 19.5ms 🔴 20.7ms +6.1% 🔴
Full details – comparing 126259f vs baseline rolling-baseline-f6e42f0-aca5355 (rolling baseline (20 main runs))
Metric Baseline Current Change
total 🔴 1.00s 🔴 1.04s +3.5%
loader 🟡 303.9ms 🟡 322.3ms +6.1% 🔴
resolver 🟢 39.9ms 🟢 39.9ms +0.1%
checker 🟡 362.3ms 🟡 371.2ms +2.4%
validation 🟢 84.5ms 🟢 85.5ms +1.3%
 ↳ validation/@azure-tools/typespec-azure-core 🟡 12.5ms 🟡 13.1ms +4.2%
 ↳ validation/@typespec/http 🟡 15.4ms 🟡 15.9ms +3.2%
 ↳ validation/@typespec/rest 🟢 1.6ms 🟢 1.6ms -0.3%
 ↳ validation/@typespec/versioning 🔴 50.9ms 🔴 51.0ms +0.2%
 ↳ validation/compiler 🟢 3.8ms 🟢 3.8ms +0.6%
linter 🟡 213.8ms 🟡 220.2ms +3.0%
 ↳ linter/@azure-tools/typespec-azure-core/auth-required 🟢 0.1ms 🟢 0.1ms +2.3%
 ↳ linter/@azure-tools/typespec-azure-core/bad-record-type 🟢 0.6ms 🟢 0.6ms -0.3%
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 8.3ms 🟢 8.4ms +1.7%
 ↳ linter/@azure-tools/typespec-azure-core/casing-style 🟢 1.4ms 🟢 1.4ms +0.8%
 ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance 🟢 0.2ms 🟢 0.2ms -0.1%
 ↳ linter/@azure-tools/typespec-azure-core/documentation-required 🟢 1.9ms 🟢 1.9ms -1.2%
 ↳ linter/@azure-tools/typespec-azure-core/friendly-name 🟢 1.4ms 🟢 1.4ms +1.5%
 ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required 🟢 0.4ms 🟢 0.4ms +1.0%
 ↳ linter/@azure-tools/typespec-azure-core/known-encoding 🟢 0.5ms 🟢 0.5ms +1.9%
 ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required 🟢 0.8ms 🟢 0.8ms +0.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch 🟢 0.7ms 🟢 0.7ms -1.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union 🟢 1.0ms 🟢 0.9ms -2.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-enum 🟢 0.2ms 🟢 0.2ms -0.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes 🟢 0.3ms 🟢 0.3ms +2.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops 🟢 0.2ms 🟢 0.2ms +1.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-format 🟢 0.8ms 🟢 0.8ms -0.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric 🟢 0.8ms 🟢 0.8ms +1.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 26.5ms 🔴 28.1ms +6.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage 🟢 2.0ms 🟢 2.1ms +2.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator 🟢 0.2ms 🟢 0.2ms +4.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-nullable 🟢 0.4ms 🟢 0.4ms +0.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime 🟢 1.9ms 🟢 2.0ms +3.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-openapi 🟢 2.3ms 🟢 2.3ms -0.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-private-usage 🟢 3.1ms 🟢 3.2ms +1.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🔴 27.7ms 🔴 28.6ms +3.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 33.0ms 🔴 34.1ms +3.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces 🟢 0.1ms 🟢 0.1ms +3.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 7.6ms 🟢 8.0ms +5.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params 🟢 0.4ms 🟢 0.4ms +1.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator 🟢 0.1ms 🟢 0.1ms +1.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-unknown 🟢 0.3ms 🟢 0.4ms +3.0%
 ↳ 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.3ms -4.0%
 ↳ linter/@azure-tools/typespec-azure-core/request-body-problem 🟢 0.5ms 🟢 0.4ms -0.5%
 ↳ linter/@azure-tools/typespec-azure-core/require-versioned 🟢 0.1ms 🟢 0.1ms +2.3%
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🔴 32.5ms 🔴 33.8ms +4.0%
 ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body 🟢 0.7ms 🟢 0.7ms +3.0%
 ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model 🟢 0.5ms 🟢 0.5ms -0.5%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 7.5ms 🟢 7.9ms +4.2%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations 🟢 0.3ms 🟢 0.2ms -1.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources 🔴 21.4ms 🔴 21.5ms +0.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-lifecycle-operations 🟢 0.3ms 🟢 0.3ms +4.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟡 12.1ms 🟡 12.4ms +2.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key 🟢 0.2ms 🟢 0.2ms +2.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage 🟢 0.1ms 🟢 0.1ms +2.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 4.9ms 🟢 5.2ms +5.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟡 17.0ms 🟡 16.9ms -1.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record 🟢 0.6ms 🟢 0.6ms +1.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes 🟢 1.4ms 🟢 1.4ms -2.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes 🟢 0.2ms 🟢 0.2ms -3.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment 🟢 0.4ms 🟢 0.4ms -0.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property 🟢 0.4ms 🟢 0.4ms +3.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator 🟢 0.1ms 🟢 0.1ms -8.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb 🟢 0.2ms 🟢 0.2ms -0.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property 🟢 0.3ms 🟢 0.3ms +4.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format 🟢 0.2ms 🟢 0.2ms -2.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars 🟢 0.5ms 🟢 0.5ms +5.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern 🟢 0.1ms 🟢 0.1ms -2.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation 🟢 0.5ms 🟢 0.5ms +0.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 8.9ms 🟢 9.0ms +1.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch 🟢 0.8ms 🟢 0.8ms -2.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars 🟢 0.4ms 🟢 0.4ms +1.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state 🟢 0.4ms 🟢 0.4ms +0.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels 🟢 0.2ms 🟢 0.2ms -0.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties 🟢 0.4ms 🟢 0.4ms -4.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation 🟢 0.1ms 🟢 0.1ms +8.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 19.5ms 🔴 20.7ms +6.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint 🟢 0.1ms 🟢 0.2ms +6.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers 🟢 1.0ms 🟢 1.0ms +0.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model 🟢 0.3ms 🟢 0.3ms +2.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-override-props 🟢 0.3ms 🟢 0.3ms +2.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-reserved-resource-property 🟢 0.0ms 🟢 0.2ms +100.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation 🟢 0.5ms 🟢 0.5ms +1.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🔴 29.7ms 🔴 31.1ms +4.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope 🟢 0.4ms 🟢 0.4ms +1.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name 🟢 0.4ms 🟢 0.4ms -0.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop 🟢 5.4ms 🟢 5.0ms -6.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type 🟢 0.7ms 🟢 0.7ms -3.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression 🟢 0.3ms 🟢 0.3ms -5.5%
 ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict 🟢 2.3ms 🟢 2.3ms +1.2%
 ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix 🟢 1.7ms 🟢 1.7ms +0.1%
emit 🔴 6.01s 🔴 6.13s +2.0%
 ↳ emit/@Azure-Tools 🟢 0.0ms 🟢 0.0ms +0.0%
 ↳ emit/@azure-tools/typespec-autorest 🟢 124.4ms 🟢 125.9ms +1.2%
 ↳ emit/@azure-tools/typespec-python 🔴 2.24s 🔴 2.29s +2.1%
 ↳ emit/@typespec 🟢 0.0ms 🟢 0.0ms +0.0%
 ↳ emit/@typespec/http-client-js 🔴 566.7ms 🔴 576.5ms +1.7%
 ↳ emit/@typespec/openapi3 🟢 106.9ms 🟢 109.8ms +2.7%
 ↳ emit/@typespec/openapi3/compute 🟢 92.9ms 🟢 95.4ms +2.7%
 ↳ emit/@typespec/openapi3/write 🟢 13.8ms 🟢 14.2ms +2.9%

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)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new Azure Resource Manager linter rule to prevent resource providers from defining a BillingData property inside an ARM resource’s properties model, since the name is reserved for platform billing integration and is being standardized via common types.

Changes:

  • Added no-billing-data-in-properties-bag linter rule implementation and registered it in the ARM linter.
  • Added rule coverage tests for direct, inherited, and spread-in property definitions (case-insensitive match).
  • Documented the rule in the website docs and added it to the published rule lists; enabled it in the ARM resource-manager ruleset; added a Chronus change entry.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
website/src/content/docs/docs/libraries/azure-resource-manager/rules/no-billing-data-in-properties-bag.md New rule documentation with correct/incorrect examples.
website/src/content/docs/docs/libraries/azure-resource-manager/reference/linter.md Adds the new rule to the linter reference table.
packages/typespec-azure-rulesets/src/rulesets/resource-manager.ts Enables the new rule in the ARM resource-manager ruleset.
packages/typespec-azure-resource-manager/test/rules/no-billing-data-in-properties-bag.test.ts Adds unit tests validating allowed/flagged cases, including inheritance/spreads and casing.
packages/typespec-azure-resource-manager/src/rules/no-billing-data-in-properties-bag.ts Implements the new linter rule.
packages/typespec-azure-resource-manager/src/linter.ts Registers the rule in the ARM linter rule list.
packages/typespec-azure-resource-manager/README.md Adds the new rule to the README rule list.
.chronus/changes/add-no-billing-data-in-properties-bag-rule-2026-7-6-12-40-0.md Records the feature addition for release notes/versioning.

@vayada vayada changed the title Added Linter rule for BillingData property presence in resource's property bag. Added Linter rule to Disallow BillingData property presence in resource's property bag. Jul 7, 2026
@vayada vayada changed the title Added Linter rule to Disallow BillingData property presence in resource's property bag. Added Linter rule to disallow BillingData property presence in resource's property bag. Jul 7, 2026
Comment thread .chronus/changes/add-no-billing-data-in-properties-bag-rule-2026-7-6-12-40-0.md Outdated
- Rename rule from no-billing-data-in-properties-bag to no-reserved-resource-property
  to accommodate additional reserved property names (per review)
- Use an extensible reserved-name -> reason map so new reserved properties are easy to add
- Parameterize the diagnostic message with the property name and reservation reason
- Match property names case-insensitively; use camelCase in docs/description

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vayada vayada changed the title Added Linter rule to disallow BillingData property presence in resource's property bag. Added Linter rule to disallow reserved property presence in resource's property bag. Jul 7, 2026
…-resource-property.ts


Updated case

Co-authored-by: Mark Cowlishaw <1054056+markcowl@users.noreply.github.com>
The reserved-name map keys are camelCase, but the lookup lowercased the
property name, so nothing matched. Build a lowercase-keyed lookup and compare
lowercased names on both sides; report the reserved name with its canonical
casing in the diagnostic.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@markcowl
markcowl added this pull request to the merge queue Jul 9, 2026
Merged via the queue into Azure:main with commit d59ad64 Jul 9, 2026
25 of 26 checks passed
github-actions Bot added a commit to XiaofeiCao/typespec-azure that referenced this pull request Jul 11, 2026
Sync documentation from Azure/typespec-azure upstream main branch.

Key changes included:
- Add docs for new ARM linter rule `no-reserved-resource-property` (PR Azure#4842)
- Add docs for new TCGC linter rule `csharp-no-url-suffix` (PR Azure#4541)
- Add ARM agent base type rules docs: `arm-agent-base-type-child-resources`,
  `arm-agent-base-type-lifecycle-operations`, `no-override-props`
- Update ARM `data-types.md`: align Agent ResponseStatus enum to PascalCase
  and `createdAt` to utcDateTime per ARM guidelines (PR Azure#4855)
- Fix `@azureBaseType` decorator doc example (PR Azure#4755)
- Improve ARM library decorators, interfaces, and models docs (PR Azure#4494)
- Add TCGC `@override` path-param and `@clientLocation` type-conflict
  caution admonitions to howto (PR Azure#4844)
- Regen Java emitter docs with default values and improved type info (PR Azure#4863)
- Update Python emitter docs with new `typeddict` models mode (upstream)
- Update TypeScript emitter reference docs
- Update autorest and autorest-canonical emitter docs
- Update azure-rulesets linter reference
- Update azure-core, azure-portal-core, TCGC reference docs
- Update howtos for ARM and Generate client libraries
- Add release notes for 2026-06-09

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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 linter Issues related to linter rules meta:website TypeSpec.io updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants