Upstream-aware downstream CI (#4860)#4874
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
No changes needing a change description found. |
In workflow_call context github.workflow resolves to the caller (downstream / CI), so ci-python and ci-java computed an identical concurrency group and cancelled each other, leaving only TypeScript to dispatch. Concurrency is already handled by the ci-downstream entrypoint, so drop the redundant per-workflow blocks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
⚡ Benchmark Results
Full details – comparing
|
| Metric | Baseline | Current | Change |
|---|---|---|---|
| total | 🔴 1.00s | 🔴 1.05s | +4.4% |
| loader | 🟡 304.5ms | 🟡 320.1ms | +5.1% 🔴 |
| resolver | 🟢 40.1ms | 🟢 41.8ms | +4.2% |
| checker | 🟡 361.4ms | 🟡 376.6ms | +4.2% |
| validation | 🟢 84.2ms | 🟢 86.8ms | +3.1% |
| ↳ validation/@azure-tools/typespec-azure-core | 🟡 12.5ms | 🟡 13.3ms | +6.2% |
| ↳ validation/@typespec/http | 🟡 15.4ms | 🟡 16.1ms | +4.6% |
| ↳ validation/@typespec/rest | 🟢 1.6ms | 🟢 1.6ms | +1.5% |
| ↳ validation/@typespec/versioning | 🔴 50.8ms | 🔴 51.8ms | +2.0% |
| ↳ validation/compiler | 🟢 3.8ms | 🟢 3.9ms | +2.4% |
| linter | 🟡 213.4ms | 🟡 222.7ms | +4.4% |
| ↳ linter/@azure-tools/typespec-azure-core/auth-required | 🟢 0.1ms | 🟢 0.1ms | +3.8% |
| ↳ linter/@azure-tools/typespec-azure-core/bad-record-type | 🟢 0.6ms | 🟢 0.6ms | +1.0% |
| ↳ linter/@azure-tools/typespec-azure-core/byos | 🟢 8.3ms | 🟢 8.5ms | +2.5% |
| ↳ linter/@azure-tools/typespec-azure-core/casing-style | 🟢 1.4ms | 🟢 1.5ms | +2.0% |
| ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance | 🟢 0.2ms | 🟢 0.2ms | +2.3% |
| ↳ linter/@azure-tools/typespec-azure-core/documentation-required | 🟢 1.9ms | 🟢 2.0ms | +3.0% |
| ↳ linter/@azure-tools/typespec-azure-core/friendly-name | 🟢 1.4ms | 🟢 1.4ms | +2.3% |
| ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required | 🟢 0.4ms | 🟢 0.4ms | +2.9% |
| ↳ linter/@azure-tools/typespec-azure-core/known-encoding | 🟢 0.5ms | 🟢 0.5ms | +4.6% |
| ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required | 🟢 0.8ms | 🟢 0.8ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch | 🟢 0.7ms | 🟢 0.7ms | +6.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union | 🟢 1.0ms | 🟢 1.0ms | +0.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-enum | 🟢 0.2ms | 🟢 0.2ms | +1.7% |
| ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes | 🟢 0.3ms | 🟢 0.3ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops | 🟢 0.2ms | 🟢 0.2ms | +2.7% |
| ↳ linter/@azure-tools/typespec-azure-core/no-format | 🟢 0.8ms | 🟢 0.8ms | +3.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric | 🟢 0.8ms | 🟢 0.8ms | +1.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-header-explode | 🔴 26.5ms | 🔴 28.3ms | +7.1% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage | 🟢 2.1ms | 🟢 2.1ms | +2.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator | 🟢 0.2ms | 🟢 0.3ms | +7.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-nullable | 🟢 0.4ms | 🟢 0.4ms | +2.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime | 🟢 2.0ms | 🟢 2.0ms | +4.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-openapi | 🟢 2.3ms | 🟢 2.3ms | +0.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-private-usage | 🟢 3.2ms | 🟢 3.2ms | +1.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-query-explode | 🔴 27.6ms | 🔴 29.5ms | +6.8% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-response-body | 🔴 33.2ms | 🔴 34.6ms | +4.3% |
| ↳ 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.6ms | 🟢 8.0ms | +5.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params | 🟢 0.4ms | 🟢 0.4ms | +5.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator | 🟢 0.1ms | 🟢 0.2ms | +7.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unknown | 🟢 0.3ms | 🟢 0.4ms | +4.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union | 🟢 0.8ms | 🟢 0.8ms | +1.4% |
| ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version | 🟢 0.4ms | 🟢 0.4ms | -1.7% |
| ↳ linter/@azure-tools/typespec-azure-core/request-body-problem | 🟢 0.5ms | 🟢 0.5ms | +2.5% |
| ↳ linter/@azure-tools/typespec-azure-core/require-versioned | 🟢 0.1ms | 🟢 0.1ms | +4.3% |
| ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem | 🔴 32.3ms | 🔴 33.5ms | +3.7% |
| ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body | 🟢 0.7ms | 🟢 0.7ms | +2.3% |
| ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model | 🟢 0.4ms | 🟢 0.5ms | +3.9% |
| ↳ linter/@azure-tools/typespec-azure-core/use-standard-names | 🟢 7.5ms | 🟢 7.9ms | +5.6% |
| ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations | 🟢 0.3ms | 🟢 0.3ms | +2.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources | 🔴 20.3ms | 🔴 22.4ms | +10.2% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-lifecycle-operations | 🟢 0.2ms | 🟢 0.3ms | +5.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version | 🟡 12.0ms | 🟡 12.6ms | +5.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key | 🟢 0.2ms | 🟢 0.2ms | +6.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage | 🟢 0.1ms | 🟢 0.1ms | +6.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes | 🟢 5.2ms | 🟢 4.6ms | -12.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-feature-file-usage-discourage | 🟢 0.1ms | 🟢 0.1ms | +3.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts | 🟡 16.9ms | 🟡 17.3ms | +2.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record | 🟢 0.6ms | 🟢 0.6ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes | 🟢 1.4ms | 🟢 1.4ms | +1.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes | 🟢 0.2ms | 🟢 0.2ms | -4.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment | 🟢 0.4ms | 🟢 0.5ms | +1.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property | 🟢 0.4ms | 🟢 0.4ms | +1.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator | 🟢 0.1ms | 🟢 0.1ms | +5.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb | 🟢 0.2ms | 🟢 0.2ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property | 🟢 0.3ms | 🟢 0.3ms | +3.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format | 🟢 0.2ms | 🟢 0.2ms | +3.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars | 🟢 0.5ms | 🟢 0.5ms | +3.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern | 🟢 0.1ms | 🟢 0.1ms | +7.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation | 🟢 0.5ms | 🟢 0.6ms | +2.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response | 🟢 8.9ms | 🟢 9.1ms | +2.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch | 🟢 0.8ms | 🟢 0.8ms | -1.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars | 🟢 0.4ms | 🟢 0.4ms | +3.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state | 🟢 0.4ms | 🟢 0.4ms | +1.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels | 🟢 0.2ms | 🟢 0.2ms | +1.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties | 🟢 0.4ms | 🟢 0.4ms | +3.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation | 🟢 0.1ms | 🟢 0.1ms | +7.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header | 🟡 19.5ms | 🔴 20.8ms | +6.7% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint | 🟢 0.1ms | 🟢 0.1ms | +3.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers | 🟢 1.0ms | 🟢 1.0ms | +0.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model | 🟢 0.3ms | 🟢 0.3ms | +1.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-override-props | 🟢 0.3ms | 🟢 0.3ms | +0.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-reserved-resource-property | 🟢 0.2ms | 🟢 0.2ms | +0.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation | 🟢 0.5ms | 🟢 0.5ms | +6.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body | 🔴 29.5ms | 🔴 31.2ms | +5.6% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope | 🟢 0.4ms | 🟢 0.4ms | +2.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name | 🟢 0.4ms | 🟢 0.4ms | +0.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop | 🟢 5.3ms | 🟢 5.4ms | +1.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type | 🟢 0.7ms | 🟢 0.7ms | +3.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression | 🟢 0.3ms | 🟢 0.3ms | -2.5% |
| ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict | 🟢 2.3ms | 🟢 2.4ms | +3.0% |
| ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix | 🟢 1.7ms | 🟢 1.7ms | +0.6% |
| emit | 🔴 5.98s | 🔴 6.24s | +4.4% |
| ↳ emit/@Azure-Tools | 🟢 0.0ms | 🟢 0.0ms | +0.0% |
| ↳ emit/@azure-tools/typespec-autorest | 🟢 124.1ms | 🟢 127.8ms | +3.0% |
| ↳ emit/@azure-tools/typespec-python | 🔴 2.23s | 🔴 2.34s | +4.9% |
| ↳ emit/@typespec | 🟢 0.0ms | 🟢 0.0ms | +0.0% |
| ↳ emit/@typespec/http-client-js | 🔴 566.1ms | 🔴 582.9ms | +3.0% |
| ↳ emit/@typespec/openapi3 | 🟢 106.7ms | 🟢 111.8ms | +4.8% |
| ↳ emit/@typespec/openapi3/compute | 🟢 92.7ms | 🟢 97.1ms | +4.8% |
| ↳ emit/@typespec/openapi3/write | 🟢 13.7ms | 🟢 14.4ms | +5.1% |
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)
- Remove docs/superpowers process artifacts from the PR (kept in session) - Drop // @ts-check from detect-affected(.test).js: they import untyped js-yaml/minimatch that are not resolvable by root tsc during check:eng (matches existing lint-resourcemanager.js convention) - Rename config key core-submodule -> coreSubmodule for valid JSDoc and clean property access - prettier-format the scripts Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
You can try these changes here
|
Replace the hand-maintained upstream dependency map with the real pnpm workspace graph: changed files are self-filtered (test/**, *.md) in code, mapped to their workspace packages, then expanded to graph dependents via pnpm. This removes the drift-prone map (which under-triggered by omitting autorest/rulesets) and covers all upstream deps automatically. - Rewrite detect-affected as zero-dependency TypeScript run directly on Node (native type-stripping), no tsx and no js-yaml/minimatch. - Inline the small residual config (per-target package name, CI-infra extra paths, coreSubmodule) that the graph cannot express as a typed const. - Self-filter ignored files in code instead of pnpm --changed-files-ignore-pattern, which unreliably matches non-trailing-** globs. - Enable allowImportingTsExtensions for eng tsconfig so the colocated test can import the .ts module under Node's native runner. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
⚡ External Spec Benchmark Results
Full details – comparing
|
| Metric | Baseline | Current | Change |
|---|---|---|---|
| total | 🔴 6.97s | 🔴 6.60s | -5.3% 🟢 |
| loader | 🔴 2.04s | 🔴 1.85s | -9.4% 🟢 |
| resolver | 🟢 152.3ms | 🟢 157.4ms | +3.4% |
| checker | 🔴 1.55s | 🔴 1.52s | -1.6% |
| validation | 🟡 382.7ms | 🟡 390.3ms | +2.0% |
| ↳ validation/@azure-tools/typespec-azure-core | 🟢 0.2ms | 🟢 0.2ms | +4.8% |
| ↳ validation/@azure-tools/typespec-client-generator-core | 🔴 20.4ms | 🔴 24.5ms | +20.4% 🔴 |
| ↳ validation/@typespec/http | 🔴 158.3ms | 🔴 153.3ms | -3.2% |
| ↳ validation/@typespec/rest | 🔴 23.4ms | 🔴 26.3ms | +12.3% 🔴 |
| ↳ validation/@typespec/versioning | 🔴 154.3ms | 🔴 156.2ms | +1.2% |
| ↳ validation/compiler | 🔴 24.7ms | 🔴 27.9ms | +13.0% 🔴 |
| linter | 🔴 2.83s | 🔴 2.69s | -5.0% |
| ↳ linter/@azure-tools/typespec-azure-core/auth-required | 🟢 0.1ms | 🟢 0.1ms | +4.7% |
| ↳ linter/@azure-tools/typespec-azure-core/byos | 🔴 131.4ms | 🔴 127.3ms | -3.1% |
| ↳ linter/@azure-tools/typespec-azure-core/casing-style | 🟢 9.6ms | 🟢 9.8ms | +2.1% |
| ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance | 🟢 1.0ms | 🟢 1.0ms | +0.2% |
| ↳ linter/@azure-tools/typespec-azure-core/documentation-required | 🟡 14.1ms | 🟡 14.4ms | +2.5% |
| ↳ linter/@azure-tools/typespec-azure-core/friendly-name | 🟡 10.4ms | 🟡 10.4ms | -0.0% |
| ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required | 🟢 3.2ms | 🟢 3.3ms | +3.0% |
| ↳ linter/@azure-tools/typespec-azure-core/known-encoding | 🟢 2.9ms | 🟢 2.8ms | -2.1% |
| ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required | 🟢 5.5ms | 🟢 5.4ms | -2.7% |
| ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch | 🟢 3.3ms | 🟢 3.3ms | +2.0% |
| ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union | 🟢 5.2ms | 🟢 5.4ms | +4.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-enum | 🟢 0.4ms | 🟢 0.4ms | +2.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes | 🟢 2.1ms | 🟢 2.1ms | +1.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops | 🟢 1.5ms | 🟢 1.5ms | +0.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-format | 🟢 7.3ms | 🟢 7.6ms | +3.2% |
| ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric | 🟢 3.6ms | 🟢 3.7ms | +1.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-header-explode | 🔴 282.9ms | 🔴 259.8ms | -8.1% 🟢 |
| ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage | 🔴 22.5ms | 🔴 22.0ms | -2.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator | 🟢 0.8ms | 🟢 0.8ms | -0.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-nullable | 🟢 2.9ms | 🟢 2.9ms | +1.4% |
| ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime | 🟡 15.2ms | 🟡 15.0ms | -1.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-openapi | 🔴 36.5ms | 🔴 36.3ms | -0.4% |
| ↳ linter/@azure-tools/typespec-azure-core/no-private-usage | 🔴 35.1ms | 🔴 36.2ms | +3.2% |
| ↳ linter/@azure-tools/typespec-azure-core/no-query-explode | 🔴 290.7ms | 🔴 270.8ms | -6.8% 🟢 |
| ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces | 🟡 16.4ms | 🟡 17.6ms | +7.1% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch | 🔴 128.6ms | 🔴 116.7ms | -9.3% 🟢 |
| ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params | 🟢 1.9ms | 🟢 2.0ms | +4.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator | 🟢 0.6ms | 🟢 0.6ms | -2.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unknown | 🟢 2.2ms | 🟢 2.2ms | +0.2% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union | 🟢 5.4ms | 🟢 5.6ms | +4.0% |
| ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version | 🟢 3.3ms | 🟢 3.4ms | +2.8% |
| ↳ linter/@azure-tools/typespec-azure-core/request-body-problem | 🟢 5.1ms | 🟢 5.5ms | +6.8% |
| ↳ linter/@azure-tools/typespec-azure-core/require-versioned | 🟢 0.1ms | 🟢 0.1ms | -4.1% |
| ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem | 🔴 324.9ms | 🔴 307.7ms | -5.3% 🟢 |
| ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body | 🟢 0.7ms | 🟢 0.7ms | -2.0% |
| ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model | 🟢 3.4ms | 🟢 3.6ms | +3.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources | 🔴 66.9ms | 🔴 62.8ms | -6.1% 🟢 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-lifecycle-operations | 🟢 0.2ms | 🟢 0.2ms | -7.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version | 🔴 127.7ms | 🔴 124.6ms | -2.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key | 🟢 0.9ms | 🟢 0.9ms | -3.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage | 🟢 0.6ms | 🟢 0.6ms | -1.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes | 🟢 3.7ms | 🟢 3.6ms | -2.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-feature-file-usage-discourage | 🟢 0.0ms | 🟢 0.1ms | +9.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts | 🔴 146.4ms | 🔴 147.5ms | +0.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record | 🟢 3.4ms | 🟢 4.6ms | +34.5% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes | 🟢 9.9ms | 🟢 9.0ms | -9.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes | 🟢 0.3ms | 🟢 0.3ms | +4.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment | 🟢 4.4ms | 🟢 4.3ms | -2.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property | 🟢 1.0ms | 🟢 1.0ms | -4.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator | 🟢 0.5ms | 🟢 0.5ms | +5.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb | 🟢 1.5ms | 🟢 1.5ms | +2.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property | 🟢 0.8ms | 🟢 0.8ms | -0.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format | 🟢 0.3ms | 🟢 0.3ms | -0.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars | 🟢 1.9ms | 🟢 1.8ms | -3.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern | 🟢 0.2ms | 🟢 0.2ms | +2.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation | 🟢 3.3ms | 🟢 3.4ms | +4.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response | 🔴 66.4ms | 🔴 65.3ms | -1.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch | 🟢 4.1ms | 🟢 4.0ms | -4.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars | 🟢 1.4ms | 🟢 1.4ms | +0.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state | 🟢 0.9ms | 🟢 1.0ms | +3.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels | 🟢 0.8ms | 🟢 0.8ms | -1.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties | 🟢 1.5ms | 🟢 1.5ms | +2.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation | 🟢 0.1ms | 🟢 0.1ms | +8.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header | 🔴 287.6ms | 🔴 264.5ms | -8.0% 🟢 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint | 🟢 0.2ms | 🟢 0.2ms | -3.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers | 🟢 4.4ms | 🟢 4.5ms | +1.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model | 🟢 0.7ms | 🟢 0.8ms | +4.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-override-props | 🟢 0.7ms | 🟢 0.8ms | +9.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-reserved-resource-property | 🟢 0.7ms | 🟢 0.7ms | -0.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation | 🟢 2.2ms | 🟢 2.3ms | +5.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body | 🔴 473.8ms | 🔴 443.4ms | -6.4% 🟢 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope | 🟢 1.5ms | 🟢 1.5ms | +1.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name | 🟢 1.6ms | 🟢 1.7ms | +5.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop | 🔴 82.4ms | 🔴 80.0ms | -2.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type | 🟢 4.1ms | 🟢 4.1ms | +0.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression | 🟢 0.3ms | 🟢 0.3ms | -1.6% |
| ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict | 🔴 29.7ms | 🔴 30.1ms | +1.5% |
| ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix | 🟢 6.6ms | 🟢 6.8ms | +2.2% |
| emit | 🔴 11.50s | 🔴 11.42s | -0.7% |
| ↳ emit/@Azure-Tools | 🟢 0.0ms | 🟢 0.0ms | +0.0% |
| ↳ emit/@azure-tools/typespec-client-generator-core | 🔴 5.75s | 🔴 5.71s | -0.7% |
Averaged across 3 specs (compute, network, web).
Threshold: changes > ±5% are highlighted.
🟢 Fast · 🟡 Moderate (stages >200ms, rules >10ms) · 🔴 Slow (stages >400ms, rules >20ms)
There was a problem hiding this comment.
Pull request overview
This PR introduces an always-on “downstream / CI” entrypoint workflow that detects which downstream emitter CI jobs (Python/Java/TypeScript) are affected by upstream dependency changes, and then conditionally runs the corresponding reusable workflows to ensure emitter checks aren’t skipped when upstream-only changes land.
Changes:
- Added
downstream / CIworkflow that runs an “affected targets” detector and gates results. - Added a new
detect-affectedscript (and accompanying tests) to compute per-target boolean outputs. - Converted existing per-emitter CI workflows (python/java/typespec-ts) to
workflow_callso they can be orchestrated by the entrypoint.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.eng.json | Enables TS extension imports for eng scripts/tests. |
| eng/scripts/package.json | Adds a new dependency for eng scripts. |
| eng/scripts/detect-affected.ts | Implements affected-target detection using git diff + pnpm workspace graph + extra path triggers. |
| eng/scripts/detect-affected.test.ts | Adds node:test unit tests for the detection logic. |
| .github/workflows/ci-typescript.yml | Converts TypeScript CI to a reusable workflow (workflow_call). |
| .github/workflows/ci-python.yml | Converts Python CI to a reusable workflow (workflow_call). |
| .github/workflows/ci-java.yml | Converts Java CI to a reusable workflow (workflow_call). |
| .github/workflows/ci-downstream.yml | Adds the orchestrating “downstream / CI” workflow and a gate job. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…ector tests - Correct the 'add a target' comment to reference CONFIG.targets (was TARGETS). - Add **/tests/** to the ignore globs so plural tests directories (e.g. typespec-python/tests) are treated as non-meaningful like **/test/**. - Remove the now-unused minimatch dependency (replaced by the built-in glob matcher during the pnpm-graph refactor). - Run the detector unit tests in CI via 'node --test' in the detect-affected job, and add a 'test:eng' root script for local parity. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
167b847 to
ecc30ad
Compare
ecc30ad to
edc68e0
Compare
edc68e0 to
7bf45b1
Compare
Replace hand-rolled file->package mapping (getWorkspacePackages, mapFilesToPackages), dependent expansion (getDependents), and glob ignore (filterIgnored) with a single pnpm command that derives affected packages from the workspace graph and applies test/markdown filtering via --changed-files-ignore-pattern. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
7bf45b1 to
16248d5
Compare
|
@timotheeguerin updated with your review comment and pls help review again. |
| if: ${{ always() }} | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Validate downstream results |
There was a problem hiding this comment.
- name: Validate CI results
run: |
if [[ "${{ needs.core.result }}" == "failure" || "${{ needs.core.result }}" == "cancelled" ]]; then
echo "Core CI failed or was cancelled"
exit 1
fi
echo "All CI checks passed or were appropriately skipped"
this is the code I have in typespec core. might be more flexible if we add more stuff
There was a problem hiding this comment.
Made the gate generic: it validates results via toJSON(needs) + jq, so no job names are hardcoded here. Adding an emitter (e.g. go) then only needs a go entry in detect-affected.config.json, a ci-go.yml, and a go job block + go in this gate's needs:. The needs: entry and job block are unavoidable (GitHub requires a static uses: and explicit needs:), but the gate body never changes.
Co-authored-by: Timothee Guerin <timothee.guerin@outlook.com>
Co-authored-by: Timothee Guerin <timothee.guerin@outlook.com>
Migrate eng/scripts/detect-affected.test.ts from node:test to the vitest API and register eng/ as a vitest project so the detector unit test runs as part of the normal `pnpm test` suite (ci.yml), mirroring the eng test setup in typespec core. - eng/vitest.config.ts: new project config merging defaultTypeSpecVitestConfig - register eng/vitest.config.ts in vitest.config.fast.ts and vitest.config.ts - test file now uses describe/it/expect and mocks console.log - tsconfig.eng.json: exclude eng/vitest.config.ts (imports core, like core/eng) - package.json test:eng: node --test -> vitest run - ci-downstream.yml: drop redundant node --test step (covered by ci.yml) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 62793370-fd78-402e-b139-26588818aa1e
Make adding a new emitter (e.g. go) a config-only change: introduce
eng/scripts/detect-affected.config.json as the single source of truth for
the ignore globs, shared/extra CI-infra paths, submodule path, and the
target -> package map. The detector, its test, and the workflow gate are
now generic and no longer enumerate emitters by name.
- detect-affected.ts: load CONFIG from the JSON (readFileSync); use
config.submodulePath; emit a single `affected=<json>` GITHUB_OUTPUT
- detect-affected.test.ts: add config-guard tests (submodulePath set,
every target has a package)
- ci-downstream.yml:
- detect-affected exposes one `affected` JSON output; emitter jobs gate
on `fromJSON(needs.detect-affected.outputs.affected).<target>`
- gate validates results generically via `toJSON(needs)` + jq, so a new
emitter only needs a `needs:` entry, not a script edit
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 62793370-fd78-402e-b139-26588818aa1e
The JSDoc example omitted `--depth -1`, which the code actually passes. Align the comment with the real command. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 62793370-fd78-402e-b139-26588818aa1e
|
python ci failure is caused by #4909 |
Implements #4860.
What
Adds upstream-aware downstream CI: when a PR/merge-group changes an upstream dependency (compiler
core/submodule or in-repo libs liketypespec-client-generator-core), the affected downstream emitter checks now run automatically. Closes the gap where an upstream-only change could merge with no emitter check.How
pnpm --filter "...<pkg>"), not a hand-maintained list — adding a new upstream lib needs zero config changes and cannot drift/under-trigger.eng/scripts/detect-affected.ts(zero external deps, run directly vianode;node --testunit/contract tests) — diffs the event's base..head (event-aware forpull_requestvsmerge_group), self-filters ignored files (**/test/**,**/tests/**,**/*.md), maps changes to workspace packages, expands to graph dependents, and emits one boolean output per target.CONFIGindetect-affected.ts: per-target package name, CI-infraextrapaths, and acoreSubmoduleflag (forcore/submodule bumps)..github/workflows/ci-downstream.yml— always-on entrypoint:detect-affected-> conditional per-target reusable-workflow jobs ->downstream-ci-gate.ci-python/java/typescript.ymlconverted toon: workflow_call(invoked only by the entrypoint -> no double-runs).Follow-up required before this gates merges (Strategy A migration)
A repo admin must add
downstream / CI / Downstream CI Gateto required status checks (PR + merge queue) and remove any obsolete standalone emitter check names in the same window.