Adopt uv for dependency management and require Python 3.10 (#2085) #3505
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: CI | |
| on: | |
| push: | |
| branches: | |
| - trunk | |
| pull_request: | |
| branches: | |
| - trunk | |
| schedule: | |
| - cron: '0 1 * * *' | |
| permissions: | |
| contents: read # for actions/checkout to fetch code | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| env: | |
| # Needed if we want colors in pytest output without tty and script -e -c wrapper | |
| PY_COLORS: "1" | |
| FORCE_COLOR: "1" | |
| jobs: | |
| unit_tests: | |
| name: Unit Tests (Python ${{ matrix.python_version }}) | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 8 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python_version: | |
| - "3.10" | |
| - "3.11" | |
| - "3.12" | |
| - "3.13" | |
| # cryptography is not compatible with older PyPy versions | |
| - "pypy-3.10" | |
| os: | |
| - ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Use Python ${{ matrix.python_version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python_version }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Install OS / deb dependencies | |
| run: | | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq gcc libvirt-dev | |
| - name: Cache uv | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/uv | |
| key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-uv- | |
| - name: Install Python Dependencies | |
| run: uv sync --extra ci | |
| - name: Add .venv to PATH | |
| run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" | |
| - name: Run unit tests tox target | |
| run: tox -e py${{ matrix.python_version }} | |
| - name: Run dist install checks tox target | |
| if: ${{ matrix.python_version != 'pypy-3.10' }} | |
| run: tox -e py${{ matrix.python_version }}-dist,py${{ matrix.python_version }}-dist-wheel | |
| code_coverage: | |
| name: Generate Code Coverage | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python_version: [ "3.10" ] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Use Python ${{ matrix.python_version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python_version }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Install OS / deb dependencies | |
| run: | | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc libvirt-dev | |
| - name: Cache uv | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/uv | |
| key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-uv- | |
| - name: Install Python Dependencies | |
| run: uv sync --extra ci | |
| - name: Add .venv to PATH | |
| run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" | |
| - name: Run Checks | |
| run: tox -e coverage-ci | |
| - name: Upload Coverage to codecov.io | |
| uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0 | |
| with: | |
| # We utilize secret for more realiable builds. Without secret being set, upload step | |
| # fails fairly often. | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| fail_ci_if_error: true | |
| verbose: true | |
| lint_checks: | |
| name: Run Various Lint and Other Checks | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python_version: [ "3.10" ] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Use Python ${{ matrix.python_version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python_version }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Install OS / deb dependencies | |
| run: | | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc libvirt-dev | |
| - name: Cache uv | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/uv | |
| key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-uv- | |
| - name: Install Python Dependencies | |
| run: uv sync --extra ci | |
| - name: Add .venv to PATH | |
| run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" | |
| - name: Run shellcheck | |
| run: shellcheck dist/*.sh contrib/*.sh | |
| - name: Run Python Checks | |
| run: tox -e black-check,isort-check,pyupgrade,checks,import-timings,lint,pylint,mypy | |
| build_test_release_artifact: | |
| name: Build and Test Release Artifact | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python_version: [ "3.10" ] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libvirt-dev pkg-config gcc | |
| - name: Use Python ${{ matrix.python_version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python_version }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Install OS / deb dependencies | |
| run: | | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq gcc libvirt-dev pkg-config | |
| - name: Cache uv | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/uv | |
| key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-uv- | |
| - name: Install Python Dependencies | |
| run: | | |
| uv sync --extra ci --extra build | |
| echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" | |
| - name: Build Release Artifact | |
| run: | | |
| pip list installed | |
| python -m build -vv | |
| - name: Set Environment | |
| run: | | |
| export PYTHONPATH=. | |
| export VERSION=$(python -c "import libcloud ; print(libcloud.__version__)") | |
| echo "VERSION=${VERSION}" >> "$GITHUB_ENV" | |
| - name: Verify Tarball Release Artifact | |
| run: | | |
| # Verify tarball file exists | |
| export TARBALL_FILENAME="apache_libcloud-${VERSION}.tar.gz" | |
| ls -la "dist/${TARBALL_FILENAME}" | |
| cd dist/ | |
| # Unpack tarball and verify + run the tests | |
| tar -xzvf "${TARBALL_FILENAME}" | |
| cd "apache_libcloud-${VERSION}/" | |
| tox -c tox.ini -epy3.10 | |
| - name: Verify Wheel Release Artifact | |
| run: | | |
| # Verify wheel file exists | |
| export WHEEL_FILENAME="apache_libcloud-${VERSION}-py3-none-any.whl" | |
| ls -la "dist/${WHEEL_FILENAME}" | |
| cd dist/ | |
| # Unpack wheel and verify + run tests | |
| unzip "${WHEEL_FILENAME}" -d "wheel" | |
| cd wheel | |
| # Since wheel doesn't include those files, we need to manually copy them over from | |
| # repo root so we can run the tests | |
| cp ../../tox.ini . | |
| cp ../../pyproject.toml . | |
| cp ../../libcloud/test/secrets.py-dist libcloud/test/secrets.py-dist | |
| tox -c tox.ini -epy3.10 | |
| build_test_docker_image: | |
| name: Build and Verify Docker Image | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python_version: [ "3.10" ] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Build Testing Docker Image | |
| run: docker build -f contrib/Dockerfile -t libcloud_runtest_img . | |
| - name: Verify Image Works | |
| # This step runs checks under various Python versions and it's slow so | |
| # we only run it on nightly basis | |
| if: ${{ github.event.schedule == '0 1 * * *' }} | |
| run: | | |
| docker run libcloud_runtest_img | |
| security_checks: | |
| name: Run Security Checks | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python_version: [ "3.10" ] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Use Python ${{ matrix.python_version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python_version }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Install OS / deb dependencies | |
| run: | | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq gcc libvirt-dev | |
| - name: Cache uv | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/uv | |
| key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-uv- | |
| - name: Install Python Dependencies | |
| run: uv sync --extra ci | |
| - name: Add .venv to PATH | |
| run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" | |
| - name: Ensure pip is available | |
| run: | | |
| python -m ensurepip --upgrade | |
| python -m pip install --upgrade pip | |
| - name: Install Library Into Virtualenv | |
| run: | | |
| python -m venv venv/ | |
| source venv/bin/activate | |
| python -m pip install --upgrade pip | |
| python -m pip install . | |
| - name: Run Pip Audit Check On Main Library Dependencies | |
| uses: pypa/gh-action-pip-audit@1220774d901786e6f652ae159f7b6bc8fea6d266 # v1.1.0 | |
| with: | |
| virtual-environment: venv/ | |
| # setuptools which we don't install or depend on directly | |
| # PYSEC-2023-228 - pip vulnerability and we don't install pip directly | |
| ignore-vulns: | | |
| GHSA-r9hx-vwmv-q579 | |
| PYSEC-2022-43012 | |
| PYSEC-2023-228 | |
| - name: Cleanup | |
| run: rm -rf venv/ || true | |
| - name: Export Development Requirements | |
| run: uv export --extra test --extra lint --extra mypy --extra docs --format requirements.txt --no-hashes --no-emit-project --output-file requirements-dev.txt | |
| - name: Run Pip Audit Check On All Development And Test Dependencies | |
| uses: pypa/gh-action-pip-audit@1220774d901786e6f652ae159f7b6bc8fea6d266 # v1.1.0 | |
| with: | |
| inputs: requirements-dev.txt | |
| # setuptools which we don't install or depend on directly | |
| ignore-vulns: | | |
| GHSA-r9hx-vwmv-q579 | |
| - name: Run Bandit Check | |
| run: tox -e bandit | |
| micro-benchmarks: | |
| name: Micro Benchmarks | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python_version: [ "3.10" ] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Use Python ${{ matrix.python_version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python_version }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Install OS / deb dependencies | |
| run: | | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc libvirt-dev | |
| - name: Cache uv | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/uv | |
| key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-uv- | |
| - name: Install Python Dependencies | |
| run: uv sync --extra ci | |
| - name: Add .venv to PATH | |
| run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" | |
| - name: Run Micro Benchmarks | |
| run: tox -e micro-benchmarks | |
| docs: | |
| name: Build and upload Documentation | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python_version: [ "3.10" ] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Use Python ${{ matrix.python_version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python_version }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Print Environment Info | |
| run: printenv | sort | |
| - name: Install OS / deb dependencies | |
| run: | | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc libvirt-dev | |
| - name: Cache uv | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/uv | |
| key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-uv- | |
| - name: Install Python Dependencies | |
| run: uv sync --extra ci | |
| - name: Add .venv to PATH | |
| run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH" | |
| - name: Build Docs | |
| run: tox -e docs | |
| - name: Trigger ReadTheDocs build | |
| if: ${{ github.ref_name == 'trunk' }} | |
| env: | |
| RTD_TOKEN: ${{ secrets.RTD_TOKEN }} | |
| BRANCH_NAME: "trunk" | |
| run: | | |
| python -m pip install requests | |
| python ./contrib/trigger_rtd_build.py |