# Python Test Pipeline Template A reusable Gitea Actions workflow for running Python tests with pytest, including optional coverage reporting and PR comment integration. ## Features - **Pytest testing** with configurable arguments - **Coverage reporting** with pytest-cov - **PR comment integration** for coverage reports - **UV package management** support - **Flexible configuration** with optional steps and customizable inputs - **Monorepo support** with working directory configuration ## Usage ### Basic Usage Create a workflow file in your repository (e.g., `.github/workflows/test.yml`): ```yaml name: Tests on: push: branches: [main] pull_request: jobs: test: uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@v1.0.0 with: coverage-package: "my_package" ``` ### Advanced Usage with PR Comments ```yaml name: Tests on: push: branches: [main] pull_request: jobs: test: uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@v1.0.0 with: python-version: "3.11" coverage-package: "data_store" pytest-args: "--verbose --tb=short" api-url: "https://gitea.gt-proj.com/api/v1" secrets: CI_RUNNER_TOKEN: ${{ secrets.CI_RUNNER_TOKEN }} ``` ### Examples ### Skip coverage reporting ```yaml jobs: test: uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@v1.0.0 with: pytest-args: "--verbose" ``` ### Custom pytest configuration ```yaml jobs: test: uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@v1.0.0 with: coverage-package: "myapp" pytest-args: "--maxfail=1 --tb=short -x" uv-extras: "test,dev" ``` ### Monorepo with specific working directory ```yaml jobs: backend-tests: uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@v1.0.0 with: working-directory: "./backend" coverage-package: "backend_api" ml-service-tests: uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@v1.0.0 with: working-directory: "./ml-service" coverage-package: "ml_models" python-version: "3.11" ``` ## Available Inputs | Input | Description | Required | Default | Type | |-------|-------------|----------|---------|------| | `python-version` | Python version to use (e.g., "3.12") | No | "3.12" | string | | `working-directory` | Working directory for the project | No | "." | string | | `uv-extras` | UV extras to install (e.g., "dev,test") | No | "all-extras" | string | | `pytest-args` | Additional arguments to pass to pytest | No | "" | string | | `coverage-package` | Package name for coverage reporting | No | "" | string | | `skip-coverage-comment` | Skip posting coverage comment to PR | No | false | boolean | | `api-url` | Gitea API URL for posting comments | No | "" | string | ## Available Secrets | Secret | Description | Required | |--------|-------------|----------| | `CI_RUNNER_TOKEN` | Token for posting PR comments | No* | *Required only if you want coverage comments on PRs ## Coverage Reporting ### Enabling Coverage Set the `coverage-package` input to your main package name: ```yaml with: coverage-package: "my_package" ``` This will: 1. Run pytest with `--cov=my_package --cov-report=term-missing` 2. Generate a coverage report 3. Save the output to `coverage.txt` ### PR Comments To enable coverage comments on pull requests: 1. **Set required inputs:** ```yaml with: coverage-package: "my_package" api-url: "https://your-gitea-instance.com/api/v1" ``` 2. **Provide the CI token secret:** ```yaml secrets: CI_RUNNER_TOKEN: ${{ secrets.CI_RUNNER_TOKEN }} ``` 3. **Create the token in Gitea:** - Go to your Gitea instance → Settings → Applications → Generate New Token - Grant `repo` permissions - Add it as a repository secret named `CI_RUNNER_TOKEN` ### Coverage Comment Format The coverage comment will appear on PRs like this: ``` **Test Coverage Report:** ``` Name Stmts Miss Cover Missing ------------------------------------------------- my_package/__init__.py 12 2 83% 45-46 my_package/utils.py 25 0 100% ------------------------------------------------- TOTAL 37 2 95% ``` ## Pytest Configuration The workflow respects your project's pytest configuration: - **pytest.ini** - Standard pytest configuration - **pyproject.toml** - Modern Python project configuration - **setup.cfg** - Legacy configuration Example `pyproject.toml` configuration: ```toml [tool.pytest.ini_options] testpaths = ["tests"] python_files = ["test_*.py", "*_test.py"] python_classes = ["Test*"] python_functions = ["test_*"] addopts = [ "--strict-markers", "--strict-config", "--verbose", ] markers = [ "slow: marks tests as slow", "unit: marks tests as unit tests", "integration: marks tests as integration tests", ] ``` ## Requirements - Repository must be public or you must have access to the template repository - Python project with `pyproject.toml` and UV for dependency management - Test dependencies should be specified in your project's extras (e.g., `test`, `dev`) - For coverage comments: Gitea API access and `CI_RUNNER_TOKEN` secret ## Dependencies The workflow expects these to be available in your project's test dependencies: - **pytest**: Test runner - **pytest-cov**: Coverage plugin (if using coverage reporting) Example `pyproject.toml` dependencies: ```toml [project.optional-dependencies] test = [ "pytest>=7.0.0", "pytest-cov>=4.0.0", "pytest-mock>=3.10.0", ] ``` ## Troubleshooting ### Coverage not working 1. Ensure `coverage-package` matches your actual package name 2. Check that `pytest-cov` is installed in your test dependencies 3. Verify your package is importable (check `PYTHONPATH`) ### PR comments not appearing 1. Verify `api-url` is correct (should include `/api/v1`) 2. Check `CI_RUNNER_TOKEN` secret exists and has repo permissions 3. Ensure the workflow runs on `pull_request` events 4. Verify coverage is being generated (`coverage-package` is set) ### Tests not found 1. Check your `pytest` configuration in `pyproject.toml` or `pytest.ini` 2. Verify test files follow naming conventions (`test_*.py` or `*_test.py`) 3. Use `pytest-args` to specify custom test discovery options ## Contributing To update this template, modify the workflow file and ensure all changes are backward compatible or properly versioned using git tags.