Python package test #325
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Python package test | |
| on: | |
| schedule: | |
| - cron: '0 8 * * 1,4' | |
| push: | |
| branches: [main] | |
| tags: ['*'] | |
| pull_request: | |
| branches: ['**'] | |
| workflow_call: | |
| inputs: | |
| override-deps-artifact: | |
| description: "Name of artifact containing updated lockfiles" | |
| required: false | |
| type: string | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| lint: | |
| name: "📝 Pre-commit / Code Quality" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: ⚡ Install uv | |
| run: curl -LsSf https://astral.sh/uv/install.sh | sh | |
| - name: 🏃 Run Pre-commit | |
| run: | | |
| uv tool install pre-commit | |
| uv tool run pre-commit run --show-diff-on-failure --all-files | |
| setup: | |
| name: "🏗️ Build Py${{ matrix.python-version }}" | |
| needs: lint | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ["3.10", "3.11", "3.12", "3.13"] | |
| container: ghcr.io/osgeo/gdal:ubuntu-small-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: 📥 Apply Dependency Overrides | |
| if: "${{ inputs.override-deps-artifact != '' && inputs.override-deps-artifact != 'null' }}" | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ inputs.override-deps-artifact }} | |
| - name: ⚡ Install uv | |
| run: | | |
| apt-get update && apt-get install -y curl | |
| curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh | |
| - name: 📝 Export Locked Requirements | |
| run: | | |
| uv export --frozen --all-extras --format requirements-txt > requirements.txt | |
| - name: 📤 Upload Requirements | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: frozen-reqs-${{ matrix.python-version }} | |
| path: requirements.txt | |
| retention-days: 1 | |
| test: | |
| needs: setup | |
| name: "🧪 py${{ matrix.python-version }} [${{ matrix.split }}/4]" | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.10", "3.11", "3.12", "3.13"] | |
| split: [1, 2, 3, 4] | |
| container: ghcr.io/osgeo/gdal:ubuntu-small-latest | |
| steps: | |
| - name: ⚡ Prepare Container | |
| run: | | |
| apt-get update | |
| apt-get install -y curl git gpg | |
| # Fix "Dubious Ownership" error (Required for containerized Git) | |
| git config --global --add safe.directory '*' | |
| - uses: actions/checkout@v4 | |
| - name: 📥 Download Requirements | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: frozen-reqs-${{ matrix.python-version }} | |
| - name: ⚡ Install uv | |
| run: | | |
| curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh | |
| uv --version | |
| - name: 🏗️ Restore Native Env | |
| run: | | |
| uv venv --python ${{ matrix.python-version }} | |
| uv pip install -r requirements.txt | |
| uv pip install -e ".[test]" --no-deps | |
| - name: 🧪 Run Tests (Split ${{ matrix.split }}/4) | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| AWS_REQUEST_PAYER: ${{ vars.AWS_REQUEST_PAYER }} | |
| AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} | |
| CDSE_S3_ACCESS_KEY: ${{ secrets.CDSE_S3_ACCESS_KEY }} | |
| CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} | |
| CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt | |
| COVERAGE_FILE: .coverage.python.${{ matrix.python-version }}.test.split.${{ matrix.split }} | |
| run: | | |
| uv run pytest -v \ | |
| --splits 4 \ | |
| --group ${{ matrix.split }} \ | |
| --cov=mapchete_eo \ | |
| --cov-report=xml:coverage.xml \ | |
| --junitxml="pytest-${{ matrix.python-version }}-${{ matrix.split }}.xml" | |
| - name: 📊 Upload to Codecov | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./coverage.xml | |
| flags: py${{ matrix.python-version }}-split${{ matrix.split }} | |
| fail_ci_if_error: true | |
| - name: 📤 Upload Coverage Chunk (Latest Only) | |
| if: matrix.python-version == '3.13' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-chunk-${{ matrix.split }} | |
| path: .coverage.python.${{ matrix.python-version }}.test.split.${{ matrix.split }} | |
| include-hidden-files: true | |
| retention-days: 1 | |
| - name: 📤 Archive JUnit Results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: results-${{ matrix.python-version }}-${{ matrix.split }} | |
| path: pytest-${{ matrix.python-version }}-${{ matrix.split }}.xml | |
| retention-days: 1 | |
| summary: | |
| name: "📊 Final Summary & Coverage" | |
| needs: test | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 # Needed for coverage to see source files | |
| - name: ⚡ Install uv | |
| run: curl -LsSf https://astral.sh/uv/install.sh | sh | |
| - name: 📥 Download Artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: all-results | |
| pattern: "*-*" | |
| merge-multiple: true | |
| - name: 📊 Check Tests & Coverage | |
| run: | | |
| echo "### 🧪 Test & Coverage Summary" >> $GITHUB_STEP_SUMMARY | |
| if [[ "${{ needs.test.result }}" != "success" ]]; then | |
| echo "❌ **Test Suite Failed**" >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| fi | |
| uv tool install coverage | |
| if ls all-results/.coverage* 1> /dev/null 2>&1; then | |
| mv all-results/.coverage* . | |
| fi | |
| cat <<EOF > .coveragerc | |
| [run] | |
| relative_files = True | |
| [paths] | |
| source = | |
| . | |
| /__w/mapchete-eo/mapchete-eo/ | |
| EOF | |
| echo "Merging coverage files with path remapping..." | |
| # 2️⃣ COMBINE & REPORT | |
| # We use the rcfile to ensure the mapping is applied during the merge | |
| uv tool run coverage combine --append --rcfile=.coveragerc || echo "No extra coverage files to combine." | |
| # ENFORCE 85% (or your chosen threshold) | |
| REPORT_OUTPUT=$(uv tool run coverage report --show-missing --fail-under=85 2>&1) | |
| EXIT_CODE=$? | |
| echo "$REPORT_OUTPUT" | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "$REPORT_OUTPUT" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| if [ $EXIT_CODE -ne 0 ]; then | |
| echo "❌ **Coverage Failed:** Python 3.13 coverage is below 85%." >> $GITHUB_STEP_SUMMARY | |
| exit $EXIT_CODE | |
| else | |
| echo "✅ **Coverage Passed:** 85% coverage achieved (Py3.13)." >> $GITHUB_STEP_SUMMARY | |
| fi |