cms.c2sgmbh/.github/workflows/ci.yml
dependabot[bot] 4e34ad5412
deps(actions): bump actions/download-artifact from 7 to 8
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 03:15:47 +00:00

385 lines
13 KiB
YAML

name: CI
# ============================================================================
# Optimiert für minimale GitHub Actions Nutzung:
# - Push auf develop: Nur Lint + Build (schnelle Feedback-Schleife)
# - PRs: Volle Test-Suite inkl. E2E
# - Push auf main: Keine CI (wird durch deploy-production getriggert)
# ============================================================================
on:
push:
branches: [develop]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/ISSUE_TEMPLATE/**'
pull_request:
branches: [main, develop]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: '20'
PNPM_VERSION: '9'
# Schnelle Builds durch Turbo Cache
TURBO_TEAM: 'payload'
TURBO_REMOTE_ONLY: true
jobs:
# ===========================================================================
# Lint Job - ESLint & Prettier
# ===========================================================================
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run ESLint
run: pnpm lint
# Warnings are allowed, only errors fail the build
- name: Check Prettier formatting
run: pnpm format:check
continue-on-error: true
# ===========================================================================
# TypeScript Type Check (optional - Next.js build has own type check)
# ===========================================================================
typecheck:
name: TypeScript
runs-on: ubuntu-latest
continue-on-error: true # Don't block CI - some legacy code has type issues
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run TypeScript compiler
run: pnpm typecheck
# ===========================================================================
# Unit & Integration Tests (nur bei PRs - spart Actions-Minuten)
# ===========================================================================
test:
name: Tests
runs-on: ubuntu-latest
needs: [lint, typecheck]
if: github.event_name == 'pull_request'
timeout-minutes: 30 # Prevent 6-hour hangs
services:
postgres:
image: postgres:17
env:
POSTGRES_USER: payload
POSTGRES_PASSWORD: payload_test_password
POSTGRES_DB: payload_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run Unit Tests
run: pnpm test:unit
timeout-minutes: 10
env:
CSRF_SECRET: test-csrf-secret
PAYLOAD_SECRET: test-payload-secret
PAYLOAD_PUBLIC_SERVER_URL: https://test.example.com
NEXT_PUBLIC_SERVER_URL: https://test.example.com
EMAIL_DELIVERY_DISABLED: 'true'
DATABASE_URI: postgresql://placeholder:placeholder@localhost:5432/placeholder
CONSENT_LOGGING_API_KEY: ci-consent-api-key-placeholder
IP_ANONYMIZATION_PEPPER: ci-anonymization-pepper-placeholder
- name: Setup Database Schema
run: |
echo "Testing database connection..."
PGPASSWORD=payload_test_password psql -h localhost -U payload -d payload_test -c "SELECT 1;"
echo "Dropping existing tables..."
PGPASSWORD=payload_test_password psql -h localhost -U payload -d payload_test -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
echo "Creating schema from generated file..."
pnpm exec drizzle-kit push --config=./drizzle.ci.config.ts --force
echo "Schema created."
timeout-minutes: 5
env:
CI: true
NODE_OPTIONS: --no-deprecation
PAYLOAD_SECRET: test-payload-secret
DATABASE_URI: postgresql://payload:payload_test_password@localhost:5432/payload_test
NEXT_PUBLIC_SERVER_URL: https://test.example.com
PAYLOAD_PUBLIC_SERVER_URL: https://test.example.com
CONSENT_LOGGING_API_KEY: ci-consent-api-key-placeholder
IP_ANONYMIZATION_PEPPER: ci-anonymization-pepper-placeholder
- name: Run Integration Tests
run: pnpm test:int
timeout-minutes: 15
env:
CSRF_SECRET: test-csrf-secret
PAYLOAD_SECRET: test-payload-secret
PAYLOAD_PUBLIC_SERVER_URL: https://test.example.com
NEXT_PUBLIC_SERVER_URL: https://test.example.com
EMAIL_DELIVERY_DISABLED: 'true'
DATABASE_URI: postgresql://payload:payload_test_password@localhost:5432/payload_test
CONSENT_LOGGING_API_KEY: ci-consent-api-key-placeholder
IP_ANONYMIZATION_PEPPER: ci-anonymization-pepper-placeholder
- name: Upload coverage report
if: always()
uses: actions/upload-artifact@v6
with:
name: test-coverage
path: coverage/
retention-days: 7
# ===========================================================================
# Build Job
# ===========================================================================
build:
name: Build
runs-on: ubuntu-latest
needs: [lint, typecheck]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build application
run: pnpm build
env:
# Minimal env vars for build (Next.js runs in NODE_ENV=production)
PAYLOAD_SECRET: build-secret-placeholder
DATABASE_URI: postgresql://placeholder:placeholder@localhost:5432/placeholder
NEXT_PUBLIC_SERVER_URL: https://build.example.com
PAYLOAD_PUBLIC_SERVER_URL: https://build.example.com
CONSENT_LOGGING_API_KEY: ci-consent-api-key-placeholder
IP_ANONYMIZATION_PEPPER: ci-anonymization-pepper-placeholder
CRON_SECRET: ci-cron-secret-placeholder
- name: Verify build output
run: |
if [ ! -f .next/BUILD_ID ]; then
echo "Build failed - no BUILD_ID found"
exit 1
fi
echo "Build successful - BUILD_ID: $(cat .next/BUILD_ID)"
- name: Upload build artifacts
uses: actions/upload-artifact@v6
with:
name: build-output
path: |
.next/
!.next/cache/
retention-days: 1
include-hidden-files: true
# ===========================================================================
# E2E Tests (nur bei PRs - sehr ressourcenintensiv)
# ===========================================================================
e2e:
name: E2E Tests
runs-on: ubuntu-latest
needs: [build]
if: github.event_name == 'pull_request'
timeout-minutes: 30 # Prevent 6-hour hangs
services:
postgres:
image: postgres:17
env:
POSTGRES_USER: payload
POSTGRES_PASSWORD: payload_test_password
POSTGRES_DB: payload_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Download build artifacts
uses: actions/download-artifact@v8
with:
name: build-output
path: .next/
- name: Install Playwright browsers
run: pnpm exec playwright install chromium --with-deps
- name: Setup Database Schema
run: |
echo "Testing database connection..."
PGPASSWORD=payload_test_password psql -h localhost -U payload -d payload_test -c "SELECT 1;"
echo "Dropping existing tables..."
PGPASSWORD=payload_test_password psql -h localhost -U payload -d payload_test -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
echo "Creating schema from generated file..."
pnpm exec drizzle-kit push --config=./drizzle.ci.config.ts --force
echo "Schema created."
timeout-minutes: 5
env:
CI: true
NODE_OPTIONS: --no-deprecation
PAYLOAD_SECRET: e2e-secret-placeholder
DATABASE_URI: postgresql://payload:payload_test_password@localhost:5432/payload_test
NEXT_PUBLIC_SERVER_URL: http://localhost:3001
PAYLOAD_PUBLIC_SERVER_URL: http://localhost:3001
CONSENT_LOGGING_API_KEY: ci-consent-api-key-placeholder
IP_ANONYMIZATION_PEPPER: ci-anonymization-pepper-placeholder
- name: Run E2E tests
run: pnpm test:e2e
timeout-minutes: 15
env:
CI: true
CSRF_SECRET: e2e-csrf-secret-placeholder
PAYLOAD_SECRET: e2e-secret-placeholder
DATABASE_URI: postgresql://payload:payload_test_password@localhost:5432/payload_test
NEXT_PUBLIC_SERVER_URL: http://localhost:3001
PAYLOAD_PUBLIC_SERVER_URL: http://localhost:3001
EMAIL_DELIVERY_DISABLED: 'true'
CONSENT_LOGGING_API_KEY: ci-consent-api-key-placeholder
IP_ANONYMIZATION_PEPPER: ci-anonymization-pepper-placeholder
- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v6
with:
name: playwright-report
path: playwright-report/
retention-days: 7
# ===========================================================================
# Summary Job
# ===========================================================================
ci-success:
name: CI Success
runs-on: ubuntu-latest
needs: [lint, typecheck, test, build, e2e]
if: always()
steps:
- name: Check required jobs
run: |
# Required jobs for all runs (must succeed)
if [ "${{ needs.lint.result }}" != "success" ] || \
[ "${{ needs.build.result }}" != "success" ]; then
echo "One or more required jobs failed"
exit 1
fi
# Jobs only required for PRs
if [ "${{ github.event_name }}" == "pull_request" ]; then
if [ "${{ needs.test.result }}" != "success" ] || \
[ "${{ needs.e2e.result }}" != "success" ]; then
echo "PR required jobs failed"
exit 1
fi
fi
# Optional jobs (typecheck) - just report status
if [ "${{ needs.typecheck.result }}" != "success" ]; then
echo "⚠️ TypeScript check failed (optional)"
fi
echo "All required CI checks passed!"
- name: Create summary
run: |
echo "## CI Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Job | Status | Required |" >> $GITHUB_STEP_SUMMARY
echo "|-----|--------|----------|" >> $GITHUB_STEP_SUMMARY
echo "| Lint | ${{ needs.lint.result }} | ✅ |" >> $GITHUB_STEP_SUMMARY
echo "| TypeScript | ${{ needs.typecheck.result }} | ⚠️ optional |" >> $GITHUB_STEP_SUMMARY
echo "| Build | ${{ needs.build.result }} | ✅ |" >> $GITHUB_STEP_SUMMARY
if [ "${{ github.event_name }}" == "pull_request" ]; then
echo "| Tests | ${{ needs.test.result }} | ✅ (PR) |" >> $GITHUB_STEP_SUMMARY
echo "| E2E | ${{ needs.e2e.result }} | ✅ (PR) |" >> $GITHUB_STEP_SUMMARY
else
echo "| Tests | skipped | ⏭️ push only |" >> $GITHUB_STEP_SUMMARY
echo "| E2E | skipped | ⏭️ push only |" >> $GITHUB_STEP_SUMMARY
fi