Skip to content

Commit 59e1bfb

Browse files
committed
👷 update Docker CI
1 parent 7a08182 commit 59e1bfb

File tree

1 file changed

+197
-17
lines changed

1 file changed

+197
-17
lines changed

.github/workflows/docker.yml

Lines changed: 197 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,73 @@ on:
1717
- .github/workflows/release.yml
1818
- .github/workflows/auto-merge.yml
1919
- .github/workflows/ruff.yml
20-
release:
21-
types: [published]
20+
workflow_run:
21+
workflows: [ "Release" ]
22+
types:
23+
- completed
2224
workflow_dispatch:
2325

26+
env:
27+
LATEST_PYTHON_VERSION: "3.13"
28+
2429
jobs:
25-
build-and-push:
30+
metadata:
2631
runs-on: ubuntu-latest
32+
if: |-
33+
github.event_name != 'workflow_run' ||
34+
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
2735
permissions:
2836
contents: read
29-
packages: write
37+
outputs:
38+
LATEST_RELEASE: ${{ steps.workflow.outputs.LATEST_RELEASE || steps.api.outputs.LATEST_RELEASE }}
3039

40+
steps:
41+
- name: Get latest release from previous workflow
42+
id: workflow
43+
if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success'
44+
run: |
45+
tag=${{ github.event.workflow_run.head_branch }}
46+
echo "LATEST_RELEASE=${tag#refs/tags/}" >> $GITHUB_OUTPUT
47+
48+
- name: Get latest release from api
49+
id: api
50+
if: github.event_name != 'workflow_run'
51+
run: |
52+
gh api repos/${{ github.repository }}/releases/latest | jq -r '.tag_name' | xargs -0 printf "LATEST_RELEASE=%s" >> $GITHUB_OUTPUT
53+
env:
54+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
55+
56+
57+
build:
58+
runs-on: ubuntu-latest
59+
needs: metadata
60+
permissions:
61+
contents: read
62+
packages: write
63+
concurrency:
64+
group: ${{ github.workflow }}-${{ needs.metadata.outputs.LATEST_RELEASE }}-${{ matrix.python_version }}${{ matrix.python_variant }}-${{ matrix.platform }}
65+
cancel-in-progress: true
66+
strategy:
67+
fail-fast: true
68+
matrix:
69+
python_version:
70+
- "3.9"
71+
- "3.10"
72+
- "3.11"
73+
- "3.12"
74+
- "3.13"
75+
python_variant:
76+
- ""
77+
- "-slim"
78+
platform:
79+
- linux/amd64
80+
- linux/arm64
81+
- linux/arm
3182
steps:
3283
- name: Checkout
3384
uses: actions/checkout@v5
85+
with:
86+
ref: ${{ needs.metadata.outputs.LATEST_RELEASE}}
3487

3588
- name: Set up QEMU
3689
uses: docker/setup-qemu-action@v3
@@ -46,22 +99,149 @@ jobs:
4699
username: ${{ github.repository_owner }}
47100
password: ${{ secrets.GIT_TOKEN }}
48101

