@@ -3,6 +3,7 @@ name: Performance Testing
33on :
44 pull_request :
55 branches : [main]
6+ workflow_dispatch :
67
78permissions :
89 contents : read
@@ -14,6 +15,167 @@ concurrency:
1415 cancel-in-progress : true
1516
1617jobs :
18+ load-testing :
19+ name : k6 Load Testing
20+ runs-on : ubuntu-latest
21+ timeout-minutes : 25
22+ services :
23+ postgres :
24+ image : postgres:15
25+ env :
26+ POSTGRES_DB : petchain
27+ POSTGRES_USER : postgres
28+ POSTGRES_PASSWORD : postgres
29+ ports :
30+ - 5432:5432
31+ options : >-
32+ --health-cmd "pg_isready -U postgres -d petchain"
33+ --health-interval 10s
34+ --health-timeout 5s
35+ --health-retries 10
36+ redis :
37+ image : redis:7
38+ ports :
39+ - 6379:6379
40+ options : >-
41+ --health-cmd "redis-cli ping"
42+ --health-interval 10s
43+ --health-timeout 5s
44+ --health-retries 10
45+ steps :
46+ - name : Checkout code
47+ uses : actions/checkout@v4
48+
49+ - name : Setup Node.js
50+ uses : actions/setup-node@v4
51+ with :
52+ node-version : 20
53+ cache : npm
54+
55+ - name : Install dependencies
56+ run : npm ci
57+
58+ - name : Install backend dependencies
59+ run : npm --prefix backend ci
60+
61+ - name : Build Next.js
62+ run : npm run build
63+
64+ - name : Build backend
65+ run : npm --prefix backend run build
66+
67+ - name : Start backend server
68+ env :
69+ NODE_ENV : production
70+ PORT : 3001
71+ API_PREFIX : api/v1
72+ DB_HOST : 127.0.0.1
73+ DB_PORT : 5432
74+ DB_USERNAME : postgres
75+ DB_PASSWORD : postgres
76+ DB_DATABASE : petchain
77+ DB_SYNCHRONIZE : " true"
78+ DB_LOGGING : " false"
79+ REDIS_HOST : 127.0.0.1
80+ REDIS_PORT : 6379
81+ JWT_SECRET : perf-test-jwt-secret-32-chars-min
82+ FIELD_ENCRYPTION_KEY : perf-test-field-encryption-key
83+ FILE_ENCRYPTION_KEY : perf-test-file-encryption-key
84+ run : |
85+ npm --prefix backend run start:prod > backend-server.log 2>&1 &
86+ echo $! > backend-server.pid
87+
88+ - name : Start production server
89+ run : |
90+ npx next start -H 127.0.0.1 -p 3000 > next-server.log 2>&1 &
91+ echo $! > next-server.pid
92+
93+ - name : Wait for backend server
94+ run : |
95+ for attempt in {1..45}; do
96+ if curl -fsS http://127.0.0.1:3001/api/v1/observability/health > /dev/null; then
97+ exit 0
98+ fi
99+ sleep 2
100+ done
101+ echo "Backend server did not start in time" >&2
102+ cat backend-server.log >&2
103+ exit 1
104+
105+ - name : Wait for server
106+ run : |
107+ for attempt in {1..30}; do
108+ if curl -fsS http://127.0.0.1:3000 > /dev/null; then
109+ exit 0
110+ fi
111+ sleep 2
112+ done
113+ echo "Next.js server did not start in time" >&2
114+ cat next-server.log >&2
115+ exit 1
116+
117+ - name : Setup k6
118+ uses : grafana/setup-k6-action@v1
119+
120+ - name : Run smoke profile
121+ run : |
122+ mkdir -p performance/results
123+ k6 run \
124+ --summary-export performance/results/smoke-summary.json \
125+ -e TARGET_FRONTEND_URL=http://127.0.0.1:3000 \
126+ -e TARGET_API_URL=http://127.0.0.1:3001/api/v1 \
127+ performance/k6/smoke.js
128+
129+ - name : Run load profile
130+ run : |
131+ k6 run \
132+ --summary-export performance/results/load-summary.json \
133+ -e TARGET_FRONTEND_URL=http://127.0.0.1:3000 \
134+ -e TARGET_API_URL=http://127.0.0.1:3001/api/v1 \
135+ performance/k6/load.js
136+
137+ - name : Enforce baseline regression gate
138+ run : |
139+ node performance/scripts/compare-baseline.mjs \
140+ performance/results/load-summary.json \
141+ performance/baselines/load-summary-baseline.json \
142+ 0.15
143+
144+ - name : Publish benchmark summary
145+ run : |
146+ echo "## k6 Smoke Report" >> "$GITHUB_STEP_SUMMARY"
147+ node performance/scripts/benchmark-report.mjs performance/results/smoke-summary.json >> "$GITHUB_STEP_SUMMARY"
148+ echo >> "$GITHUB_STEP_SUMMARY"
149+ echo "## k6 Load Report" >> "$GITHUB_STEP_SUMMARY"
150+ node performance/scripts/benchmark-report.mjs performance/results/load-summary.json >> "$GITHUB_STEP_SUMMARY"
151+ echo >> "$GITHUB_STEP_SUMMARY"
152+ echo "## Baseline Regression Check" >> "$GITHUB_STEP_SUMMARY"
153+ node performance/scripts/compare-baseline.mjs \
154+ performance/results/load-summary.json \
155+ performance/baselines/load-summary-baseline.json \
156+ 0.15 \
157+ --summary-only >> "$GITHUB_STEP_SUMMARY"
158+
159+ - name : Upload load test artifacts
160+ uses : actions/upload-artifact@v4
161+ with :
162+ name : k6-performance-results
163+ path : |
164+ performance/results/*.json
165+ next-server.log
166+ backend-server.log
167+ retention-days : 14
168+
169+ - name : Stop production server
170+ if : always()
171+ run : |
172+ if [ -f next-server.pid ]; then
173+ kill $(cat next-server.pid) || true
174+ fi
175+ if [ -f backend-server.pid ]; then
176+ kill $(cat backend-server.pid) || true
177+ fi
178+
17179 lighthouse :
18180 name : Lighthouse Audit
19181 runs-on : ubuntu-latest
0 commit comments