name: CI on: push: branches: [main] pull_request: branches: [main] workflow_dispatch: inputs: target: type: choice description: Deploy target options: [preview, production] default: preview permissions: contents: read pull-requests: read jobs: ci: name: Lint, Typecheck, Test & Build runs-on: ubuntu-latest if: github.event_name != 'workflow_dispatch' steps: - name: Checkout uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v5 with: node-version: '24' cache: 'npm' - name: Install dependencies run: npm ci - name: Generate Prisma client run: npx prisma generate --generator client - name: Lint run: npm run lint - name: Typecheck run: npx tsc --noEmit - name: Prisma validate run: npx prisma validate - name: Test run: npm test - name: Check doc links run: npm run docs:check-links - name: Build run: npm run build env: DATABASE_URL: ${{ secrets.DATABASE_URL }} DIRECT_URL: ${{ secrets.DIRECT_URL }} SESSION_SECRET: ${{ secrets.SESSION_SECRET }} changes: name: Detect deploy-relevant changes runs-on: ubuntu-latest needs: ci # Alleen relevant voor auto-deploy jobs; skip wanneer auto-deploy uit staat. if: vars.AUTO_DEPLOY_ENABLED == 'true' && github.event_name != 'workflow_dispatch' outputs: code: ${{ steps.filter.outputs.code }} steps: - uses: actions/checkout@v5 - uses: dorny/paths-filter@v3 id: filter with: filters: | code: - 'app/**' - 'components/**' - 'lib/**' - 'actions/**' - 'stores/**' - 'prisma/**' - 'public/**' - 'package.json' - 'package-lock.json' - 'next.config.ts' - 'tsconfig.json' - 'vercel.json' - 'proxy.ts' - 'middleware.ts' - '.github/workflows/**' deploy-preview: name: Deploy Preview (PR) runs-on: ubuntu-latest needs: [ci, changes] # Auto-deploy is uit. Gebruik "Run workflow" (workflow_dispatch) op de # Actions-pagina voor handmatige deploys. Zet repo-variable # AUTO_DEPLOY_ENABLED=true in Settings → Secrets and variables → Actions # om PR-preview-deploys weer in te schakelen. if: | vars.AUTO_DEPLOY_ENABLED == 'true' && github.event_name == 'pull_request' && ( (needs.changes.outputs.code == 'true' && !contains(github.event.pull_request.labels.*.name, 'skip-deploy')) || contains(github.event.pull_request.labels.*.name, 'force-deploy') ) steps: - name: Checkout uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v5 with: node-version: '24' cache: 'npm' - name: Install dependencies run: npm ci - name: Install Vercel CLI run: npm install -g vercel@latest - name: Deploy Preview to Vercel run: vercel deploy --token=${{ secrets.VERCEL_TOKEN }} env: VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} deploy-production: name: Deploy Production (main) runs-on: ubuntu-latest needs: [ci, changes] # Auto-deploy is uit. Gebruik "Run workflow" (workflow_dispatch) → # target=production voor handmatige productie-deploys. Zet repo-variable # AUTO_DEPLOY_ENABLED=true om push-naar-main weer auto te deployen. if: | vars.AUTO_DEPLOY_ENABLED == 'true' && github.ref == 'refs/heads/main' && github.event_name == 'push' && needs.changes.outputs.code == 'true' steps: - name: Checkout uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v5 with: node-version: '24' cache: 'npm' - name: Install dependencies run: npm ci - name: Install Vercel CLI run: npm install -g vercel@latest - name: Run database migrations run: npx prisma migrate deploy env: DATABASE_URL: ${{ secrets.DATABASE_URL }} DIRECT_URL: ${{ secrets.DIRECT_URL }} - name: Deploy Production to Vercel run: vercel deploy --prod --token=${{ secrets.VERCEL_TOKEN }} env: VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} deploy-manual: name: Deploy Manual (workflow_dispatch) runs-on: ubuntu-latest if: github.event_name == 'workflow_dispatch' steps: - name: Checkout uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v5 with: node-version: '24' cache: 'npm' - name: Install dependencies run: npm ci - name: Install Vercel CLI run: npm install -g vercel@latest - name: Run database migrations (production only) if: inputs.target == 'production' run: npx prisma migrate deploy env: DATABASE_URL: ${{ secrets.DATABASE_URL }} DIRECT_URL: ${{ secrets.DIRECT_URL }} - name: Deploy run: | if [ "${{ inputs.target }}" = "production" ]; then vercel deploy --prod --token=${{ secrets.VERCEL_TOKEN }} else vercel deploy --token=${{ secrets.VERCEL_TOKEN }} fi env: VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}