Skip to content

Adopt uv for dependency management and require Python 3.10 (#2085) #3505

Adopt uv for dependency management and require Python 3.10 (#2085)

Adopt uv for dependency management and require Python 3.10 (#2085) #3505

Workflow file for this run

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