CI/CD #1044
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/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/** | |
| ... |