Skip to content

Commit d7b8a83

Browse files
authored
ci: Improve GitHub Actions workflows (#37)
2 parents 925ef3c + 2438cb6 commit d7b8a83

5 files changed

Lines changed: 117 additions & 131 deletions

File tree

.github/workflows/image-build-push.yaml

Lines changed: 76 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@ name: Docker Build
33
on:
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+
1118
permissions:
1219
contents: read
1320
packages: write
@@ -17,6 +24,16 @@ env:
1724
GHCR_IMAGE: ghcr.io/perun-engineering/aws-helm-kubectl
1825

1926
jobs:
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 }}

.github/workflows/pr-title.yaml

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,41 +16,22 @@ jobs:
1616
name: Validate PR title
1717
runs-on: ubuntu-latest
1818
steps:
19-
# Please look up the latest version from
20-
# https://github.com/amannn/action-semantic-pull-request/releases
2119
- uses: amannn/action-semantic-pull-request@v6
2220
env:
2321
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2422
with:
25-
# Configure which types are allowed.
26-
# Default: https://github.com/commitizen/conventional-commit-types
2723
types: |
2824
fix
2925
feat
3026
docs
3127
ci
3228
chore
33-
# Configure that a scope must always be provided.
29+
refactor
30+
test
31+
perf
32+
build
33+
revert
3434
requireScope: false
35-
# Configure additional validation for the subject based on a regex.
36-
# This example ensures the subject starts with an uppercase character.
37-
subjectPattern: ^[A-Z].+$
38-
# If `subjectPattern` is configured, you can use this property to override
39-
# the default error message that is shown when the pattern doesn't match.
40-
# The variables `subject` and `title` can be used within the message.
41-
subjectPatternError: |
42-
The subject "{subject}" found in the pull request title "{title}"
43-
didn't match the configured pattern. Please ensure that the subject
44-
starts with an uppercase character.
45-
# For work-in-progress PRs you can typically use draft pull requests
46-
# from Github. However, private repositories on the free plan don't have
47-
# this option and therefore this action allows you to opt-in to using the
48-
# special "[WIP]" prefix to indicate this state. This will avoid the
49-
# validation of the PR title and the pull request checks remain pending.
50-
# Note that a second check will be reported if this is enabled.
35+
subjectPattern: ^.+$
5136
wip: true
52-
# When using "Squash and merge" on a PR with only one commit, GitHub
53-
# will suggest using that commit message instead of the PR title for the
54-
# merge commit, and it's easy to commit this by mistake. Enable this option
55-
# to also validate the commit message for one commit PRs.
5637
validateSingleCommit: false

.github/workflows/release.yaml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ on:
99
branches:
1010
- main
1111

12+
concurrency:
13+
group: release
14+
cancel-in-progress: false
15+
1216
permissions:
1317
contents: read
1418

@@ -20,8 +24,9 @@ jobs:
2024
pull-requests: write
2125
name: Release
2226
runs-on: ubuntu-latest
23-
# Skip running release workflow on forks and only run if Docker Build succeeded
24-
if: github.repository_owner == 'Perun-Engineering' && github.event.workflow_run.conclusion == 'success'
27+
if: >-
28+
github.repository_owner == 'Perun-Engineering' &&
29+
(github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success')
2530
steps:
2631
- name: Checkout
2732
uses: actions/checkout@v6
@@ -46,6 +51,7 @@ jobs:
4651

4752
dockerHubDescription:
4853
runs-on: ubuntu-latest
54+
if: github.repository_owner == 'Perun-Engineering'
4955
steps:
5056
- uses: actions/checkout@v6
5157

0 commit comments

Comments
 (0)