文件
hyb-oa/.github/workflows/ci-regression.yml
T

155 行
4.9 KiB
YAML

name: ci-regression
on:
workflow_dispatch:
schedule:
- cron: "30 18 * * *"
jobs:
server-regression:
runs-on: ubuntu-latest
timeout-minutes: 45
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: hyb_oa
POSTGRES_USER: hyboa_user
POSTGRES_PASSWORD: hyboa_password
ports:
- 5432:5432
options: >-
--health-cmd="pg_isready -U hyboa_user -d hyb_oa"
--health-interval=10s
--health-timeout=5s
--health-retries=10
env:
NODE_ENV: test
PORT: 3000
HOST: 127.0.0.1
APP_ORIGIN: http://127.0.0.1:5173
DATABASE_URL: postgresql://hyboa_user:[email protected]:5432/hyb_oa?schema=public
JWT_SECRET: ci_regression_secret_key
OCR_PROVIDER: mock
OCR_MAX_ATTEMPTS: 3
DELEGATION_REVOKE_CRON: "0 * * * *"
REGRESSION_REPORT_DIR: /tmp/hyb-oa-regression
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: server/package-lock.json
- name: Install server dependencies
working-directory: server
run: npm ci
- name: Migrate database
working-directory: server
run: npm run prisma:migrate:deploy
- name: Seed database
working-directory: server
run: npm run seed:dev
- name: Start server
working-directory: server
run: |
nohup npm run dev > /tmp/hyb-oa-server.log 2>&1 &
echo $! > /tmp/hyb-oa-server.pid
- name: Wait for health
run: |
for i in {1..30}; do
if curl -fsS "http://127.0.0.1:3000/health" >/dev/null; then
exit 0
fi
sleep 2
done
echo "Server health check timed out" >&2
exit 1
- name: Run full regression suite
working-directory: server
run: |
mkdir -p "$REGRESSION_REPORT_DIR"
RUN_AUDIT_REGRESSION=1 RUN_OCR_REGRESSION=1 ./scripts/regression-all.sh --json-report "$REGRESSION_REPORT_DIR/report.json"
- name: Generate Job Summary
if: always()
run: |
if [[ -f "$REGRESSION_REPORT_DIR/report.json" ]]; then
python3 -c "
import json, os
try:
with open('$REGRESSION_REPORT_DIR/report.json') as f:
d = json.load(f)
ov = d.get('overall', {})
summary = f'## Regression Run Status: {ov.get(\"status\")}\\n'
summary += f'- Passed: {ov.get(\"passed\")} | Failed: {ov.get(\"failed\")} | Skipped: {ov.get(\"skipped\")}\\n'
summary += f'- Duration: {ov.get(\"duration_ms\")} ms\\n\\n'
failed = [s for s in d.get('steps', []) if s.get('status') == 'failed']
if failed:
summary += '### Failed Steps\\n'
for s in failed:
summary += f'- **{s.get(\"name\")}** (exit {s.get(\"exit_code\")})\\n'
with open(os.environ['GITHUB_STEP_SUMMARY'], 'a') as out:
out.write(summary)
except Exception as e:
with open(os.environ['GITHUB_STEP_SUMMARY'], 'a') as out:
out.write(f'❌ Failed to parse report: {e}')
"
else:
echo "❌ Regression JSON report not found." >> $GITHUB_STEP_SUMMARY
fi
- name: Upload regression report artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: regression-report-${{ github.run_id }}-${{ github.sha }}
path: /tmp/hyb-oa-regression/report.json
if-no-files-found: warn
- name: Generate CFR Report
if: always()
run: |
mkdir -p artifacts/regression
if [[ -f "$REGRESSION_REPORT_DIR/report.json" ]]; then
cp "$REGRESSION_REPORT_DIR/report.json" artifacts/regression/
fi
python3 scripts/cfr_report.py --input-dir artifacts/regression --window 7d,30d --output-json /tmp/cfr.json --output-md /tmp/cfr.md
echo "## Change Failure Rate" >> $GITHUB_STEP_SUMMARY
cat /tmp/cfr.md >> $GITHUB_STEP_SUMMARY
- name: Upload CFR report artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: cfr-report-${{ github.run_id }}-${{ github.sha }}
path: |
/tmp/cfr.json
/tmp/cfr.md
if-no-files-found: warn
- name: Stop server
if: always()
run: |
if [[ -f /tmp/hyb-oa-server.pid ]]; then
kill "$(cat /tmp/hyb-oa-server.pid)" || true
fi
- name: Dump server log on failure
if: failure()
run: |
echo "==== /tmp/hyb-oa-server.log ===="
cat /tmp/hyb-oa-server.log || true