Skip to content

Commit 3dbfe69

Browse files
authored
[#389] Configure CI to run in Github Actions
* New Github actions folder * Match exact node version * Set up env vars * Format file * Debugging DATABASE_URL * Try again * Hostname should be service name * Add postgres host auth trust * Set secrets in env * Remove deploy step * Set up Dockerfile for image based deployment * Invoke pm2-runtime from server package.json
1 parent 211518c commit 3dbfe69

4 files changed

Lines changed: 753 additions & 18 deletions

File tree

.github/workflows/ci.yml

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
name: CI
2+
on:
3+
push:
4+
branches:
5+
- 'dev'
6+
- 'main'
7+
pull_request:
8+
types: [opened, reopened, synchronize]
9+
10+
jobs:
11+
meta:
12+
name: Generate and check metadata
13+
runs-on: ubuntu-latest
14+
outputs:
15+
environment: ${{ steps.environment.outputs.environment }}
16+
labels: ${{ steps.meta.outputs.labels }}
17+
tag: ${{ steps.meta.outputs.tags }}
18+
tag_names: ${{ steps.meta.outputs.tag_names }}
19+
tag_exists: ${{ steps.check-image.outputs.tag_exists }}
20+
json: ${{ steps.meta.outputs.json }}
21+
version: ${{ steps.meta.outputs.version }}
22+
steps:
23+
- name: Set environment variable based on branch
24+
id: environment
25+
run: |
26+
if [[ "${{ github.ref_name }}" == "main" ]]; then
27+
echo "environment=main" >> "$GITHUB_OUTPUT"
28+
elif [[ "${{ github.ref_name }}" == "dev" ]]; then
29+
echo "environment=dev" >> "$GITHUB_OUTPUT"
30+
fi
31+
- name: Docker meta
32+
id: meta
33+
uses: docker/metadata-action@v5
34+
with:
35+
images: ${{ vars.REGISTRY_IMAGE }}
36+
tags: |
37+
type=sha,format=long
38+
- name: Login to Docker Hub
39+
uses: docker/login-action@v3
40+
with:
41+
username: ${{ secrets.DOCKERHUB_USERNAME }}
42+
password: ${{ secrets.DOCKERHUB_TOKEN }}
43+
- name: Check if image exists already
44+
id: check-image
45+
run: |
46+
if docker manifest inspect ${{ steps.meta.outputs.tags }} > /dev/null 2>&1; then
47+
echo "tag_exists=true" >> "$GITHUB_OUTPUT"
48+
else
49+
echo "tag_exists=false" >> "$GITHUB_OUTPUT"
50+
fi
51+
52+
test:
53+
name: Test
54+
needs: meta
55+
runs-on: ubuntu-latest
56+
if: ${{ needs.meta.outputs.tag_exists == 'false' }}
57+
container: node:18.10.0-bullseye
58+
services:
59+
db:
60+
image: postgres:12
61+
env:
62+
POSTGRES_HOST_AUTH_METHOD: trust
63+
mailcatcher:
64+
image: dockage/mailcatcher:0.8.2
65+
env:
66+
DATABASE_URL: postgres://postgres@db/bats
67+
SMTP_HOST: mailcatcher
68+
AGORA_APP_CERTIFICATE: ${{ secrets.AGORA_APP_CERTIFICATE }}
69+
REACT_APP_AGORA_APP_ID: ${{ secrets.REACT_APP_AGORA_APP_ID }}
70+
steps:
71+
- name: Check out repository code
72+
uses: actions/checkout@v4
73+
- name: Set up package cache
74+
uses: actions/setup-node@v4
75+
with:
76+
node-version: '18.10.0'
77+
cache: 'yarn'
78+
- name: Install Dependencies
79+
run: yarn install && yarn workspace e2e install-chromium
80+
- name: Create database
81+
run: yarn workspace server sequelize db:create && yarn workspace server sequelize db:create --env test
82+
- name: Run migrations
83+
run: yarn workspace server sequelize db:migrate && yarn workspace server sequelize db:migrate --env test
84+
- name: Run seeds
85+
run: yarn workspace server sequelize db:seed:all
86+
- name: Run Tests
87+
run: eval $(cat example.env | grep -v -e 'AGORA_APP_CERTIFICATE' -e 'REACT_APP_AGORA_APP_ID' -e 'DATABASE_URL' -e 'SMTP_HOST' | sed 's/^/export /'); yarn run test
88+
89+
build:
90+
name: Build Image
91+
needs: [meta, test]
92+
strategy:
93+
fail-fast: false
94+
matrix:
95+
runner:
96+
- ubuntu-24.04
97+
- ubuntu-24.04-arm
98+
runs-on: ${{ matrix.runner }}
99+
if: ${{ github.ref_name == 'dev' || github.ref_name == 'main' }}
100+
steps:
101+
- name: Prepare
102+
run: |
103+
if [[ ${{ matrix.runner }} == "ubuntu-24.04-arm" ]]; then
104+
platform=linux/arm64
105+
else
106+
platform=linux/amd64
107+
fi
108+
echo "PLATFORM=${platform}" >> $GITHUB_ENV
109+
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
110+
- name: Set up docker buildx
111+
uses: docker/setup-buildx-action@v3
112+
- name: Login to docker hub
113+
uses: docker/login-action@v3
114+
with:
115+
username: ${{ secrets.DOCKERHUB_USERNAME }}
116+
password: ${{ secrets.DOCKERHUB_TOKEN }}
117+
- name: Build and push by digest
118+
id: build
119+
uses: docker/build-push-action@v6
120+
with:
121+
platforms: ${{ env.PLATFORM }}
122+
labels: ${{ needs.meta.outputs.labels }}
123+
tags: ${{ vars.REGISTRY_IMAGE }}
124+
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
125+
- name: Export digest
126+
run: |
127+
mkdir -p ${{ runner.temp }}/digests
128+
digest="${{ steps.build.outputs.digest }}"
129+
touch "${{ runner.temp }}/digests/${digest#sha256:}"
130+
- name: Upload digest
131+
uses: actions/upload-artifact@v4
132+
with:
133+
name: digests-${{ env.PLATFORM_PAIR }}
134+
path: ${{ runner.temp }}/digests/*
135+
if-no-files-found: error
136+
retention-days: 1
137+
138+
merge:
139+
runs-on: ubuntu-latest
140+
needs: [meta, build]
141+
env:
142+
DOCKER_METADATA_OUTPUT_VERSION: ${{ needs.meta.outputs.version }}
143+
DOCKER_METADATA_OUTPUT_TAGS: ${{ needs.meta.outputs.tag }}
144+
DOCKER_METADATA_OUTPUT_TAG_NAMES: ${{ needs.meta.outputs.tag_names }}
145+
DOCKER_METADATA_OUTPUT_LABELS: ${{ needs.meta.outputs.labels }}
146+
DOCKER_METADATA_OUTPUT_JSON: ${{ needs.meta.outputs.json }}
147+
steps:
148+
- name: Download digests
149+
uses: actions/download-artifact@v4
150+
with:
151+
path: ${{ runner.temp }}/digests
152+
pattern: digests-*
153+
merge-multiple: true
154+
- name: Login to Docker Hub
155+
uses: docker/login-action@v3
156+
with:
157+
username: ${{ secrets.DOCKERHUB_USERNAME }}
158+
password: ${{ secrets.DOCKERHUB_TOKEN }}
159+
- name: Set up Docker Buildx
160+
uses: docker/setup-buildx-action@v3
161+
- name: Create manifest list and push
162+
working-directory: ${{ runner.temp }}/digests
163+
run: |
164+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
165+
$(printf '${{ vars.REGISTRY_IMAGE }}@sha256:%s ' *)
166+
- name: Inspect image
167+
run: |
168+
docker buildx imagetools inspect ${{ needs.meta.outputs.tag }}

Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@ ADD . $APP_HOME
2020
WORKDIR $APP_HOME
2121

2222
RUN yarn install && yarn workspace client build
23+
24+
# Set up default command
25+
CMD ["yarn", "workspace", "server", "start:prod"]

server/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"passport-oauth2": "^1.6.1",
3232
"passport-oauth2-refresh": "^2.2.0",
3333
"pg": "^8.7.3",
34+
"pm2": "^6.0.14",
3435
"randomstring": "^1.3.0",
3536
"rollbar": "^2.26.3",
3637
"sequelize": "^6.37.7",
@@ -49,7 +50,7 @@
4950
},
5051
"scripts": {
5152
"start:dev": "./bin/init; nodemon -V --ignore ./test ./bin/www",
52-
"start:prod": "node ./bin/www",
53+
"start:prod": "pm2-runtime ./bin/www",
5354
"test": "mocha --recursive test"
5455
}
5556
}

0 commit comments

Comments
 (0)