Skip to content

Commit 139241d

Browse files
author
Xiting Zhang
committed
Merge remote-tracking branch 'upstream/main'
2 parents 92c5df0 + 9afe0f0 commit 139241d

Some content is hidden

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

45 files changed

+3670
-830
lines changed

eng/common/instructions/azsdk-tools/create-sdk-locally.instructions.md

Lines changed: 0 additions & 32 deletions
This file was deleted.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
description: "Guide the user to generate and build SDKs locally for a TypeSpec based API spec"
3+
---
4+
5+
# Goal
6+
7+
Help the user generate and build SDKs locally from TypeSpec API specifications using the `azure-sdk-mcp` tools.
8+
9+
---
10+
11+
## Part A: Generate SDK Locally
12+
13+
### Step 1: Outline workflow
14+
15+
**Goal**: Ensure the user understands the overall SDK generation and build process before starting.
16+
**Actions**:
17+
18+
- Present the high-level steps involved in generating and building SDK locally:
19+
1. Select target language
20+
2. Verify SDK repository
21+
3. Validate repository path
22+
4. Identify path to configuration file
23+
5. Generate SDK using `azsdk_package_generate_code` MCP tool
24+
6. Identify SDK project path
25+
7. Build/Compile SDK using `azsdk_package_build_code` MCP tool
26+
- Ask the user to confirm readiness to proceed.
27+
28+
---
29+
30+
### Step 2: Select language
31+
32+
**Goal**: Confirm the target language for SDK generation.
33+
**Actions**:
34+
35+
- Prompt user to choose one of the supported languages:
36+
- .NET
37+
- Java
38+
- JavaScript
39+
- Python
40+
- Go
41+
- Validate input against the allowed list.
42+
43+
---
44+
45+
### Step 3: Verify SDK repository
46+
47+
**Goal**: Ensure the correct Azure SDK language repository is available locally.
48+
**Actions**:
49+
50+
- Prompt user to provide the path to their **locally cloned repository** for the selected language.
51+
- Note: The **local folder name can be arbitrary**, but the repository must have originated from one of the official Azure SDK repositories:
52+
- `azure-sdk-for-net` (.NET)
53+
- `azure-sdk-for-java` (Java)
54+
- `azure-sdk-for-js` (JavaScript)
55+
- `azure-sdk-for-python` (Python)
56+
- `azure-sdk-for-go` (Go)
57+
- If the repository is not cloned → instruct user to clone the appropriate remote repository from GitHub.
58+
- MCP tool will automatically validate the remote origin and repository structure.
59+
60+
---
61+
62+
### Step 4: Validate repository path
63+
64+
**Actions**:
65+
66+
- Check if the provided repository path exists and matches the selected SDK language repository.
67+
- If invalid → prompt user to re-enter a valid path.
68+
69+
---
70+
71+
### Step 5: Identify path to configuration file
72+
73+
**Goal**: Determine the correct path to the TypeSpec configuration file based on the working context.
74+
**Actions**:
75+
76+
- **Scenario A: Working in a repository cloned from `azure-rest-api-specs`**
77+
- Identify the path to `tspconfig.yaml` (local path or HTTPS URL).
78+
- The local folder name can be arbitrary; the MCP tool will validate that the remote origin URL points to the official `azure-rest-api-specs` repository.
79+
- Example paths (pointing directly to tspconfig.yaml):
80+
- `/home/usr/azure-rest-api-specs/specification/contosowidgetmanager/Contoso.Management/tspconfig.yaml`
81+
- `https://github.com/Azure/azure-rest-api-specs/blob/4af373fc5826cf5a2365a20dde01c4b2efde48f0/specification/contosowidgetmanager/Contoso.Management/tspconfig.yaml`
82+
83+
- **Scenario B: Working in one of the official Azure SDK language repositories**
84+
(i.e., originally cloned from `azure-sdk-for-net`, `azure-sdk-for-java`, `azure-sdk-for-js`, `azure-sdk-for-python`, `azure-sdk-for-go`)
85+
- Identify the path to `tsp-location.yaml`.
86+
- The local folder name can be arbitrary; MCP tool will validate the remote origin URL.
87+
- Example path:
88+
`/home/usr/azure-sdk-for-net/sdk/contoso/Azure.ResourceManager.Contoso/tsp-location.yaml`
89+
90+
---
91+
92+
### Step 6: Generate SDK
93+
94+
**Actions**:
95+
96+
- Run `azsdk_package_generate_code` MCP tool to generate the SDK locally.
97+
98+
---
99+
100+
## Part B: Build / Compile SDK Locally
101+
102+
### Step 1: Identify SDK project path
103+
104+
**Goal**: Locate the generated SDK project directory for building/compiling.
105+
**Actions**:
106+
107+
- Find the project directory inside the selected Azure SDK language repository.
108+
- Typical structure:
109+
`sdk/{service-name}/{package-name}/`
110+
- Example:
111+
`/path/to/azure-sdk-for-net/contoso/Azure.ResourceManager.Contoso/`
112+
113+
---
114+
115+
### Step 2: Build/Compile the SDK
116+
117+
**Actions**:
118+
119+
- Run `azsdk_package_build_code` MCP tool to compile the SDK in the identified project directory.

