Accept custom interceptors in ConfigClient and AsyncConfigClient #181
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # CI pipeline for the OpenDecree Python SDK. | |
| # | |
| # Jobs: lint, typecheck, test (matrix: 3.11-3.13), examples → check (alls-green gate) | |
| # Integration job is optional — runs on workflow_dispatch or when | |
| # DECREE_TEST_ADDR secret is set, starting a live server via docker-compose. | |
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_call: | |
| workflow_dispatch: | |
| inputs: | |
| run-integration: | |
| description: "Run integration tests against a live server" | |
| type: boolean | |
| default: false | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} | |
| cancel-in-progress: true | |
| jobs: | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Install ruff | |
| run: pip install ruff | |
| - name: Check lint | |
| run: ruff check sdk/src/ sdk/tests/ | |
| - name: Check formatting | |
| run: ruff format --check sdk/src/ sdk/tests/ | |
| typecheck: | |
| name: Typecheck | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: sdk/pyproject.toml | |
| - name: Install SDK with dev dependencies | |
| run: pip install -e "sdk[dev]" | |
| - name: Run mypy | |
| run: cd sdk && mypy src/ | |
| test: | |
| name: Test (Python ${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.11", "3.12", "3.13"] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: pip | |
| cache-dependency-path: sdk/pyproject.toml | |
| - name: Install SDK with dev dependencies | |
| run: pip install -e "sdk[dev]" | |
| - name: Run tests with coverage | |
| run: cd sdk && pytest --cov --cov-report=term-missing --cov-report=xml:coverage.xml | |
| - name: Upload coverage to Codecov | |
| if: matrix.python-version == '3.12' | |
| # codecov/codecov-action@v6.0.0 | |
| uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 | |
| with: | |
| files: sdk/coverage.xml | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| examples: | |
| name: Examples | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: sdk/pyproject.toml | |
| - name: Install SDK | |
| run: pip install -e sdk/ | |
| - name: Compile-check all examples | |
| run: | | |
| python -m py_compile examples/quickstart/main.py | |
| python -m py_compile examples/async-client/main.py | |
| python -m py_compile examples/live-config/main.py | |
| python -m py_compile examples/error-handling/main.py | |
| python -m py_compile examples/setup.py | |
| wheel-check: | |
| name: Wheel contents | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Build wheel | |
| run: | | |
| pip install build | |
| python -m build sdk/ --wheel --outdir /tmp/dist | |
| - name: Assert py.typed present | |
| run: | | |
| pip install zipfile36 | |
| python - <<'EOF' | |
| import zipfile, glob, sys | |
| wheels = glob.glob("/tmp/dist/*.whl") | |
| assert wheels, "no wheel found" | |
| with zipfile.ZipFile(wheels[0]) as whl: | |
| names = whl.namelist() | |
| found = [n for n in names if n.endswith("py.typed")] | |
| if not found: | |
| print("FAIL: py.typed missing from wheel"); print("\n".join(names)); sys.exit(1) | |
| print(f"OK: {found[0]}") | |
| EOF | |
| integration: | |
| name: Integration tests | |
| runs-on: ubuntu-latest | |
| if: >- | |
| github.event_name == 'workflow_dispatch' && | |
| inputs.run-integration == true | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: read | |
| packages: read | |
| steps: | |
| - name: Checkout decree-python | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Checkout decree (for docker-compose + server) | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: opendecree/decree | |
| path: decree | |
| persist-credentials: false | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: sdk/pyproject.toml | |
| - name: Install SDK with dev dependencies | |
| run: pip install -e "sdk[dev]" | |
| - name: Log in to ghcr.io | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| with: | |
| driver: docker-container | |
| driver-opts: network=host | |
| - name: Build server image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: decree | |
| file: decree/build/Dockerfile | |
| load: true | |
| tags: decree-server | |
| cache-from: | | |
| type=registry,ref=ghcr.io/opendecree/decree:buildcache | |
| type=gha,scope=py-integ-server | |
| cache-to: type=gha,scope=py-integ-server,mode=max | |
| - name: Build tools image (for migrations) | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: decree/build | |
| file: decree/build/Dockerfile.tools | |
| load: true | |
| tags: decree-tools | |
| cache-from: | | |
| type=registry,ref=ghcr.io/opendecree/decree-tools:buildcache | |
| type=gha,scope=py-integ-tools | |
| cache-to: type=gha,scope=py-integ-tools,mode=max | |
| - name: Start decree service | |
| run: docker compose -f decree/docker-compose.yml up -d --wait service | |
| env: | |
| SERVICE_IMAGE: decree-server | |
| TOOLS_IMAGE: decree-tools | |
| - name: Run integration tests | |
| run: cd sdk && pytest -m integration -v | |
| env: | |
| DECREE_TEST_ADDR: "localhost:9090" | |
| - name: Tear down services | |
| if: always() | |
| run: docker compose -f decree/docker-compose.yml down -v | |
| check: | |
| name: CI check | |
| if: always() | |
| needs: [lint, typecheck, test, examples, wheel-check] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: re-actors/alls-green@release/v1 | |
| with: | |
| jobs: ${{ toJSON(needs) }} |