Skip to content

Commit 066f6ac

Browse files
committed
chore(repo): add docker smoke tests
1 parent 4a3c172 commit 066f6ac

3 files changed

Lines changed: 768 additions & 0 deletions

File tree

.github/workflows/docker-smoke.yml

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
name: Docker build and smoke test for apps
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
branches: ["preview"]
7+
paths:
8+
- "apps/web/**"
9+
- "apps/space/**"
10+
- "apps/admin/**"
11+
- "apps/live/**"
12+
- "packages/**"
13+
- "turbo.json"
14+
- "pnpm-lock.yaml"
15+
- "pnpm-workspace.yaml"
16+
- ".github/workflows/docker-smoke.yml"
17+
push:
18+
branches: ["preview"]
19+
paths:
20+
- "apps/web/**"
21+
- "apps/space/**"
22+
- "apps/admin/**"
23+
- "apps/live/**"
24+
- "packages/**"
25+
- "turbo.json"
26+
- "pnpm-lock.yaml"
27+
- "pnpm-workspace.yaml"
28+
- ".github/workflows/docker-smoke.yml"
29+
30+
jobs:
31+
determine-matrix:
32+
name: Determine matrix
33+
runs-on: ubuntu-latest
34+
outputs:
35+
matrix: ${{ steps.build-matrix.outputs.matrix }}
36+
steps:
37+
- name: Checkout repository
38+
uses: actions/checkout@v4
39+
with:
40+
fetch-depth: 0
41+
42+
- name: Detect changed paths
43+
id: changes
44+
uses: dorny/paths-filter@v3
45+
with:
46+
filters: |
47+
web:
48+
- 'apps/web/**'
49+
space:
50+
- 'apps/space/**'
51+
admin:
52+
- 'apps/admin/**'
53+
live:
54+
- 'apps/live/**'
55+
common:
56+
- 'turbo.json'
57+
- 'pnpm-lock.yaml'
58+
- 'pnpm-workspace.yaml'
59+
- '.github/workflows/docker-smoke.yml'
60+
- 'packages/**'
61+
62+
- name: Build matrix
63+
id: build-matrix
64+
uses: actions/github-script@v7
65+
with:
66+
script: |
67+
const include = [];
68+
const eventName = context.eventName;
69+
const anyCommon = '${{ steps.changes.outputs.common }}' === 'true';
70+
const changed = {
71+
web: '${{ steps.changes.outputs.web }}' === 'true',
72+
space: '${{ steps.changes.outputs.space }}' === 'true',
73+
admin: '${{ steps.changes.outputs.admin }}' === 'true',
74+
live: '${{ steps.changes.outputs.live }}' === 'true',
75+
};
76+
const add = (name, dockerfile, image, container, port, path, env_flags = "") => include.push({ name, dockerfile, image, container, host_port: port, path, env_flags });
77+
const buildAll = anyCommon || eventName === 'push' || eventName === 'workflow_dispatch';
78+
if (buildAll || changed.web) add('web', 'apps/web/Dockerfile.web', 'plane-web:ci-smoke', 'plane-web-ci', 3001, '/');
79+
if (buildAll || changed.space) add('space', 'apps/space/Dockerfile.space', 'plane-space:ci-smoke', 'plane-space-ci', 3002, '/spaces');
80+
if (buildAll || changed.admin) add('admin', 'apps/admin/Dockerfile.admin', 'plane-admin:ci-smoke', 'plane-admin-ci', 3003, '/god-mode');
81+
if (buildAll || changed.live) add('live', 'apps/live/Dockerfile.live', 'plane-live:ci-smoke', 'plane-live-ci', 3005, '/live/health', '-e NODE_ENV=production -e LIVE_BASE_PATH=/live');
82+
if (include.length === 0) {
83+
core.warning('No changes detected for any app. Matrix is empty. Skipping smoke tests.');
84+
}
85+
core.setOutput('matrix', JSON.stringify({ include }));
86+
smoke:
87+
name: Build and smoke test ${{ matrix.name }}
88+
runs-on: ubuntu-latest
89+
needs: determine-matrix
90+
if: ${{ needs.determine-matrix.outputs.matrix != '{"include":[]}' }}
91+
timeout-minutes: 25
92+
93+
strategy:
94+
fail-fast: false
95+
matrix: ${{ fromJSON(needs.determine-matrix.outputs.matrix) }}
96+
97+
steps:
98+
- name: Checkout repository
99+
uses: actions/checkout@v4
100+
with:
101+
fetch-depth: 0
102+
103+
- name: Show Docker version
104+
run: |
105+
docker version
106+
docker info
107+
108+
- name: Build image (${{ matrix.name }})
109+
working-directory: .
110+
run: |
111+
docker build -f ${{ matrix.dockerfile }} -t ${{ matrix.image }} .
112+
113+
- name: Run container (${{ matrix.name }})
114+
run: |
115+
docker run -d --name ${{ matrix.container }} -p ${{ matrix.host_port }}:3000 ${{ matrix.env_flags }} ${{ matrix.image }}
116+
docker ps -a
117+
118+
- name: Smoke test HTTP endpoint (${{ matrix.name }})
119+
shell: bash
120+
run: |
121+
set -euo pipefail
122+
URL="http://localhost:${{ matrix.host_port }}${{ matrix.path }}"
123+
echo "Probing $URL ..."
124+
# Try up to ~120 seconds (60 attempts * 2s)
125+
for i in {1..60}; do
126+
STATUS="$(curl -sS -o /dev/null -w "%{http_code}" -L "${URL}" || true)"
127+
if [ "${STATUS}" = "200" ]; then
128+
echo "Success: HTTP ${STATUS} from ${URL}"
129+
exit 0
130+
fi
131+
echo "Attempt ${i}: HTTP ${STATUS} (waiting 2s)"
132+
sleep 2
133+
done
134+
echo "Failed to get HTTP 200 from ${URL}"
135+
echo "::group::Container logs (${{ matrix.container }})"
136+
docker logs ${{ matrix.container }} || true
137+
echo "::endgroup::"
138+
exit 1
139+
140+
- name: Cleanup container (${{ matrix.name }})
141+
if: always()
142+
run: |
143+
docker rm -f ${{ matrix.container }} || true

0 commit comments

Comments
 (0)