@@ -3,11 +3,18 @@ name: Docker Build
33on :
44 push :
55 branches :
6- - main # Only build and push after PR is merged to main
6+ - main
7+ pull_request :
8+ branches :
9+ - main
710 workflow_dispatch :
811 release :
912 types : [published, edited]
1013
14+ concurrency :
15+ group : docker-build-${{ github.ref }}
16+ cancel-in-progress : true
17+
1118permissions :
1219 contents : read
1320 packages : write
1724 GHCR_IMAGE : ghcr.io/perun-engineering/aws-helm-kubectl
1825
1926jobs :
27+ lint :
28+ runs-on : ubuntu-latest
29+ steps :
30+ - name : Checkout
31+ uses : actions/checkout@v6
32+ - name : Lint Dockerfile
33+ uses : hadolint/hadolint-action@v3.1.0
34+ with :
35+ dockerfile : Dockerfile
36+
2037 define :
2138 runs-on : ubuntu-latest
2239 outputs :
@@ -27,17 +44,45 @@ jobs:
2744 - name : Read environment file
2845 id : read_env
2946 run : |
30- # Extract only the KUBERNETES_VERSIONS line and get the array part
3147 VERSIONS=$(grep '^KUBERNETES_VERSIONS=' .env | cut -d'=' -f2-)
3248 echo "versions=$VERSIONS" >> $GITHUB_OUTPUT
3349
50+ validate :
51+ if : github.event_name == 'pull_request'
52+ needs : [lint, define]
53+ runs-on : ubuntu-latest
54+ steps :
55+ - name : Checkout
56+ uses : actions/checkout@v6
57+ - name : Read environment file
58+ run : cat .env >> ${GITHUB_ENV}
59+ - name : Set up Docker Buildx
60+ uses : docker/setup-buildx-action@v3
61+ - name : Build (validation only)
62+ uses : docker/build-push-action@v6
63+ with :
64+ context : .
65+ platforms : linux/amd64
66+ push : false
67+ build-args : |
68+ KUBE_VERSION=${{ fromJson(needs.define.outputs.kubernetes_versions)[0] }}
69+ HELM_VERSION=${{ env.HELM_VERSION }}
70+ SOPS_VERSION=${{ env.SOPS_VERSION }}
71+ HELM_SECRETS_VERSION=${{ env.HELM_SECRETS_VERSION }}
72+ HELM_S3_VERSION=${{ env.HELM_S3_VERSION }}
73+ HELMFILE_VERSION=${{ env.HELMFILE_VERSION }}
74+ AWS_CLI_VERSION=${{ env.AWS_CLI_VERSION }}
75+ HELM_DIFF_VERSION=${{ env.HELM_DIFF_VERSION }}
76+ ALPINE_PYTHON=${{ env.ALPINE_PYTHON }}
77+ ALPINE_VERSION=${{ env.ALPINE_VERSION }}
78+
3479 build :
35- needs :
36- - define
80+ if : github.event_name != 'pull_request'
81+ needs : [lint, define]
3782 strategy :
3883 fail-fast : true
3984 matrix :
40- version : ${{fromJson(needs.define.outputs.kubernetes_versions)}}
85+ version : ${{ fromJson(needs.define.outputs.kubernetes_versions) }}
4186 platform :
4287 - linux/amd64
4388 - linux/arm64
@@ -52,21 +97,13 @@ jobs:
5297 uses : actions/checkout@v6
5398 - name : Read environment file
5499 run : cat .env >> ${GITHUB_ENV}
55- - name : Set up QEMU
56- uses : docker/setup-qemu-action@v4
57100 - name : Set up Docker Buildx
58101 uses : docker/setup-buildx-action@v3
59102 - name : Login to Docker Hub
60103 uses : docker/login-action@v4
61104 with :
62105 username : ${{ vars.DOCKER_USERNAME }}
63106 password : ${{ secrets.DOCKER_PASSWORD }}
64- - name : Login to GitHub Container Registry
65- uses : docker/login-action@v4
66- with :
67- registry : ghcr.io
68- username : ${{ github.actor }}
69- password : ${{ secrets.GITHUB_TOKEN }}
70107 - name : Extract metadata
71108 id : meta
72109 uses : docker/metadata-action@v6
@@ -76,10 +113,9 @@ jobs:
76113 ${{ env.GHCR_IMAGE }}
77114 tags : |
78115 type=ref,event=branch
79- type=ref,event=pr
80116 type=semver,pattern={{version}}
81117 type=semver,pattern={{major}}.{{minor}}
82- - name : Build and push to Docker Hub
118+ - name : Build and push
83119 id : build
84120 uses : docker/build-push-action@v6
85121 with :
@@ -98,66 +134,29 @@ jobs:
98134 ALPINE_PYTHON=${{ env.ALPINE_PYTHON }}
99135 ALPINE_VERSION=${{ env.ALPINE_VERSION }}
100136 labels : ${{ steps.meta.outputs.labels }}
101- cache-from : type=gha
102- cache-to : type=gha,mode=max
137+ cache-from : type=gha,scope=${{ matrix.version }}-${{ matrix.platform }}
138+ cache-to : type=gha,mode=max,scope=${{ matrix.version }}-${{ matrix.platform }}
103139
104- - name : Re-tag and push to GHCR
105- id : build-ghcr
106- uses : docker/build-push-action@v6
107- with :
108- context : .
109- platforms : ${{ matrix.platform }}
110- outputs : type=image,name=${{ env.GHCR_IMAGE }},push-by-digest=true,name-canonical=true,push=true
111- build-args : |
112- KUBE_VERSION=${{ matrix.version }}
113- HELM_VERSION=${{ env.HELM_VERSION }}
114- SOPS_VERSION=${{ env.SOPS_VERSION }}
115- HELM_SECRETS_VERSION=${{ env.HELM_SECRETS_VERSION }}
116- HELM_S3_VERSION=${{ env.HELM_S3_VERSION }}
117- HELMFILE_VERSION=${{ env.HELMFILE_VERSION }}
118- AWS_CLI_VERSION=${{ env.AWS_CLI_VERSION }}
119- HELM_DIFF_VERSION=${{ env.HELM_DIFF_VERSION }}
120- ALPINE_PYTHON=${{ env.ALPINE_PYTHON }}
121- ALPINE_VERSION=${{ env.ALPINE_VERSION }}
122- labels : ${{ steps.meta.outputs.labels }}
123- cache-from : type=gha
124-
125- - name : Export digest (Docker Hub)
140+ - name : Export digest
126141 run : |
127142 mkdir -p /tmp/digests
128143 digest="${{ steps.build.outputs.digest }}"
129144 echo "$digest" | sed 's/^sha256://' > "/tmp/digests/${digest#sha256:}"
130145
131- - name : Export digest (GHCR)
132- run : |
133- mkdir -p /tmp/digests-ghcr
134- digest="${{ steps.build-ghcr.outputs.digest }}"
135- echo "$digest" | sed 's/^sha256://' > "/tmp/digests-ghcr/${digest#sha256:}"
136-
137- - name : Upload digest (Docker Hub)
146+ - name : Upload digest
138147 uses : actions/upload-artifact@v7
139148 with :
140149 name : digests-${{ matrix.version }}-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
141150 path : /tmp/digests/*
142151 if-no-files-found : error
143152 retention-days : 1
144153
145- - name : Upload digest (GHCR)
146- uses : actions/upload-artifact@v7
147- with :
148- name : digests-ghcr-${{ matrix.version }}-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
149- path : /tmp/digests-ghcr/*
150- if-no-files-found : error
151- retention-days : 1
152-
153154 merge :
154- needs :
155- - define
156- - build
155+ needs : [define, build]
157156 runs-on : ubuntu-latest
158157 strategy :
159158 matrix :
160- version : ${{fromJson(needs.define.outputs.kubernetes_versions)}}
159+ version : ${{ fromJson(needs.define.outputs.kubernetes_versions) }}
161160 steps :
162161 - name : Download digests
163162 uses : actions/download-artifact@v8
@@ -175,21 +174,17 @@ jobs:
175174 username : ${{ vars.DOCKER_USERNAME }}
176175 password : ${{ secrets.DOCKER_PASSWORD }}
177176
178- - name : Create manifest list and push (Docker Hub)
177+ - name : Create manifest list and push
179178 run : |
180- # First verify the directory and files exist
181179 ls -la /tmp/digests
182-
183- # Create the manifest list
184180 cd /tmp/digests
185181 docker buildx imagetools create -t ${{ env.DOCKERHUB_IMAGE }}:${{ matrix.version }} \
186182 $(for digest in *; do echo -n "${{ env.DOCKERHUB_IMAGE }}@sha256:$digest "; done)
187183
188- - name : Inspect image (Docker Hub)
189- run : |
190- docker buildx imagetools inspect ${{ env.DOCKERHUB_IMAGE }}:${{ matrix.version }}
184+ - name : Inspect image
185+ run : docker buildx imagetools inspect ${{ env.DOCKERHUB_IMAGE }}:${{ matrix.version }}
191186
192- - name : Test final image (Docker Hub)
187+ - name : Test final image
193188 run : |
194189 echo "Testing final image functionality..."
195190 docker run --rm ${{ env.DOCKERHUB_IMAGE }}:${{ matrix.version }} /bin/bash -c "
@@ -202,55 +197,34 @@ jobs:
202197 echo 'All tools working correctly!'
203198 "
204199
205- merge-ghcr :
206- needs :
207- - define
208- - build
200+ copy-to-ghcr :
201+ needs : [define, merge]
209202 runs-on : ubuntu-latest
210203 strategy :
211204 matrix :
212- version : ${{fromJson(needs.define.outputs.kubernetes_versions)}}
205+ version : ${{ fromJson(needs.define.outputs.kubernetes_versions) }}
213206 steps :
214- - name : Download digests (GHCR)
215- uses : actions/download-artifact@v8
216- with :
217- pattern : digests-ghcr-${{ matrix.version }}-*
218- path : /tmp/digests-ghcr
219- merge-multiple : true
220-
221207 - name : Set up Docker Buildx
222208 uses : docker/setup-buildx-action@v3
223209
210+ - name : Login to Docker Hub
211+ uses : docker/login-action@v4
212+ with :
213+ username : ${{ vars.DOCKER_USERNAME }}
214+ password : ${{ secrets.DOCKER_PASSWORD }}
215+
224216 - name : Login to GitHub Container Registry
225217 uses : docker/login-action@v4
226218 with :
227219 registry : ghcr.io
228220 username : ${{ github.actor }}
229221 password : ${{ secrets.GITHUB_TOKEN }}
230222
231- - name : Create manifest list and push (GHCR)
232- run : |
233- # First verify the directory and files exist
234- ls -la /tmp/digests-ghcr
235-
236- # Create the manifest list
237- cd /tmp/digests-ghcr
238- docker buildx imagetools create -t ${{ env.GHCR_IMAGE }}:${{ matrix.version }} \
239- $(for digest in *; do echo -n "${{ env.GHCR_IMAGE }}@sha256:$digest "; done)
240-
241- - name : Inspect image (GHCR)
223+ - name : Copy manifest to GHCR
242224 run : |
243- docker buildx imagetools inspect ${{ env.GHCR_IMAGE }}:${{ matrix.version }}
225+ docker buildx imagetools create \
226+ -t ${{ env.GHCR_IMAGE }}:${{ matrix.version }} \
227+ ${{ env.DOCKERHUB_IMAGE }}:${{ matrix.version }}
244228
245- - name : Test final image (GHCR)
246- run : |
247- echo "Testing final image functionality..."
248- docker run --rm ${{ env.GHCR_IMAGE }}:${{ matrix.version }} /bin/bash -c "
249- echo 'Testing tool versions:' &&
250- kubectl version --client &&
251- helm version &&
252- aws --version &&
253- sops --version &&
254- helmfile --version &&
255- echo 'All tools working correctly!'
256- "
229+ - name : Inspect image
230+ run : docker buildx imagetools inspect ${{ env.GHCR_IMAGE }}:${{ matrix.version }}
0 commit comments