Merge pull request #106 from madhura68/feat/pbi-36-deploy-controle

feat(PBI-36 ST-1218): selectieve deploy-controle via labels + path-filter
This commit is contained in:
Janpeter Visser 2026-05-06 00:15:48 +02:00 committed by GitHub
commit f570f07d4a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 256 additions and 5 deletions

View file

@ -5,11 +5,23 @@ on:
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
@ -49,11 +61,46 @@ jobs:
DIRECT_URL: ${{ secrets.DIRECT_URL }}
SESSION_SECRET: ${{ secrets.SESSION_SECRET }}
changes:
name: Detect deploy-relevant changes
runs-on: ubuntu-latest
needs: ci
if: 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
if: github.event_name == 'pull_request'
needs: [ci, changes]
if: |
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
@ -80,8 +127,11 @@ jobs:
deploy-production:
name: Deploy Production (main)
runs-on: ubuntu-latest
needs: ci
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
needs: [ci, changes]
if: |
github.ref == 'refs/heads/main'
&& github.event_name == 'push'
&& needs.changes.outputs.code == 'true'
steps:
- name: Checkout
@ -110,3 +160,42 @@ jobs:
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 }}

View file

@ -56,7 +56,7 @@ Volledige MCP-tool documentatie: [docs/runbooks/mcp-integration.md](./docs/runbo
- **Enum:** DB UPPER_SNAKE ↔ API lowercase — uitsluitend via `lib/task-status.ts`
- **Foutcodes:** 400 = parse-fout, 422 = Zod-validatie, 403 = demo-token
- **Server/client grens:** `*-server.ts` bevat DB/node-only; nooit importeren in client component
- **Deployment:** `npm run lint && npm test && npm run build` vóór elke PR
- **Deployment:** `npm run lint && npm test && npm run build` vóór elke PR. Selectieve deploy-controle (labels + path-filter): zie [docs/runbooks/deploy-control.md](./docs/runbooks/deploy-control.md)
---

View file

@ -111,6 +111,7 @@ Auto-generated on 2026-05-05 from front-matter and headings.
| [Realtime smoke-checklist — PBI / Story / Task](./realtime-smoke.md) | `realtime-smoke.md` | active | 2026-05-03 |
| [Agent-flow: open issues & decision log](./runbooks/agent-flow-pitfalls.md) | `runbooks/agent-flow-pitfalls.md` | active | 2026-05-03 |
| [Branch, PR & Commit Strategy](./runbooks/branch-and-commit.md) | `runbooks/branch-and-commit.md` | active | 2026-05-03 |
| [Deploy-controle: triggers, labels, path-filter](./runbooks/deploy-control.md) | `runbooks/deploy-control.md` | active | 2026-05-05 |
| [Vercel Deployment](./runbooks/deploy-vercel.md) | `runbooks/deploy-vercel.md` | active | 2026-05-03 |
| [MCP Integration — Scrum4Me Tools](./runbooks/mcp-integration.md) | `runbooks/mcp-integration.md` | active | 2026-05-03 |
| [v1.0 Smoke Test Checklist](./runbooks/v1-smoke-test.md) | `runbooks/v1-smoke-test.md` | active | 2026-05-04 |

View file

@ -0,0 +1,160 @@
---
title: "Deploy-controle: triggers, labels, path-filter"
status: active
audience: [contributor, ai-agent]
language: nl
last_updated: 2026-05-05
when_to_read: "Vóór een PR mergen, vóór doc-only changes pushen, of bij troubleshooting van Vercel-deployments."
---
# Deploy-controle
Selectieve controle over wanneer Vercel-deployments worden uitgevoerd
vanuit de GitHub Actions workflow `.github/workflows/ci.yml`. Vercel's
eigen Git-integratie staat **uit** (`vercel.json: git.deploymentEnabled:
false`) — de workflow is de enige bron van deploy-truth.
---
## Triggers en defaults
| Event | Default-deploy |
|---|---|
| `push` naar `main` | Productie (`vercel deploy --prod`) — alleen als path-filter zegt "code" |
| `pull_request` naar `main` | Preview (`vercel deploy`) — alleen als path-filter zegt "code" en geen `skip-deploy` label |
| `workflow_dispatch` | Handmatig — kies `target: preview \| production` in Actions-tab |
CI (lint, typecheck, test, build) draait **altijd** op push/PR — ook
voor doc-only changes. Alleen de deploy-jobs respecteren path-filter
en labels.
---
## Path-filter
Job `changes` (dorny/paths-filter@v3) zet output `code=true` als
één van deze paden gewijzigd is:
```
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/**
```
Wijzigingen aan `docs/`, `CLAUDE.md`, `README.md`, `.vscode/**`, etc.
zetten `code=false`**geen deploy** (zelfs niet preview).
---
## Labels (alleen op PRs)
| Label | Effect |
|---|---|
| `skip-deploy` | Preview-deploy overslaan, ook als path-filter "code" zegt |
| `force-deploy` | Preview-deploy forceren, ook als path-filter "geen code" zegt |
Beide labels werken alleen op **PR's**. Op pushes naar `main` heeft
alleen path-filter invloed (productie-gate).
---
## Beslismatrix per scenario
| Trigger | Path-filter | Labels | Resultaat |
|---|---|---|---|
| PR met code-change | `code=true` | (geen) | ✅ Preview-deploy |
| PR met code-change | `code=true` | `skip-deploy` | ❌ Preview overgeslagen |
| PR met doc-only | `code=false` | (geen) | ❌ Geen deploy |
| PR met doc-only | `code=false` | `force-deploy` | ✅ Preview-deploy |
| PR met code-change | `code=true` | `skip-deploy` + `force-deploy` | ✅ `force-deploy` wint |
| Push main code | `code=true` | n.v.t. | ✅ Productie-deploy + migrate |
| Push main doc-only | `code=false` | n.v.t. | ❌ Geen deploy |
| `workflow_dispatch` `target=preview` | n.v.t. | n.v.t. | ✅ Manuele preview |
| `workflow_dispatch` `target=production` | n.v.t. | n.v.t. | ✅ Manuele prod + migrate |
---
## Voorbeelden
**Doc-only PR die je niet wil deployen** (default):
```bash
git checkout -b docs/fix-typo
# alleen docs/foo.md aanpassen
git commit -am "docs: typo"
gh pr create
# → CI runt, deploy-preview = SKIPPED
```
**Doc-only PR die je wél visueel wil checken**:
```bash
gh pr create
gh pr edit --add-label force-deploy
# → CI runt, deploy-preview RUNT
```
**Code-PR die je niet wil deployen** (bv. WIP):
```bash
gh pr create
gh pr edit --add-label skip-deploy
# → CI runt, deploy-preview SKIPPED
```
**Manuele productie-redeploy zonder push**:
1. GitHub repo → Actions → CI workflow → "Run workflow" knop
2. `target: production` → Run
3. → `deploy-manual` job draait `prisma migrate deploy` + `vercel deploy --prod`
---
## Troubleshooting
**Probleem**: Twee deploys verschijnen op Vercel-dashboard per push.
→ Check `vercel.json` bevat `"git": { "deploymentEnabled": false }`. Zo
niet: Vercel's eigen Git-integratie deployt parallel naast de workflow.
**Probleem**: Mijn PR met code-change deployt geen preview.
→ Check labels: heb je `skip-deploy` aangezet? Verwijder het label of
voeg `force-deploy` toe.
→ Check `changes`-job output in Actions-tab: zegt het `code=false`?
Mogelijk staat je wijziging buiten de path-filter (bv. een nieuw
top-level bestand). Pas filter aan in `ci.yml` als nodig.
**Probleem**: Push naar main triggert geen prod-deploy.
→ Check Actions-tab `changes`-job output. `code=false` betekent geen
deploy.
→ Forceer via `workflow_dispatch` met `target=production`.
**Probleem**: `workflow_dispatch` toont geen "Run workflow" knop.
→ Workflow moet minstens één keer op de default branch (main) hebben
gedraaid voordat de knop verschijnt. Eerste keer: merge naar main of
push direct naar main.
---
## Referenties
- Workflow: `.github/workflows/ci.yml`
- Vercel-config: `vercel.json`
- Plan: `docs/plans/auto-pr-deploy-sync.md` Deel A
- Branch- & commit-strategie: [`docs/runbooks/branch-and-commit.md`](./branch-and-commit.md)
- Auto-PR-flow (toekomstig): `docs/plans/auto-pr-deploy-sync.md` Deel B

View file

@ -1,5 +1,6 @@
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"git": { "deploymentEnabled": false },
"crons": [
{
"path": "/api/cron/expire-questions",