eng/common/instructions/azsdk-tools/sdk-details-in-release-plan.instructions.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ description: 'Identify languages configured in the TypeSpec project and add it t
55
**Goal**: Identify languages configured in the TypeSpec project and generate the json object with language and package name.
66
1. Identify the language emitter configuration in the `tspconfig.yaml` file in the TypeSpec project root.
77
2. Identify the package name or namespace for each language emitter.
8+
- For Java and Python, use `emitter-output-dir` for package name if it exists. Otherwise use `package-dir` to get the package name as fallback approach.
9+
- For .NET, use namespace property to get package name.
10+
- For JavaScript, use `packagedetails:name` property to get package name.
11+
- For Go, use module name and remove `github.com/Azure/azure-sdk-for-go/` to get package name
812
3. Map the language name in emitter to one of the following in Pascal case(except .NET):
913
- .NET
1014
- Java
1115
- Python
1216
- JavaScript
1317
- Go
14-
4. Remove `github.com/Azure/azure-sdk-for-go/` from Go package name.
1518
4. Create a JSON array object with the following structure:
1619
```json
1720
[

eng/common/instructions/azsdk-tools/typespec-to-sdk.instructions.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,12 @@ Wait for the user to respond with a confirmation before proceeding to Step 1. Us
5757
**Goal**: Determine how to generate SDKs
5858
**Actions**:
5959
1. Present options: "How would you like to generate SDKs?"
60-
- Option A: "Generate SDK locally". This is currently supported only for Python. Do not recommend this for other languages.
60+
- Option A: "Generate SDK locally".
6161
- Option B: "Use SDK generation pipeline"
6262
2. Based on selection:
63-
- If Option A: Refer to #file:create-sdk-locally.instructions.md and then proceed to Step 6
63+
- If Option A:
64+
- Follow #file:./local-sdk-workflow.instructions.md to generate and compile the SDK.
65+
- After SDK has been generated, to continue the SDK release, users can create the SDK pull request manually then proceed to Step 9.
6466
- If Option B: Continue to Step 6
6567
**Success Criteria**: SDK generation method selected
6668

eng/common/scripts/Helpers/Resource-Helpers.ps1

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,32 @@ function Get-PurgeableGroupResources {
3838
$purgeableResources += $deletedKeyVaults
3939
}
4040

41+
Write-Verbose "Retrieving AI resources from resource group $ResourceGroupName"
42+
43+
# Get AI resources that will go into soft-deleted state when the resource group is deleted
44+
$subscriptionId = (Get-AzContext).Subscription.Id
45+
$aiResources = @()
46+
47+
# Get active Cognitive Services accounts from the resource group
48+
$response = Invoke-AzRestMethod -Method GET -Path "/subscriptions/$subscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.CognitiveServices/accounts?api-version=2024-10-01" -ErrorAction Ignore
49+
if ($response.StatusCode -ge 200 -and $response.StatusCode -lt 300 -and $response.Content) {
50+
$content = $response.Content | ConvertFrom-Json
51+
52+
foreach ($r in $content.value) {
53+
$aiResources += [pscustomobject] @{
54+
AzsdkResourceType = "Cognitive Services ($($r.kind))"
55+
AzsdkName = $r.name
56+
Name = $r.name
57+
Id = $r.id
58+
}
59+
}
60+
}
61+
62+
if ($aiResources) {
63+
Write-Verbose "Found $($aiResources.Count) AI resources to potentially purge after resource group deletion."
64+
$purgeableResources += $aiResources
65+
}
66+
4167
return $purgeableResources
4268
}
4369

@@ -94,6 +120,29 @@ function Get-PurgeableResources {
94120
}
95121
catch { }
96122

123+
Write-Verbose "Retrieving deleted Cognitive Services accounts from subscription $subscriptionId"
124+
125+
# Get deleted Cognitive Services accounts for the current subscription.
126+
$response = Invoke-AzRestMethod -Method GET -Path "/subscriptions/$subscriptionId/providers/Microsoft.CognitiveServices/deletedAccounts?api-version=2024-10-01" -ErrorAction Ignore
127+
if ($response.StatusCode -ge 200 -and $response.StatusCode -lt 300 -and $response.Content) {
128+
$content = $response.Content | ConvertFrom-Json
129+
130+
$deletedCognitiveServices = @()
131+
foreach ($r in $content.value) {
132+
$deletedCognitiveServices += [pscustomobject] @{
133+
AzsdkResourceType = "Cognitive Services ($($r.kind))"
134+
AzsdkName = $r.name
135+
Name = $r.name
136+
Id = $r.id
137+
}
138+
}
139+
140+
if ($deletedCognitiveServices) {
141+
Write-Verbose "Found $($deletedCognitiveServices.Count) deleted Cognitive Services accounts to potentially purge."
142+
$purgeableResources += $deletedCognitiveServices
143+
}
144+
}
145+
97146
return $purgeableResources
98147
}
99148

@@ -117,33 +166,37 @@ filter Remove-PurgeableResources {
117166
}
118167

119168
$subscriptionId = (Get-AzContext).Subscription.Id
169+
$verboseFlag = $VerbosePreference -eq 'Continue'
120170

121171
foreach ($r in $Resource) {
122-
Log "Attempting to purge $($r.AzsdkResourceType) '$($r.AzsdkName)'"
123172
switch ($r.AzsdkResourceType) {
124173
'Key Vault' {
125174
if ($r.EnablePurgeProtection) {
126-
Write-Warning "Key Vault '$($r.VaultName)' has purge protection enabled and may not be purged until $($r.ScheduledPurgeDate)"
175+
Write-Verbose "Key Vault '$($r.VaultName)' has purge protection enabled and may not be purged until $($r.ScheduledPurgeDate)" -Verbose:$verboseFlag
127176
continue
128177
}
129178

179+
Log "Attempting to purge $($r.AzsdkResourceType) '$($r.AzsdkName)'"
180+
130181
# Use `-AsJob` to start a lightweight, cancellable job and pass to `Wait-PurgeableResoruceJob` for consistent behavior.
131182
Remove-AzKeyVault -VaultName $r.VaultName -Location $r.Location -InRemovedState -Force -ErrorAction Continue -AsJob `
132183
| Wait-PurgeableResourceJob -Resource $r -Timeout $Timeout -PassThru:$PassThru
133184
}
134185

