Skip to content

Commit 5bceb55

Browse files
authored
ci: Improve docker cache and test that the image works (#349)
1 parent 601d476 commit 5bceb55

File tree

5 files changed

+98
-19
lines changed

5 files changed

+98
-19
lines changed

.github/actions/docker-build/action.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
# Action that wraps together all the necessary actions to build an image and publish it.
22
# It does not include login actions.
33
# This is a convenience, so that we know that everything related to the build lies in this file,
4-
# and if it gets updated we can automatically run our `test-docker-build` from `build-test.yml.`
4+
# and if it gets updated we can automatically run our `test-docker-build` from `build-test.yml.`,
5+
# so there is no confusion about which is the job that was updated, if there are many in the same workflow file.
56

67
name: "Docker Build"
78
description: "Builds Docker images with optional caching and multi-platform support"
89

910
inputs:
10-
push-image:
11+
push:
1112
description: "Whether to push the built image"
1213
required: false
1314
default: "false"
15+
load:
16+
description: "Whether to load the built image"
17+
required: false
18+
default: "false"
1419
platforms:
1520
description: "Target platforms for the build"
1621
required: false
@@ -55,9 +60,10 @@ runs:
5560
with:
5661
context: ${{ inputs.context }}
5762
file: ${{ inputs.dockerfile }}
58-
push: ${{ inputs['push-image'] }}
63+
push: ${{ inputs.push }}
5964
platforms: ${{ inputs.platforms }}
6065
tags: ${{ steps.meta.outputs.tags }}
6166
labels: ${{ steps.meta.outputs.labels }}
6267
cache-from: ${{ inputs['cache-from'] }}
6368
cache-to: ${{ inputs['cache-to'] }}
69+
load: ${{ inputs.load }}

.github/workflows/build-test.yml

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
branches: ["main"]
88
pull_request:
99
branches: ["main"]
10-
10+
1111
jobs:
1212
test-build-package:
1313
name: Test package build
@@ -34,7 +34,7 @@ jobs:
3434
WHEEL_FILE=$(ls dist/*.whl | head -1)
3535
echo "Installing wheel: $WHEEL_FILE"
3636
uv pip install "$WHEEL_FILE"
37-
37+
3838
- name: Test twyn as a library
3939
run: uv run python -c "import twyn; twyn.check_dependencies"
4040

@@ -73,12 +73,22 @@ jobs:
7373

7474
test-docker-build:
7575
needs: [should-test-docker-build]
76-
name: Test Docker build
76+
name: Test Docker build ${{ matrix.arch }}
7777
runs-on: ubuntu-latest
7878
if: (needs.should-test-docker-build.outputs.workflow == 'true' || needs.should-test-docker-build.outputs.docker == 'true') && !startsWith(github.event.head_commit.message, 'bump:')
7979
permissions:
8080
contents: read
8181
packages: read
82+
strategy:
83+
matrix:
84+
include:
85+
- arch: amd64
86+
platform: linux/amd64
87+
image-name: build-amd64
88+
- arch: arm64
89+
platform: linux/arm64
90+
image-name: build-arm64
91+
needs-qemu: true
8292
steps:
8393
- name: Check out the repo
8494
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
@@ -90,12 +100,23 @@ jobs:
90100
username: ${{ github.actor }}
91101
password: ${{ secrets.GITHUB_TOKEN }}
92102

103+
- name: Set up QEMU
104+
if: matrix.needs-qemu
105+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
106+
with:
107+
platforms: ${{ matrix.platform }}
108+
93109
- name: Build image
94110
uses: ./.github/actions/docker-build
95111
with:
96112
context: .
97113
file: ./Dockerfile
98114
push: false
99-
platforms: linux/amd64,linux/arm64
100-
cache-from: type=registry,ref=ghcr.io/elementsinteractive/twyn:buildcache
101-
115+
load: true
116+
platforms: ${{ matrix.platform }}
117+
cache-from: type=registry,ref=ghcr.io/elementsinteractive/twyn:buildcache-${{ matrix.arch }}
118+
image-name: ${{ matrix.image-name }}
119+
120+
- name: Test
121+
run: |
122+
docker run --platform ${{ matrix.platform }} --rm ${{ matrix.image-name }}:pr-${{ github.event.pull_request.number }} --version

.github/workflows/publish.yml

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,59 @@ jobs:
2727
uv build
2828
uv publish
2929
30-
push_to_docker_hub:
31-
name: Push Docker image to Docker Hub
30+
build_and_test_docker:
31+
name: Build and test Docker image (${{ matrix.arch }})
3232
runs-on: ubuntu-latest
33+
permissions:
34+
contents: read
35+
packages: write
36+
strategy:
37+
matrix:
38+
include:
39+
- arch: amd64
40+
platform: linux/amd64
41+
cache-ref: buildcache-amd64
42+
- arch: arm64
43+
platform: linux/arm64
44+
cache-ref: buildcache-arm64
45+
needs-qemu: true
46+
steps:
47+
- name: Check out the repo
48+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
49+
50+
- name: Log in to GitHub Container Registry
51+
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
52+
with:
53+
registry: ghcr.io
54+
username: ${{ github.actor }}
55+
password: ${{ secrets.GITHUB_TOKEN }}
56+
57+
- name: Set up QEMU
58+
if: matrix.needs-qemu
59+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
60+
with:
61+
platforms: ${{ matrix.arch }}
62+
63+
- name: Build Docker image (${{ matrix.arch }})
64+
uses: ./.github/actions/docker-build
65+
with:
66+
push: false
67+
load: true
68+
platforms: ${{ matrix.platform }}
69+
dockerfile: ./Dockerfile
70+
context: .
71+
image-name: elementsinteractive/twyn
72+
cache-from: type=registry,ref=ghcr.io/elementsinteractive/twyn:${{ matrix.cache-ref }}
73+
cache-to: type=registry,ref=ghcr.io/elementsinteractive/twyn:${{ matrix.cache-ref }},mode=max,compression=zstd,force-compression=true,oci-mediatypes=true
74+
75+
- name: Test Docker image (${{ matrix.arch }})
76+
run: |
77+
docker run --platform ${{ matrix.platform }} --rm elementsinteractive/twyn --version
78+
79+
publish_docker_images:
80+
name: Push Docker images to registries
81+
runs-on: ubuntu-latest
82+
needs: [build_and_test_docker]
3383
permissions:
3484
contents: read
3585
packages: write
@@ -50,16 +100,15 @@ jobs:
50100
username: ${{ github.actor }}
51101
password: ${{ secrets.GITHUB_TOKEN }}
52102

53-
- name: Build and push Docker image
103+
- name: Push Docker images
54104
uses: ./.github/actions/docker-build
55105
with:
56-
push-image: "true"
106+
push: "true"
57107
platforms: linux/amd64,linux/arm64
58108
dockerfile: ./Dockerfile
59109
context: .
60110
image-name: elementsinteractive/twyn
61-
cache-from: type=registry,ref=ghcr.io/elementsinteractive/twyn:buildcache
62-
cache-to: type=registry,ref=ghcr.io/elementsinteractive/twyn:buildcache,mode=max,compression=zstd,force-compression=true,oci-mediatypes=true
111+
cache-from: type=registry,ref=ghcr.io/elementsinteractive/twyn:buildcache-amd64,ref=ghcr.io/elementsinteractive/twyn:buildcache-arm64
63112

64113
- name: Delete old cache entries
65114
env:
@@ -68,17 +117,18 @@ jobs:
68117
# Get all versions of the container package
69118
versions=$(gh api "orgs/elementsinteractive/packages/container/twyn/versions" --paginate)
70119
71-
# Extract version IDs that do NOT have the 'buildcache' tag
72-
ids_to_delete=$(echo "$versions" | jq -r '.[] | select(.metadata.container.tags | index("buildcache") | not) | .id')
120+
# Extract version IDs that do NOT have any buildcache-* tags (buildcache-amd64, buildcache-arm64, etc.)
121+
ids_to_delete=$(echo "$versions" | jq -r '.[] | select(.metadata.container.tags | map(test("^buildcache-")) | any | not) | .id')
73122
74123
# Delete them
75124
for id in $ids_to_delete; do
76125
echo "Deleting old cache version ID: $id"
77126
gh api -X DELETE "orgs/elementsinteractive/packages/container/twyn/versions/$id"
78127
done
128+
79129
release_notes:
80130
runs-on: ubuntu-latest
81-
needs: [push_to_pypi, push_to_docker_hub]
131+
needs: [push_to_pypi, publish_docker_images]
82132
steps:
83133
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
84134
- name: Release

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ RUN ${BIN_PATH}/python -m ensurepip
4444
COPY uv.lock pyproject.toml ./
4545

4646
# Install dependencies using uv (only dependencies, not the project itself)
47-
RUN uv sync --inexact --frozen --all-extras --no-install-project --compile-bytecode
47+
RUN uv sync --inexact --frozen --all-extras --no-install-project --compile-bytecode
4848

4949
# --------------- `final` stage ---------------
5050
FROM base AS final

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ download = [
6262
]
6363
local = ["ipdb<1.0.0,>=0.13.9", "commitizen<5.0,>=2.38", "pdbpp<1.0.0,>=0.11.6"]
6464

65+
[tool.uv]
66+
default-groups = []
6567

6668
[build-system]
6769
requires = ["hatchling"]

0 commit comments

Comments
 (0)