Skip to content

chore: update uv.lock and conda recipe (#72) #364

chore: update uv.lock and conda recipe (#72)

chore: update uv.lock and conda recipe (#72) #364

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
# 1. CHECK OVERALL TEST STATUS
if [[ "${{ needs.test.result }}" != "success" ]]; then
echo "❌ **Test Suite Failed**" >> $GITHUB_STEP_SUMMARY
echo "Coverage check skipped because tests failed." >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "✅ **Test Suite Passed**" >> $GITHUB_STEP_SUMMARY
# 2. COMBINE COVERAGE (Only 3.13 files exist here)
uv tool install coverage
# Move the specific files to root
mv all-results/.coverage* .
# 🧹 Delete any empty (0-byte) coverage files that cause exit code 2
echo "Cleaning up empty or invalid coverage artifacts..."
find . -maxdepth 1 -name ".coverage*" -size 0 -print -delete
echo "Merging coverage files..."
# Disable automatic exit on error temporarily so we can catch the crash
set +e
uv tool run coverage combine
COMBINE_EXIT=$?
set -e
# 🐞 If it still fails, run it again in debug mode so the logs show the exact corrupted file or path issue
if [ $COMBINE_EXIT -ne 0 ]; then
echo "❌ 'coverage combine' crashed! Running with debug trace..."
uv tool run coverage combine --debug=data,sys,pathmap
exit $COMBINE_EXIT
fi
# 3. ENFORCE 80%
echo "Generating coverage report..."
# Temporarily disable exit-on-error so a failed report doesn't kill the script!
set +e
OUTPUT=$(uv tool run coverage report --show-missing --fail-under=80 2>&1)
EXIT_CODE=$?
set -e
echo "$OUTPUT"
echo '```' >> $GITHUB_STEP_SUMMARY
echo "$OUTPUT" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
# 🔗 GENERATE DYNAMIC CODECOV LINK
CODECOV_URL="https://app.codecov.io/github/${{ github.repository }}/commit/${{ github.sha }}"
echo "🔗 **[View full line-by-line report on Codecov]($CODECOV_URL)**" >> $GITHUB_STEP_SUMMARY
if [ $EXIT_CODE -ne 0 ]; then
echo "❌ **Coverage Failed:** Python 3.13 coverage check failed." >> $GITHUB_STEP_SUMMARY
exit $EXIT_CODE
else
echo "✅ **Coverage Passed:** 80% coverage achieved (Py3.13)." >> $GITHUB_STEP_SUMMARY
exit 0
fi