Skip to content

TypeSpec Python Regenerate Tests #10

TypeSpec Python Regenerate Tests

TypeSpec Python Regenerate Tests #10

name: TypeSpec Python Regenerate Tests
on:
# Trigger when eng/emitter-package.json is updated on main (branded emitter version bump)
push:
branches: [main]
paths:
- "eng/emitter-package.json"
# Allow manual triggering with emitter choice
workflow_dispatch:
inputs:
emitter:
description: "Which emitter to regenerate with"
required: true
type: choice
options:
- "branded (@azure-tools/typespec-python)"
- "unbranded (@typespec/http-client-python)"
default: "branded (@azure-tools/typespec-python)"
version:
description: "Emitter version (leave empty to use version from emitter-package.json for branded, or latest for unbranded)"
required: false
typespec_ref:
description: "Git ref of microsoft/typespec to build regeneration infrastructure from"
required: false
default: "main"
permissions:
contents: write
pull-requests: write
issues: write
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
jobs:
regenerate:
name: "Regenerate TypeSpec Python tests"
runs-on: ubuntu-latest
steps:
- name: Checkout azure-sdk-for-python
# SHA corresponds to actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Determine emitter to use
id: emitter-info
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "push" ]; then
# Push trigger: always use branded emitter at version from emitter-package.json
EMITTER_NAME="@azure-tools/typespec-python"
VERSION=$(jq -r '.dependencies["@azure-tools/typespec-python"]' eng/emitter-package.json)
echo "Push trigger: using branded emitter @ $VERSION"
elif [[ "${{ github.event.inputs.emitter }}" == branded* ]]; then
EMITTER_NAME="@azure-tools/typespec-python"
VERSION="${{ github.event.inputs.version }}"
if [ -z "$VERSION" ]; then
VERSION=$(jq -r '.dependencies["@azure-tools/typespec-python"]' eng/emitter-package.json)
echo "No version specified, using emitter-package.json version: $VERSION"
fi
else
EMITTER_NAME="@typespec/http-client-python"
VERSION="${{ github.event.inputs.version }}"
if [ -z "$VERSION" ]; then
VERSION=$(npm view @typespec/http-client-python version 2>/dev/null)
echo "No version specified, using latest npm version: $VERSION"
fi
fi
echo "emitter_name=$EMITTER_NAME" >> $GITHUB_OUTPUT
echo "emitter_version=$VERSION" >> $GITHUB_OUTPUT
echo "::notice::Regenerating with $EMITTER_NAME@$VERSION"
- name: Checkout microsoft/typespec
# SHA corresponds to actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
repository: microsoft/typespec
ref: ${{ github.event.inputs.typespec_ref || 'main' }}
path: typespec
fetch-depth: 0
- name: Setup Node.js
# SHA corresponds to actions/setup-node@v6
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: lts/*
- name: Setup Python
# SHA corresponds to actions/setup-python@v5
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: "3.12"
- name: Build http-client-python
working-directory: typespec/packages/http-client-python
run: |
npm install --ignore-scripts
npm run build
- name: Install target emitter
working-directory: typespec/packages/http-client-python
run: |
EMITTER="${{ steps.emitter-info.outputs.emitter_name }}"
VERSION="${{ steps.emitter-info.outputs.emitter_version }}"
echo "Installing $EMITTER@$VERSION"
npm install "${EMITTER}@${VERSION}"
- name: Prepare Python environment
working-directory: typespec/packages/http-client-python
run: |
npm run install
npm run prepare
- name: Regenerate tests
working-directory: typespec/packages/http-client-python
run: |
EMITTER="${{ steps.emitter-info.outputs.emitter_name }}"
npm run regenerate -- --emitterName "$EMITTER"
- name: Copy regenerated tests
run: |
set -euo pipefail
TARGET="eng/tools/emitter/gen"
rm -rf "$TARGET/azure" "$TARGET/unbranded"
mkdir -p "$TARGET"
cp -r typespec/packages/http-client-python/tests/generated/azure "$TARGET/azure"
cp -r typespec/packages/http-client-python/tests/generated/unbranded "$TARGET/unbranded"
- name: Clean up typespec checkout
run: rm -rf typespec
- name: Commit and push changes
id: push-changes
run: |
set -euo pipefail
EMITTER="${{ steps.emitter-info.outputs.emitter_name }}"
VERSION="${{ steps.emitter-info.outputs.emitter_version }}"
BRANCH="auto/typespec-python-regenerate"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add eng/tools/emitter/gen/
if git diff --cached --quiet; then
echo "No changes to commit"
echo "has_changes=false" >> $GITHUB_OUTPUT
exit 0
fi
git checkout -B "$BRANCH"
git commit -m "[typespec-python] Regenerate tests with ${EMITTER}@${VERSION}"
git push origin "$BRANCH" --force
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "branch=$BRANCH" >> $GITHUB_OUTPUT
- name: Create or update Pull Request
id: create-pr
if: steps.push-changes.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
EMITTER="${{ steps.emitter-info.outputs.emitter_name }}"
VERSION="${{ steps.emitter-info.outputs.emitter_version }}"
BRANCH="${{ steps.push-changes.outputs.branch }}"
TITLE="[typespec-python] Regenerate tests with ${EMITTER}@${VERSION}"
BODY="Automated regeneration of TypeSpec Python generated tests.
- Emitter: \`${EMITTER}@${VERSION}\`
- Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
This PR was auto-generated."
# Check if a PR already exists for this branch
EXISTING_PR=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number' || echo "")
if [ -n "$EXISTING_PR" ]; then
echo "Updating existing PR #$EXISTING_PR"
gh pr edit "$EXISTING_PR" --title "$TITLE" --body "$BODY" --add-reviewer iscai-msft,msyyc
PR_NUMBER="$EXISTING_PR"
else
echo "Creating new PR"
PR_NUMBER=$(gh pr create --head "$BRANCH" --base main \
--title "$TITLE" --body "$BODY" \
--reviewer iscai-msft,msyyc | grep -oP '\d+$')
echo "Created PR #$PR_NUMBER"
fi
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
- name: Enable auto-merge
if: steps.push-changes.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
gh pr merge "${{ steps.create-pr.outputs.pr_number }}" --auto --squash || \
echo "::warning::Auto-merge could not be enabled (may require branch protection rules)"
notify-on-failure:
name: "Notify on failure"
needs: regenerate
if: failure()
runs-on: ubuntu-latest
steps:
- name: Send failure notification
# SHA corresponds to actions/github-script@v7
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b
with:
script: |
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: '[typespec-python] Regeneration workflow failed',
body: `The TypeSpec Python test regeneration workflow failed.\n\n` +
`- **Run:** ${runUrl}\n` +
`- **Trigger:** ${context.eventName}\n\n` +
`cc @iscai-msft @msyyc`,
labels: ['typespec-python'],
assignees: ['iscai-msft', 'msyyc']
});