248 lines
6.4 KiB
Markdown
248 lines
6.4 KiB
Markdown
# 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@main
|
|
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@main
|
|
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@main
|
|
with:
|
|
pytest-args: "--verbose"
|
|
```
|
|
|
|
### Custom pytest configuration
|
|
|
|
```yaml
|
|
jobs:
|
|
test:
|
|
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@main
|
|
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@main
|
|
with:
|
|
working-directory: "./backend"
|
|
coverage-package: "backend_api"
|
|
|
|
ml-service-tests:
|
|
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@main
|
|
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. |