fix: Properly collect Python dependencies during image build. Next attempt at build cache #253
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: main | |
on: | |
pull_request: | |
release: | |
types: [published] | |
push: | |
branches: | |
- main | |
- master | |
jobs: | |
version: | |
name: Generate package version | |
runs-on: ubuntu-latest | |
outputs: | |
value: ${{ steps.package-version.outputs.value }} | |
steps: | |
- name: Checkout the code | |
uses: actions/checkout@v4 | |
with: | |
# Disable shallow clone for `setuptools_scm`, as it needs access to the | |
# history | |
fetch-depth: 0 | |
- name: Set Python up | |
uses: actions/setup-python@v5 | |
- name: Install dependencies | |
run: >- | |
python -m pip install --upgrade setuptools setuptools_scm | |
- name: Determine package version | |
id: package-version | |
run: | | |
package_version=`python -m setuptools_scm --format plain` | |
echo "value=$package_version" >> $GITHUB_OUTPUT | |
tests: | |
name: Tests | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- os: ubuntu-latest | |
python: 3.8 | |
toxenv: py | |
- os: ubuntu-latest | |
python: 3.9 | |
toxenv: py | |
- os: ubuntu-latest | |
python: '3.10' | |
toxenv: py | |
- os: ubuntu-latest | |
python: '3.11' | |
toxenv: py | |
- os: ubuntu-latest | |
python: '3.12' | |
toxenv: py | |
runs-on: ${{ matrix.os }} | |
needs: [version] | |
steps: | |
- name: Checkout the code | |
uses: actions/checkout@v4 | |
with: | |
# Disable shallow clone for Sonar scanner, as it needs access to the | |
# history | |
fetch-depth: 0 | |
- name: Set Python up | |
uses: actions/setup-python@v5 | |
with: | |
python-version: ${{ matrix.python }} | |
- name: Install testing tools | |
run: >- | |
python -m pip install --upgrade \ | |
setuptools setuptools_scm pip tox virtualenv coverage | |
- name: Run the tests | |
run: tox -e ${{ matrix.toxenv }} | |
- name: Generage Coverage combined XML report | |
run: coverage xml | |
- name: SonarCloud scanning | |
uses: sonarsource/sonarcloud-github-action@master | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
with: | |
# yamllint disable rule:line-length | |
args: >- | |
-Dsonar.projectKey=${{ github.repository_owner }}_${{ github.event.repository.name }} | |
-Dsonar.organization=${{ github.repository_owner }} | |
-Dsonar.projectVersion=${{ needs.version.outputs.value }} | |
# yamllint enable rule:line-length | |
docker-metadata: | |
name: Generata metadata for container images | |
runs-on: ubuntu-latest | |
needs: [version] | |
outputs: | |
version: ${{ steps.meta.outputs.version }} | |
labels: ${{ steps.meta.outputs.labels }} | |
json: ${{ steps.meta.outputs.json }} | |
steps: | |
- name: Prepare Docker metadata | |
id: meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ghcr.io/${{ github.repository }} | |
tags: | | |
type=pep440,pattern={{raw}},value=${{ needs.version.outputs.value }} | |
type=raw,value=latest,enable=${{ | |
github.event_name == 'release' | |
&& github.event.action == 'published' | |
&& (github.event.release.target_commitish == 'main' | |
|| github.event.release.target_commitish == 'master') | |
}} | |
type=ref,event=pr | |
type=edge | |
docker-publish: | |
name: Build and publish Docker images | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- platform_id: linux/arm/v7 | |
platform_name: linux-arm-v7 | |
- platform_id: linux/arm/v6 | |
platform_name: linux-arm-v6 | |
- platform_id: linux/arm64 | |
platform_name: linux-arm64 | |
- platform_id: linux/amd64 | |
platform_name: linux-amd64 | |
runs-on: ubuntu-latest | |
needs: [version, tests, docker-metadata] | |
permissions: | |
contents: read | |
packages: write | |
steps: | |
- name: Checkout the code | |
uses: actions/checkout@v4 | |
- name: Set up QEMU for more platforms supported by Buildx | |
uses: docker/setup-qemu-action@v3 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Login to GitHub Container Registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.repository_owner }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Build and push images | |
uses: docker/build-push-action@v6 | |
id: build | |
with: | |
# No explicit context used, since that makes cache misses most of the | |
# time. | |
# See https://github.com/docker/build-push-action/issues/286 for more | |
# details | |
platforms: ${{ matrix.platform_id }} | |
labels: ${{ needs.docker-metadata.outputs.labels }} | |
# Implicit context points to working copy, not Git respository, so | |
# `setuptools_scm` needs to receive the version explicitly | |
build-args: | | |
VERSION=${{ needs.version.outputs.value }} | |
# Push by digest only, manifest will be added later | |
outputs: >- | |
type=image,name=ghcr.io/${{ github.repository }},push-by-digest=true,name-canonical=true,push=true | |
# Cache the buildx cache between builds using GitHub registry. `gha` | |
# cache has been mentioned to introduce cache misses for | |
# multi-platform builds, see https://github.com/docker/buildx/discussions/1382 | |
# for potential hints | |
cache-from: | | |
type=registry,ref=ghcr.io/${{ github.repository }}/buildcache:${{ matrix.platform_name }} | |
cache-to: | | |
type=registry,ref=ghcr.io/${{ github.repository }}/buildcache:${{ matrix.platform_name }},mode=max | |
- name: Store image information | |
uses: GoCodeAlone/github-action-matrix-outputs-write@v1 | |
id: out | |
with: | |
matrix-step-name: ${{ github.job }} | |
matrix-key: ${{ matrix.platform_name }} | |
outputs: |- | |
image_digest: | |
value: ${{ steps.build.outputs.digest }} | |
docker-manifest: | |
name: Create and push Docker manifest | |
runs-on: ubuntu-latest | |
needs: [docker-metadata, docker-publish] | |
steps: | |
- name: Read image information from publish job | |
uses: GoCodeAlone/github-action-matrix-outputs-read@v1 | |
id: read | |
with: | |
matrix-step-name: docker-publish | |
- uses: actions/github-script@v7 | |
id: buildx-imagetools-create-args | |
env: | |
JSON_METADATA: ${{ needs.docker-metadata.outputs.json }} | |
with: | |
result-encoding: string | |
script: |- | |
try { | |
const jsonMetadata = process.env.JSON_METADATA; | |
if (jsonMetadata === undefined) { | |
throw new Error('JSON_METADATA is not defined'); | |
} | |
const metadata = JSON.parse(jsonMetadata); | |
if (metadata.tags === undefined) { | |
throw new Error("'tags' element is not defined in 'JSON_METADATA'"); | |
} | |
const tagsArg = (metadata.tags || []).reduce((acc, item) => { | |
acc += ` --tags ${item}`; | |
return acc; | |
}, ''); | |
if (metadata.annotations === undefined) { | |
throw new Error("'annotations' element is not defined in 'JSON_METADATA'"); | |
} | |
const annotationsArg = (metadata.annotations || []).reduce((acc, item) => { | |
acc += ` --annotations '${item}'`; | |
return acc; | |
}, ''); | |
return `${tagsArg} ${annotationsArg}`; | |
} catch (e) { | |
core.setFailed(`Unable to construct arguments: ${e.message}`); | |
} | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Create and push Docker manifest | |
run: >- | |
docker buildx imagetools create | |
${{ steps.buildx-imagetools-create-args.outputs.result }} | |
${{ join(fromJson(steps.read.outputs.result).image_digest.*.value, ' ') }} | |
docker-test: | |
name: Test Docker images | |
runs-on: ubuntu-latest | |
needs: [docker-metadata, docker-manifest] | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- platform_id: linux/arm/v7 | |
platform_name: linux-arm-v7 | |
- platform_id: linux/arm/v6 | |
platform_name: linux-arm-v6 | |
- platform_id: linux/arm64 | |
platform_name: linux-arm64 | |
- platform_id: linux/amd64 | |
platform_name: linux-amd64 | |
steps: | |
- name: Read image information from publish job | |
uses: GoCodeAlone/github-action-matrix-outputs-read@v1 | |
id: read | |
with: | |
matrix-step-name: docker-publish | |
- name: Set up QEMU for more platforms supported by Buildx | |
uses: docker/setup-qemu-action@v3 | |
with: | |
platforms: ${{ matrix.platform_id }} | |
- name: Test images | |
run: >- | |
docker run --rm | |
--platform ${{ matrix.platform_id }} | |
ghcr.io/${{ github.repository }}:${{ needs.docker-metadata.outputs.version }} | |
--help |