Skip to content

Commit 413179f

Browse files
committed
Add CI for docker image build and push to dockerhub (#46)
Signed-off-by: SeeuSim <[email protected]>
1 parent 80a208c commit 413179f

File tree

2 files changed

+218
-0
lines changed

2 files changed

+218
-0
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
name: Build & publish PeerPrep images
2+
on:
3+
pull_request:
4+
types: [review_requested, ready_for_review]
5+
push:
6+
branches:
7+
- main
8+
9+
env:
10+
DOCKER_REGISTRY_USN: ay2425s1cs3219g16
11+
USER_EXPRESS_PORT: 9001
12+
QUESTION_EXPRESS_PORT: 9002
13+
COLLAB_EXPRESS_PORT: 9003
14+
MATCH_EXPRESS_PORT: 9004
15+
FRONTEND_PORT: 3000
16+
17+
jobs:
18+
changes:
19+
runs-on: ubuntu-latest
20+
# Required permissions
21+
permissions:
22+
pull-requests: read
23+
# Set job outputs to values from filter step
24+
outputs:
25+
matrix: ${{ steps.set-matrix.outputs.matrix }} # Output the matrix as a JSON string
26+
steps:
27+
- uses: actions/checkout@v4
28+
if: contains(github.ref, 'main')
29+
# For pull requests it's not necessary to checkout the code
30+
- uses: dorny/paths-filter@v3
31+
id: filter
32+
with:
33+
filters: |
34+
user:
35+
- 'backend/user/**'
36+
question:
37+
- 'backend/question/**'
38+
collaboration:
39+
- 'backend/collaboration/**'
40+
matching:
41+
- 'backend/matching/**'
42+
frontend:
43+
- 'frontend/**'
44+
- name: output-job-matrix
45+
id: set-matrix
46+
run: |
47+
is_main=${{ contains(github.ref, 'main') }}
48+
matrix=()
49+
if [[ "${{ steps.filter.outputs.user }}" == "true" || "$is_main" == "true" ]]; then
50+
config=$(jq -n \
51+
--arg pkg "user" \
52+
--arg img "$DOCKER_REGISTRY_USN/user-express" \
53+
--arg ctx "./backend/user" \
54+
--arg dkr "./backend/user/express.Dockerfile" \
55+
--arg bag "port=$USER_EXPRESS_PORT" \
56+
'{package: $pkg, image: $img, context: $ctx, dockerfile: $dkr, "build-args": $bag}')
57+
matrix+=("$config")
58+
fi
59+
if [[ "${{ steps.filter.outputs.question }}" == "true" || "$is_main" == "true" ]]; then
60+
config=$(jq -n \
61+
--arg pkg "question" \
62+
--arg img "$DOCKER_REGISTRY_USN/question-express" \
63+
--arg ctx "./backend/question" \
64+
--arg dkr "./backend/question/express.Dockerfile" \
65+
--arg bag "port=$QUESTION_EXPRESS_PORT" \
66+
'{package: $pkg, image: $img, context: $ctx, dockerfile: $dkr, "build-args": $bag}')
67+
matrix+=("$config")
68+
fi
69+
if [[ "${{ steps.filter.outputs.collaboration }}" == "true" || "$is_main" == "true" ]]; then
70+
config=$(jq -n \
71+
--arg pkg "collaboration" \
72+
--arg img "$DOCKER_REGISTRY_USN/collab-express" \
73+
--arg ctx "./backend/collaboration" \
74+
--arg dkr "./backend/collaboration/express.Dockerfile" \
75+
--arg bag "port=$COLLAB_EXPRESS_PORT" \
76+
'{package: $pkg, image: $img, context: $ctx, dockerfile: $dkr, "build-args": $bag}')
77+
matrix+=("$config")
78+
fi
79+
if [[ "${{ steps.filter.outputs.matching }}" == "true" || "$is_main" == "true" ]]; then
80+
config=$(jq -n \
81+
--arg pkg "matching" \
82+
--arg img "$DOCKER_REGISTRY_USN/match-express" \
83+
--arg ctx "./backend/matching" \
84+
--arg dkr "./backend/matching/express.Dockerfile" \
85+
--arg bag "port=$MATCH_EXPRESS_PORT" \
86+
'{package: $pkg, image: $img, context: $ctx, dockerfile: $dkr, "build-args": $bag}')
87+
matrix+=("$config")
88+
fi
89+
if [[ "${{ steps.filter.outputs.frontend }}" == "true" || "$is_main" == "true" ]]; then
90+
config=$(jq -n \
91+
--arg pkg "frontend" \
92+
--arg img "$DOCKER_REGISTRY_USN/frontend" \
93+
--arg ctx "./frontend" \
94+
--arg dkr "./frontend/express.Dockerfile" \
95+
--arg bag "port=$FRONTEND_PORT" \
96+
'{package: $pkg, image: $img, context: $ctx, dockerfile: $dkr, "build-args": $bag}')
97+
matrix+=("$config")
98+
fi
99+
formatted_matrix=$(echo "${matrix[@]}" | jq -cs .)
100+
echo "Outputs Generated: $formatted_matrix"
101+
echo "matrix=$formatted_matrix" >> $GITHUB_OUTPUT
102+
103+
build-and-push-image:
104+
needs: changes
105+
if: ${{ fromJson(needs.changes.outputs.matrix)[0] != null }}
106+
runs-on: ubuntu-latest
107+
strategy:
108+
fail-fast: true
109+
matrix:
110+
include: ${{ fromJson(needs.changes.outputs.matrix) }} # Use the matrix from the first job
111+
# - package: user
112+
# image: ay2425s1cs3219g16/user-express
113+
# context: ./backend/user
114+
# dockerfile: ./backend/user/express.Dockerfile
115+
# build-args: |
116+
# port=9001
117+
# - package: question
118+
# image: ay2425s1cs3219g16/question-express
119+
# context: ./backend/question
120+
# dockerfile: ./backend/question/express.Dockerfile
121+
# build-args: |
122+
# port=9002
123+
# - package: collaboration
124+
# image: ay2425s1cs3219g16/collab-express
125+
# context: ./backend/collaboration
126+
# dockerfile: ./backend/collaboration/express.Dockerfile
127+
# build-args: |
128+
# port=9003
129+
# - package: matching
130+
# image: ay2425s1cs3219g16/match-express
131+
# context: ./backend/matching
132+
# dockerfile: ./backend/matching/express.Dockerfile
133+
# build-args: |
134+
# port=9004
135+
# - package: frontend
136+
# image: ay2425s1cs3219g16/frontend
137+
# context: ./frontend
138+
# dockerfile: ./frontend/frontend.Dockerfile
139+
# build-args: |
140+
# port=3000
141+
permissions:
142+
contents: read
143+
packages: write
144+
145+
steps:
146+
- name: Checkout repository
147+
uses: actions/checkout@v4
148+
149+
- name: Set up QEMU
150+
uses: docker/setup-qemu-action@v3
151+
152+
- name: Set up Docker Buildx
153+
uses: docker/setup-buildx-action@v3
154+
155+
- name: Log in to the Container registry
156+
uses: docker/login-action@v3
157+
with:
158+
username: ${{ secrets.DOCKER_USERNAME }}
159+
password: ${{ secrets.DOCKER_PASSWORD }}
160+
161+
- name: Extract metadata (tags, labels) for Docker
162+
id: meta
163+
uses: docker/metadata-action@v5
164+
with:
165+
images: ${{ matrix.image }}
166+
167+
- name: Build and push Docker images for PeerPrep Services
168+
uses: docker/build-push-action@v6
169+
with:
170+
platforms: linux/amd64,linux/arm64
171+
context: ${{ matrix.context }}
172+
file: ${{ matrix.dockerfile }}
173+
build-args: ${{ matrix.build-args }}
174+
push: true
175+
tags: ${{ steps.meta.outputs.tags }}
176+
labels: ${{ steps.meta.outputs.labels }}
177+
cache-from: type=gha
178+
cache-to: type=gha,mode=max

.github/workflows/clear-cache.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Cleanup caches after merge
2+
on:
3+
pull_request:
4+
types:
5+
- closed
6+
workflow_dispatch:
7+
8+
jobs:
9+
cleanup:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
# `actions:write` permission is required to delete caches
13+
# See also: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-a-github-actions-cache-for-a-repository-using-a-cache-id
14+
actions: write
15+
contents: read
16+
17+
steps:
18+
- name: Check out code
19+
uses: actions/checkout@v4
20+
21+
- name: Cleanup cache
22+
run: |
23+
gh extension install actions/gh-actions-cache
24+
25+
REPO=${{ github.repository }}
26+
BRANCH=refs/pull/${{ github.event.pull_request.number }}/merge
27+
28+
echo "Fetching list of cache key"
29+
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH --limit 100 --sort size | cut -f 1 )
30+
31+
## Setting this to not fail the workflow while deleting cache keys.
32+
set +e
33+
echo "Deleting caches..."
34+
for cacheKey in $cacheKeysForPR
35+
do
36+
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
37+
done
38+
echo "Done"
39+
env:
40+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)