Skip to content

chore(deps): sync uv and conda #180

chore(deps): sync uv and conda

chore(deps): sync uv and conda #180

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.11", "3.12", "3.13"]
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 }}"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: 📥 Download Requirements
uses: actions/download-artifact@v4
with:
name: frozen-reqs-${{ matrix.python-version }}
- name: ⚡ Install uv, git & GIS Dependencies
run: |
sudo apt-add-repository -y ppa:ubuntugis/ubuntugis-unstable
sudo apt-get update
sudo apt-get install -y curl git gpg gdal-bin libgdal-dev libproj-dev libgeos-dev g++
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
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 }}
CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt
COVERAGE_FILE: .coverage.python.${{ matrix.python-version }}
run: |
uv run pytest -v \
--cov=mapchete_hub \
--cov-report=xml:coverage.xml \
--junitxml="pytest-${{ matrix.python-version }}.xml"
- name: 📊 Upload to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
flags: py${{ matrix.python-version }}
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-all
path: .coverage.python.${{ matrix.python-version }}
include-hidden-files: true
retention-days: 1
- name: 📤 Archive JUnit Results
if: always()
uses: actions/upload-artifact@v4
with:
name: results-${{ matrix.python-version }}
path: pytest-${{ matrix.python-version }}.xml
retention-days: 1
integration-tests:
name: "🚀 Integration Tests"
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 🏃 Run Integration Tests
run: |
chmod +x ./run_integration_tests.sh
./run_integration_tests.sh
build-docker-image:
name: "🐳 Docker Build & CLI Check"
if: github.event_name == 'pull_request'
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: ⚡ Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: 🏗️ Build image for validation
uses: docker/build-push-action@v5
with:
context: .
push: false
load: true
tags: mapchete-hub:test
- name: 🏃 Run CLI checks
run: |
docker run --rm mapchete-hub:test mhub-server --help
docker run --rm mapchete-hub:test mhub-manager --help
docker run --rm mapchete-hub:test mhub-worker --help
summary:
name: "📊 Final Summary & Coverage"
needs: [test, integration-tests, build-docker-image]
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" || "${{ needs.integration-tests.result }}" != "success" || ( "${{ github.event_name }}" == "pull_request" && "${{ needs.build-docker-image.result }}" != "success" ) ]]; then
echo "❌ **Test Suite Failed**" >> $GITHUB_STEP_SUMMARY
echo "- Unit/Doc Tests: ${{ needs.test.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Integration Tests: ${{ needs.integration-tests.result }}" >> $GITHUB_STEP_SUMMARY
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "- Docker Build: ${{ needs.build-docker-image.result }}" >> $GITHUB_STEP_SUMMARY
fi
echo "Coverage check skipped because tests failed." >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "✅ **Test Suite Passed**" >> $GITHUB_STEP_SUMMARY
echo "- Unit/Doc Tests: Passed" >> $GITHUB_STEP_SUMMARY
echo "- Integration Tests: Passed" >> $GITHUB_STEP_SUMMARY
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "- Docker Build: Passed" >> $GITHUB_STEP_SUMMARY
else
echo "- Docker Build: Skipped (Not a PR)" >> $GITHUB_STEP_SUMMARY
fi
# 2. PREPARE COVERAGE DATA
uv tool install coverage
if ls all-results/.coverage* 1> /dev/null 2>&1; then
mv all-results/.coverage* .
fi
echo "Merging/Preparing coverage data..."
# combine will merge .coverage.* into .coverage
uv tool run coverage combine --append || echo "No extra coverage files to combine."
# 3. ENFORCE 70%
REPORT_OUTPUT=$(uv tool run coverage report --show-missing --fail-under=70 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 70%." >> $GITHUB_STEP_SUMMARY
exit $EXIT_CODE
else
echo "✅ **Coverage Passed:** 70% coverage achieved (Py3.13)." >> $GITHUB_STEP_SUMMARY
fi