feat: Just-in-time plugin installation #6459
Workflow file for this run
This file contains 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: Tests | |
on: | |
pull_request: | |
paths: | |
- src/** | |
- tests/** | |
- noxfile.py | |
- poetry.lock | |
- pyproject.toml | |
- .github/workflows/test.yml | |
- .github/workflows/resources/constraints.txt | |
push: | |
branches: [main] | |
paths: | |
- src/** | |
- tests/** | |
- noxfile.py | |
- poetry.lock | |
- pyproject.toml | |
- .github/workflows/test.yml | |
- .github/workflows/resources/constraints.txt | |
workflow_dispatch: | |
inputs: {} | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
cancel-in-progress: true | |
jobs: | |
tests: | |
strategy: | |
matrix: | |
include: | |
- { id: '01', python-version: '3.8', os: ubuntu-latest, backend-db: sqlite } | |
- { id: '02', python-version: '3.9', os: ubuntu-latest, backend-db: sqlite } | |
- { id: '03', python-version: '3.10', os: ubuntu-latest, backend-db: sqlite } | |
- { id: '04', python-version: '3.11', os: ubuntu-latest, backend-db: sqlite } | |
- { id: '05', python-version: '3.12', os: ubuntu-latest, backend-db: sqlite } | |
- { id: '06', python-version: '3.8', os: ubuntu-latest, backend-db: postgresql } | |
- { id: '07', python-version: '3.9', os: ubuntu-latest, backend-db: postgresql } | |
- { id: '08', python-version: '3.10', os: ubuntu-latest, backend-db: postgresql } | |
- { id: '09', python-version: '3.11', os: ubuntu-latest, backend-db: postgresql } | |
- { id: '10', python-version: '3.12', os: ubuntu-latest, backend-db: postgresql } | |
- { id: '11', python-version: '3.8', os: ubuntu-latest, backend-db: mssql } | |
- { id: '12', python-version: '3.9', os: ubuntu-latest, backend-db: mssql } | |
- { id: '13', python-version: '3.10', os: ubuntu-latest, backend-db: mssql } | |
- { id: '14', python-version: '3.11', os: ubuntu-latest, backend-db: mssql } | |
- { id: '15', python-version: '3.12', os: ubuntu-latest, backend-db: mssql } | |
# We'd like to run Windows tests for all backend-dbs see https://github.com/meltano/meltano/issues/6281 | |
- { id: '16', python-version: '3.8', os: windows-2022, backend-db: sqlite } | |
- { id: '17', python-version: '3.9', os: windows-2022, backend-db: sqlite } | |
- { id: '18', python-version: '3.10', os: windows-2022, backend-db: sqlite } | |
- { id: '19', python-version: '3.11', os: windows-2022, backend-db: sqlite } | |
- { id: '20', python-version: '3.12', os: windows-2022, backend-db: sqlite } | |
- { id: '21', python-version: '3.8', os: ubuntu-latest, backend-db: postgresql_psycopg3 } | |
- { id: '22', python-version: '3.9', os: ubuntu-latest, backend-db: postgresql_psycopg3 } | |
- { id: '23', python-version: '3.10', os: ubuntu-latest, backend-db: postgresql_psycopg3 } | |
- { id: '24', python-version: '3.11', os: ubuntu-latest, backend-db: postgresql_psycopg3 } | |
- { id: '25', python-version: '3.12', os: ubuntu-latest, backend-db: postgresql_psycopg3 } | |
fail-fast: false | |
# GitHub doesn't handle matrix outputs well: https://stackoverflow.com/questions/70287603 | |
outputs: | |
pytest-results-row-01: ${{ steps.append-results.outputs.pytest-results-row-01 }} | |
pytest-results-row-02: ${{ steps.append-results.outputs.pytest-results-row-02 }} | |
pytest-results-row-03: ${{ steps.append-results.outputs.pytest-results-row-03 }} | |
pytest-results-row-04: ${{ steps.append-results.outputs.pytest-results-row-04 }} | |
pytest-results-row-05: ${{ steps.append-results.outputs.pytest-results-row-05 }} | |
pytest-results-row-06: ${{ steps.append-results.outputs.pytest-results-row-06 }} | |
pytest-results-row-07: ${{ steps.append-results.outputs.pytest-results-row-07 }} | |
pytest-results-row-08: ${{ steps.append-results.outputs.pytest-results-row-08 }} | |
pytest-results-row-09: ${{ steps.append-results.outputs.pytest-results-row-09 }} | |
pytest-results-row-10: ${{ steps.append-results.outputs.pytest-results-row-10 }} | |
pytest-results-row-11: ${{ steps.append-results.outputs.pytest-results-row-11 }} | |
pytest-results-row-12: ${{ steps.append-results.outputs.pytest-results-row-12 }} | |
pytest-results-row-13: ${{ steps.append-results.outputs.pytest-results-row-13 }} | |
pytest-results-row-14: ${{ steps.append-results.outputs.pytest-results-row-14 }} | |
pytest-results-row-15: ${{ steps.append-results.outputs.pytest-results-row-15 }} | |
pytest-results-row-16: ${{ steps.append-results.outputs.pytest-results-row-16 }} | |
pytest-results-row-17: ${{ steps.append-results.outputs.pytest-results-row-17 }} | |
pytest-results-row-18: ${{ steps.append-results.outputs.pytest-results-row-18 }} | |
pytest-results-row-19: ${{ steps.append-results.outputs.pytest-results-row-19 }} | |
pytest-results-row-20: ${{ steps.append-results.outputs.pytest-results-row-20 }} | |
name: "Pytest on py${{ matrix.python-version }} (OS: ${{ matrix.os }}, DB: ${{ matrix.backend-db }})" | |
runs-on: ${{ matrix.os }} | |
env: | |
PYTEST_MARKERS: not concurrent | |
FORCE_COLOR: 1 | |
NOXPYTHON: ${{ matrix.python-version }} | |
steps: | |
- name: Check out the repository | |
uses: actions/checkout@v4.1.6 | |
- name: Install Poetry | |
env: | |
PIP_CONSTRAINT: ${{ github.workspace }}/.github/workflows/resources/constraints.txt | |
run: | | |
pipx install poetry | |
poetry --version | |
- name: Setup Python ${{ matrix.python-version }} | |
uses: actions/setup-python@v5.1.0 | |
with: | |
python-version: ${{ matrix.python-version }} | |
architecture: x64 | |
# Nox uses pip, so we cache with pip | |
cache: 'pip' | |
cache-dependency-path: 'poetry.lock' | |
check-latest: true | |
- name: Set up Docker Buildx | |
if: always() && (matrix.backend-db == 'mssql') | |
uses: docker/setup-buildx-action@v3.3.0 | |
- name: Get Docker | |
if: always() && (matrix.backend-db == 'mssql') | |
uses: actions-hub/docker/cli@v1.0.3 | |
env: | |
SKIP_LOGIN: true | |
- name: Start Postgres Container | |
if: always() && (matrix.backend-db == 'postgresql' || matrix.backend-db == 'postgresql_psycopg3') | |
run: > | |
docker run -d | |
-p "5432:5432" | |
-e "POSTGRES_PASSWORD=postgres" | |
--name postgres | |
--health-cmd "pg_isready -d postgres -U postgres" | |
--health-interval 10s | |
--health-timeout 5s | |
--health-retries 5 | |
postgres:11 | |
- name: Start MSSQL Container | |
if: always() && (matrix.backend-db == 'mssql') | |
run: | | |
docker compose -f .github/workflows/resources/docker-compose.mssql.yaml up -d --wait --quiet-pull | |
- name: Check running containers | |
run: | | |
docker ps -a | |
- name: Install Nox | |
env: | |
PIP_CONSTRAINT: ${{ github.workspace }}/.github/workflows/resources/constraints.txt | |
run: | | |
pipx install nox | |
pipx inject nox nox-poetry | |
- name: Run pytest | |
env: | |
SQLALCHEMY_WARN_20: 1 | |
COLUMNS: 160 | |
PYTEST_BACKEND: ${{ matrix.backend-db }} | |
# Postgres backend | |
POSTGRES_HOST_AUTH_METHOD: trust | |
POSTGRES_ADDRESS: localhost | |
POSTGRES_PORT: 5432 | |
POSTGRES_USER: postgres | |
POSTGRES_PASSWORD: postgres | |
POSTGRES_DB: pytest_warehouse | |
# MSSQL backend | |
MSSQL_ADDRESS: localhost | |
MSSQL_PORT: 1433 | |
MSSQL_USER: sa | |
MSSQL_PASSWORD: Meltan0admin | |
MSSQL_DB: pytest_warehouse | |
shell: bash | |
run: | | |
nox -t test -- -m "${{ env.PYTEST_MARKERS }}" 2>&1 | \ | |
tee >( \ | |
tail | sed -r "s/[[:cntrl:]]\[([0-9]{1,3};)*[0-9]{1,3}m//g" | grep -E '^=+ [0-9].+ =+$' | \ | |
{ read pytest_results; echo "pytest_results='${pytest_results}'" >> ${GITHUB_ENV}; } ) | |
- name: Append row to workflow summary table | |
id: append-results | |
shell: bash | |
run: | | |
echo "pytest_results='${{ env.pytest_results }}'" | |
pytest_results_count () { pattern="([0-9]+) $1" && [[ ${{ env.pytest_results }} =~ $pattern ]] && echo "${BASH_REMATCH[1]}" || echo 0; } | |
echo "pytest-results-row-${{ matrix.id }}=| \ | |
${{ matrix.python-version }} | \ | |
${RUNNER_OS} ${RUNNER_ARCH,,} | \ | |
${{ matrix.backend-db }} | \ | |
$( pytest_results_count passed ) | \ | |
$( pytest_results_count failed ) | \ | |
$( pytest_results_count xpassed ) | \ | |
$( pytest_results_count xfailed ) | \ | |
$( pytest_results_count skipped ) | \ | |
$( pytest_results_count deselected ) | \ | |
$( pytest_results_count warning ) | \ | |
$( pytest_results_count error ) | \ | |
$( pattern='in ([0-9]+)\.[0-9]+s' && [[ ${{ env.pytest_results }} =~ $pattern ]] && echo "${BASH_REMATCH[1]}" )s |" >> $GITHUB_OUTPUT | |
- name: Upload coverage data | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: coverage-data-${{ matrix.id }} | |
path: ".coverage.*" | |
- name: Upload test logs | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: test-logs-${{ matrix.id }} | |
path: pytest.log | |
summary: | |
runs-on: ubuntu-latest | |
needs: tests | |
steps: | |
- name: Summarize workflow | |
run: | | |
echo '## Test results' >> ${GITHUB_STEP_SUMMARY} | |
echo '' >> ${GITHUB_STEP_SUMMARY} | |
echo '| PYTHON | OS | DB | PASSED | FAILED | XPASSED | XFAILED | SKIPPED | DESELECTED | WARNINGS | ERRORS | DURATION |' >> ${GITHUB_STEP_SUMMARY} | |
echo '|--------|--------|--------|--------|--------|---------|---------|---------|------------|----------|--------|----------|' >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-01 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-02 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-03 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-04 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-05 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-06 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-07 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-08 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-09 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-10 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-11 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-12 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-13 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-14 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-15 }}" >> ${GITHUB_STEP_SUMMARY} | |
# echo "${{ needs.tests.outputs.pytest-results-row-16 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-17 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-18 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-19 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo "${{ needs.tests.outputs.pytest-results-row-20 }}" >> ${GITHUB_STEP_SUMMARY} | |
echo '' >> ${GITHUB_STEP_SUMMARY} | |
echo 'Please address any tests which have errored, failed, or xpassed, and any warnings emitted.' >> ${GITHUB_STEP_SUMMARY} | |
coverage: | |
runs-on: ubuntu-latest | |
needs: tests | |
steps: | |
- name: Check out the repository | |
uses: actions/checkout@v4.1.6 | |
- name: Install Poetry | |
env: | |
PIP_CONSTRAINT: ${{ github.workspace }}/.github/workflows/resources/constraints.txt | |
run: | | |
pipx install poetry | |
poetry --version | |
- name: Set up Python 3.10 | |
uses: actions/setup-python@v5.1.0 | |
with: | |
python-version: '3.10' | |
architecture: x64 | |
# Nox uses pip, so we cache with pip | |
cache: 'pip' | |
cache-dependency-path: 'poetry.lock' | |
- name: Download coverage data | |
uses: actions/download-artifact@v4 | |
with: | |
pattern: coverage-data-* | |
merge-multiple: true | |
- name: Install Nox | |
env: | |
PIP_CONSTRAINT: ${{ github.workspace }}/.github/workflows/resources/constraints.txt | |
run: | | |
pipx install nox | |
pipx inject nox nox-poetry | |
- name: Combine coverage data and display human readable report | |
run: | | |
nox -rs coverage -- combine --debug=pathmap | |
nox -rs coverage -- report --show-missing --ignore-errors | |
- name: Create coverage report | |
run: | | |
nox -rs coverage -- xml --ignore-errors | |
- name: Upload coverage report | |
with: | |
fail_ci_if_error: true | |
files: ./coverage.xml | |
token: ${{ secrets.CODECOV_TOKEN }} | |
uses: codecov/codecov-action@v4.4.1 | |
mypy: | |
name: "Static type checking" | |
runs-on: ubuntu-latest | |
env: | |
FORCE_COLOR: 1 | |
steps: | |
- name: Check out the repository | |
uses: actions/checkout@v4.1.6 | |
- name: Install Poetry | |
env: | |
PIP_CONSTRAINT: ${{ github.workspace }}/.github/workflows/resources/constraints.txt | |
run: | | |
pipx install poetry | |
poetry --version | |
- name: Setup Python 3.10 | |
uses: actions/setup-python@v5.1.0 | |
with: | |
python-version: '3.10' | |
architecture: x64 | |
# Nox uses pip, so we cache with pip | |
cache: 'pip' | |
cache-dependency-path: 'poetry.lock' | |
- name: Install Nox | |
env: | |
PIP_CONSTRAINT: ${{ github.workspace }}/.github/workflows/resources/constraints.txt | |
run: | | |
pipx install nox | |
pipx inject nox nox-poetry | |
- name: Run mypy | |
run: | | |
nox -rs mypy |