Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .chronus/changes/python-ci-gate-2026-08-04.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: internal
packages:
- "@typespec/http-client-python"
---

Move Python emitter PR validation into GitHub Actions CI Gate.
242 changes: 242 additions & 0 deletions .github/workflows/ci-python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
name: Python CI

on:
workflow_call:

permissions:
contents: read

jobs:
build:
name: "Build & Regenerate (Linux)"
runs-on: ubuntu-latest
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
# 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

- 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

- name: Upload generated artifacts
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
packages/http-client-python/dist
packages/http-client-python/generator/dist
retention-days: 1

test:
name: "Mock API Tests"
needs: build
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: packages/http-client-python

Comment on lines +76 to +81

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional. upload-artifact roots the artifact at the least common ancestor of the uploaded paths, which is packages/http-client-python here. The downloaded artifact contains top-level tests/, dist/, and generator/, not packages/http-client-python/....

Downloading into packages/http-client-python restores those directories to the paths expected by the package scripts. Downloading to . was the previous issue: the package scripts then only saw checked-in placeholders under packages/http-client-python/tests/generated, while the full generated artifact was restored under repo-root tests/.

- name: Install repo dependencies
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
venv/bin/python eng/scripts/setup/prepare.py
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
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: packages/http-client-python

- name: Install repo dependencies
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
venv/bin/python eng/scripts/setup/prepare.py
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
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: packages/http-client-python

- name: Install repo dependencies
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
venv/bin/python eng/scripts/setup/prepare.py
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: 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

docs:
name: "Docs Validation"
needs: build
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: packages/http-client-python

- name: Install repo dependencies
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
venv/bin/python eng/scripts/setup/prepare.py
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 & Regenerate && Test (Windows)"
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

- uses: actions/setup-python@v7
with:
python-version: "3.12"

- name: Install repo dependencies
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
.\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
27 changes: 23 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ on:

permissions:
contents: read
pull-requests: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand All @@ -22,12 +23,13 @@ jobs:
name: Detect Changes
runs-on: ubuntu-slim
outputs:
core: ${{ steps.filter.outputs.core }}
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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that tool was letting multiple filters to be defined in the same task

with:
predicate-quantifier: "every"
filters: |
Expand All @@ -42,22 +44,39 @@ 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'
- '.github/workflows/ci-python.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/ci-python.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: |
if [[ "${{ needs.core.result }}" == "failure" || "${{ needs.core.result }}" == "cancelled" ]]; then
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"
6 changes: 0 additions & 6 deletions eng/common/pipelines/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,3 @@ extends:
parameters:
DependsOn: InitStage
Condition: eq('true', stageDependencies.InitStage.outputs['InitJob.InitStep.RunJava'])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need to delete some fileS?

# 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'])
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -12,7 +11,6 @@ export default [
{
ignores: ["**/dist/**/*", "**/node_modules/**/*"],
},
eslint.configs.recommended,
...tsEslint.configs.recommended,
{
languageOptions: {
Expand Down
Loading