135186
'Managed HSM' {
136187
if ($r.EnablePurgeProtection) {
137-
Write-Warning "Managed HSM '$($r.Name)' has purge protection enabled and may not be purged until $($r.ScheduledPurgeDate)"
188+
Write-Verbose "Managed HSM '$($r.Name)' has purge protection enabled and may not be purged until $($r.ScheduledPurgeDate)" -Verbose:$verboseFlag
138189
continue
139190
}
140191

192+
Log "Attempting to purge $($r.AzsdkResourceType) '$($r.AzsdkName)'"
193+
141194
# Use `GetNewClosure()` on the `-Action` ScriptBlock to make sure variables are captured.
142195
Invoke-AzRestMethod -Method POST -Path "/subscriptions/$subscriptionId/providers/Microsoft.KeyVault/locations/$($r.Location)/deletedManagedHSMs/$($r.Name)/purge?api-version=2023-02-01" -ErrorAction Ignore -AsJob `
143196
| Wait-PurgeableResourceJob -Resource $r -Timeout $Timeout -PassThru:$PassThru -Action {
144197
param ( $response )
145198
if ($response.StatusCode -ge 200 -and $response.StatusCode -lt 300) {
146-
Write-Warning "Successfully requested that Managed HSM '$($r.Name)' be purged, but may take a few minutes before it is actually purged."
199+
Write-Verbose "Successfully requested that Managed HSM '$($r.Name)' be purged, but may take a few minutes before it is actually purged." -Verbose:$verboseFlag
147200
}
148201
elseif ($response.Content) {
149202
$content = $response.Content | ConvertFrom-Json
@@ -155,6 +208,22 @@ filter Remove-PurgeableResources {
155208
}.GetNewClosure()
156209
}
157210

211+
{ $_.StartsWith('Cognitive Services') }
212+
{
213+
Log "Attempting to purge $($r.AzsdkResourceType) '$($r.AzsdkName)'"
214+
# Use `GetNewClosure()` on the `-Action` ScriptBlock to make sure variables are captured.
215+
Invoke-AzRestMethod -Method DELETE -Path "$($r.id)?api-version=2024-10-01" -ErrorAction Ignore -AsJob `
216+
| Wait-PurgeableResourceJob -Resource $r -Timeout $Timeout -PassThru:$PassThru -Action {
217+
param ( $response )
218+
219+
if ($response.StatusCode -eq 200 -or $response.StatusCode -eq 202 -or $response.StatusCode -eq 204) {
220+
Write-Verbose "Successfully purged $($r.AzsdkResourceType) '$($r.Name)'." -Verbose:$verboseFlag
221+
} else {
222+
Write-Warning "Failed purging $($r.AzsdkResourceType) '$($r.Name)' with status code $($response.StatusCode)."
223+
}
224+
}.GetNewClosure()
225+
}
226+
158227
default {
159228
Write-Warning "Cannot purge $($r.AzsdkResourceType) '$($r.AzsdkName)'. Add support to https://github.com/Azure/azure-sdk-tools/blob/main/eng/common/scripts/Helpers/Resource-Helpers.ps1."
160229
}

