266 lines
8.7 KiB
YAML
266 lines
8.7 KiB
YAML
name: Test Python SDK
|
|
|
|
on:
|
|
push:
|
|
branches: [master, next]
|
|
paths:
|
|
- 'python/**/*.py'
|
|
- '.github/workflows/py.test.yml'
|
|
- '.github/actions/setup-python-uv/action.yml'
|
|
- 'mise.toml'
|
|
- 'mise.lock'
|
|
- 'toolchain-versions.json'
|
|
- 'python/pyproject.toml'
|
|
- 'python/requirements*.txt'
|
|
pull_request:
|
|
branches: [master, next]
|
|
paths:
|
|
- 'python/**/*.py'
|
|
- '.github/workflows/py.test.yml'
|
|
- '.github/actions/setup-python-uv/action.yml'
|
|
- 'mise.toml'
|
|
- 'mise.lock'
|
|
- 'toolchain-versions.json'
|
|
- 'python/pyproject.toml'
|
|
- 'python/requirements*.txt'
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
|
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
toolchain-versions:
|
|
name: Read toolchain test matrix
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
python: ${{ steps.versions.outputs.python }}
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
|
|
- name: Read versions
|
|
id: versions
|
|
run: echo "python=$(jq -c '.python' toolchain-versions.json)" >> "$GITHUB_OUTPUT"
|
|
|
|
test:
|
|
name: Test Python SDK
|
|
needs: toolchain-versions
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
python-version: ${{ fromJSON(needs.toolchain-versions.outputs.python) }}
|
|
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
|
|
- name: Set up Python ${{ matrix.python-version }}
|
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
|
with:
|
|
python-version: ${{ matrix.python-version }}
|
|
|
|
- name: Cache uv dependencies
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: ~/.cache/uv
|
|
key: uv-${{ matrix.python-version }}-${{ hashFiles('python/pyproject.toml', 'mise.toml') }}
|
|
restore-keys: |
|
|
uv-${{ matrix.python-version }}-
|
|
|
|
- name: Install UV
|
|
run: |
|
|
UV_VERSION="$(sed -n 's/^uv[[:space:]]*=[[:space:]]*"\([^"]*\)"/\1/p' mise.toml)"
|
|
pip install "uv==${UV_VERSION}"
|
|
|
|
- name: Install Dependencies
|
|
run: |
|
|
cd python/
|
|
uv venv --python ${{ matrix.python-version }}
|
|
source .venv/bin/activate
|
|
uv pip install -e .
|
|
uv pip install -e providers/langchain
|
|
uv pip install -e providers/autogen
|
|
uv pip install pytest pytest-mock
|
|
|
|
- name: Run Import Tests
|
|
run: |
|
|
cd python/
|
|
source .venv/bin/activate
|
|
python -c "from composio import Composio; print('✓ Basic import successful')"
|
|
# Guards against the autogen provider becoming un-importable on a fresh
|
|
# install (e.g. a broken framework dependency). A hard import here fails
|
|
# loudly, unlike the importorskip-guarded unit tests, which would skip.
|
|
python -c "import composio_autogen; print('✓ Autogen provider import successful')"
|
|
|
|
- name: Run Unit Tests
|
|
run: |
|
|
cd python/
|
|
source .venv/bin/activate
|
|
python -m pytest tests/ -v --tb=short
|
|
|
|
- name: Test Package Installation
|
|
run: |
|
|
cd python/
|
|
# Test that the package can be installed and imported in a fresh environment
|
|
uv venv test-env --python ${{ matrix.python-version }}
|
|
source test-env/bin/activate
|
|
uv pip install -e .
|
|
python -c "
|
|
from composio import Composio, ToolkitVersionParam
|
|
from composio.types import Modifiers
|
|
from composio.core.types import ToolkitVersion
|
|
print('✓ All critical imports successful')
|
|
"
|
|
|
|
test-circular-imports:
|
|
name: Test Circular Import Prevention
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
|
|
- name: Setup Python with UV
|
|
uses: ./.github/actions/setup-python-uv
|
|
|
|
- name: Install Dependencies
|
|
run: |
|
|
cd python/
|
|
uv venv
|
|
source .venv/bin/activate
|
|
uv pip install -e .
|
|
|
|
- name: Test Circular Import Prevention
|
|
run: |
|
|
cd python/
|
|
source .venv/bin/activate
|
|
python -c "
|
|
# Test various import combinations that previously caused circular imports
|
|
import sys
|
|
|
|
# Test 1: Basic imports
|
|
from composio import Composio
|
|
print('✓ Basic Composio import')
|
|
|
|
# Test 2: Import toolkit version types
|
|
from composio import ToolkitVersionParam
|
|
from composio.core.types import ToolkitVersion
|
|
print('✓ Toolkit version types import')
|
|
|
|
# Test 3: Import from types module
|
|
from composio.types import Modifiers
|
|
print('✓ Types module import')
|
|
|
|
# Test 4: Import core models
|
|
from composio.core.models.tools import Tools
|
|
print('✓ Core models import')
|
|
|
|
# Test 5: Cross-module imports that caused the original circular import
|
|
from composio.core.models.tools import Modifiers as CoreModifiers
|
|
from composio.types import Modifiers as TypesModifiers
|
|
assert CoreModifiers is TypesModifiers
|
|
print('✓ Cross-module import consistency')
|
|
|
|
print('✓ All circular import prevention tests passed!')
|
|
"
|
|
|
|
lint-and-format:
|
|
name: Lint and Format Check
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
|
|
- name: Setup Python with UV
|
|
uses: ./.github/actions/setup-python-uv
|
|
|
|
- name: Install Dependencies
|
|
run: |
|
|
cd python/
|
|
uv venv
|
|
source .venv/bin/activate
|
|
uv pip install -e .
|
|
uv pip install ruff
|
|
|
|
- name: Run Ruff Linter
|
|
run: |
|
|
cd python/
|
|
source .venv/bin/activate
|
|
ruff check --config config/ruff.toml composio/ tests/
|
|
|
|
- name: Run Ruff Formatter Check
|
|
run: |
|
|
cd python/
|
|
source .venv/bin/activate
|
|
ruff format --check --config config/ruff.toml composio/ tests/
|
|
|
|
integration-tests:
|
|
name: Integration Tests
|
|
runs-on: ubuntu-22.04 # Use Ubuntu 22.04 for stability
|
|
permissions: read-all
|
|
env:
|
|
COMPOSIO_API_KEY: ${{ secrets.COMPOSIO_API_KEY }}
|
|
COMPOSIO_BASE_URL: ${{ secrets.COMPOSIO_BASE_URL_STAGING }}
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
|
|
- name: Install UV
|
|
id: setup-python
|
|
uses: ./.github/actions/setup-python-uv
|
|
|
|
- name: Cache UV dependencies
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: ~/.cache/uv
|
|
key: uv-${{ hashFiles('mise.lock') }}-py${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('python/pyproject.toml') }}
|
|
restore-keys: |
|
|
uv-${{ hashFiles('mise.lock') }}-py${{ steps.setup-python.outputs.python-version }}-
|
|
|
|
- name: Install Python Dependencies
|
|
working-directory: ./python
|
|
run: |
|
|
# Let UV manage Python version to satisfy workspace requirements
|
|
uv sync --group dev
|
|
|
|
- name: Check API key
|
|
id: api-key
|
|
run: |
|
|
if [ -z "$COMPOSIO_API_KEY" ]; then
|
|
echo "available=false" >> "$GITHUB_OUTPUT"
|
|
if [ "$GITHUB_ACTOR" = "dependabot[bot]" ]; then
|
|
echo "::notice::Skipping secret-backed Python integration tests for Dependabot; missing COMPOSIO_API_KEY."
|
|
exit 0
|
|
fi
|
|
|
|
echo "::error::COMPOSIO_API_KEY is not set"
|
|
exit 1
|
|
fi
|
|
|
|
echo "available=true" >> "$GITHUB_OUTPUT"
|
|
echo "✅ API key is configured"
|
|
|
|
- name: Run Integration Tests
|
|
if: steps.api-key.outputs.available == 'true'
|
|
working-directory: ./python
|
|
run: |
|
|
echo "🧪 Running Integration Tests..."
|
|
# Run with per-test timeout of 2 minutes and overall timeout
|
|
# pytest-timeout should be installed via pyproject.toml dev dependencies
|
|
uv run pytest composio/integration_test/ -v --tb=short --maxfail=3 --timeout=120 --timeout-method=thread
|
|
timeout-minutes: 10
|
|
|
|
- name: Upload Test Results
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: integration-test-results
|
|
path: |
|
|
python/composio/integration_test/
|
|
retention-days: 7
|