Skip to content

CI/CD

CI/CD #1055

Workflow file for this run

---
name: CI/CD
concurrency:
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: true
on:
merge_group:
push:
branches: [ main ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 6 * * *' # Daily 6AM UTC build
env:
PYTHON_LATEST: '3.14'
PROJECT_NAME: aiodocker
# For re-actors/checkout-python-sdist
dists-artifact-name: python-package-distributions
jobs:
build:
name: 📦 Build the distribution packages
runs-on: ubuntu-latest
steps:
- name: Checkout project
uses: actions/checkout@v5
with:
# Fetch all history but without their actual contents,
# so that dynamic version for build work correctly.
fetch-depth: 0
filter: 'blob:none'
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_LATEST }}
cache: pip
- name: Install core libraries for build
run: python -m pip install build
- name: Build artifacts
run: python -m build
- name: Upload built artifacts for testing
uses: actions/upload-artifact@v4
with:
name: ${{ env.dists-artifact-name }}
path: |
dist/${{ env.PROJECT_NAME }}*.tar.gz
dist/${{ env.PROJECT_NAME }}*.whl
retention-days: 15
lint:
name: Linter
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Setup Python ${{ env.PYTHON_LATEST }}
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_LATEST }}
cache: pip
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e '.[lint]'
- uses: actions/cache@v4
with:
path: ~/.cache/pre-commit/
key: pre-commit-4|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}
- name: Run linters
run: |
make lint
twine-check:
name: Twine check
runs-on: ubuntu-latest
needs:
- build
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: ${{ env.dists-artifact-name }}
path: dist
- name: Setup Python ${{ env.PYTHON_LATEST }}
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_LATEST }}
cache: pip
- name: Run twine checker
run: |
pip install twine
twine check --strict dist/*
test:
name: 'test (Python ${{ matrix.python-version }}, aiohttp ${{ matrix.aiohttp-version }}, ${{ matrix.os }})'
needs:
- build
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
aiohttp-version: ['3.10', '3.13']
os: [ubuntu]
pytest-arg: ['']
# NOTE: Temporarily disabled due to mismatch of:
# - Path(r"\\.\pipe").iterdir()
# - Path(r"\\.\pipe\docker_engine").exists()
# which works fine in my local Windows machine
# but not in GitHub Action's Windows runner.
# include:
# - python-version: '3.14'
# aiohttp-version: ['3.10', '3.13']
# os: windows
# pytest-arg: '-k test_integration'
runs-on: ${{ matrix.os }}-latest
timeout-minutes: 30
steps:
- name: Show environment info
run: |
docker context inspect
docker version
- name: Checkout
uses: actions/checkout@v5
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: pip
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: ${{ env.dists-artifact-name }}
path: dist
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e '.[test]' 'aiohttp~=${{ matrix.aiohttp-version }}.0'
- name: Install the build artifact
run: |
python -m pip install dist/aiodocker*.whl
# NOTE: Unfortunately the gain of image caching is too small,
# and even it increases the latency of Linux jobs. :(
# - name: Cache Docker images
# uses: ScribeMD/[email protected]
# with:
# key: docker-${{ runner.os }}
- name: Run tests
env:
COLOR: 'yes'
run: |
python -m pytest -s -vv --durations=10 ${{ matrix.pytest-arg }}
- name: Rename coverage logs
run: |
mv coverage.xml "coverage-unit-py${{ matrix.python-version }}-aiohttp${{ matrix.aiohttp-version }}-${{ matrix.os }}-${{ matrix.registry }}.xml"
- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-unit-py${{ matrix.python-version }}-aiohttp${{ matrix.aiohttp-version }}-${{ matrix.os }}-${{ matrix.registry }}
path: coverage-unit-py${{ matrix.python-version }}-aiohttp${{ matrix.aiohttp-version }}-${{ matrix.os }}-${{ matrix.registry }}.xml
if-no-files-found: error
retention-days: 1
- name: Clean up Docker images produced during tests
run: |
docker image list --filter 'reference=aiodocker-*' --format '{{.Repository}}:{{.Tag}}' | xargs -r docker rmi
check: # This job does nothing and is only used for the branch protection
name: ✅ Ensure the required checks passing
if: always()
needs:
- lint
- twine-check
- test
runs-on: ubuntu-latest
steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
- name: Checkout
uses: actions/checkout@v5
with:
ref: ${{ github.sha }}
- name: Download coverage artifact
uses: actions/download-artifact@v4
with:
pattern: coverage-unit-*
path: coverage
merge-multiple: true
- name: Upload code coverage report
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
directory: coverage
publish: # Run only on creating release for new tag
name: 📦 Publish to PyPI
needs:
- check
runs-on: ubuntu-latest
# Run only on pushing a tag
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
permissions:
contents: write # IMPORTANT: mandatory for making GitHub Releases
id-token: write # IMPORTANT: mandatory for trusted publishing & sigstore
environment:
name: pypi
url: >-
https://pypi.org/project/${{ env.PROJECT_NAME }}/${{ github.ref_name }}
steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: ${{ env.dists-artifact-name }}
path: dist
- name: Release
uses: aio-libs/[email protected]
with:
changes_file: CHANGES.rst
name: ${{ env.PROJECT_NAME }}
github_token: ${{ secrets.GITHUB_TOKEN }}
head_line: "{version}\\s+\\({date}\\)\n====+\n?"
- name: >-
Publish 🐍📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
- name: Sign the dists with Sigstore
uses: sigstore/[email protected]
with:
inputs: >-
./dist/${{ env.PROJECT_NAME }}*.tar.gz
./dist/${{ env.PROJECT_NAME }}*.whl
- name: Upload artifact signatures to GitHub Release
# Confusingly, this action also supports updating releases, not
# just creating them. This is what we want here, since we've manually
# created the release above.
uses: softprops/action-gh-release@v2
with:
# dist/ contains the built packages, which smoketest-artifacts/
# contains the signatures and certificates.
files: dist/**
...