Skip to content

Commit d992d70

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

File tree

1 file changed

+208
-18
lines changed

1 file changed

+208
-18
lines changed

.github/workflows/docker.yml

Lines changed: 208 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,77 @@ 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

3140
steps:
32-
- name: Checkout
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
82+
steps:
83+
- name: Checkout (Latest Release)
84+
if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success'
85+
uses: actions/checkout@v5
86+
with:
87+
ref: ${{ needs.metadata.outputs.LATEST_RELEASE}}
88+
89+
- name: Checkout (Other)
90+
if: github.event_name != 'workflow_run'
3391
uses: actions/checkout@v5
3492

3593
- name: Set up QEMU
@@ -46,22 +104,154 @@ jobs:
46104
username: ${{ github.repository_owner }}
47105
password: ${{ secrets.GIT_TOKEN }}
48106

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

0 commit comments

Comments
 (0)