Skip to content

Commit 69ef5d4

Browse files
committed
ci: implement action for building Docker image
1 parent 77449a3 commit 69ef5d4

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
name: Docker
2+
3+
on:
4+
push:
5+
branches: [ "main", "ci/implement-docker-action" ]
6+
tags: [ 'v*.*.*' ]
7+
pull_request:
8+
branches: [ "main" ]
9+
10+
env:
11+
REGISTRY: ghcr.io
12+
IMAGE_NAME_PREFIX: ${{ github.repository }}
13+
14+
jobs:
15+
detect-affected:
16+
runs-on: ubuntu-latest
17+
outputs:
18+
matrix: ${{ steps.set-matrix.outputs.matrix }}
19+
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
23+
24+
- if: github.ref != 'refs/heads/main'
25+
run: |
26+
set -euo pipefail
27+
28+
git branch
29+
30+
git rev-parse --verify main || git remote set-branches origin main && git fetch --depth 1 origin main && git branch main origin/main
31+
32+
git branch
33+
34+
- name: Setup pnpm
35+
uses: pnpm/action-setup@v4
36+
with:
37+
version: 10.7
38+
39+
- name: Setup Node.js
40+
uses: actions/setup-node@v4
41+
with:
42+
node-version: 22
43+
cache: "pnpm"
44+
45+
- name: Setup GoLang
46+
uses: actions/setup-go@v5
47+
with:
48+
go-version-file: "go.work"
49+
50+
- name: Install dependencies
51+
run: pnpm install --frozen-lockfile
52+
53+
- name: Get affected projects
54+
id: get-affected
55+
run: |
56+
set -euo pipefail
57+
58+
AFFECTED_PROJECTS=$(npx nx show projects --affected --projects "apps/*" --json)
59+
60+
echo "affected_projects=$AFFECTED_PROJECTS" >> $GITHUB_OUTPUT
61+
62+
- name: Set matrix
63+
id: set-matrix
64+
run: |
65+
set -euo pipefail
66+
67+
cat > docker-config.json << EOL
68+
{
69+
"ui": {
70+
"dockerfile": "apps/ui/Dockerfile",
71+
"context": "."
72+
},
73+
"api": {
74+
"dockerfile": "apps/api/build/package/Dockerfile",
75+
"context": "."
76+
}
77+
}
78+
EOL
79+
80+
AFFECTED_PROJECTS='${{ steps.get-affected.outputs.affected_projects }}'
81+
MATRIX=$(echo $AFFECTED_PROJECTS | jq -c --slurpfile config docker-config.json '
82+
. as $projects |
83+
$config[0] as $dockerConfigs |
84+
{
85+
project: $projects | map(select(. as $p | $dockerConfigs[$p] != null)) | map({
86+
name: .,
87+
dockerfile: $dockerConfigs[.].dockerfile,
88+
context: $dockerConfigs[.].context
89+
})
90+
}
91+
')
92+
93+
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
94+
95+
build-docker:
96+
needs: detect-affected
97+
if: ${{ needs.detect-affected.outputs.matrix != '{"project":[]}' }}
98+
runs-on: ubuntu-latest
99+
strategy:
100+
matrix: ${{ fromJson(needs.detect-affected.outputs.matrix) }}
101+
fail-fast: false
102+
permissions:
103+
contents: read
104+
packages: write
105+
id-token: write
106+
107+
steps:
108+
- name: Checkout repository
109+
uses: actions/checkout@v4
110+
111+
- name: Install cosign
112+
if: github.event_name != 'pull_request'
113+
uses: sigstore/cosign-installer@v3
114+
with:
115+
cosign-release: 'v2.2.4'
116+
117+
- name: Set up Docker Buildx
118+
uses: docker/setup-buildx-action@v3
119+
120+
- name: Log into registry ${{ env.REGISTRY }}
121+
if: github.event_name != 'pull_request'
122+
uses: docker/login-action@v3
123+
with:
124+
registry: ${{ env.REGISTRY }}
125+
username: ${{ github.actor }}
126+
password: ${{ secrets.GITHUB_TOKEN }}
127+
128+
- name: Extract Docker metadata
129+
id: meta
130+
uses: docker/metadata-action@v5
131+
with:
132+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_PREFIX }}-${{ matrix.project.name }}
133+
tags: |
134+
type=ref,event=branch
135+
type=ref,event=pr
136+
type=sha
137+
type=semver,pattern={{version}}
138+
type=semver,pattern={{major}}.{{minor}}
139+
type=semver,pattern={{major}}
140+
141+
- name: Build and push Docker image
142+
id: build-and-push
143+
uses: docker/build-push-action@v6
144+
with:
145+
context: ${{ matrix.project.context }}
146+
file: ${{ matrix.project.dockerfile }}
147+
push: ${{ github.event_name != 'pull_request' }}
148+
tags: ${{ steps.meta.outputs.tags }}
149+
labels: ${{ steps.meta.outputs.labels }}
150+
cache-from: type=gha
151+
cache-to: type=gha,mode=max
152+
153+
- name: Sign the published Docker image
154+
if: ${{ github.event_name != 'pull_request' }}
155+
env:
156+
TAGS: ${{ steps.meta.outputs.tags }}
157+
DIGEST: ${{ steps.build-and-push.outputs.digest }}
158+
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}

0 commit comments

Comments
 (0)