eng/common/tsp-client/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# TypeSpec Client Generator CLI
2+
3+
This directory contains npm package definitions for `@azure-tools/typespec-client-generator-cli` (tsp-client) with pinned versions to ensure reproducible builds across environments.
4+
5+
## Files
6+
7+
- **`package.json`** - npm package definition with pinned tsp-client version
8+
- **`package-lock.json`** - Lock file ensuring exact dependency versions
9+
10+
## Prerequisites
11+
12+
- **Node.js** (with npm) - Required to install and run tsp-client
13+
14+
## Installation
15+
16+
### Install dependencies
17+
18+
```bash
19+
# Navigate to this directory
20+
cd eng/common/tsp-client
21+
22+
# Install dependencies
23+
npm ci
24+
```
25+
26+
## Usage
27+
28+
After installation, you can run tsp-client by navigating to the directory and using npm exec:
29+
30+
```bash
31+
cd eng/common/tsp-client
32+
33+
# Get help
34+
npm exec --no -- tsp-client --help
35+
36+
# Check version
37+
npm exec --no -- tsp-client version
38+
39+
# Generate client code
40+
npm exec --no -- tsp-client generate --output-dir ./generated
41+
42+
# Initialize a new project
43+
npm exec --no -- tsp-client init --tsp-config ./tspconfig.yaml
44+
```
45+
46+
## CI/CD Best Practices
47+
48+
```bash
49+
cd eng/common/tsp-client
50+
npm ci
51+
npm exec --no -- tsp-client init --update-if-exists --tsp-config https://github.com/Azure/azure-rest-api-specs/blob/dee71463cbde1d416c47cf544e34f7966a94ddcb/specification/contosowidgetmanager/Contoso.WidgetManager/tspconfig.yaml
52+
```
53+
54+
## Package Management
55+
56+
### Automatic Updates via Dependabot
57+
58+
Dependabot is configured to automatically check for updates to `@azure-tools/typespec-client-generator-cli` daily and create pull requests with updated `package.json` and `package-lock.json` files. This ensures the package stays current with the latest versions while maintaining security through the PR review process.
59+
60+
### Manual Version Updates
61+
62+
If you need to manually update the tsp-client version:
63+
64+
1. Edit `package.json` to update the version:
65+
66+
```json
67+
{
68+
"dependencies": {
69+
"@azure-tools/typespec-client-generator-cli": "0.28.1"
70+
}
71+
}
72+
```
73+
74+
2. Update the lock file:
75+
76+
```bash
77+
npm install
78+
```
79+
80+
3. Commit both `package.json` and `package-lock.json`

0 commit comments

Comments
 (0)