|
| 1 | +# GitHub Actions Workflows |
| 2 | + |
| 3 | +This directory contains GitHub Actions workflows for automated testing and CI/CD. |
| 4 | + |
| 5 | +## Workflows |
| 6 | + |
| 7 | +### `test.yml` - Main Test Suite |
| 8 | + |
| 9 | +Runs on every push and pull request to main branches. Includes: |
| 10 | + |
| 11 | +- **test-cpu**: Unit tests on CPU across Python 3.10, 3.11, and 3.12 |
| 12 | + - Uses PyTorch CPU version to avoid GPU dependencies |
| 13 | + - Runs tests marked with `unit` and excludes GPU-requiring tests |
| 14 | + - Generates coverage reports |
| 15 | + |
| 16 | +- **test-gpu**: Tests on self-hosted GPU runners (if available) |
| 17 | + - Uses PyTorch with CUDA 12.6 support |
| 18 | + - Runs all tests except those marked as slow |
| 19 | + - Requires self-hosted runner with `[self-hosted, linux, gpu]` labels |
| 20 | + |
| 21 | +- **test-integration**: Integration tests on CPU |
| 22 | + - Runs after CPU tests pass |
| 23 | + - Tests marked with `integration` marker |
| 24 | + |
| 25 | +- **code-quality**: Static code analysis |
| 26 | + - Black, isort, ruff, flake8 checks |
| 27 | + - Does not fail the build (continue-on-error: true) |
| 28 | + |
| 29 | +### `test-slow.yml` - Long-Running Tests |
| 30 | + |
| 31 | +Runs nightly or on manual trigger. Includes: |
| 32 | + |
| 33 | +- **test-slow-gpu**: Slow tests requiring GPU |
| 34 | + - Tests marked with `slow` marker |
| 35 | + - Extended timeout (3600 seconds) |
| 36 | + - Uses self-hosted GPU runners |
| 37 | + |
| 38 | +## Caching Strategy |
| 39 | + |
| 40 | +The workflows use multiple caching layers to speed up builds: |
| 41 | + |
| 42 | +1. **Python package cache** via `setup-python` action |
| 43 | + - Caches pip packages based on `pyproject.toml` hash |
| 44 | + |
| 45 | +2. **Additional pip cache** via `actions/cache` |
| 46 | + - Caches `~/.cache/pip` directory |
| 47 | + - Separate keys for CPU, GPU, and integration tests |
| 48 | + - Hierarchical restore keys for fallback |
| 49 | + |
| 50 | +## GPU Support |
| 51 | + |
| 52 | +### Self-Hosted Runners |
| 53 | + |
| 54 | +GPU tests require self-hosted runners with: |
| 55 | +- Linux OS |
| 56 | +- NVIDIA GPU with CUDA 12.6+ support |
| 57 | +- Runner labels: `[self-hosted, linux, gpu]` |
| 58 | + |
| 59 | +### Setting Up Self-Hosted GPU Runners |
| 60 | + |
| 61 | +1. **Install GitHub Actions Runner**: |
| 62 | + ```bash |
| 63 | + # Download and configure runner from GitHub repository Settings > Actions > Runners |
| 64 | + ``` |
| 65 | + |
| 66 | +2. **Install NVIDIA Drivers and CUDA**: |
| 67 | + ```bash |
| 68 | + # Install NVIDIA drivers |
| 69 | + sudo apt-get install nvidia-driver-535 |
| 70 | + |
| 71 | + # Install CUDA toolkit 12.6 |
| 72 | + wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.0-1_all.deb |
| 73 | + sudo dpkg -i cuda-keyring_1.0-1_all.deb |
| 74 | + sudo apt-get update |
| 75 | + sudo apt-get install cuda-toolkit-12-6 |
| 76 | + ``` |
| 77 | + |
| 78 | +3. **Configure Runner Labels**: |
| 79 | + - Add labels: `self-hosted`, `linux`, `gpu` |
| 80 | + - Verify GPU is accessible: `nvidia-smi` |
| 81 | + |
| 82 | +4. **Start the Runner**: |
| 83 | + ```bash |
| 84 | + ./run.sh |
| 85 | + ``` |
| 86 | + |
| 87 | +### GitHub-Hosted Runners |
| 88 | + |
| 89 | +GitHub-hosted runners do **not** have GPU support. GPU tests will be skipped automatically if no self-hosted runners are available (`continue-on-error: true`). |
| 90 | + |
| 91 | +## Test Dependencies |
| 92 | + |
| 93 | +Test dependencies are installed from `pyproject.toml`: |
| 94 | + |
| 95 | +```bash |
| 96 | +pip install -e ".[test]" |
| 97 | +``` |
| 98 | + |
| 99 | +This installs: |
| 100 | +- pytest >= 7.0.0 |
| 101 | +- pytest-cov >= 4.0.0 |
| 102 | +- pytest-xdist >= 3.0.0 |
| 103 | +- pytest-timeout >= 2.0.0 |
| 104 | +- coverage[toml] >= 7.0.0 |
| 105 | + |
| 106 | +## Test Markers |
| 107 | + |
| 108 | +Tests should be marked appropriately: |
| 109 | + |
| 110 | +```python |
| 111 | +import pytest |
| 112 | + |
| 113 | +@pytest.mark.unit |
| 114 | +def test_simple_function(): |
| 115 | + """Fast unit test""" |
| 116 | + pass |
| 117 | + |
| 118 | +@pytest.mark.integration |
| 119 | +def test_full_pipeline(): |
| 120 | + """Integration test""" |
| 121 | + pass |
| 122 | + |
| 123 | +@pytest.mark.slow |
| 124 | +def test_long_running(): |
| 125 | + """Long-running test""" |
| 126 | + pass |
| 127 | + |
| 128 | +@pytest.mark.requires_gpu |
| 129 | +def test_gpu_function(): |
| 130 | + """Test requiring GPU""" |
| 131 | + if not torch.cuda.is_available(): |
| 132 | + pytest.skip("GPU not available") |
| 133 | + pass |
| 134 | +``` |
| 135 | + |
| 136 | +## Running Tests Locally |
| 137 | + |
| 138 | +### CPU Tests |
| 139 | +```bash |
| 140 | +# Install dependencies |
| 141 | +pip install -e ".[test]" |
| 142 | + |
| 143 | +# Run unit tests |
| 144 | +pytest tests/ -m "unit and not requires_gpu" |
| 145 | + |
| 146 | +# Run with coverage |
| 147 | +pytest tests/ -m "unit and not requires_gpu" --cov=physiomotion4d |
| 148 | +``` |
| 149 | + |
| 150 | +### GPU Tests |
| 151 | +```bash |
| 152 | +# Install with CUDA support |
| 153 | +pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126 |
| 154 | +pip install -e ".[test]" |
| 155 | + |
| 156 | +# Run all tests (including GPU) |
| 157 | +pytest tests/ -m "not slow" |
| 158 | + |
| 159 | +# Run slow tests |
| 160 | +pytest tests/ -m "slow" |
| 161 | +``` |
| 162 | + |
| 163 | +## Coverage Reports |
| 164 | + |
| 165 | +Coverage reports are: |
| 166 | +1. Uploaded to Codecov (if configured) |
| 167 | +2. Stored as artifacts for 7 days |
| 168 | +3. Available as HTML reports in the `htmlcov/` directory |
| 169 | + |
| 170 | +## Troubleshooting |
| 171 | + |
| 172 | +### GPU Tests Not Running |
| 173 | + |
| 174 | +If GPU tests are not running: |
| 175 | +1. Verify self-hosted runner is online: Settings > Actions > Runners |
| 176 | +2. Check runner labels include `gpu` |
| 177 | +3. Verify `nvidia-smi` works on the runner |
| 178 | +4. Check workflow logs for runner assignment |
| 179 | + |
| 180 | +### Cache Not Working |
| 181 | + |
| 182 | +If builds are slow: |
| 183 | +1. Check cache hit/miss in workflow logs |
| 184 | +2. Verify `pyproject.toml` hasn't changed unexpectedly |
| 185 | +3. Try clearing caches: Settings > Actions > Caches |
| 186 | + |
| 187 | +### Test Failures |
| 188 | + |
| 189 | +For test failures: |
| 190 | +1. Check individual test logs in the workflow run |
| 191 | +2. Run tests locally to reproduce |
| 192 | +3. Use `pytest -v --tb=long` for detailed error traces |
| 193 | +4. Check if tests are marked correctly (unit/integration/slow/requires_gpu) |
| 194 | + |
0 commit comments