Skip to content

Restore default English localization file for wata-board-frontend #78

Restore default English localization file for wata-board-frontend

Restore default English localization file for wata-board-frontend #78

Workflow file for this run

name: Performance Testing
on:
pull_request:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pull-requests: write
issues: write
concurrency:
group: perf-${{ github.ref }}
cancel-in-progress: true
jobs:
load-testing:
name: k6 Load Testing
runs-on: ubuntu-latest
timeout-minutes: 25
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: petchain
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres -d petchain"
--health-interval 10s
--health-timeout 5s
--health-retries 10
redis:
image: redis:7
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Install backend dependencies
run: npm --prefix backend ci
- name: Build Next.js
run: npm run build
- name: Build backend
run: npm --prefix backend run build
- name: Start backend server
env:
NODE_ENV: production
PORT: 3001
API_PREFIX: api/v1
DB_HOST: 127.0.0.1
DB_PORT: 5432
DB_USERNAME: postgres
DB_PASSWORD: postgres
DB_DATABASE: petchain
DB_SYNCHRONIZE: "true"
DB_LOGGING: "false"
REDIS_HOST: 127.0.0.1
REDIS_PORT: 6379
JWT_SECRET: perf-test-jwt-secret-32-chars-min
FIELD_ENCRYPTION_KEY: perf-test-field-encryption-key
FILE_ENCRYPTION_KEY: perf-test-file-encryption-key
run: |
npm --prefix backend run start:prod > backend-server.log 2>&1 &
echo $! > backend-server.pid
- name: Start production server
run: |
npx next start -H 127.0.0.1 -p 3000 > next-server.log 2>&1 &
echo $! > next-server.pid
- name: Wait for backend server
run: |
for attempt in {1..45}; do
if curl -fsS http://127.0.0.1:3001/api/v1/observability/health > /dev/null; then
exit 0
fi
sleep 2
done
echo "Backend server did not start in time" >&2
cat backend-server.log >&2
exit 1
- name: Wait for server
run: |
for attempt in {1..30}; do
if curl -fsS http://127.0.0.1:3000 > /dev/null; then
exit 0
fi
sleep 2
done
echo "Next.js server did not start in time" >&2
cat next-server.log >&2
exit 1
- name: Setup k6
uses: grafana/setup-k6-action@v1
- name: Run smoke profile
run: |
mkdir -p performance/results
k6 run \
--summary-export performance/results/smoke-summary.json \
-e TARGET_FRONTEND_URL=http://127.0.0.1:3000 \
-e TARGET_API_URL=http://127.0.0.1:3001/api/v1 \
performance/k6/smoke.js
- name: Run load profile
run: |
k6 run \
--summary-export performance/results/load-summary.json \
-e TARGET_FRONTEND_URL=http://127.0.0.1:3000 \
-e TARGET_API_URL=http://127.0.0.1:3001/api/v1 \
performance/k6/load.js
- name: Enforce baseline regression gate
run: |
node performance/scripts/compare-baseline.mjs \
performance/results/load-summary.json \
performance/baselines/load-summary-baseline.json \
0.15
- name: Publish benchmark summary
run: |
echo "## k6 Smoke Report" >> "$GITHUB_STEP_SUMMARY"
node performance/scripts/benchmark-report.mjs performance/results/smoke-summary.json >> "$GITHUB_STEP_SUMMARY"
echo >> "$GITHUB_STEP_SUMMARY"
echo "## k6 Load Report" >> "$GITHUB_STEP_SUMMARY"
node performance/scripts/benchmark-report.mjs performance/results/load-summary.json >> "$GITHUB_STEP_SUMMARY"
echo >> "$GITHUB_STEP_SUMMARY"
echo "## Baseline Regression Check" >> "$GITHUB_STEP_SUMMARY"
node performance/scripts/compare-baseline.mjs \
performance/results/load-summary.json \
performance/baselines/load-summary-baseline.json \
0.15 \
--summary-only >> "$GITHUB_STEP_SUMMARY"
- name: Upload load test artifacts
uses: actions/upload-artifact@v4
with:
name: k6-performance-results
path: |
performance/results/*.json
next-server.log
backend-server.log
retention-days: 14
- name: Stop production server
if: always()
run: |
if [ -f next-server.pid ]; then
kill $(cat next-server.pid) || true
fi
if [ -f backend-server.pid ]; then
kill $(cat backend-server.pid) || true
fi
lighthouse:
name: Lighthouse Audit
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Build Next.js
run: npx next build
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v12
id: lighthouse
with:
uploadArtifacts: true
temporaryPublicStorage: true
configPath: .github/lighthouserc.json
- name: Format Lighthouse results
if: always()
uses: actions/github-script@v7
with:
script: |
const results = ${{ steps.lighthouse.outputs.manifest }};
if (!results || results.length === 0) {
core.info('No Lighthouse results found');
return;
}
const result = results[0];
const summary = result.summary;
const score = (v) => `${Math.round(v * 100)}`;
const emoji = (v) => v >= 0.9 ? '🟢' : v >= 0.5 ? '🟡' : '🔴';
const body = `## ⚡ Lighthouse Performance Report
| Category | Score |
|----------|-------|
| ${emoji(summary.performance)} Performance | ${score(summary.performance)} |
| ${emoji(summary.accessibility)} Accessibility | ${score(summary.accessibility)} |
| ${emoji(summary['best-practices'])} Best Practices | ${score(summary['best-practices'])} |
| ${emoji(summary.seo)} SEO | ${score(summary.seo)} |
📊 [Full Report](${result.url})`;
if (context.issue?.number || context.payload?.pull_request?.number) {
const issueNumber = context.issue?.number || context.payload?.pull_request?.number;
try {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body: body,
});
} catch (error) {
core.error(`Failed to post comment: ${error.message}`);
if (error.status !== 404) throw error;
}
} else {
core.warning('No PR context found for posting comment');
}
bundle-analysis:
name: Bundle Size Analysis
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Build and analyze
run: |
ANALYZE=true npx next build 2>&1 | tee build-output.txt
- name: Report bundle size
run: |
echo "### 📦 Bundle Size Report" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
# Extract the route summary from Next.js build output
sed -n '/Route (app)/,/First Load JS shared/p' build-output.txt >> "$GITHUB_STEP_SUMMARY" 2>/dev/null || echo "Build output captured" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
- name: Upload build output
uses: actions/upload-artifact@v4
with:
name: bundle-analysis
path: build-output.txt
retention-days: 7