Skip to content

Commit 4d17ede

Browse files
authored
Merge branch 'main' into storagefiles
2 parents bdf2abb + 0ad3d05 commit 4d17ede

3,540 files changed

Lines changed: 1511513 additions & 324871 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/skills/emitter-package-update/SKILL.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@ npx npm-check-updates --packageFile eng/emitter-package.json -u
7070
> (cross-checked against `packages/typespec-python/package.json` on `main`) — and edit
7171
> `eng/emitter-package.json` by hand to that version.
7272
73-
Align `@azure-tools/openai-typespec` and `@typespec/openapi3` with the versions pinned in [azure-rest-api-specs/package.json](https://github.com/Azure/azure-rest-api-specs/blob/main/package.json) to ensure consistency between the emitter and the spec repo. Read the spec repo's current values for those two packages and set them to match in `eng/emitter-package.json` (do not assume specific version numbers — use whatever the spec repo currently pins).
73+
Align the packages listed in `alignment-sources.json` with the versions pinned in each
74+
configured source repo package file to ensure consistency between the emitter and its
75+
upstream sources. For each source, read `packageJsonUrl`, set every package listed in
76+
that source's `packages` array to the version currently pinned there, and do not assume
77+
specific version numbers. To add more libraries for alignment later, add their package
78+
names to the relevant `packages` array in `alignment-sources.json`.
7479

7580
If a specific version was requested, pin `@azure-tools/typespec-python` to that exact
7681
version in `eng/emitter-package.json` (overriding what npm-check-updates picked).
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"azure-rest-api-specs": {
3+
"packageJsonUrl": "https://github.com/Azure/azure-rest-api-specs/blob/main/package.json",
4+
"packages": [
5+
"@azure-tools/openai-typespec",
6+
"@typespec/openapi3",
7+
"@azure-tools/typespec-liftr-base",
8+
"@azure-tools/typespec-azure-portal-core"
9+
]
10+
}
11+
}

.github/workflows/api-consistency.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ jobs:
5353
API_MD_CHANGED_FILE: .artifacts/changed_package_dirs.txt
5454
API_MD_PACKAGES_FILE: .artifacts/affected_package_dirs.txt
5555
API_MD_MISMATCHES_FILE: .artifacts/mismatched_api_files.txt
56+
API_MD_MISMATCH_DETAILS_FILE: .artifacts/mismatched_api_details.txt
5657
API_MD_MISSING_FILE: .artifacts/missing_api_files.txt
5758
with:
5859
script: |

.github/workflows/src/api-md-consistency/api-md-consistency.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ function readLines(fileRelativePath, workspace) {
3434
.filter((line) => Boolean(line));
3535
}
3636