49-
- name: Extract metadata
50-
id: meta
102+
- name: Generate Image Name and Scope
103+
id: image
104+
run: |
105+
echp "IMAGE=ghcr.io/${{ github.repository }}" >> $GITHUB_OUTPUT
106+
echo "SCOPE=${{ hashFiles('**/pdm.lock') }}-${{ matrix.python_version }}${{ matrix.python_variant }}-${{ matrix.platform }}" >> $GITHUB_OUTPUT
107+
platform="${{ matrix.platform }}"
108+
echo "ARTIFACT=${{ matrix.python_version }}${{ matrix.python_variant }}-${platform/\//-}-digests" >> $GITHUB_OUTPUT
109+
110+
- name: Generate Labels
51111
uses: docker/metadata-action@v5
112+
id: metadata
52113
with:
53-
images: ghcr.io/${{ github.repository }}
54-
tags: |
55-
type=edge,value=nightly
56-
type=sha,event=branch
57-
type=ref,event=tag
58-
type=ref,event=pr
59-
60-
- name: Build and push
114+
images: ${{ steps.image.outputs.IMAGE }}
115+
116+
- name: Build and Publish
61117
uses: docker/build-push-action@v6
118+
id: build
62119
with:
63120
context: .
64-
file: Dockerfile
121+
platforms: ${{ matrix.platform }}
65122
push: ${{ github.event_name != 'pull_request' }}
66-
tags: ${{ steps.meta.outputs.tags }}
67-
labels: ${{ steps.meta.outputs.labels }}
123+
build-args: |
124+
PYTHON_IMAGE=${{ matrix.python_version }}
125+
VARIANT=${{ matrix.python_variant }}
126+
labels: ${{ steps.metadata.outputs.labels }}
127+
cache-from: type=gha,scope=${{ steps.image.outputs.SCOPE }}
128+
cache-to: type=gha,scope=${{ steps.image.outputs.SCOPE }},mode=max
129+
outputs: type=image,name=${{ steps.image.outputs.IMAGE }},push-by-digest=true,name-canonical=true,push=true
130+
131+
- name: Export digest
132+
run: |
133+
mkdir -p /tmp/digests/
134+
digest="${{ steps.build.outputs.digest }}"
135+
touch "/tmp/digests/${digest#sha256:}"
136+
137+
- name: Upload digest
138+
uses: actions/upload-artifact@v4
139+
with:
140+
name: ${{ steps.image.outputs.ARTIFACT }}
141+
path: /tmp/digests/*
142+
if-no-files-found: error
143+
retention-days: 1
144+
145+
push:
146+
runs-on: ubuntu-latest
147+
needs: [metadata, build]
148+
strategy:
149+
matrix:
150+
python_version:
151+
- "3.9"
152+
- "3.10"
153+
- "3.11"
154+
- "3.12"
155+
- "3.13"
156+
python_variant:
157+
- ""
158+
- "-slim"
159+
160+
steps:
161+
- name: Checkout
162+
uses: actions/checkout@v5
163+
with:
164+
ref: ${{ needs.metadata.outputs.LATEST_RELEASE }}
165+
166+
- name: Download digests
167+
uses: actions/download-artifact@v5
168+
with:
169+
path: /tmp/artifacts
170+
pattern: "*-digests"
171+
172+
- name: Copy digests
173+
run: |
174+
mkdir -p /tmp/digests
175+
cp /tmp/artifacts/${{ matrix.python_version }}${{ matrix.python_variant }}-*-digests/* /tmp/digests
176+
177+
- name: Set up Docker Buildx
178+
uses: docker/setup-buildx-action@v3
179+
180+
- name: Login to GitHub Container Registry
181+
uses: docker/login-action@v3
182+
if: github.event_name != 'pull_request'
183+
with:
184+
registry: ghcr.io
185+
username: ${{ github.repository_owner }}
186+
password: ${{ secrets.GIT_TOKEN }}
187+
188+
- name: Generate Image Name
189+
id: image
190+
run: |
191+
echo "IMAGE=ghcr.io/${{ github.repository }}" >> $GITHUB_OUTPUT
192+
193+
- name: Generate Tags
194+
uses: docker/metadata-action@v5
195+
id: metadata
196+
with:
197+
context: git
198+
images: |
199+
ghcr.io/${{ github.repository }}
200+
flavor: |
201+
suffix=-py${{ matrix.python_version }}${{ matrix.python_variant }},onlatest=true
202+
tags: |
203+
type=edge,value=nightly
204+
type=ref,event=pr
205+
type=sha,event=branch
206+
type=semver,pattern={{version}}
207+
type=semver,pattern={{major}}.{{minor}}
208+
type=semver,pattern={{major}}
209+
210+
- name: Create manifest list and push
211+
working-directory: /tmp/digests
212+
run: |
213+
docker buildx imagetools create --dry-run $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
214+
$(printf '${{ steps.image.outputs.IMAGE }}@sha256:%s ' *)
215+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
216+
$(printf '${{ steps.image.outputs.IMAGE }}@sha256:%s ' *)
217+
218+
- name: Generate Tags
219+
uses: docker/metadata-action@v5
220+
id: metadata-latest
221+
if: matrix.python_version == env.LATEST_PYTHON_VERSION
222+
with:
223+
context: git
224+
images: |
225+
ghcr.io/${{ github.repository }}
226+
flavor: |
227+
suffix=${{ matrix.python_variant }},onlatest=true
228+
tags: |
229+
type=semver,pattern={{version}}
230+
type=semver,pattern={{major}}.{{minor}}
231+
type=semver,pattern={{major}}
232+
233+
- name: Create manifest list and push for latest python version
234+
if: matrix.python_version == env.LATEST_PYTHON_VERSION
235+
working-directory: /tmp/digests
236+
run: |
237+
docker buildx imagetools create --dry-run $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
238+
$(printf '${{ steps.image.outputs.IMAGE }}@sha256:%s ' *)
239+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
240+
$(printf '${{ steps.image.outputs.IMAGE }}@sha256:%s ' *)
241+
242+
- name: Docker Hub Description
243+
uses: peter-evans/dockerhub-description@v4
244+
with:
245+
username: ${{ secrets.DOCKERHUB_USERNAME }}
246+
password: ${{ secrets.DOCKERHUB_PASSWORD }}
247+
short-description: ${{ github.event.repository.description }}

0 commit comments

Comments
 (0)