# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. name: Continuous Integration on: push: branches: [main, v1] paths: - '**.py' - '.pre-commit-config.yaml' - 'pyproject.toml' - 'tests/**' pull_request: branches: [main, v1] paths: - '**.py' - '.pre-commit-config.yaml' - 'pyproject.toml' - 'tests/**' permissions: contents: read jobs: # 1. Code format and linting (Linter) lint: name: Pre-commit Linter runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v6 - name: Run pre-commit checks uses: pre-commit/action@v3.0.1 # 2. Static type analysis (Mypy Check with Matrix) # Compares new changes against the target base branch dynamically to support v1. type-check: name: Mypy Check (Python ${{ matrix.python-version }}) runs-on: ubuntu-latest strategy: fail-fast: false matrix: python-version: ['3.10', '3.11', '3.12', '3.13'] steps: - name: Checkout code uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true - name: Generate Baseline env: TARGET_BRANCH: ${{ github.base_ref || github.ref_name }} run: | # Switch to target base branch to generate baseline git checkout origin/$TARGET_BRANCH git checkout ${{ github.sha }} -- pyproject.toml # Install dependencies for target branch uv venv .venv source .venv/bin/activate uv sync --all-extras # Run mypy, filter for errors only, remove line numbers, and sort # We ignore exit code (|| true) because we expect errors on baseline uv run mypy . | grep "error:" | sed 's/:\([0-9]\+\):/::/g' | sort > baseline_errors.txt || true echo "Found $(wc -l < baseline_errors.txt) errors on $TARGET_BRANCH." - name: Check PR Branch run: | # Switch back to the PR commit git checkout ${{ github.sha }} # Re-sync dependencies in case the PR changed them source .venv/bin/activate uv sync --all-extras # Run mypy on PR code, apply same processing uv run mypy . | grep "error:" | sed 's/:\([0-9]\+\):/::/g' | sort > pr_errors.txt || true echo "Found $(wc -l < pr_errors.txt) errors on PR branch." - name: Compare and Fail on New Errors run: | # 'comm -13' suppresses unique lines in file1 (baseline) and common lines, # leaving only lines unique to file2 (PR) -> The new errors. comm -13 baseline_errors.txt pr_errors.txt > new_errors.txt if [ -s new_errors.txt ]; then echo "::error::The following NEW mypy errors were introduced:" cat new_errors.txt exit 1 else echo "Great job! No new mypy errors introduced." fi # 3a. Unit testing (Unit Tests with Matrix) unit-test: name: Unit Tests (Python ${{ matrix.python-version }}) runs-on: ubuntu-latest strategy: fail-fast: false matrix: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] timeout-minutes: 10 steps: - name: Checkout code uses: actions/checkout@v6 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Install the latest version of uv uses: astral-sh/setup-uv@v7 with: enable-cache: true - name: Install dependencies run: | uv venv .venv source .venv/bin/activate uv sync --extra test - name: Run unit tests with pytest run: | source .venv/bin/activate pytest tests/unittests \ -n auto \ --ignore=tests/unittests/artifacts/test_artifact_service.py \ --ignore=tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py # 3b. Dual-version A2A coverage: This job pins a2a-sdk to 0.3.x and # runs only the A2A-related tests, so the a2a/_compat.py shim stays # verified against both SDK majors. # TODO: Remove this 0.3.x re-run once a2a-sdk 0.3.x support is dropped. unit-test-a2a-v0-3: name: A2A v0.3 Tests (Python ${{ matrix.python-version }}) runs-on: ubuntu-latest strategy: fail-fast: false matrix: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] timeout-minutes: 10 steps: - name: Checkout code uses: actions/checkout@v6 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Install the latest version of uv uses: astral-sh/setup-uv@v7 with: enable-cache: true - name: Install dependencies run: | uv venv .venv source .venv/bin/activate uv sync --extra test - name: Run A2A tests against a2a-sdk v0.3 run: | source .venv/bin/activate uv pip install --reinstall-package a2a-sdk 'a2a-sdk>=0.3.4,<0.4' pytest tests/unittests/a2a \ tests/unittests/agents/test_remote_a2a_agent.py \ tests/unittests/integrations/agent_registry/test_agent_registry.py