xpeditis2.0/.github/workflows/pr-checks.yml
David da93e86756 feat(cicd): add complete CI/CD pipeline for dev/preprod/prod (Hetzner k3s)
- ci.yml: dev branch CI — lint, type-check, unit tests (~5min)
- pr-checks.yml: PR gate to preprod (+ integration tests) and main
- cd-preprod.yml: full preprod pipeline — quality → integration → docker → deploy → smoke tests
- cd-main.yml: prod pipeline — promote Scaleway preprod image → kubectl rollout on k3s
- rollback.yml: emergency rollback (kubectl undo or specific tag, Portainer for preprod)
- docs: replace GHCR references with Scaleway registry in Hetzner k8s manifests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:52:14 +02:00

177 lines
5.5 KiB
YAML

name: PR Checks
# Validation gate for pull requests.
# PRs to preprod → lint + unit tests + integration tests
# PRs to main → lint + unit tests only (code was integration-tested in preprod already)
#
# Configure these as required status checks in GitHub branch protection rules.
on:
pull_request:
branches: [preprod, main]
concurrency:
group: pr-${{ github.event.pull_request.number }}
cancel-in-progress: true
env:
NODE_VERSION: '20'
jobs:
# ──────────────────────────────────────────
# Lint & Type-check (both apps, parallel)
# ──────────────────────────────────────────
quality:
name: Quality (${{ matrix.app }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
app: [backend, frontend]
defaults:
run:
working-directory: apps/${{ matrix.app }}
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: apps/${{ matrix.app }}/package-lock.json
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Lint
run: npm run lint
- name: Type-check (frontend only)
if: matrix.app == 'frontend'
run: npm run type-check
# ──────────────────────────────────────────
# Unit Tests (both apps, parallel)
# ──────────────────────────────────────────
unit-tests:
name: Unit Tests (${{ matrix.app }})
runs-on: ubuntu-latest
needs: quality
strategy:
fail-fast: false
matrix:
app: [backend, frontend]
defaults:
run:
working-directory: apps/${{ matrix.app }}
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: apps/${{ matrix.app }}/package-lock.json
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Run unit tests
run: npm test -- --passWithNoTests --coverage
# ──────────────────────────────────────────
# Integration Tests — PRs to preprod only
# ──────────────────────────────────────────
integration-tests:
name: Integration Tests
runs-on: ubuntu-latest
needs: unit-tests
if: github.base_ref == 'preprod'
defaults:
run:
working-directory: apps/backend
services:
postgres:
image: postgres:15-alpine
env:
POSTGRES_USER: xpeditis_test
POSTGRES_PASSWORD: xpeditis_test_password
POSTGRES_DB: xpeditis_test
options: >-
--health-cmd pg_isready
--health-interval 5s
--health-timeout 5s
--health-retries 10
ports:
- 5432:5432
redis:
image: redis:7-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 5s
--health-timeout 5s
--health-retries 10
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: apps/backend/package-lock.json
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Run integration tests
env:
NODE_ENV: test
DATABASE_HOST: localhost
DATABASE_PORT: 5432
DATABASE_USER: xpeditis_test
DATABASE_PASSWORD: xpeditis_test_password
DATABASE_NAME: xpeditis_test
DATABASE_SYNCHRONIZE: false
REDIS_HOST: localhost
REDIS_PORT: 6379
REDIS_PASSWORD: ''
JWT_SECRET: test-secret-key-for-ci-only
SMTP_HOST: localhost
SMTP_PORT: 1025
SMTP_FROM: test@xpeditis.com
run: npm run test:integration -- --passWithNoTests
# ──────────────────────────────────────────
# PR Summary
# ──────────────────────────────────────────
pr-summary:
name: PR Summary
runs-on: ubuntu-latest
needs: [quality, unit-tests]
if: always()
steps:
- name: Write job summary
run: |
echo "## PR Check Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Quality (lint + type-check) | ${{ needs.quality.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Unit Tests | ${{ needs.unit-tests.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Target Branch | \`${{ github.base_ref }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Author | ${{ github.actor }} |" >> $GITHUB_STEP_SUMMARY