Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
02b435c
Set Github actions env in sandbox to use workload identity auth
praveenkuttappan Feb 20, 2026
9655685
Update manual dispatch inputs
praveenkuttappan Feb 20, 2026
5e86029
Manual troubleshooting changes
praveenkuttappan Feb 20, 2026
a691ba5
Add github action env variable in sandbox
praveenkuttappan Feb 20, 2026
ecd7831
Add a step to verify token file
praveenkuttappan Feb 20, 2026
3107394
network access changes
praveenkuttappan Feb 20, 2026
93429f5
network access changes2
praveenkuttappan Feb 20, 2026
a4d2ae2
Add auth step inside sandbox
praveenkuttappan Feb 20, 2026
a080306
Additional network permission
praveenkuttappan Feb 20, 2026
86c44d4
SDK generation agent with imports
praveenkuttappan Feb 20, 2026
f513048
Add default issue url for debug
praveenkuttappan Feb 20, 2026
f15aa81
Renamed yml
praveenkuttappan Feb 20, 2026
9520a26
Reduce common import
praveenkuttappan Feb 20, 2026
f43a25b
Rename file
praveenkuttappan Feb 20, 2026
0d31edd
Fix missing filename issue
praveenkuttappan Feb 20, 2026
398f5f6
Add Azure login in workflow
praveenkuttappan Feb 20, 2026
262a92f
Add Azure login in workflow
praveenkuttappan Feb 20, 2026
f637fb4
Rebuild workflow
praveenkuttappan Feb 20, 2026
5ac9630
Force regenerate agent workflow
praveenkuttappan Feb 20, 2026
e2ac9e2
gh-aw rebuild
praveenkuttappan Feb 20, 2026
83fe08b
gh-aw rebuild with gh token
praveenkuttappan Feb 20, 2026
328de84
Remove debug lines
praveenkuttappan Feb 20, 2026
671723e
Merge branch 'main' into sdk_generation_agent_auth_changes
praveenkuttappan Feb 20, 2026
2cca95a
Update to load copilot token from keyvault
praveenkuttappan Feb 22, 2026
e76c225
Update to remove test changes to remove reference to kv
praveenkuttappan Feb 22, 2026
abfa283
Add azsdk into path and create a sahred import for azsdk install
praveenkuttappan Feb 22, 2026
4787d60
Remove debug changes
praveenkuttappan Feb 22, 2026
fdccafc
Add a step to set repo secret from kv
praveenkuttappan Feb 23, 2026
8e7e9a0
Add step to install gh aw cli
praveenkuttappan Feb 23, 2026
bfcc338
Checkout repo before auth step
praveenkuttappan Feb 23, 2026
4b625c3
Reduce to use only one pat
praveenkuttappan Feb 23, 2026
bc13235
Revert to use the PAT
praveenkuttappan Feb 23, 2026
b9585ea
Use two PATs for agent workflow
praveenkuttappan Feb 23, 2026
831bce8
Merge branch 'main' into sdk_generation_agent_auth_changes
praveenkuttappan Feb 24, 2026
8f85eb4
Remove debug PR link
praveenkuttappan Feb 24, 2026
583bc86
Merge branch 'sdk_generation_agent_auth_changes' of https://github.co…
praveenkuttappan Feb 24, 2026
ab468d6
Merge branch 'main' into sdk_generation_agent_auth_changes
praveenkuttappan Feb 24, 2026
a513873
Merge branch 'main' into sdk_generation_agent_auth_changes
praveenkuttappan Feb 24, 2026
109b151
Remove redundant az login from workflow
praveenkuttappan Feb 24, 2026
7af5006
Merge branch 'sdk_generation_agent_auth_changes' of https://github.co…
praveenkuttappan Feb 24, 2026
e3de0d0
Merge kv fetch and copilot token persist to one step
praveenkuttappan Feb 25, 2026
4049948
Merge branch 'main' into sdk_generation_agent_auth_changes
praveenkuttappan Feb 25, 2026
17acb5d
Merge branch 'main' into sdk_generation_agent_auth_changes
praveenkuttappan Feb 25, 2026
a846272
Merge branch 'main' into sdk_generation_agent_auth_changes
praveenkuttappan Feb 26, 2026
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
2 changes: 1 addition & 1 deletion .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
paths:
.github/workflows/*.lock.yaml:
.github/workflows/*.lock.yml:
ignore:
- ".+"

Large diffs are not rendered by default.

132 changes: 35 additions & 97 deletions .github/workflows/sdk-generation-agent.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---
description: Trigger SDK generation from issues and comments, monitor pipeline status, and report SDK PR links.
on:
Expand All @@ -7,18 +7,8 @@
types: [created]
workflow_dispatch:
inputs:
work_item_id:
description: "Release plan work item ID"
required: true
release_plan_id:
description: "Release plan ID"
required: true
languages:
description: "Comma-separated languages to generate (Python,.NET,JavaScript,Java,go). Leave blank to use release plan defaults."
required: false
pr_number:
description: "Optional TypeSpec PR number to associate with SDK generation"
required: false
issue_url:
description: "Issue URL providing SDK generation context"
if: >
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'issues' &&
Expand All @@ -36,83 +26,35 @@
- name: Checkout code
uses: actions/checkout@v6

- name: Acquire OIDC token for Azure
id: oidc
uses: actions/github-script@v7
with:
script: |
const token = await core.getIDToken('api://AzureADTokenExchange');
const fs = require('fs');
fs.writeFileSync('/tmp/azure-oidc-token', token);

- name: Verify Azure CLI authentication
shell: bash
run: |
set -euo pipefail
if ! command -v az >/dev/null 2>&1; then
echo "Azure CLI (az) is not installed on this runner." >&2
exit 1
fi

if [[ -z "${AZURE_CLIENT_ID:-}" || -z "${AZURE_TENANT_ID:-}" || -z "${AZURE_FEDERATED_TOKEN_FILE:-}" ]]; then
echo "Azure federated authentication variables are missing." >&2
exit 1
fi

FED_TOKEN=$(cat "$AZURE_FEDERATED_TOKEN_FILE")
if [[ -z "$FED_TOKEN" ]]; then
echo "Federated token file $AZURE_FEDERATED_TOKEN_FILE is empty." >&2
exit 1
fi

echo "Ensuring Azure CLI session is authenticated using workload identity..."
az login --service-principal \
--username "$AZURE_CLIENT_ID" \
--tenant "$AZURE_TENANT_ID" \
--federated-token "$FED_TOKEN" \
--allow-no-subscriptions >/tmp/az-login.json

if az account show --output json > /tmp/az-account.json 2>/tmp/az-account.err; then
echo "Azure CLI authentication verified. Active subscription (if any):"
jq -r '"- " + (.name // "No subscription") + " (" + (.id // "n/a") + ")"' /tmp/az-account.json || cat /tmp/az-account.json
else
echo "Unable to verify Azure CLI login status:" >&2
cat /tmp/az-account.err >&2 || true
exit 1
fi

- name: Install azsdk mcp server
shell: pwsh
run: |
./eng/common/mcp/azure-sdk-mcp.ps1 -InstallDirectory /tmp/bin

permissions:
contents: read
actions: read
issues: read
pull-requests: read
id-token: write
strict: false
imports:
- shared-github-aw-imports\global_networks_auth_import.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
AZSDK_CLI_PATH: /tmp/bin
AZURE_CLIENT_ID: c277c2aa-5326-4d16-90de-98feeca69cbc
AZURE_TENANT_ID: 72f988bf-86f1-41af-91ab-2d7cd011db47
AZURE_FEDERATED_TOKEN_FILE: /tmp/azure-oidc-token
strict: false
network:
allowed:
- defaults
- "login.microsoftonline.com"
- "dev.azure.com"
- "vssps.dev.azure.com"
GITHUB_TOKEN: ${{ secrets.GITHUB_PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
GITHUB_ACTIONS: "true"
tools:
github:
toolsets: [default, actions]
safe-outputs:
add-comment:
max: 20
max: 15
hide-older-comments: true
messages:
run-started: "[{workflow_name}]({run_url}) started. Debug link to this workflow run."
run-started: "[{workflow_name}]({run_url}) started."
noop:
---

Expand Down Expand Up @@ -140,37 +82,40 @@

3. **Manual dispatch**

- Ensure required inputs `work_item_id` and `release_plan_id` are provided via `github.event.inputs`.
- Parse optional inputs `languages` (comma-separated list, normalized) and `pr_number` (numeric).
- Parse `issue_url` from `github.event.inputs.issue_url`.
- Validate that `issue_url` points to an issue in this repository, extract the numeric issue ID, and hydrate issue context via the GitHub API.
- Treat the resolved issue exactly the same as if the workflow were triggered directly from that issue.

If the triggering event does not meet its corresponding requirements, immediately call `noop` with guidance (for example: missing label, missing `Regenerate SDK`, or missing workflow_dispatch inputs).

## Workflow Behavior

When validation succeeds, execute the following steps in order.

1. Add a debug comment on the target issue with the workflow run link:
1. Azure CLI Login using az login:

- Run `mkdir -p /tmp/gh-aw/agent/.azure`.
- Set env variable AZURE_CONFIG_DIR=/tmp/gh-aw/agent/.azure
- Run `az login --service-principal --username $AZURE_CLIENT_ID --tenant $AZURE_TENANT_ID --federated-token $(cat /tmp/azure-oidc-token) --allow-no-subscriptions 2>&1`
- If authentication fails, call the `noop` safe output with the captured response (labelled `authentication_failed`) and stop further processing.

- `https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}`
2. Announce workflow start by commenting on the resolved issue with `https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}`. If the issue cannot be determined for any reason, fall back to the `messages.run-started` safe output.

3. Identify the target issue number and collect issue context (for manual dispatch, use the supplied or default `issue_url`).

2. Set following env variables(if not present):
AZURE_CLIENT_ID: c277c2aa-5326-4d16-90de-98feeca69cbc
AZURE_TENANT_ID: 72f988bf-86f1-41af-91ab-2d7cd011db47
AZURE_FEDERATED_TOKEN_FILE: /tmp/azure-oidc-token
3. Identify the target issue number and collect issue context.
4. Find whether there is an open TypeSpec API spec pull request associated with this request.
- Identify TypeSpec API spec PR from issue context.
- Check if API spec PR is in open status or merged status.

- If such a PR is found and if it's open, set source branch to exactly `refs/pull/<PR number>`.
- Identify TypeSpec API spec PR from issue context.
- Check if API spec PR is in open status or merged status.
- If such a PR is found and if it's open, set source branch for SDK generation to exactly `refs/pull/<PR number>`.
- If no such PR is found, use default branch context.

5. Use the azsdk CLI at `/tmp/bin/azsdk` (installed earlier) to gather release plan metadata and required arguments:
5. Use the azsdk CLI at `$AZSDK_CLI_PATH/azsdk` (installed earlier) to gather release plan metadata and required arguments:

- Execute `/tmp/bin/azsdk release-plan get --work-item-id <WORK_ITEM_ID> --release-plan-id <RELEASE_PLAN_ID>`
- Capture the TypeSpec project path, API version, release type, and target languages from the issue context.
- Execute `$AZSDK_CLI_PATH/azsdk release-plan get --work-item-id <WORK_ITEM_ID> --release-plan-id <RELEASE_PLAN_ID>`. Release plan and work item ID are numeric values.
- Capture the TypeSpec project path, API version, release type, and target languages from the issue context (dispatch runs rely on the issue referenced by `issue_url`).

6. Trigger SDK generation by calling `/tmp/bin/azsdk spec-workflow generate-sdk` with the following options:
6. Trigger SDK generation by calling `$AZSDK_CLI_PATH/azsdk spec-workflow generate-sdk` with the following options:

- `--typespec-project <PATH>` (required)
- `--api-version <VERSION>` (required)
Expand All @@ -179,22 +124,15 @@
- `--workitem-id <WORK_ITEM_ID>` to tie the generation back to the release plan work item
- Capture the pipeline/run URL emitted by the CLI for status tracking.

7. Immediately add a comment with:
- Pipeline run link/status URL, or
- Failure details if triggering the pipeline failed.
7. Immediately add a comment with the pipeline run link/status URL or failure details (use `noop` only if no issue comment can be posted).

## Monitoring and Status Updates

1. After successful trigger, monitor the pipeline run referenced in the CLI output.
2. Poll status every 5 minutes by querying the pipeline's status endpoint or, when available, `azsdk` status commands using the recorded run identifier.
3. On each poll, determine whether pipeline is still running, failed, or completed.
4. If still running, update status via comment (keep concise).
5. If failed, add a comment indicating failure and include pipeline link and failure summary.
6. If completed:

- Refresh release plan data via `/tmp/bin/azsdk release-plan get --work-item-id <WORK_ITEM_ID> --release-plan-id <RELEASE_PLAN_ID>` and inspect the SDK pull request references per language.
- Add a comment that includes one line per language using this exact format:
- `sdk pr for <language>`: `<Link to sdk pull request>`
1. After successful trigger, monitor the release plan and check SDK generation status, SDK pull request status and SDK pull request link.
- Refresh release plan data every 5 minutes via `$AZSDK_CLI_PATH/azsdk release-plan get --work-item-id <WORK_ITEM_ID> --release-plan-id <RELEASE_PLAN_ID>` and inspect the SDK pull request references per language.
2. On each poll, determine whether SDK pull request link is available for each language.
3. If failed, add a comment indicating failure and include pipeline link and failure summary (fallback to `noop` only when comments are unavailable).
4. Add a final status update by commenting one line per language using the exact format `sdk pr for <language>: <Link to sdk pull request>` (fallback to `noop` only if commenting fails).

## Output Requirements

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
# No `on:` here — this is a shared component meant to be imported.
description: Steps to generate OIDC token and authenticate GitHub agent workflow
network:
allowed:
- defaults
- "login.microsoftonline.com"
- "dev.azure.com"
- "*.dev.azure.com"
- "*.applicationinsights.azure.com"
- "*.visualstudio.com"
- "management.azure.com"
steps:
- name: Acquire OIDC token for Azure
id: oidc
uses: actions/github-script@v7
with:
script: |
const token = await core.getIDToken('api://AzureADTokenExchange');
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.

I understand why you did this, but I don't like us putting this into a file but for now until we have a better option we can use this for testing.

const fs = require('fs');
fs.writeFileSync('/tmp/azure-oidc-token', token);

- name: Verify Azure CLI authentication
shell: bash
run: |
set -euo pipefail
if ! command -v az >/dev/null 2>&1; then
echo "Azure CLI (az) is not installed on this runner." >&2
exit 1
fi

if [[ -z "${AZURE_CLIENT_ID:-}" || -z "${AZURE_TENANT_ID:-}" || -z "${AZURE_FEDERATED_TOKEN_FILE:-}" ]]; then
echo "Azure federated authentication variables are missing." >&2
exit 1
fi

FED_TOKEN=$(cat "$AZURE_FEDERATED_TOKEN_FILE")
if [[ -z "$FED_TOKEN" ]]; then
echo "Federated token file $AZURE_FEDERATED_TOKEN_FILE is empty." >&2
exit 1
fi

echo "Ensuring Azure CLI session is authenticated using workload identity..."
az login --service-principal \
--username "$AZURE_CLIENT_ID" \
--tenant "$AZURE_TENANT_ID" \
--federated-token "$FED_TOKEN" \
--allow-no-subscriptions >/tmp/az-login.json

if az account show --output json > /tmp/az-account.json 2>/tmp/az-account.err; then
echo "Azure CLI authentication verified. Active subscription (if any):"
jq -r '"- " + (.name // "No subscription") + " (" + (.id // "n/a") + ")"' /tmp/az-account.json || cat /tmp/az-account.json
else
echo "Unable to verify Azure CLI login status:" >&2
cat /tmp/az-account.err >&2 || true
exit 1
fi
---

## Workflow Behavior

Login using Azure CLI Login

- Run `mkdir -p /tmp/gh-aw/agent/.azure`.
- Set env variable AZURE_CONFIG_DIR=/tmp/gh-aw/agent/.azure
- Run `az login --service-principal --username $AZURE_CLIENT_ID --tenant $AZURE_TENANT_ID --federated-token $(cat /tmp/azure-oidc-token) --allow-no-subscriptions 2>&1`
- If authentication fails, call the `noop` safe output with the captured response (labelled `authentication_failed`) and stop further processing.
2 changes: 1 addition & 1 deletion .github/workflows/test/workflows.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { readdir } from "fs/promises";
import { dirname, extname, resolve } from "path";
import { fileURLToPath } from "url";
Expand All @@ -15,7 +15,7 @@
.map((e) => e.name)
.filter((f) => {
const extension = extname(f);
return extension !== ".yaml" && extension !== ".md";
return extension !== ".yaml" && extension !== ".yml" && extension !== ".md";
});

expect(disallowedFiles, "workflow files must use extension '.yaml' or '.md'").toEqual([]);
Expand Down
2 changes: 1 addition & 1 deletion cspell.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
version: '0.2'
language: en
flagWords:
Expand All @@ -13,7 +13,7 @@
- eng/**
- node_modules/**
- specification/suppressions.yaml
- .github/workflows/*.lock.yaml
- .github/workflows/*.lock.yml
- .github/workflows/sdk-generation-agent.md
ignoreRegExpList:
- Base64
Expand Down
Loading