DORA-dashboard
Het DORA-dashboard toont de vier metrics uit het State of DevOps-rapport van DevOps Research and Assessment (DORA), live per tenant berekend uit de deploymentgebeurtenissen die fremforge vastlegt. Je vindt het onder Organisatiebeheer → DORA.
Geen externe dienst. Geen gegevens naar een SaaS-dashboard van derden. De cijfers worden binnen fremforge berekend, naast je repository’s, auditlog en bevindingen, en ze hebben dezelfde garanties voor opslag in de EU en scheiding tussen tenants als al het andere onder /<slug>/_admin/*.
De vier metrics
| Metric | Wat het meet | Hoe fremforge het berekent |
|---|---|---|
| Deployfrequentie | Hoe vaak je naar productie uitrolt | Aantal geslaagde deploymentgebeurtenissen naar productie, gedeeld door het voortschrijdende venster. Gerapporteerd als deployments per dag en daarna ingedeeld in de DORA-categorieën (Elite: ≥1 per dag, Hoog: 1 per dag tot 1 per week, Gemiddeld: 1 per week tot 1 per maand, Laag: <1 per maand). |
| Doorlooptijd voor wijzigingen | Tijd van commit tot deploy | deployed_at − committed_at, p50 + p95 over het venster. Telt alleen deployments die een commit_sha + committed_at meegaven. Gerapporteerd in uren of dagen. |
| Wijzigingsfaalpercentage | Aandeel deployments dat faalt of een fix nodig heeft | count(success=false OR is_rework=true) / count(*) over het venster. Uitgedrukt als percentage. |
| Gemiddelde hersteltijd (MTTR) | Tijd om te herstellen van een mislukte deployment | Voor elke gebeurtenis met success=false de verstreken tijd van deployed_at tot de volgende geslaagde deployment naar dezelfde (repo, environment). Gerapporteerd als mediaan. |
Het venster is standaard 30 dagen voortschrijdend. In te stellen onder Organisatiebeheer → DORA → Instellingen: 7 d / 30 d / 90 d.
Hoe deployments in de tabel komen
Er lopen twee invoerroutes naast elkaar. Gebruik de route die bij je manier van releasen past; veel tenants gebruiken beide.
1. Forgejo-release-webhook (automatisch)
Maakt een repository een Forgejo-release aan (een geannoteerde tag v* of een releaseobject dat via de UI of POST /api/v1/repos/{owner}/{repo}/releases is gepubliceerd), dan legt fremforge één deploymentgebeurtenis vast met:
environment=production(standaard)deployed_at=created_atvan de releasecommit_sha=target_commitishvan de release, omgezet naar een SHAcommitted_at= deauthor.datevan de commitsuccess=trueexternal_ref=release:{release_id}(idempotent: de webhook kan veilig opnieuw worden afgespeeld)
Je hoeft niets te koppelen. Het doel van de webhook is op platformniveau ingesteld; het inschakelen per organisatie gaat automatisch.
2. POST /_app/api/v1/dora/deployments (eigen invoer, aanbevolen voor rijkere telemetrie)
Bij tenants die geen releases taggen (continuous deployment, GitOps met push bij merge, blue/green-omschakelingen) mist de automatische invoer elke deploy. POST vanuit je CI-workflow één record per deployment:
curl -X POST https://frem.sh/_app/api/v1/dora/deployments \
-H "Authorization: Bearer ffp_<your-token>" \
-H "Content-Type: application/json" \
-d '{
"repo_full_name": "acme/web",
"environment": "production",
"deployed_at": "2026-05-14T10:00:00Z",
"commit_sha": "abc1234...",
"committed_at": "2026-05-14T09:30:00Z",
"success": true,
"external_ref": "deploy-12345"
}'Verplicht: repo_full_name, environment, deployed_at.
Optioneel maar aanbevolen:
commit_sha+committed_at: zonder deze velden valt de rij helemaal buiten de berekening van de doorlooptijd. De andere drie metrics tellen hem wel mee.success(standaardtrue): zet opfalsebij een rollback of mislukte deploy. Bepaalt het wijzigingsfaalpercentage + MTTR.external_ref: sleutel voor ontdubbeling, per tenant. Het endpoint is idempotent op(tenant_id, repo_full_name, environment, external_ref): speel je de aanroep opnieuw af vanuit een herhaalde CI-job, dan krijg je een 200 met de id van de bestaande rij in plaats van een dubbele invoer. Laat weg als je geen ontdubbeling wilt.is_rework(standaardfalse): markeer dit als hotfix, revert of vervolgwijziging. Telt mee voor het wijzigingsfaalpercentage, ook alssuccess=true. Bepaalt de 5e metric (Rework Rate) uit het DORA-rapport van 2025.
Vereiste scope op het token: findings:write, dezelfde scope die CI-workflows gebruiken voor dep-scan en het invoeren van SBOM’s. Maak het aan onder Organisatiebeheer → API-tokens (of gebruik tokenuitwisseling vanuit de IdP van je organisatie voor een kortlevend token).
Vorm van het antwoord (201 bij de eerste invoer, 200 bij een ontdubbelde aanroep):
{
"id": "0191e3b6-0000-7000-0000-000000000001",
"tenant_id": "0191e3b6-0000-7000-0000-000000000000",
"repo_full_name": "acme/web",
"environment": "production",
"deployed_at": "2026-05-14T10:00:00Z",
"deduped": false
}Voorbeelden van workflowintegraties
Actions-workflow in GitHub-stijl op fremforge
# .forgejo/workflows/dora-ingest.yaml
name: Report deploy to DORA
on:
workflow_run:
workflows: [Deploy to production]
types: [completed]
jobs:
report:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: fremforge
steps:
- uses: actions/checkout@v4
- name: POST dora deployment
run: |
curl -X POST https://frem.sh/_app/api/v1/dora/deployments \
-H "Authorization: Bearer ${{ secrets.FREMFORGE_API_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{
"repo_full_name": "${{ github.repository }}",
"environment": "production",
"deployed_at": "'"$(date -u +%FT%TZ)"'",
"commit_sha": "${{ github.sha }}",
"committed_at": "'"$(git show -s --format=%cI HEAD)"'",
"success": true,
"external_ref": "actions-run:${{ github.run_id }}"
}'Argo CD-post-sync-hook
# argocd-postsync-dora.yaml
apiVersion: batch/v1
kind: Job
metadata:
generateName: argocd-dora-
annotations:
argocd.argoproj.io/hook: PostSync
spec:
template:
spec:
restartPolicy: Never
containers:
- name: dora-report
image: curlimages/curl:8.5.0
envFrom:
- secretRef: { name: fremforge-dora-token }
args:
- sh
- -c
- |
curl -sS -X POST https://frem.sh/_app/api/v1/dora/deployments \
-H "Authorization: Bearer $FREMFORGE_API_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"repo_full_name\": \"$REPO\",
\"environment\": \"$ENV\",
\"deployed_at\": \"$(date -u +%FT%TZ)\",
\"commit_sha\": \"$ARGOCD_APP_REVISION\",
\"success\": true,
\"external_ref\": \"argocd:$ARGOCD_APP_NAME:$ARGOCD_APP_REVISION\"
}"Een deploy als rollback markeren
curl -X POST https://frem.sh/_app/api/v1/dora/deployments \
-H "Authorization: Bearer ffp_..." \
-H "Content-Type: application/json" \
-d '{
"repo_full_name": "acme/web",
"environment": "production",
"deployed_at": "2026-05-14T10:30:00Z",
"success": false,
"is_rework": true,
"external_ref": "rollback-from-deploy-12345"
}'Deze rij telt mee voor het wijzigingsfaalpercentage EN start de MTTR-klok. De volgende deploy met success=true naar (acme/web, production) sluit hem af.
Het dashboard lezen
De beheerpagina toont de laatst berekende waarden voor het huidige venster plus per metric een sparkline van 30 dagen. Beweeg over een datapunt voor de onderliggende lijst van deploys. Klik op een metric voor de uitsplitsing per repository.
De DORA-categorieën (Elite / Hoog / Gemiddeld / Laag) worden per metric live berekend tegen de drempels uit Accelerate, dezelfde banden die het DORA-rapport van Google Cloud gebruikt.
Wat we bewust niet doen
- Geen aggregatie per team. De as “Team” van DORA vereist dat elke deploy aan een team wordt toegeschreven, en dat valt bij monorepo’s en deploys over meerdere tenants niet betrouwbaar af te leiden uit alleen
repo_full_name. Vandaag beschikbaar via de uitsplitsing per repository; volwaardige aggregatie per team staat gepland. - Geen vergelijking buiten de tenant. Branchebenchmarks worden niet getoond: vergelijken zou betekenen dat je cijfers naar een aggregator van derden gaan, en dat botst met het contract over opslag in de EU. Gebruik het openbare DORA-rapport voor de vraag “waar staan we ten opzichte van de branche”.
- Geen automatische koppeling aan “incidenten”. MTTR wordt berekend uit je paar
success=false→ volgendesuccess=true. We proberen geen incidentvensters af te leiden uit PagerDuty, Statuspage of activiteit in Forgejo-issues; het signaal van de klant over het slagen of falen van een deploy is de gezaghebbende invoer.
Gerelateerd
- Wat er in elke omgeving live staat: de huidige en de vorige deploy per omgeving, gelezen uit de deploy-poort, ook als
GET /_app/api/v1/orgs/<org>/deployments/live. - Auditlog: elke DORA-invoer levert een auditgebeurtenis op (
api.dora.deployments.ingested), zodat een beheerder de herkomst van elk getoond getal kan nagaan. - Authenticatie voor agents: wissel een JWT van de IdP van je organisatie in voor een kortlevend
findings:write-token als je geen langlevend PAT wilt onderhouden. - API-tokens: maak langlevende
findings:write-PAT’s voor CI-workflows aan onder Gebruikersinstellingen → API-tokens; zie Authenticatiebeleid voor de maximale levensduur en het rotatiebeleid voor de hele organisatie.