From e1b262eac51545d72028f678d7c60198a6a0ace5 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Mon, 3 Aug 2026 16:45:28 +0800 Subject: [PATCH 01/16] ci: migrate Python checks to CI Gate Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci.yml | 21 +++- .github/workflows/python-integration.yml | 120 +++++++++++++++++------ eng/common/pipelines/ci.yml | 6 -- 3 files changed, 107 insertions(+), 40 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f6c252662fd..63a16c52a3d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,7 @@ on: permissions: contents: read + pull-requests: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -23,13 +24,14 @@ jobs: runs-on: ubuntu-slim outputs: core: ${{ steps.filter.outputs.core }} + python: ${{ steps.filter.outputs.python }} steps: - uses: actions/checkout@v7 # cspell:ignore dorny - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4 id: filter with: - predicate-quantifier: "every" + predicate-quantifier: "some-with-excludes" filters: | core: - '**' @@ -42,17 +44,26 @@ jobs: - '!packages/http-client-csharp/**' - '!packages/http-client-java/**' - '!packages/http-client-python/**' + python: + - 'packages/http-client-python/**' + - '.github/workflows/ci.yml' + - '.github/workflows/python-integration.yml' core: needs: changes if: needs.changes.outputs.core == 'true' uses: ./.github/workflows/core-ci.yml + python: + needs: changes + if: needs.changes.outputs.python == 'true' + uses: ./.github/workflows/python-integration.yml + ci-gate: name: CI Gate runs-on: ubuntu-slim - if: "!cancelled() || needs.core.result == 'cancelled'" - needs: [core] + if: "!cancelled() || contains(needs.*.result, 'cancelled')" + needs: [core, python] steps: - name: Validate CI results run: | @@ -60,4 +71,8 @@ jobs: echo "Core CI failed or was cancelled" exit 1 fi + if [[ "${{ needs.python.result }}" == "failure" || "${{ needs.python.result }}" == "cancelled" ]]; then + echo "Python CI failed or was cancelled" + exit 1 + fi echo "All CI checks passed or were appropriately skipped" diff --git a/.github/workflows/python-integration.yml b/.github/workflows/python-integration.yml index a5b548fc142..83a35e0bf0f 100644 --- a/.github/workflows/python-integration.yml +++ b/.github/workflows/python-integration.yml @@ -1,11 +1,7 @@ name: Python Integration on: - pull_request: - branches: ["main"] - paths: - - "packages/http-client-python/**" - - ".github/workflows/python-integration.yml" + workflow_call: # Allow manual triggering workflow_dispatch: @@ -13,7 +9,7 @@ permissions: contents: read concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-python-integration-${{ github.ref }} cancel-in-progress: true jobs: @@ -32,13 +28,15 @@ jobs: repository: Azure/typespec-azure submodules: recursive - - name: Update core submodule to PR commit - if: github.event_name == 'pull_request' + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} run: | cd core - git remote add pr https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git - git fetch pr ${{ github.event.pull_request.head.sha }} - git checkout ${{ github.event.pull_request.head.sha }} + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF - uses: ./.github/actions/setup @@ -116,13 +114,15 @@ jobs: repository: Azure/typespec-azure submodules: recursive - - name: Update core submodule to PR commit - if: github.event_name == 'pull_request' + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} run: | cd core - git remote add pr https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git - git fetch pr ${{ github.event.pull_request.head.sha }} - git checkout ${{ github.event.pull_request.head.sha }} + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF - uses: ./.github/actions/setup @@ -158,13 +158,15 @@ jobs: repository: Azure/typespec-azure submodules: recursive - - name: Update core submodule to PR commit - if: github.event_name == 'pull_request' + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} run: | cd core - git remote add pr https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git - git fetch pr ${{ github.event.pull_request.head.sha }} - git checkout ${{ github.event.pull_request.head.sha }} + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF - uses: ./.github/actions/setup @@ -197,13 +199,15 @@ jobs: repository: Azure/typespec-azure submodules: recursive - - name: Update core submodule to PR commit - if: github.event_name == 'pull_request' + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} run: | cd core - git remote add pr https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git - git fetch pr ${{ github.event.pull_request.head.sha }} - git checkout ${{ github.event.pull_request.head.sha }} + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF - uses: ./.github/actions/setup @@ -244,13 +248,15 @@ jobs: repository: Azure/typespec-azure submodules: recursive - - name: Update core submodule to PR commit - if: github.event_name == 'pull_request' + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} run: | cd core - git remote add pr https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git - git fetch pr ${{ github.event.pull_request.head.sha }} - git checkout ${{ github.event.pull_request.head.sha }} + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF - uses: ./.github/actions/setup @@ -272,3 +278,55 @@ jobs: - name: API View & Sphinx run: pnpm run test:python:e2e --env apiview,sphinx working-directory: packages/typespec-python + + windows-test: + name: "Build & Test (Windows)" + needs: build + runs-on: windows-latest + steps: + - name: Checkout Azure/typespec-azure repo + uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + shell: bash + run: | + cd core + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile + + - name: Build http-client-python from PR + run: | + npm install --ignore-scripts + npm run build + working-directory: core/packages/http-client-python + + - name: Build + run: pnpm turbo run --filter "@azure-tools/typespec-python..." build + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: Test + run: pnpm run test:python:e2e + working-directory: packages/typespec-python diff --git a/eng/common/pipelines/ci.yml b/eng/common/pipelines/ci.yml index 64f7ea29b64..5723a1e8bd4 100644 --- a/eng/common/pipelines/ci.yml +++ b/eng/common/pipelines/ci.yml @@ -55,9 +55,3 @@ extends: parameters: DependsOn: InitStage Condition: eq('true', stageDependencies.InitStage.outputs['InitJob.InitStep.RunJava']) - - # Run python stages if RunPython == true - - template: /packages/http-client-python/eng/pipeline/templates/ci-stages.yml - parameters: - DependsOn: InitStage - Condition: eq('true', stageDependencies.InitStage.outputs['InitJob.InitStep.RunPython']) From 6cdf761288fcfc98047798df666ecff9c517b5a4 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Mon, 3 Aug 2026 16:58:59 +0800 Subject: [PATCH 02/16] ci: share Python workflow template Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python-template.yml | 330 +++++++++++++++++++++++ .github/workflows/ci-python.yml | 12 + .github/workflows/ci.yml | 4 +- .github/workflows/python-integration.yml | 324 +--------------------- 4 files changed, 348 insertions(+), 322 deletions(-) create mode 100644 .github/workflows/ci-python-template.yml create mode 100644 .github/workflows/ci-python.yml diff --git a/.github/workflows/ci-python-template.yml b/.github/workflows/ci-python-template.yml new file mode 100644 index 00000000000..87b8127838d --- /dev/null +++ b/.github/workflows/ci-python-template.yml @@ -0,0 +1,330 @@ +name: Python CI Template + +on: + workflow_call: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-python-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: "Build & Regenerate" + runs-on: ubuntu-latest + if: | + !startsWith(github.head_ref, 'dependabot/') && + !startsWith(github.head_ref, 'publish/') && + !startsWith(github.head_ref, 'backmerge/') && + !startsWith(github.head_ref, 'revert-') + steps: + - name: Checkout Azure/typespec-azure repo + uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + run: | + cd core + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Build and pack http-client-python from PR + run: | + cd core/packages/http-client-python + npm install --ignore-scripts + npm run build + npm pack + + - name: Override http-client-python with PR version + run: | + HCP_TGZ=$(ls core/packages/http-client-python/typespec-http-client-python-*.tgz) + node -e ' + const pkg = require("./packages/typespec-python/package.json"); + const fs = require("fs"); + pkg.dependencies["@typespec/http-client-python"] = "file:../../" + process.argv[1]; + fs.writeFileSync("./packages/typespec-python/package.json", JSON.stringify(pkg, null, 2) + "\n"); + ' "$HCP_TGZ" + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile + + - name: Build + run: pnpm turbo run --filter "@azure-tools/typespec-python..." build + + - name: Build http-specs and azure-http-specs from source + # Build the mock servers from the checked-out typespec-azure (+ PR core) + # source, so the mock stays in lockstep with the client that is + # regenerated from the same source below. Previously these build outputs + # were overwritten with the versions resolved via http-client-python's + # package.json pin, which caused client/mock spec skew whenever + # typespec-azure main advanced a spec beyond the pinned bundle and failed + # otherwise-green PRs. See microsoft/typespec#11348. + run: pnpm turbo run build --filter "@typespec/http-specs..." --filter "@azure-tools/azure-http-specs..." + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: Regenerate + run: pnpm run regenerate + working-directory: packages/typespec-python + + - name: Pre-build wheels + working-directory: packages/typespec-python + run: | + venv/bin/python tests/install_packages.py build azure tests + venv/bin/python tests/install_packages.py build unbranded tests + + - name: Upload generated artifacts + uses: actions/upload-artifact@v7 + with: + name: python-generated + path: | + packages/typespec-python/tests/generated + packages/typespec-python/tests/.wheels + packages/typespec-python/dist + packages/typespec-python/package.json + core/packages/http-client-python/typespec-http-client-python-*.tgz + core/packages/spector/dist + core/packages/http-specs/dist + packages/azure-http-specs/dist + retention-days: 1 + + test: + name: "Mock API Tests" + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + run: | + cd core + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile + + - name: Build spector + run: pnpm turbo run --filter "@typespec/spector..." build + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: Test + run: pnpm run test:python:e2e + working-directory: packages/typespec-python + + typecheck: + name: "Type Checking" + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + run: | + cd core + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: Mypy & Pyright + run: pnpm run test:python:e2e --env mypy,pyright + working-directory: packages/typespec-python + + lint: + name: "Lint & Format" + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + run: | + cd core + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: Pylint + run: pnpm run test:python:e2e --env lint + working-directory: packages/typespec-python + + - name: Lint (extra) + run: pnpm run lint:extra + working-directory: packages/typespec-python + + - name: Format check (extra) + run: pnpm run format:extra:check + working-directory: packages/typespec-python + + docs: + name: "Docs Validation" + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + run: | + cd core + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: API View & Sphinx + run: pnpm run test:python:e2e --env apiview,sphinx + working-directory: packages/typespec-python + + windows-test: + name: "Build & Test (Windows)" + needs: build + runs-on: windows-latest + steps: + - name: Checkout Azure/typespec-azure repo + uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to TypeSpec commit + env: + TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} + TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + shell: bash + run: | + cd core + git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git + git fetch typespec $TYPESPEC_REF + git checkout $TYPESPEC_REF + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile + + - name: Build http-client-python from PR + run: | + npm install --ignore-scripts + npm run build + working-directory: core/packages/http-client-python + + - name: Build + run: pnpm turbo run --filter "@azure-tools/typespec-python..." build + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: Test + run: pnpm run test:python:e2e + working-directory: packages/typespec-python diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml new file mode 100644 index 00000000000..82fb543be10 --- /dev/null +++ b/.github/workflows/ci-python.yml @@ -0,0 +1,12 @@ +name: Python CI + +on: + workflow_call: + +permissions: + contents: read + +jobs: + python: + name: Python CI + uses: ./.github/workflows/ci-python-template.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 63a16c52a3d..18af6c1029e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,8 @@ jobs: python: - 'packages/http-client-python/**' - '.github/workflows/ci.yml' + - '.github/workflows/ci-python.yml' + - '.github/workflows/ci-python-template.yml' - '.github/workflows/python-integration.yml' core: @@ -57,7 +59,7 @@ jobs: python: needs: changes if: needs.changes.outputs.python == 'true' - uses: ./.github/workflows/python-integration.yml + uses: ./.github/workflows/ci-python.yml ci-gate: name: CI Gate diff --git a/.github/workflows/python-integration.yml b/.github/workflows/python-integration.yml index 83a35e0bf0f..5d6841a47bc 100644 --- a/.github/workflows/python-integration.yml +++ b/.github/workflows/python-integration.yml @@ -8,325 +8,7 @@ on: permissions: contents: read -concurrency: - group: ${{ github.workflow }}-python-integration-${{ github.ref }} - cancel-in-progress: true - jobs: - build: - name: "Build & Regenerate" - runs-on: ubuntu-latest - if: | - !startsWith(github.head_ref, 'dependabot/') && - !startsWith(github.head_ref, 'publish/') && - !startsWith(github.head_ref, 'backmerge/') && - !startsWith(github.head_ref, 'revert-') - steps: - - name: Checkout Azure/typespec-azure repo - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Build and pack http-client-python from PR - run: | - cd core/packages/http-client-python - npm install --ignore-scripts - npm run build - npm pack - - - name: Override http-client-python with PR version - run: | - HCP_TGZ=$(ls core/packages/http-client-python/typespec-http-client-python-*.tgz) - node -e ' - const pkg = require("./packages/typespec-python/package.json"); - const fs = require("fs"); - pkg.dependencies["@typespec/http-client-python"] = "file:../../" + process.argv[1]; - fs.writeFileSync("./packages/typespec-python/package.json", JSON.stringify(pkg, null, 2) + "\n"); - ' "$HCP_TGZ" - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile - - - name: Build - run: pnpm turbo run --filter "@azure-tools/typespec-python..." build - - - name: Build http-specs and azure-http-specs from source - # Build the mock servers from the checked-out typespec-azure (+ PR core) - # source, so the mock stays in lockstep with the client that is - # regenerated from the same source below. Previously these build outputs - # were overwritten with the versions resolved via http-client-python's - # package.json pin, which caused client/mock spec skew whenever - # typespec-azure main advanced a spec beyond the pinned bundle and failed - # otherwise-green PRs. See microsoft/typespec#11348. - run: pnpm turbo run build --filter "@typespec/http-specs..." --filter "@azure-tools/azure-http-specs..." - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - - name: Regenerate - run: pnpm run regenerate - working-directory: packages/typespec-python - - - name: Pre-build wheels - working-directory: packages/typespec-python - run: | - venv/bin/python tests/install_packages.py build azure tests - venv/bin/python tests/install_packages.py build unbranded tests - - - name: Upload generated artifacts - uses: actions/upload-artifact@v7 - with: - name: python-generated - path: | - packages/typespec-python/tests/generated - packages/typespec-python/tests/.wheels - packages/typespec-python/dist - packages/typespec-python/package.json - core/packages/http-client-python/typespec-http-client-python-*.tgz - core/packages/spector/dist - core/packages/http-specs/dist - packages/azure-http-specs/dist - retention-days: 1 - - test: - name: "Mock API Tests" - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile - - - name: Build spector - run: pnpm turbo run --filter "@typespec/spector..." build - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - - name: Test - run: pnpm run test:python:e2e - working-directory: packages/typespec-python - - typecheck: - name: "Type Checking" - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - - name: Mypy & Pyright - run: pnpm run test:python:e2e --env mypy,pyright - working-directory: packages/typespec-python - - lint: - name: "Lint & Format" - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - - name: Pylint - run: pnpm run test:python:e2e --env lint - working-directory: packages/typespec-python - - - name: Lint (extra) - run: pnpm run lint:extra - working-directory: packages/typespec-python - - - name: Format check (extra) - run: pnpm run format:extra:check - working-directory: packages/typespec-python - - docs: - name: "Docs Validation" - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - - name: API View & Sphinx - run: pnpm run test:python:e2e --env apiview,sphinx - working-directory: packages/typespec-python - - windows-test: - name: "Build & Test (Windows)" - needs: build - runs-on: windows-latest - steps: - - name: Checkout Azure/typespec-azure repo - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - shell: bash - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile - - - name: Build http-client-python from PR - run: | - npm install --ignore-scripts - npm run build - working-directory: core/packages/http-client-python - - - name: Build - run: pnpm turbo run --filter "@azure-tools/typespec-python..." build - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - - name: Test - run: pnpm run test:python:e2e - working-directory: packages/typespec-python + python: + name: Python Integration + uses: ./.github/workflows/ci-python-template.yml From c1267685f1701af014105478650fc3b99f3618e6 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Mon, 3 Aug 2026 17:12:56 +0800 Subject: [PATCH 03/16] ci: keep Python CI wrappers distinct Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python-template.yml | 265 +++++------------------ .github/workflows/ci-python.yml | 47 +++- .github/workflows/python-integration.yml | 49 ++++- 3 files changed, 142 insertions(+), 219 deletions(-) diff --git a/.github/workflows/ci-python-template.yml b/.github/workflows/ci-python-template.yml index 87b8127838d..d285d784ac8 100644 --- a/.github/workflows/ci-python-template.yml +++ b/.github/workflows/ci-python-template.yml @@ -2,23 +2,24 @@ name: Python CI Template on: workflow_call: + inputs: + check: + description: Python check to run. + required: true + type: string + runner: + description: GitHub runner image. + required: false + type: string + default: ubuntu-latest permissions: contents: read -concurrency: - group: ${{ github.workflow }}-python-${{ github.ref }} - cancel-in-progress: true - jobs: - build: - name: "Build & Regenerate" - runs-on: ubuntu-latest - if: | - !startsWith(github.head_ref, 'dependabot/') && - !startsWith(github.head_ref, 'publish/') && - !startsWith(github.head_ref, 'backmerge/') && - !startsWith(github.head_ref, 'revert-') + check: + name: ${{ inputs.check }} + runs-on: ${{ inputs.runner }} steps: - name: Checkout Azure/typespec-azure repo uses: actions/checkout@v7 @@ -30,6 +31,7 @@ jobs: env: TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + shell: bash run: | cd core git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git @@ -40,7 +42,15 @@ jobs: - uses: ./.github/actions/setup-python + - name: Download generated artifacts + if: inputs.check != 'build' + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + - name: Build and pack http-client-python from PR + if: inputs.check == 'build' run: | cd core/packages/http-client-python npm install --ignore-scripts @@ -48,6 +58,7 @@ jobs: npm pack - name: Override http-client-python with PR version + if: inputs.check == 'build' run: | HCP_TGZ=$(ls core/packages/http-client-python/typespec-http-client-python-*.tgz) node -e ' @@ -58,12 +69,26 @@ jobs: ' "$HCP_TGZ" - name: Install dependencies + if: inputs.check == 'build' || inputs.check == 'test' || inputs.check == 'windows-test' run: pnpm install --no-frozen-lockfile + - name: Install Python package dependencies + if: inputs.check == 'typecheck' || inputs.check == 'lint' || inputs.check == 'docs' + run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." + + - name: Build http-client-python from PR + if: inputs.check == 'windows-test' + run: | + npm install --ignore-scripts + npm run build + working-directory: core/packages/http-client-python + - name: Build + if: inputs.check == 'build' || inputs.check == 'windows-test' run: pnpm turbo run --filter "@azure-tools/typespec-python..." build - name: Build http-specs and azure-http-specs from source + if: inputs.check == 'build' # Build the mock servers from the checked-out typespec-azure (+ PR core) # source, so the mock stays in lockstep with the client that is # regenerated from the same source below. Previously these build outputs @@ -73,21 +98,28 @@ jobs: # otherwise-green PRs. See microsoft/typespec#11348. run: pnpm turbo run build --filter "@typespec/http-specs..." --filter "@azure-tools/azure-http-specs..." + - name: Build spector + if: inputs.check == 'test' + run: pnpm turbo run --filter "@typespec/spector..." build + - name: Prepare Python environment run: pnpm run prepare working-directory: packages/typespec-python - name: Regenerate + if: inputs.check == 'build' run: pnpm run regenerate working-directory: packages/typespec-python - name: Pre-build wheels + if: inputs.check == 'build' working-directory: packages/typespec-python run: | venv/bin/python tests/install_packages.py build azure tests venv/bin/python tests/install_packages.py build unbranded tests - name: Upload generated artifacts + if: inputs.check == 'build' uses: actions/upload-artifact@v7 with: name: python-generated @@ -102,229 +134,32 @@ jobs: packages/azure-http-specs/dist retention-days: 1 - test: - name: "Mock API Tests" - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile - - - name: Build spector - run: pnpm turbo run --filter "@typespec/spector..." build - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - name: Test + if: inputs.check == 'test' || inputs.check == 'windows-test' run: pnpm run test:python:e2e working-directory: packages/typespec-python - typecheck: - name: "Type Checking" - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - name: Mypy & Pyright + if: inputs.check == 'typecheck' run: pnpm run test:python:e2e --env mypy,pyright working-directory: packages/typespec-python - lint: - name: "Lint & Format" - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - name: Pylint + if: inputs.check == 'lint' run: pnpm run test:python:e2e --env lint working-directory: packages/typespec-python - name: Lint (extra) + if: inputs.check == 'lint' run: pnpm run lint:extra working-directory: packages/typespec-python - name: Format check (extra) + if: inputs.check == 'lint' run: pnpm run format:extra:check working-directory: packages/typespec-python - docs: - name: "Docs Validation" - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - name: API View & Sphinx + if: inputs.check == 'docs' run: pnpm run test:python:e2e --env apiview,sphinx working-directory: packages/typespec-python - - windows-test: - name: "Build & Test (Windows)" - needs: build - runs-on: windows-latest - steps: - - name: Checkout Azure/typespec-azure repo - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - shell: bash - run: | - cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF - - - uses: ./.github/actions/setup - - - uses: ./.github/actions/setup-python - - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile - - - name: Build http-client-python from PR - run: | - npm install --ignore-scripts - npm run build - working-directory: core/packages/http-client-python - - - name: Build - run: pnpm turbo run --filter "@azure-tools/typespec-python..." build - - - name: Prepare Python environment - run: pnpm run prepare - working-directory: packages/typespec-python - - - name: Test - run: pnpm run test:python:e2e - working-directory: packages/typespec-python diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 82fb543be10..3757282b170 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -7,6 +7,49 @@ permissions: contents: read jobs: - python: - name: Python CI + build: + name: "Build & Regenerate" + if: | + !startsWith(github.head_ref, 'dependabot/') && + !startsWith(github.head_ref, 'publish/') && + !startsWith(github.head_ref, 'backmerge/') && + !startsWith(github.head_ref, 'revert-') uses: ./.github/workflows/ci-python-template.yml + with: + check: build + + test: + name: "Mock API Tests" + needs: build + uses: ./.github/workflows/ci-python-template.yml + with: + check: test + + typecheck: + name: "Type Checking" + needs: build + uses: ./.github/workflows/ci-python-template.yml + with: + check: typecheck + + lint: + name: "Lint & Format" + needs: build + uses: ./.github/workflows/ci-python-template.yml + with: + check: lint + + docs: + name: "Docs Validation" + needs: build + uses: ./.github/workflows/ci-python-template.yml + with: + check: docs + + windows-test: + name: "Build & Test (Windows)" + needs: build + uses: ./.github/workflows/ci-python-template.yml + with: + check: windows-test + runner: windows-latest diff --git a/.github/workflows/python-integration.yml b/.github/workflows/python-integration.yml index 5d6841a47bc..b5af9a2ae70 100644 --- a/.github/workflows/python-integration.yml +++ b/.github/workflows/python-integration.yml @@ -2,13 +2,58 @@ name: Python Integration on: workflow_call: + pull_request: + branches: ["main"] + paths: + - "packages/http-client-python/**" + - ".github/workflows/ci-python-template.yml" + - ".github/workflows/python-integration.yml" # Allow manual triggering workflow_dispatch: permissions: contents: read +concurrency: + group: ${{ github.workflow }}-python-integration-${{ github.ref }} + cancel-in-progress: true + jobs: - python: - name: Python Integration + build: + name: "Build & Regenerate" + if: | + !startsWith(github.head_ref, 'dependabot/') && + !startsWith(github.head_ref, 'publish/') && + !startsWith(github.head_ref, 'backmerge/') && + !startsWith(github.head_ref, 'revert-') + uses: ./.github/workflows/ci-python-template.yml + with: + check: build + + test: + name: "Mock API Tests" + needs: build + uses: ./.github/workflows/ci-python-template.yml + with: + check: test + + typecheck: + name: "Type Checking" + needs: build + uses: ./.github/workflows/ci-python-template.yml + with: + check: typecheck + + lint: + name: "Lint & Format" + needs: build + uses: ./.github/workflows/ci-python-template.yml + with: + check: lint + + docs: + name: "Docs Validation" + needs: build uses: ./.github/workflows/ci-python-template.yml + with: + check: docs From b0d6b2f679b216f692c086d7087e52a20766d64f Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Mon, 3 Aug 2026 17:29:11 +0800 Subject: [PATCH 04/16] ci: fix Python workflow gating Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python-template.yml | 151 +++++++++++++++++------ .github/workflows/ci.yml | 12 +- .github/workflows/python-integration.yml | 5 + 3 files changed, 127 insertions(+), 41 deletions(-) diff --git a/.github/workflows/ci-python-template.yml b/.github/workflows/ci-python-template.yml index d285d784ac8..05943e813da 100644 --- a/.github/workflows/ci-python-template.yml +++ b/.github/workflows/ci-python-template.yml @@ -12,6 +12,11 @@ on: required: false type: string default: ubuntu-latest + use-typespec-azure: + description: Check out Azure/typespec-azure and point its core submodule at this TypeSpec commit. + required: false + type: boolean + default: false permissions: contents: read @@ -21,22 +26,28 @@ jobs: name: ${{ inputs.check }} runs-on: ${{ inputs.runner }} steps: + - name: Checkout TypeSpec repo + if: ${{ !inputs.use-typespec-azure }} + uses: actions/checkout@v7 + - name: Checkout Azure/typespec-azure repo + if: ${{ inputs.use-typespec-azure }} uses: actions/checkout@v7 with: repository: Azure/typespec-azure submodules: recursive - name: Update core submodule to TypeSpec commit + if: ${{ inputs.use-typespec-azure }} env: TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} shell: bash run: | cd core - git remote add typespec https://github.com/$TYPESPEC_REPOSITORY.git - git fetch typespec $TYPESPEC_REF - git checkout $TYPESPEC_REF + git remote add typespec "https://github.com/$TYPESPEC_REPOSITORY.git" + git fetch typespec "$TYPESPEC_REF" + git checkout "$TYPESPEC_REF" - uses: ./.github/actions/setup @@ -50,7 +61,7 @@ jobs: path: . - name: Build and pack http-client-python from PR - if: inputs.check == 'build' + if: inputs.use-typespec-azure && inputs.check == 'build' run: | cd core/packages/http-client-python npm install --ignore-scripts @@ -58,7 +69,7 @@ jobs: npm pack - name: Override http-client-python with PR version - if: inputs.check == 'build' + if: inputs.use-typespec-azure && inputs.check == 'build' run: | HCP_TGZ=$(ls core/packages/http-client-python/typespec-http-client-python-*.tgz) node -e ' @@ -68,27 +79,41 @@ jobs: fs.writeFileSync("./packages/typespec-python/package.json", JSON.stringify(pkg, null, 2) + "\n"); ' "$HCP_TGZ" - - name: Install dependencies - if: inputs.check == 'build' || inputs.check == 'test' || inputs.check == 'windows-test' + - name: Install integration dependencies + if: inputs.use-typespec-azure && (inputs.check == 'build' || inputs.check == 'test') run: pnpm install --no-frozen-lockfile - - name: Install Python package dependencies - if: inputs.check == 'typecheck' || inputs.check == 'lint' || inputs.check == 'docs' + - name: Install integration Python package dependencies + if: inputs.use-typespec-azure && (inputs.check == 'typecheck' || inputs.check == 'lint' || inputs.check == 'docs') run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." - - name: Build http-client-python from PR - if: inputs.check == 'windows-test' + - name: Install TypeSpec repo dependencies + if: ${{ !inputs.use-typespec-azure }} + run: pnpm install + + - name: Install local http-client-python dependencies + if: ${{ !inputs.use-typespec-azure }} + run: npm install --ignore-scripts + working-directory: packages/http-client-python + + - name: Setup local http-client-python + if: ${{ !inputs.use-typespec-azure }} + run: npm run setup + working-directory: packages/http-client-python + + - name: Build integration typespec-python + if: inputs.use-typespec-azure && (inputs.check == 'build' || inputs.check == 'windows-test') + run: pnpm turbo run --filter "@azure-tools/typespec-python..." build + + - name: Build integration http-client-python from PR + if: inputs.use-typespec-azure && inputs.check == 'windows-test' run: | npm install --ignore-scripts npm run build working-directory: core/packages/http-client-python - - name: Build - if: inputs.check == 'build' || inputs.check == 'windows-test' - run: pnpm turbo run --filter "@azure-tools/typespec-python..." build - - name: Build http-specs and azure-http-specs from source - if: inputs.check == 'build' + if: inputs.use-typespec-azure && inputs.check == 'build' # Build the mock servers from the checked-out typespec-azure (+ PR core) # source, so the mock stays in lockstep with the client that is # regenerated from the same source below. Previously these build outputs @@ -98,28 +123,39 @@ jobs: # otherwise-green PRs. See microsoft/typespec#11348. run: pnpm turbo run build --filter "@typespec/http-specs..." --filter "@azure-tools/azure-http-specs..." - - name: Build spector - if: inputs.check == 'test' + - name: Build integration spector + if: inputs.use-typespec-azure && inputs.check == 'test' run: pnpm turbo run --filter "@typespec/spector..." build - - name: Prepare Python environment + - name: Prepare integration Python environment + if: inputs.use-typespec-azure run: pnpm run prepare working-directory: packages/typespec-python - - name: Regenerate - if: inputs.check == 'build' + - name: Regenerate integration clients + if: inputs.use-typespec-azure && inputs.check == 'build' run: pnpm run regenerate working-directory: packages/typespec-python - - name: Pre-build wheels - if: inputs.check == 'build' + - name: Regenerate local test clients + if: ${{ !inputs.use-typespec-azure && inputs.check == 'build' }} + run: npm run regenerate + working-directory: packages/http-client-python + + - name: Check local generated output + if: ${{ !inputs.use-typespec-azure && inputs.check == 'build' }} + run: npm run check-unstaged + working-directory: packages/http-client-python + + - name: Pre-build integration wheels + if: inputs.use-typespec-azure && inputs.check == 'build' working-directory: packages/typespec-python run: | venv/bin/python tests/install_packages.py build azure tests venv/bin/python tests/install_packages.py build unbranded tests - - name: Upload generated artifacts - if: inputs.check == 'build' + - name: Upload integration generated artifacts + if: inputs.use-typespec-azure && inputs.check == 'build' uses: actions/upload-artifact@v7 with: name: python-generated @@ -134,32 +170,73 @@ jobs: packages/azure-http-specs/dist retention-days: 1 - - name: Test - if: inputs.check == 'test' || inputs.check == 'windows-test' + - name: Upload local generated artifacts + if: ${{ !inputs.use-typespec-azure && inputs.check == 'build' }} + uses: actions/upload-artifact@v7 + with: + name: python-generated + path: | + packages/http-client-python/tests/generated + packages/http-client-python/dist + packages/http-client-python/generator/dist + retention-days: 1 + + - name: Test integration clients + if: inputs.use-typespec-azure && inputs.check == 'test' run: pnpm run test:python:e2e working-directory: packages/typespec-python - - name: Mypy & Pyright - if: inputs.check == 'typecheck' + - name: Test local generated clients + if: ${{ !inputs.use-typespec-azure && (inputs.check == 'test' || inputs.check == 'windows-test') }} + run: npm run test:generator -- --env=test + working-directory: packages/http-client-python + + - name: Typecheck integration clients + if: inputs.use-typespec-azure && inputs.check == 'typecheck' run: pnpm run test:python:e2e --env mypy,pyright working-directory: packages/typespec-python - - name: Pylint - if: inputs.check == 'lint' + - name: Typecheck local generated clients + if: ${{ !inputs.use-typespec-azure && inputs.check == 'typecheck' }} + run: npm run test:generator -- --env=mypy,pyright + working-directory: packages/http-client-python + + - name: Lint integration clients + if: inputs.use-typespec-azure && inputs.check == 'lint' run: pnpm run test:python:e2e --env lint working-directory: packages/typespec-python - - name: Lint (extra) - if: inputs.check == 'lint' + - name: Lint integration source + if: inputs.use-typespec-azure && inputs.check == 'lint' run: pnpm run lint:extra working-directory: packages/typespec-python - - name: Format check (extra) - if: inputs.check == 'lint' + - name: Format check integration source + if: inputs.use-typespec-azure && inputs.check == 'lint' run: pnpm run format:extra:check working-directory: packages/typespec-python - - name: API View & Sphinx - if: inputs.check == 'docs' + - name: Lint local generated clients + if: ${{ !inputs.use-typespec-azure && inputs.check == 'lint' }} + run: npm run test:generator -- --env=lint + working-directory: packages/http-client-python + + - name: Lint local source + if: ${{ !inputs.use-typespec-azure && inputs.check == 'lint' }} + run: npm run lint + working-directory: packages/http-client-python + + - name: Format check local source + if: ${{ !inputs.use-typespec-azure && inputs.check == 'lint' }} + run: npm run format:check + working-directory: packages/http-client-python + + - name: Validate integration docs + if: inputs.use-typespec-azure && inputs.check == 'docs' run: pnpm run test:python:e2e --env apiview,sphinx working-directory: packages/typespec-python + + - name: Validate local docs + if: ${{ !inputs.use-typespec-azure && inputs.check == 'docs' }} + run: npm run test:generator -- --env=apiview,sphinx + working-directory: packages/http-client-python diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18af6c1029e..75f07aee819 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,15 +23,15 @@ jobs: name: Detect Changes runs-on: ubuntu-slim outputs: - core: ${{ steps.filter.outputs.core }} - python: ${{ steps.filter.outputs.python }} + core: ${{ steps.core-filter.outputs.core }} + python: ${{ steps.python-filter.outputs.python }} steps: - uses: actions/checkout@v7 # cspell:ignore dorny - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4 - id: filter + id: core-filter with: - predicate-quantifier: "some-with-excludes" + predicate-quantifier: "every" filters: | core: - '**' @@ -44,6 +44,10 @@ jobs: - '!packages/http-client-csharp/**' - '!packages/http-client-java/**' - '!packages/http-client-python/**' + - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4 + id: python-filter + with: + filters: | python: - 'packages/http-client-python/**' - '.github/workflows/ci.yml' diff --git a/.github/workflows/python-integration.yml b/.github/workflows/python-integration.yml index b5af9a2ae70..d6f37dba839 100644 --- a/.github/workflows/python-integration.yml +++ b/.github/workflows/python-integration.yml @@ -29,6 +29,7 @@ jobs: uses: ./.github/workflows/ci-python-template.yml with: check: build + use-typespec-azure: true test: name: "Mock API Tests" @@ -36,6 +37,7 @@ jobs: uses: ./.github/workflows/ci-python-template.yml with: check: test + use-typespec-azure: true typecheck: name: "Type Checking" @@ -43,6 +45,7 @@ jobs: uses: ./.github/workflows/ci-python-template.yml with: check: typecheck + use-typespec-azure: true lint: name: "Lint & Format" @@ -50,6 +53,7 @@ jobs: uses: ./.github/workflows/ci-python-template.yml with: check: lint + use-typespec-azure: true docs: name: "Docs Validation" @@ -57,3 +61,4 @@ jobs: uses: ./.github/workflows/ci-python-template.yml with: check: docs + use-typespec-azure: true From 62cde21285115d14d15ed838bbf70b763d7baabd Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Mon, 3 Aug 2026 17:33:02 +0800 Subject: [PATCH 05/16] ci: use local Python setup for Python CI Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python-template.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-python-template.yml b/.github/workflows/ci-python-template.yml index 05943e813da..5943663a6fc 100644 --- a/.github/workflows/ci-python-template.yml +++ b/.github/workflows/ci-python-template.yml @@ -51,7 +51,15 @@ jobs: - uses: ./.github/actions/setup - - uses: ./.github/actions/setup-python + - name: Set up integration Python + if: ${{ inputs.use-typespec-azure }} + uses: ./.github/actions/setup-python + + - name: Set up local Python + if: ${{ !inputs.use-typespec-azure }} + uses: actions/setup-python@v7 + with: + python-version: "3.12" - name: Download generated artifacts if: inputs.check != 'build' From 6e9597fc198101c133575f50144cb689b8e2c267 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Mon, 3 Aug 2026 17:50:04 +0800 Subject: [PATCH 06/16] ci: simplify Python CI workflow Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python-template.yml | 250 ---------------------- .github/workflows/python-integration.yml | 256 +++++++++++++++++++++-- 2 files changed, 233 insertions(+), 273 deletions(-) delete mode 100644 .github/workflows/ci-python-template.yml diff --git a/.github/workflows/ci-python-template.yml b/.github/workflows/ci-python-template.yml deleted file mode 100644 index 5943663a6fc..00000000000 --- a/.github/workflows/ci-python-template.yml +++ /dev/null @@ -1,250 +0,0 @@ -name: Python CI Template - -on: - workflow_call: - inputs: - check: - description: Python check to run. - required: true - type: string - runner: - description: GitHub runner image. - required: false - type: string - default: ubuntu-latest - use-typespec-azure: - description: Check out Azure/typespec-azure and point its core submodule at this TypeSpec commit. - required: false - type: boolean - default: false - -permissions: - contents: read - -jobs: - check: - name: ${{ inputs.check }} - runs-on: ${{ inputs.runner }} - steps: - - name: Checkout TypeSpec repo - if: ${{ !inputs.use-typespec-azure }} - uses: actions/checkout@v7 - - - name: Checkout Azure/typespec-azure repo - if: ${{ inputs.use-typespec-azure }} - uses: actions/checkout@v7 - with: - repository: Azure/typespec-azure - submodules: recursive - - - name: Update core submodule to TypeSpec commit - if: ${{ inputs.use-typespec-azure }} - env: - TYPESPEC_REPOSITORY: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} - TYPESPEC_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - shell: bash - run: | - cd core - git remote add typespec "https://github.com/$TYPESPEC_REPOSITORY.git" - git fetch typespec "$TYPESPEC_REF" - git checkout "$TYPESPEC_REF" - - - uses: ./.github/actions/setup - - - name: Set up integration Python - if: ${{ inputs.use-typespec-azure }} - uses: ./.github/actions/setup-python - - - name: Set up local Python - if: ${{ !inputs.use-typespec-azure }} - uses: actions/setup-python@v7 - with: - python-version: "3.12" - - - name: Download generated artifacts - if: inputs.check != 'build' - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - - name: Build and pack http-client-python from PR - if: inputs.use-typespec-azure && inputs.check == 'build' - run: | - cd core/packages/http-client-python - npm install --ignore-scripts - npm run build - npm pack - - - name: Override http-client-python with PR version - if: inputs.use-typespec-azure && inputs.check == 'build' - run: | - HCP_TGZ=$(ls core/packages/http-client-python/typespec-http-client-python-*.tgz) - node -e ' - const pkg = require("./packages/typespec-python/package.json"); - const fs = require("fs"); - pkg.dependencies["@typespec/http-client-python"] = "file:../../" + process.argv[1]; - fs.writeFileSync("./packages/typespec-python/package.json", JSON.stringify(pkg, null, 2) + "\n"); - ' "$HCP_TGZ" - - - name: Install integration dependencies - if: inputs.use-typespec-azure && (inputs.check == 'build' || inputs.check == 'test') - run: pnpm install --no-frozen-lockfile - - - name: Install integration Python package dependencies - if: inputs.use-typespec-azure && (inputs.check == 'typecheck' || inputs.check == 'lint' || inputs.check == 'docs') - run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." - - - name: Install TypeSpec repo dependencies - if: ${{ !inputs.use-typespec-azure }} - run: pnpm install - - - name: Install local http-client-python dependencies - if: ${{ !inputs.use-typespec-azure }} - run: npm install --ignore-scripts - working-directory: packages/http-client-python - - - name: Setup local http-client-python - if: ${{ !inputs.use-typespec-azure }} - run: npm run setup - working-directory: packages/http-client-python - - - name: Build integration typespec-python - if: inputs.use-typespec-azure && (inputs.check == 'build' || inputs.check == 'windows-test') - run: pnpm turbo run --filter "@azure-tools/typespec-python..." build - - - name: Build integration http-client-python from PR - if: inputs.use-typespec-azure && inputs.check == 'windows-test' - run: | - npm install --ignore-scripts - npm run build - working-directory: core/packages/http-client-python - - - name: Build http-specs and azure-http-specs from source - if: inputs.use-typespec-azure && inputs.check == 'build' - # Build the mock servers from the checked-out typespec-azure (+ PR core) - # source, so the mock stays in lockstep with the client that is - # regenerated from the same source below. Previously these build outputs - # were overwritten with the versions resolved via http-client-python's - # package.json pin, which caused client/mock spec skew whenever - # typespec-azure main advanced a spec beyond the pinned bundle and failed - # otherwise-green PRs. See microsoft/typespec#11348. - run: pnpm turbo run build --filter "@typespec/http-specs..." --filter "@azure-tools/azure-http-specs..." - - - name: Build integration spector - if: inputs.use-typespec-azure && inputs.check == 'test' - run: pnpm turbo run --filter "@typespec/spector..." build - - - name: Prepare integration Python environment - if: inputs.use-typespec-azure - run: pnpm run prepare - working-directory: packages/typespec-python - - - name: Regenerate integration clients - if: inputs.use-typespec-azure && inputs.check == 'build' - run: pnpm run regenerate - working-directory: packages/typespec-python - - - name: Regenerate local test clients - if: ${{ !inputs.use-typespec-azure && inputs.check == 'build' }} - run: npm run regenerate - working-directory: packages/http-client-python - - - name: Check local generated output - if: ${{ !inputs.use-typespec-azure && inputs.check == 'build' }} - run: npm run check-unstaged - working-directory: packages/http-client-python - - - name: Pre-build integration wheels - if: inputs.use-typespec-azure && inputs.check == 'build' - working-directory: packages/typespec-python - run: | - venv/bin/python tests/install_packages.py build azure tests - venv/bin/python tests/install_packages.py build unbranded tests - - - name: Upload integration generated artifacts - if: inputs.use-typespec-azure && inputs.check == 'build' - uses: actions/upload-artifact@v7 - with: - name: python-generated - path: | - packages/typespec-python/tests/generated - packages/typespec-python/tests/.wheels - packages/typespec-python/dist - packages/typespec-python/package.json - core/packages/http-client-python/typespec-http-client-python-*.tgz - core/packages/spector/dist - core/packages/http-specs/dist - packages/azure-http-specs/dist - retention-days: 1 - - - name: Upload local generated artifacts - if: ${{ !inputs.use-typespec-azure && inputs.check == 'build' }} - uses: actions/upload-artifact@v7 - with: - name: python-generated - path: | - packages/http-client-python/tests/generated - packages/http-client-python/dist - packages/http-client-python/generator/dist - retention-days: 1 - - - name: Test integration clients - if: inputs.use-typespec-azure && inputs.check == 'test' - run: pnpm run test:python:e2e - working-directory: packages/typespec-python - - - name: Test local generated clients - if: ${{ !inputs.use-typespec-azure && (inputs.check == 'test' || inputs.check == 'windows-test') }} - run: npm run test:generator -- --env=test - working-directory: packages/http-client-python - - - name: Typecheck integration clients - if: inputs.use-typespec-azure && inputs.check == 'typecheck' - run: pnpm run test:python:e2e --env mypy,pyright - working-directory: packages/typespec-python - - - name: Typecheck local generated clients - if: ${{ !inputs.use-typespec-azure && inputs.check == 'typecheck' }} - run: npm run test:generator -- --env=mypy,pyright - working-directory: packages/http-client-python - - - name: Lint integration clients - if: inputs.use-typespec-azure && inputs.check == 'lint' - run: pnpm run test:python:e2e --env lint - working-directory: packages/typespec-python - - - name: Lint integration source - if: inputs.use-typespec-azure && inputs.check == 'lint' - run: pnpm run lint:extra - working-directory: packages/typespec-python - - - name: Format check integration source - if: inputs.use-typespec-azure && inputs.check == 'lint' - run: pnpm run format:extra:check - working-directory: packages/typespec-python - - - name: Lint local generated clients - if: ${{ !inputs.use-typespec-azure && inputs.check == 'lint' }} - run: npm run test:generator -- --env=lint - working-directory: packages/http-client-python - - - name: Lint local source - if: ${{ !inputs.use-typespec-azure && inputs.check == 'lint' }} - run: npm run lint - working-directory: packages/http-client-python - - - name: Format check local source - if: ${{ !inputs.use-typespec-azure && inputs.check == 'lint' }} - run: npm run format:check - working-directory: packages/http-client-python - - - name: Validate integration docs - if: inputs.use-typespec-azure && inputs.check == 'docs' - run: pnpm run test:python:e2e --env apiview,sphinx - working-directory: packages/typespec-python - - - name: Validate local docs - if: ${{ !inputs.use-typespec-azure && inputs.check == 'docs' }} - run: npm run test:generator -- --env=apiview,sphinx - working-directory: packages/http-client-python diff --git a/.github/workflows/python-integration.yml b/.github/workflows/python-integration.yml index d6f37dba839..a5b548fc142 100644 --- a/.github/workflows/python-integration.yml +++ b/.github/workflows/python-integration.yml @@ -1,12 +1,10 @@ name: Python Integration on: - workflow_call: pull_request: branches: ["main"] paths: - "packages/http-client-python/**" - - ".github/workflows/ci-python-template.yml" - ".github/workflows/python-integration.yml" # Allow manual triggering workflow_dispatch: @@ -15,50 +13,262 @@ permissions: contents: read concurrency: - group: ${{ github.workflow }}-python-integration-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: build: name: "Build & Regenerate" + runs-on: ubuntu-latest if: | !startsWith(github.head_ref, 'dependabot/') && !startsWith(github.head_ref, 'publish/') && !startsWith(github.head_ref, 'backmerge/') && !startsWith(github.head_ref, 'revert-') - uses: ./.github/workflows/ci-python-template.yml - with: - check: build - use-typespec-azure: true + steps: + - name: Checkout Azure/typespec-azure repo + uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to PR commit + if: github.event_name == 'pull_request' + run: | + cd core + git remote add pr https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git + git fetch pr ${{ github.event.pull_request.head.sha }} + git checkout ${{ github.event.pull_request.head.sha }} + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Build and pack http-client-python from PR + run: | + cd core/packages/http-client-python + npm install --ignore-scripts + npm run build + npm pack + + - name: Override http-client-python with PR version + run: | + HCP_TGZ=$(ls core/packages/http-client-python/typespec-http-client-python-*.tgz) + node -e ' + const pkg = require("./packages/typespec-python/package.json"); + const fs = require("fs"); + pkg.dependencies["@typespec/http-client-python"] = "file:../../" + process.argv[1]; + fs.writeFileSync("./packages/typespec-python/package.json", JSON.stringify(pkg, null, 2) + "\n"); + ' "$HCP_TGZ" + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile + + - name: Build + run: pnpm turbo run --filter "@azure-tools/typespec-python..." build + + - name: Build http-specs and azure-http-specs from source + # Build the mock servers from the checked-out typespec-azure (+ PR core) + # source, so the mock stays in lockstep with the client that is + # regenerated from the same source below. Previously these build outputs + # were overwritten with the versions resolved via http-client-python's + # package.json pin, which caused client/mock spec skew whenever + # typespec-azure main advanced a spec beyond the pinned bundle and failed + # otherwise-green PRs. See microsoft/typespec#11348. + run: pnpm turbo run build --filter "@typespec/http-specs..." --filter "@azure-tools/azure-http-specs..." + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: Regenerate + run: pnpm run regenerate + working-directory: packages/typespec-python + + - name: Pre-build wheels + working-directory: packages/typespec-python + run: | + venv/bin/python tests/install_packages.py build azure tests + venv/bin/python tests/install_packages.py build unbranded tests + + - name: Upload generated artifacts + uses: actions/upload-artifact@v7 + with: + name: python-generated + path: | + packages/typespec-python/tests/generated + packages/typespec-python/tests/.wheels + packages/typespec-python/dist + packages/typespec-python/package.json + core/packages/http-client-python/typespec-http-client-python-*.tgz + core/packages/spector/dist + core/packages/http-specs/dist + packages/azure-http-specs/dist + retention-days: 1 test: name: "Mock API Tests" needs: build - uses: ./.github/workflows/ci-python-template.yml - with: - check: test - use-typespec-azure: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to PR commit + if: github.event_name == 'pull_request' + run: | + cd core + git remote add pr https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git + git fetch pr ${{ github.event.pull_request.head.sha }} + git checkout ${{ github.event.pull_request.head.sha }} + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile + + - name: Build spector + run: pnpm turbo run --filter "@typespec/spector..." build + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: Test + run: pnpm run test:python:e2e + working-directory: packages/typespec-python typecheck: name: "Type Checking" needs: build - uses: ./.github/workflows/ci-python-template.yml - with: - check: typecheck - use-typespec-azure: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to PR commit + if: github.event_name == 'pull_request' + run: | + cd core + git remote add pr https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git + git fetch pr ${{ github.event.pull_request.head.sha }} + git checkout ${{ github.event.pull_request.head.sha }} + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: Mypy & Pyright + run: pnpm run test:python:e2e --env mypy,pyright + working-directory: packages/typespec-python lint: name: "Lint & Format" needs: build - uses: ./.github/workflows/ci-python-template.yml - with: - check: lint - use-typespec-azure: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to PR commit + if: github.event_name == 'pull_request' + run: | + cd core + git remote add pr https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git + git fetch pr ${{ github.event.pull_request.head.sha }} + git checkout ${{ github.event.pull_request.head.sha }} + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: Pylint + run: pnpm run test:python:e2e --env lint + working-directory: packages/typespec-python + + - name: Lint (extra) + run: pnpm run lint:extra + working-directory: packages/typespec-python + + - name: Format check (extra) + run: pnpm run format:extra:check + working-directory: packages/typespec-python docs: name: "Docs Validation" needs: build - uses: ./.github/workflows/ci-python-template.yml - with: - check: docs - use-typespec-azure: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + repository: Azure/typespec-azure + submodules: recursive + + - name: Update core submodule to PR commit + if: github.event_name == 'pull_request' + run: | + cd core + git remote add pr https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git + git fetch pr ${{ github.event.pull_request.head.sha }} + git checkout ${{ github.event.pull_request.head.sha }} + + - uses: ./.github/actions/setup + + - uses: ./.github/actions/setup-python + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile --filter "@azure-tools/typespec-python..." + + - name: Prepare Python environment + run: pnpm run prepare + working-directory: packages/typespec-python + + - name: API View & Sphinx + run: pnpm run test:python:e2e --env apiview,sphinx + working-directory: packages/typespec-python From 295e2f013d65bf85d385c379b0ec6a426330ab60 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Mon, 3 Aug 2026 17:50:17 +0800 Subject: [PATCH 07/16] ci: add standalone Python CI Gate workflow Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python.yml | 203 +++++++++++++++++++++++++++++--- .github/workflows/ci.yml | 2 - 2 files changed, 184 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 3757282b170..3552b89a8e0 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -9,47 +9,212 @@ permissions: jobs: build: name: "Build & Regenerate" + runs-on: ubuntu-latest if: | !startsWith(github.head_ref, 'dependabot/') && !startsWith(github.head_ref, 'publish/') && !startsWith(github.head_ref, 'backmerge/') && !startsWith(github.head_ref, 'revert-') - uses: ./.github/workflows/ci-python-template.yml - with: - check: build + steps: + - uses: actions/checkout@v7 + + - uses: ./.github/actions/setup + + - uses: actions/setup-python@v7 + with: + python-version: "3.12" + + - name: Install repo dependencies + run: pnpm install + + - name: Setup http-client-python + run: | + npm install --ignore-scripts + npm run setup + working-directory: packages/http-client-python + + - name: Regenerate + run: npm run regenerate + working-directory: packages/http-client-python + + - name: Check for unstaged changes + run: npm run check-unstaged + working-directory: packages/http-client-python + + - name: Upload generated artifacts + uses: actions/upload-artifact@v7 + with: + name: python-generated + path: | + packages/http-client-python/tests/generated + packages/http-client-python/dist + packages/http-client-python/generator/dist + retention-days: 1 test: name: "Mock API Tests" needs: build - uses: ./.github/workflows/ci-python-template.yml - with: - check: test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - uses: ./.github/actions/setup + + - uses: actions/setup-python@v7 + with: + python-version: "3.12" + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install repo dependencies + run: pnpm install + + - name: Setup http-client-python + run: | + npm install --ignore-scripts + npm run setup + working-directory: packages/http-client-python + + - name: Test + run: npm run test:generator -- --env=test + working-directory: packages/http-client-python typecheck: name: "Type Checking" needs: build - uses: ./.github/workflows/ci-python-template.yml - with: - check: typecheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - uses: ./.github/actions/setup + + - uses: actions/setup-python@v7 + with: + python-version: "3.12" + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install repo dependencies + run: pnpm install + + - name: Setup http-client-python + run: | + npm install --ignore-scripts + npm run setup + working-directory: packages/http-client-python + + - name: Mypy & Pyright + run: npm run test:generator -- --env=mypy,pyright + working-directory: packages/http-client-python lint: name: "Lint & Format" needs: build - uses: ./.github/workflows/ci-python-template.yml - with: - check: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - uses: ./.github/actions/setup + + - uses: actions/setup-python@v7 + with: + python-version: "3.12" + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install repo dependencies + run: pnpm install + + - name: Setup http-client-python + run: | + npm install --ignore-scripts + npm run setup + working-directory: packages/http-client-python + + - name: Pylint + run: npm run test:generator -- --env=lint + working-directory: packages/http-client-python + + - name: Lint source + run: npm run lint + working-directory: packages/http-client-python + + - name: Format check source + run: npm run format:check + working-directory: packages/http-client-python docs: name: "Docs Validation" needs: build - uses: ./.github/workflows/ci-python-template.yml - with: - check: docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - uses: ./.github/actions/setup + + - uses: actions/setup-python@v7 + with: + python-version: "3.12" + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install repo dependencies + run: pnpm install + + - name: Setup http-client-python + run: | + npm install --ignore-scripts + npm run setup + working-directory: packages/http-client-python + + - name: API View & Sphinx + run: npm run test:generator -- --env=apiview,sphinx + working-directory: packages/http-client-python windows-test: name: "Build & Test (Windows)" needs: build - uses: ./.github/workflows/ci-python-template.yml - with: - check: windows-test - runner: windows-latest + runs-on: windows-latest + steps: + - uses: actions/checkout@v7 + + - uses: ./.github/actions/setup + + - uses: actions/setup-python@v7 + with: + python-version: "3.12" + + - name: Download generated artifacts + uses: actions/download-artifact@v8 + with: + name: python-generated + path: . + + - name: Install repo dependencies + run: pnpm install + + - name: Setup http-client-python + run: | + npm install --ignore-scripts + npm run setup + working-directory: packages/http-client-python + + - name: Test + run: npm run test:generator -- --env=test + working-directory: packages/http-client-python diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75f07aee819..98ad52785a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,8 +52,6 @@ jobs: - 'packages/http-client-python/**' - '.github/workflows/ci.yml' - '.github/workflows/ci-python.yml' - - '.github/workflows/ci-python-template.yml' - - '.github/workflows/python-integration.yml' core: needs: changes From 60c7525bd9c749bf0a2e27aca2266b2cdedbdf38 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Mon, 3 Aug 2026 18:06:22 +0800 Subject: [PATCH 08/16] ci: avoid Python CI lockfile mutation Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 3552b89a8e0..42ec8c758e1 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -29,7 +29,7 @@ jobs: - name: Setup http-client-python run: | - npm install --ignore-scripts + npm install --ignore-scripts --package-lock=false npm run setup working-directory: packages/http-client-python @@ -75,7 +75,7 @@ jobs: - name: Setup http-client-python run: | - npm install --ignore-scripts + npm install --ignore-scripts --package-lock=false npm run setup working-directory: packages/http-client-python @@ -107,7 +107,7 @@ jobs: - name: Setup http-client-python run: | - npm install --ignore-scripts + npm install --ignore-scripts --package-lock=false npm run setup working-directory: packages/http-client-python @@ -139,7 +139,7 @@ jobs: - name: Setup http-client-python run: | - npm install --ignore-scripts + npm install --ignore-scripts --package-lock=false npm run setup working-directory: packages/http-client-python @@ -179,7 +179,7 @@ jobs: - name: Setup http-client-python run: | - npm install --ignore-scripts + npm install --ignore-scripts --package-lock=false npm run setup working-directory: packages/http-client-python @@ -211,7 +211,7 @@ jobs: - name: Setup http-client-python run: | - npm install --ignore-scripts + npm install --ignore-scripts --package-lock=false npm run setup working-directory: packages/http-client-python From 9fa805590dc017cd0b1600776f70d8a9bd754ea6 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Tue, 4 Aug 2026 10:51:20 +0800 Subject: [PATCH 09/16] ci: prepare Python test environment Install the Python package dev requirements in each CI Gate job so tox-based test, lint, docs, and typecheck commands can run after restoring generated artifacts. Also enable Git long paths before the Windows checkout to avoid failures on long test-data paths. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 42ec8c758e1..97654b7c129 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -31,6 +31,7 @@ jobs: run: | npm install --ignore-scripts --package-lock=false npm run setup + npm run prepare working-directory: packages/http-client-python - name: Regenerate @@ -77,6 +78,7 @@ jobs: run: | npm install --ignore-scripts --package-lock=false npm run setup + npm run prepare working-directory: packages/http-client-python - name: Test @@ -109,6 +111,7 @@ jobs: run: | npm install --ignore-scripts --package-lock=false npm run setup + npm run prepare working-directory: packages/http-client-python - name: Mypy & Pyright @@ -141,6 +144,7 @@ jobs: run: | npm install --ignore-scripts --package-lock=false npm run setup + npm run prepare working-directory: packages/http-client-python - name: Pylint @@ -181,6 +185,7 @@ jobs: run: | npm install --ignore-scripts --package-lock=false npm run setup + npm run prepare working-directory: packages/http-client-python - name: API View & Sphinx @@ -192,6 +197,9 @@ jobs: needs: build runs-on: windows-latest steps: + - name: Enable Git long paths + run: git config --system core.longpaths true + - uses: actions/checkout@v7 - uses: ./.github/actions/setup @@ -213,6 +221,7 @@ jobs: run: | npm install --ignore-scripts --package-lock=false npm run setup + npm run prepare working-directory: packages/http-client-python - name: Test From 524568e1ff7e226dfa1e574f420016b5c46ee6c9 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Tue, 4 Aug 2026 11:13:18 +0800 Subject: [PATCH 10/16] ci: align Python CI setup with integration flow Pre-build generated package wheels in the build job and upload them with generated artifacts. Run downstream jobs against restored artifacts with package install plus a fail-fast Python prepare step instead of rebuilding the package in each job. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python.yml | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 97654b7c129..aa45a3f48c5 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -31,13 +31,22 @@ jobs: run: | npm install --ignore-scripts --package-lock=false npm run setup - npm run prepare + working-directory: packages/http-client-python + + - name: Prepare Python environment + run: venv/bin/python eng/scripts/setup/prepare.py working-directory: packages/http-client-python - name: Regenerate run: npm run regenerate working-directory: packages/http-client-python + - name: Pre-build wheels + run: | + venv/bin/python tests/install_packages.py build azure tests + venv/bin/python tests/install_packages.py build unbranded tests + working-directory: packages/http-client-python + - name: Check for unstaged changes run: npm run check-unstaged working-directory: packages/http-client-python @@ -48,6 +57,7 @@ jobs: name: python-generated path: | packages/http-client-python/tests/generated + packages/http-client-python/tests/.wheels packages/http-client-python/dist packages/http-client-python/generator/dist retention-days: 1 @@ -77,8 +87,8 @@ jobs: - name: Setup http-client-python run: | npm install --ignore-scripts --package-lock=false - npm run setup - npm run prepare + npm run install + venv/bin/python eng/scripts/setup/prepare.py working-directory: packages/http-client-python - name: Test @@ -110,8 +120,8 @@ jobs: - name: Setup http-client-python run: | npm install --ignore-scripts --package-lock=false - npm run setup - npm run prepare + npm run install + venv/bin/python eng/scripts/setup/prepare.py working-directory: packages/http-client-python - name: Mypy & Pyright @@ -143,8 +153,8 @@ jobs: - name: Setup http-client-python run: | npm install --ignore-scripts --package-lock=false - npm run setup - npm run prepare + npm run install + venv/bin/python eng/scripts/setup/prepare.py working-directory: packages/http-client-python - name: Pylint @@ -184,8 +194,8 @@ jobs: - name: Setup http-client-python run: | npm install --ignore-scripts --package-lock=false - npm run setup - npm run prepare + npm run install + venv/bin/python eng/scripts/setup/prepare.py working-directory: packages/http-client-python - name: API View & Sphinx @@ -220,8 +230,8 @@ jobs: - name: Setup http-client-python run: | npm install --ignore-scripts --package-lock=false - npm run setup - npm run prepare + npm run install + .\venv\Scripts\python.exe eng\scripts\setup\prepare.py working-directory: packages/http-client-python - name: Test From 2b191d95e7568a446466a1743ac979f6a4083570 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Tue, 4 Aug 2026 11:20:50 +0800 Subject: [PATCH 11/16] ci: run Windows Python build and test together Rename the Linux build job and make the Windows Python CI job build, regenerate, and test independently without restoring Linux artifacts. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python.yml | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index aa45a3f48c5..43c1b73a6da 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -8,13 +8,8 @@ permissions: jobs: build: - name: "Build & Regenerate" + name: "Build & Regenerate (Linux)" runs-on: ubuntu-latest - if: | - !startsWith(github.head_ref, 'dependabot/') && - !startsWith(github.head_ref, 'publish/') && - !startsWith(github.head_ref, 'backmerge/') && - !startsWith(github.head_ref, 'revert-') steps: - uses: actions/checkout@v7 @@ -203,8 +198,7 @@ jobs: working-directory: packages/http-client-python windows-test: - name: "Build & Test (Windows)" - needs: build + name: "Build & Regenerate && Test (Windows)" runs-on: windows-latest steps: - name: Enable Git long paths @@ -218,22 +212,20 @@ jobs: with: python-version: "3.12" - - name: Download generated artifacts - uses: actions/download-artifact@v8 - with: - name: python-generated - path: . - - name: Install repo dependencies run: pnpm install - name: Setup http-client-python run: | npm install --ignore-scripts --package-lock=false - npm run install + npm run setup .\venv\Scripts\python.exe eng\scripts\setup\prepare.py working-directory: packages/http-client-python + - name: Regenerate + run: npm run regenerate + working-directory: packages/http-client-python + - name: Test run: npm run test:generator -- --env=test working-directory: packages/http-client-python From 021600fdbab507b08d06bb6cf469b2fab761d549 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Tue, 4 Aug 2026 11:55:07 +0800 Subject: [PATCH 12/16] ci: upload Python wheel artifacts Allow the Python generated artifact upload to include the hidden .wheels directory so downstream Linux jobs install pre-built wheels instead of falling back to source builds. Add concise comments documenting the CI-specific npm and Python prepare steps. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 43c1b73a6da..dc70bd90934 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -23,12 +23,14 @@ jobs: run: pnpm install - name: Setup http-client-python + # Avoid npm lifecycle side effects and lockfile rewrites in CI; setup still runs build + generator install. run: | npm install --ignore-scripts --package-lock=false npm run setup working-directory: packages/http-client-python - name: Prepare Python environment + # Run prepare.py directly so missing tox/dev dependencies fail the job instead of being swallowed by the npm wrapper. run: venv/bin/python eng/scripts/setup/prepare.py working-directory: packages/http-client-python @@ -50,6 +52,7 @@ jobs: uses: actions/upload-artifact@v7 with: name: python-generated + include-hidden-files: true path: | packages/http-client-python/tests/generated packages/http-client-python/tests/.wheels @@ -80,6 +83,7 @@ jobs: run: pnpm install - name: Setup http-client-python + # Generated artifacts come from the build job; downstream jobs only need the Python package installed and test tools prepared. run: | npm install --ignore-scripts --package-lock=false npm run install @@ -113,6 +117,7 @@ jobs: run: pnpm install - name: Setup http-client-python + # Generated artifacts come from the build job; downstream jobs only need the Python package installed and test tools prepared. run: | npm install --ignore-scripts --package-lock=false npm run install @@ -146,6 +151,7 @@ jobs: run: pnpm install - name: Setup http-client-python + # Generated artifacts come from the build job; downstream jobs only need the Python package installed and test tools prepared. run: | npm install --ignore-scripts --package-lock=false npm run install @@ -187,6 +193,7 @@ jobs: run: pnpm install - name: Setup http-client-python + # Generated artifacts come from the build job; downstream jobs only need the Python package installed and test tools prepared. run: | npm install --ignore-scripts --package-lock=false npm run install @@ -216,6 +223,7 @@ jobs: run: pnpm install - name: Setup http-client-python + # Windows validates build/regenerate/test in one job, so run the full setup instead of restoring Linux artifacts. run: | npm install --ignore-scripts --package-lock=false npm run setup From 21f0f56fddd7ca8c6d4afe1ed115b1a228617596 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Tue, 4 Aug 2026 13:04:11 +0800 Subject: [PATCH 13/16] ci: restore Python artifacts into package path Download generated Python artifacts into packages/http-client-python so downstream jobs find tests/generated, tests/.wheels, dist, and generator at the paths expected by the package scripts. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index dc70bd90934..13fd5b49f87 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -77,7 +77,7 @@ jobs: uses: actions/download-artifact@v8 with: name: python-generated - path: . + path: packages/http-client-python - name: Install repo dependencies run: pnpm install @@ -111,7 +111,7 @@ jobs: uses: actions/download-artifact@v8 with: name: python-generated - path: . + path: packages/http-client-python - name: Install repo dependencies run: pnpm install @@ -145,7 +145,7 @@ jobs: uses: actions/download-artifact@v8 with: name: python-generated - path: . + path: packages/http-client-python - name: Install repo dependencies run: pnpm install @@ -187,7 +187,7 @@ jobs: uses: actions/download-artifact@v8 with: name: python-generated - path: . + path: packages/http-client-python - name: Install repo dependencies run: pnpm install From cff98382408e31914ba20c22e7db7cbb6ed0c66a Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Tue, 4 Aug 2026 13:46:25 +0800 Subject: [PATCH 14/16] ci: declare Python ESLint dependencies Add direct dev dependencies for eslint and @eslint/js because the standalone http-client-python lint config imports @eslint/js in CI. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- packages/http-client-python/package-lock.json | 2 ++ packages/http-client-python/package.json | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/http-client-python/package-lock.json b/packages/http-client-python/package-lock.json index 6c2da666b97..79c0409e4bf 100644 --- a/packages/http-client-python/package-lock.json +++ b/packages/http-client-python/package-lock.json @@ -23,6 +23,7 @@ "@azure-tools/typespec-azure-resource-manager": "~0.70.0", "@azure-tools/typespec-azure-rulesets": "~0.70.0", "@azure-tools/typespec-client-generator-core": "~0.70.0", + "@eslint/js": "^9.39.4", "@types/js-yaml": "~4.0.5", "@types/node": "~25.0.2", "@types/semver": "7.5.8", @@ -39,6 +40,7 @@ "@typespec/versioning": "~0.84.0", "@typespec/xml": "~0.84.0", "c8": "^10.1.3", + "eslint": "^9.39.4", "picocolors": "~1.1.1", "prettier": "^3.9.5", "rimraf": "~6.1.2", diff --git a/packages/http-client-python/package.json b/packages/http-client-python/package.json index d3d837fcad5..df836c42dad 100644 --- a/packages/http-client-python/package.json +++ b/packages/http-client-python/package.json @@ -110,6 +110,7 @@ "@azure-tools/typespec-azure-rulesets": "~0.70.0", "@azure-tools/typespec-client-generator-core": "~0.70.0", "@azure-tools/azure-http-specs": "0.1.0-alpha.43", + "@eslint/js": "^9.39.4", "@typespec/compiler": "^1.14.0", "@typespec/http": "^1.14.0", "@typespec/openapi": "^1.14.0", @@ -126,6 +127,7 @@ "@types/node": "~25.0.2", "@types/semver": "7.5.8", "c8": "^10.1.3", + "eslint": "^9.39.4", "picocolors": "~1.1.1", "rimraf": "~6.1.2", "typescript": "~5.9.2", From a3a70d19cae3de68ebb5ec35fbfe76cc6fdc8374 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Tue, 4 Aug 2026 14:57:28 +0800 Subject: [PATCH 15/16] ci: isolate Python formatter config Use a package-local Prettier config for standalone http-client-python formatting so CI does not require the monorepo TypeSpec Prettier plugin build output. Avoid importing @eslint/js from the standalone ESLint config and add an internal Chronus entry for the Python CI Gate migration. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .chronus/changes/python-ci-gate-2026-08-04.md | 7 +++++++ .../eng/scripts/ci/config/eslint-ci.config.mjs | 2 -- .../eng/scripts/ci/config/prettier-ci.json | 9 +++++++++ packages/http-client-python/eng/scripts/ci/format.ts | 4 ++++ packages/http-client-python/package-lock.json | 2 -- packages/http-client-python/package.json | 2 -- 6 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 .chronus/changes/python-ci-gate-2026-08-04.md create mode 100644 packages/http-client-python/eng/scripts/ci/config/prettier-ci.json diff --git a/.chronus/changes/python-ci-gate-2026-08-04.md b/.chronus/changes/python-ci-gate-2026-08-04.md new file mode 100644 index 00000000000..11ae6785567 --- /dev/null +++ b/.chronus/changes/python-ci-gate-2026-08-04.md @@ -0,0 +1,7 @@ +--- +changeKind: internal +packages: + - "@typespec/http-client-python" +--- + +Move Python emitter PR validation into GitHub Actions CI Gate. diff --git a/packages/http-client-python/eng/scripts/ci/config/eslint-ci.config.mjs b/packages/http-client-python/eng/scripts/ci/config/eslint-ci.config.mjs index 3b51a3fc0d0..95fe8a3d657 100644 --- a/packages/http-client-python/eng/scripts/ci/config/eslint-ci.config.mjs +++ b/packages/http-client-python/eng/scripts/ci/config/eslint-ci.config.mjs @@ -1,7 +1,6 @@ // @ts-check // Standalone eslint config for http-client-python package // This config is used in CI where monorepo dependencies may not be available -import eslint from "@eslint/js"; import { dirname } from "path"; import tsEslint from "typescript-eslint"; import { fileURLToPath } from "url"; @@ -12,7 +11,6 @@ export default [ { ignores: ["**/dist/**/*", "**/node_modules/**/*"], }, - eslint.configs.recommended, ...tsEslint.configs.recommended, { languageOptions: { diff --git a/packages/http-client-python/eng/scripts/ci/config/prettier-ci.json b/packages/http-client-python/eng/scripts/ci/config/prettier-ci.json new file mode 100644 index 00000000000..405804bb2ef --- /dev/null +++ b/packages/http-client-python/eng/scripts/ci/config/prettier-ci.json @@ -0,0 +1,9 @@ +{ + "arrowParens": "always", + "bracketSpacing": true, + "endOfLine": "lf", + "printWidth": 100, + "semi": true, + "singleQuote": false, + "tabWidth": 2 +} diff --git a/packages/http-client-python/eng/scripts/ci/format.ts b/packages/http-client-python/eng/scripts/ci/format.ts index 96d08dedc39..b2d563ef35f 100644 --- a/packages/http-client-python/eng/scripts/ci/format.ts +++ b/packages/http-client-python/eng/scripts/ci/format.ts @@ -118,6 +118,8 @@ async function formatEmitter(check: boolean): Promise { const args = check ? [ "--check", + "--config", + "eng/scripts/ci/config/prettier-ci.json", "emitter/", "eng/scripts/", "*.json", @@ -127,6 +129,8 @@ async function formatEmitter(check: boolean): Promise { ] : [ "--write", + "--config", + "eng/scripts/ci/config/prettier-ci.json", "emitter/", "eng/scripts/", "*.json", diff --git a/packages/http-client-python/package-lock.json b/packages/http-client-python/package-lock.json index 79c0409e4bf..6c2da666b97 100644 --- a/packages/http-client-python/package-lock.json +++ b/packages/http-client-python/package-lock.json @@ -23,7 +23,6 @@ "@azure-tools/typespec-azure-resource-manager": "~0.70.0", "@azure-tools/typespec-azure-rulesets": "~0.70.0", "@azure-tools/typespec-client-generator-core": "~0.70.0", - "@eslint/js": "^9.39.4", "@types/js-yaml": "~4.0.5", "@types/node": "~25.0.2", "@types/semver": "7.5.8", @@ -40,7 +39,6 @@ "@typespec/versioning": "~0.84.0", "@typespec/xml": "~0.84.0", "c8": "^10.1.3", - "eslint": "^9.39.4", "picocolors": "~1.1.1", "prettier": "^3.9.5", "rimraf": "~6.1.2", diff --git a/packages/http-client-python/package.json b/packages/http-client-python/package.json index df836c42dad..d3d837fcad5 100644 --- a/packages/http-client-python/package.json +++ b/packages/http-client-python/package.json @@ -110,7 +110,6 @@ "@azure-tools/typespec-azure-rulesets": "~0.70.0", "@azure-tools/typespec-client-generator-core": "~0.70.0", "@azure-tools/azure-http-specs": "0.1.0-alpha.43", - "@eslint/js": "^9.39.4", "@typespec/compiler": "^1.14.0", "@typespec/http": "^1.14.0", "@typespec/openapi": "^1.14.0", @@ -127,7 +126,6 @@ "@types/node": "~25.0.2", "@types/semver": "7.5.8", "c8": "^10.1.3", - "eslint": "^9.39.4", "picocolors": "~1.1.1", "rimraf": "~6.1.2", "typescript": "~5.9.2", From fbec5e5ed5d4b61a85e008df2c410317aedab3c4 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Tue, 4 Aug 2026 15:03:55 +0800 Subject: [PATCH 16/16] ci: build Prettier plugin for Python format check Build the TypeSpec Prettier plugin only in the Python Lint & Format job before running package format checks, instead of carrying a separate package-local Prettier config. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: df233d93-3288-4a30-a629-d9e53a234021 --- .github/workflows/ci-python.yml | 3 +++ .../eng/scripts/ci/config/prettier-ci.json | 9 --------- packages/http-client-python/eng/scripts/ci/format.ts | 4 ---- 3 files changed, 3 insertions(+), 13 deletions(-) delete mode 100644 packages/http-client-python/eng/scripts/ci/config/prettier-ci.json diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 13fd5b49f87..9ca23bd41e3 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -166,6 +166,9 @@ jobs: run: npm run lint working-directory: packages/http-client-python + - name: Build TypeSpec Prettier plugin + run: pnpm --filter "@typespec/prettier-plugin-typespec..." run build + - name: Format check source run: npm run format:check working-directory: packages/http-client-python diff --git a/packages/http-client-python/eng/scripts/ci/config/prettier-ci.json b/packages/http-client-python/eng/scripts/ci/config/prettier-ci.json deleted file mode 100644 index 405804bb2ef..00000000000 --- a/packages/http-client-python/eng/scripts/ci/config/prettier-ci.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "arrowParens": "always", - "bracketSpacing": true, - "endOfLine": "lf", - "printWidth": 100, - "semi": true, - "singleQuote": false, - "tabWidth": 2 -} diff --git a/packages/http-client-python/eng/scripts/ci/format.ts b/packages/http-client-python/eng/scripts/ci/format.ts index b2d563ef35f..96d08dedc39 100644 --- a/packages/http-client-python/eng/scripts/ci/format.ts +++ b/packages/http-client-python/eng/scripts/ci/format.ts @@ -118,8 +118,6 @@ async function formatEmitter(check: boolean): Promise { const args = check ? [ "--check", - "--config", - "eng/scripts/ci/config/prettier-ci.json", "emitter/", "eng/scripts/", "*.json", @@ -129,8 +127,6 @@ async function formatEmitter(check: boolean): Promise { ] : [ "--write", - "--config", - "eng/scripts/ci/config/prettier-ci.json", "emitter/", "eng/scripts/", "*.json",