37+
function readText(fileRelativePath, workspace) {
38+
const fullPath = path.join(workspace, fileRelativePath);
39+
if (!fs.existsSync(fullPath)) {
40+
return "";
41+
}
42+
43+
return fs.readFileSync(fullPath, "utf-8").trim();
44+
}
45+
3746
function formatIssueSection(title, apiFiles) {
3847
if (!apiFiles.length) {
3948
return "";
@@ -55,6 +64,16 @@ function formatIssueSection(title, apiFiles) {
5564
return lines.join("\n");
5665
}
5766

67+
function logMismatchDetails(core, mismatchDetails) {
68+
if (!mismatchDetails) {
69+
return;
70+
}
71+
72+
core.startGroup("API.md mismatch details");
73+
core.info(mismatchDetails);
74+
core.endGroup();
75+
}
76+
5877
export default async function apiMdConsistency({ core }) {
5978
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
6079

@@ -81,6 +100,7 @@ export default async function apiMdConsistency({ core }) {
81100

82101
const mismatches = readLines(process.env.API_MD_MISMATCHES_FILE, workspace);
83102
const missing = readLines(process.env.API_MD_MISSING_FILE, workspace);
103+
const mismatchDetails = readText(process.env.API_MD_MISMATCH_DETAILS_FILE, workspace);
84104

85105
const mismatchCount = mismatches.length;
86106
const missingCount = missing.length;
@@ -91,12 +111,15 @@ export default async function apiMdConsistency({ core }) {
91111
core.setOutput("issue_count", String(issueCount));
92112

93113
if (issueCount > 0) {
114+
logMismatchDetails(core, mismatchDetails);
115+
94116
const messageParts = [
95117
"Generated api.md or api.metadata.yml does not match the committed files, or required API files are missing, for one or more affected packages.",
96118
"api.metadata.yml must be committed alongside api.md, and selected metadata fields are part of pass/fail gating.",
97119
"",
98120
formatIssueSection("Mismatched packages:", mismatches),
99121
formatIssueSection("Missing required API files:", missing),
122+
mismatchDetails ? ["Mismatch details:", mismatchDetails].join("\n") : "",
100123
"To regenerate api.md and api.metadata.yml locally, run the command shown for each package from the repository root.",
101124
].filter((part) => part !== "");
102125

.github/workflows/src/api-md-consistency/find_mismatches.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import fs from "fs";
55
import { appendGithubOutput, envPath, getDefaultLogger, readLines, runAsync, writeLines } from "./common.js";
66
import { loadAdapter, loadWorkflowConfig } from "./adapter_config.js";
77

8+
const MAX_DIFF_LINES = 200;
9+
810
/**
911
* Parse a simple key: value YAML file into an object.
1012
* Only handles flat scalar mappings (no nesting, no multi-line values).
@@ -20,6 +22,36 @@ function parseSimpleYaml(text) {
2022
return result;
2123
}
2224

25+
function truncateLines(text, maxLines) {
26+
const lines = text.split(/\r?\n/);
27+
if (lines.length <= maxLines) {
28+
return text.trimEnd();
29+
}
30+
31+
return `${lines.slice(0, maxLines).join("\n")}\n... diff truncated after ${maxLines} lines ...`;
32+
}
33+
34+
function formatMetadataDiff(metadataFile, keys, committed, current) {
35+
const lines = [`${metadataFile} gated metadata differences:`];
36+
for (const key of keys) {
37+
if (current[key] !== committed[key]) {
38+
lines.push(` ${key}:`);
39+
lines.push(` committed: ${committed[key] ?? "<missing>"}`);
40+
lines.push(` generated: ${current[key] ?? "<missing>"}`);
41+
}
42+
}
43+
return lines.join("\n");
44+
}
45+
46+
async function formatApiDiff(apiFile) {
47+
const diffResult = await runAsync("git", ["diff", "--no-ext-diff", "--unified=3", "--", apiFile], {
48+
check: false,
49+
maxBuffer: 1024 * 1024 * 10,
50+
});
51+
const diff = diffResult.stdout || diffResult.stderr;
52+
return diff ? truncateLines(diff, MAX_DIFF_LINES) : `${apiFile} changed, but no diff output was captured.`;
53+
}
54+
2355
async function main() {
2456
const config = loadWorkflowConfig();
2557
const adapter = await loadAdapter(config.adapter);
@@ -31,10 +63,12 @@ async function main() {
3163
const packagesFile = envPath("API_MD_PACKAGES_FILE", ".artifacts/affected_package_dirs.txt");
3264
const mismatchesFile = envPath("API_MD_MISMATCHES_FILE", ".artifacts/mismatched_api_files.txt");
3365
const missingFile = envPath("API_MD_MISSING_FILE", ".artifacts/missing_api_files.txt");
66+
const mismatchDetailsFile = envPath("API_MD_MISMATCH_DETAILS_FILE", ".artifacts/mismatched_api_details.txt");
3467
const packages = readLines(packagesFile);
3568

3669
const mismatches = [];
3770
const missing = [];
71+
const mismatchDetails = [];
3872
for (const pkgDir of packages) {
3973
const apiFile = `${pkgDir}/api.md`;
4074
const metadataFile = `${pkgDir}/api.metadata.yml`;
@@ -72,6 +106,7 @@ async function main() {
72106
const mismatch = keys.some((key) => current[key] !== committed[key]);
73107
if (mismatch) {
74108
mismatches.push(metadataFile);
109+
mismatchDetails.push(formatMetadataDiff(metadataFile, keys, committed, current));
75110
}
76111
}
77112
}
@@ -82,11 +117,13 @@ async function main() {
82117
});
83118
if (quietDiffResult.status !== 0) {
84119
mismatches.push(apiFile);
120+
mismatchDetails.push(await formatApiDiff(apiFile));
85121
}
86122
}
87123

88124
writeLines(mismatchesFile, mismatches);
89125
writeLines(missingFile, missing);
126+
writeLines(mismatchDetailsFile, mismatchDetails);
90127
appendGithubOutput("mismatch_count", mismatches.length);
91128
appendGithubOutput("missing_count", missing.length);
92129
appendGithubOutput("issue_count", mismatches.length + missing.length);

.vscode/cspell.json

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@
301301
"ivars",
302302
"jwks",
303303
"kashifkhan",
304+
"liftr",
304305
"keybak",
305306
"kube",
306307
"kubeconfig",
@@ -1663,18 +1664,6 @@
16631664
"Igog",
16641665
]
16651666
},
1666-
{
1667-
"filename": "sdk/deviceupdate/azure-iot-deviceupdate/**",
1668-
"words": [
1669-
"wday",
1670-
"mday",
1671-
"unflattened",
1672-
"deseralize",
1673-
"astimezone",
1674-
"ctxt",
1675-
"Nify"
1676-
]
1677-
},
16781667
{
16791668
"filename": "sdk/cosmos/azure-cosmos/**",
16801669
"words": [

doc/analyze_check_versions.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ This table is to clarify the currently pinned version of tools we run in CI and
55

66
| Tool | Current Version | Next Version | Next Version Merge Date |
77
|------|-----------------|--------------|-------------------------|
8-
Pylint | 4.0.4 | 4.0.4 | 2026-07-13 |
8+
Pylint | 4.0.4 | 4.0.6 | 2026-10-05 |
99
Pylint Guidelines Checker | 0.5.7 | 0.5.7 | 2026-07-13 |
10-
MyPy | 1.19.1 | 1.19.1 | 2026-07-13 |
11-
Pyright | 1.1.407 | 1.1.407 | 2026-07-13 |
10+
MyPy | 1.19.1 | 2.1.0 | 2026-10-05 |
11+
Pyright | 1.1.407 | 1.1.411 | 2026-10-05 |
1212
Sphinx | 8.2.0 | N/A | N/A |
1313
Black | 24.4.0 | N/A | N/A |
14-
Ruff | 0.15.11 | N/A | N/A |

eng/common/TestResources/SubConfig-Helpers.ps1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ function ShouldMarkValueAsSecret([string]$serviceName, [string]$key, [string]$va
8282
"SERVICE_MANAGEMENT_URL",
8383
"ENDPOINT_SUFFIX",
8484
"SERVICE_DIRECTORY",
85+
"RUST_TEST_THREADS",
86+
"RUST_BACKTRACE",
87+
"COSMOS_RUSTFLAGS",
88+
"DATABASE_NAME",
89+
"ACCOUNT_HOST",
8590
# This is used in many places and is harder to extract from the base subscription config, so hardcode it for now.
8691
"STORAGE_ENDPOINT_SUFFIX",
8792
# Parameters

eng/common/pipelines/live-eval.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Live-tier eval CI: nightly end-to-end run of the live workflow scenarios against the real
2+
# azsdk-cli MCP and real Azure DevOps (writes confined to a test area).
3+
4+
# Nightly only — no CI/PR trigger.
5+
trigger: none
6+
pr: none
7+
8+
schedules:
9+
- cron: '0 9 * * *' # 09:00 UTC daily
10+
displayName: 'Nightly live eval'
11+
branches:
12+
include:
13+
- main
14+
always: true # run even when main has not changed
15+
16+
variables:
17+
# Managed-pool image selection (LINUXPOOL/LINUXVMIMAGE). Repo-local.
18+
- template: /eng/pipelines/templates/variables/image.yml
19+
# Provides the secret azuresdk-copilot-github-pat, mapped into GITHUB_TOKEN in the invoke step.
20+
- group: AzSDK_Eval_Variable_group
21+
22+
extends:
23+
template: /eng/common/pipelines/templates/stages/archetype-eval.yml
24+
parameters:
25+
# Shared mock/live builder; select the live tier (real Cli MCP).
26+
mcpSetupTemplate: /eng/common/pipelines/templates/steps/eval-mcp-setup.yml
27+
TestType: live
28+
vallyRoot: tools/azsdk-cli/Azure.Sdk.Tools.Vally
29+
evalGlobs:
30+
- 'evals/workflow-scenarios/live/*.eval.yaml'
31+
# Run each shard under AzureCLI@2 so the real MCP's DevOps calls are authenticated.
32+
UseAzSdkAuthentication: true
33+
failOnFailedTests: true
34+
# Live scenarios are end-to-end, so give each shard more headroom than the report-only tiers.
35+
shardTimeoutInMinutes: 45
36+
# Pass-rate gate for `vally eval`. This tier gates (failOnFailedTests: true), so the threshold
37+
# is the real bar the nightly run must clear; raise it here as live coverage stabilizes.
38+
threshold: 0.8
39+
# This repo needs no repo-specific setup (the live MCP is built by the common BuildMcp job).
40+
# A spec/language repo that must start its own bot / server / MCP copies the example hook and
41+
# points these at it — see eng/common/pipelines/templates/steps/eval-hook-example.yml.
42+
# preEvalTemplate: /eng/pipelines/eval/start-my-bot.yml
43+
# postEvalTemplate: /eng/pipelines/eval/stop-my-bot.yml
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Skill-compliance eval CI: runs the per-skill Vally evals under .github/skills (one job per skill).
2+
3+
trigger:
4+
branches:
5+
include:
6+
- main
7+
paths:
8+
include:
9+
- .github/skills/**
10+
# Retrigger when the mock MCP's tool catalog changes (it can move results).
11+
- tools/azsdk-cli/Azure.Sdk.Tools.Mock/**
12+
- eng/common/pipelines/skill-eval.yml
13+
- eng/common/pipelines/templates/jobs/**
14+
- eng/common/pipelines/templates/steps/eval-invoke.yml
15+
- eng/common/pipelines/templates/steps/eval-mcp-setup.yml
16+
- eng/common/pipelines/templates/stages/archetype-eval.yml
17+
- eng/common/scripts/eval/**
18+
19+
pr: none
20+
21+
variables:
22+
# Managed-pool image selection (LINUXPOOL/LINUXVMIMAGE). Repo-local.
23+
- template: /eng/pipelines/templates/variables/image.yml
24+
# Provides the secret azuresdk-copilot-github-pat, mapped into GITHUB_TOKEN in the invoke step.
25+
- group: AzSDK_Eval_Variable_group
26+
27+
extends:
28+
template: /eng/common/pipelines/templates/stages/archetype-eval.yml
29+
parameters:
30+
# Shared mock/live builder; select the mock tier.
31+
mcpSetupTemplate: /eng/common/pipelines/templates/steps/eval-mcp-setup.yml
32+
TestType: mock
33+
vallyRoot: .github/skills
34+
# Single-level glob excludes azure-typespec-author/evaluate/ (its own benchmark pipeline).
35+
evalGlobs:
36+
- '*/evals/*.eval.yaml'
37+
# Per-shard job timeout (report-only tier).
38+
shardTimeoutInMinutes: 20

0 commit comments

Comments
 (0)