Zum Hauptinhalt springen

DORA-Dashboard

Das DORA-Dashboard zeigt die vier Metriken aus dem State-of-DevOps-Report von DevOps Research and Assessment (DORA), live pro Organisation berechnet aus den Deployment-Ereignissen, die fremforge aufzeichnet. Du findest es unter Organisationsverwaltung → DORA-Metriken.

Kein externer Dienst. Keine Daten gehen an ein SaaS-Dashboard eines Drittanbieters. Die Zahlen werden in fremforge neben deinen Repositorys, deinem Audit-Log und deinen Befunden berechnet und haben dieselben Garantien für EU-Datenresidenz und Mandantentrennung wie alles andere unter /<slug>/_admin/*.

Die vier Metriken

MetrikWas sie misstWie fremforge sie berechnet
Deployment-HäufigkeitWie oft du in Produktion auslieferstAnzahl erfolgreicher Produktions-Deployment-Ereignisse, geteilt durch das rollierende Fenster. Angegeben als Deployments pro Tag und dann in die DORA-Kategorien eingeordnet (Elite: ≥1/Tag, High: 1/Tag–1/Woche, Medium: 1/Woche–1/Monat, Low: <1/Monat).
Durchlaufzeit für ÄnderungenZeit vom Commit bis zum Deploymentdeployed_at − committed_at, p50 + p95 über das Fenster. Zählt nur Deployments, die commit_sha + committed_at mitgeliefert haben. Angegeben in Stunden/Tagen.
ÄnderungsfehlerrateAnteil der Deployments, die fehlschlagen oder eine Korrektur brauchencount(success=false OR is_rework=true) / count(*) über das Fenster. Angegeben in Prozent.
Mittlere Wiederherstellungszeit (MTTR)Zeit bis zur Erholung von einem fehlgeschlagenen DeploymentFür jedes Ereignis mit success=false die reale Zeit von deployed_at bis zum nächsten erfolgreichen Deployment in dasselbe (repo, environment). Angegeben als Median.

Das Fenster ist standardmäßig 30 Tage rollierend. Einstellbar unter Organisationsverwaltung → DORA-Metriken → Einstellungen auf 7, 30 oder 90 Tage.

Wie Deployments in die Tabelle kommen

Zwei Erfassungswege laufen parallel. Nimm den, der zu deiner Art zu releasen passt; viele Organisationen nutzen beide.

1. Forgejo-Webhook release (automatisch)

Wenn ein Repository ein Forgejo-Release anlegt (annotierter Tag v* oder ein beliebiges Release-Objekt, veröffentlicht über die Oberfläche oder POST /api/v1/repos/{owner}/{repo}/releases), zeichnet fremforge ein Deployment-Ereignis auf mit:

  • environment = production (Standard)
  • deployed_at = created_at des Releases
  • commit_sha = target_commitish des Releases, aufgelöst zu einem SHA
  • committed_at = author.date des Commits
  • success = true
  • external_ref = release:{release_id} (idempotent: der Webhook kann gefahrlos erneut zugestellt werden)

Du musst nichts verdrahten. Das Webhook-Ziel ist auf Plattformebene konfiguriert; pro Organisation ist es automatisch aktiv.

2. POST /_app/api/v1/dora/deployments (eigene Erfassung, empfohlen für reichere Telemetrie)

Organisationen, die keine Releases taggen (Continuous Deployment, GitOps mit Push beim Merge, Blue/Green-Umschaltungen), entgeht mit der automatischen Erfassung jedes Deployment. Sende pro Deployment einen Datensatz per POST aus deinem CI-Workflow:

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"
  }'

Pflichtfelder: repo_full_name, environment, deployed_at.

Optional, aber empfohlen:

  • commit_sha + committed_at: ohne diese Felder fällt die Zeile komplett aus der Berechnung der Durchlaufzeit heraus. Die anderen drei Metriken zählen sie trotzdem.
  • success (Standard true): bei Rollback oder fehlgeschlagenem Deployment auf false setzen. Bestimmt Änderungsfehlerrate und MTTR.
  • external_ref: Deduplizierungsschlüssel, pro Organisation. Der Endpunkt ist idempotent auf (tenant_id, repo_full_name, environment, external_ref): Wiederholt ein CI-Job den Aufruf, bekommst du eine 200 mit der ID der bestehenden Zeile statt eines doppelten Eintrags. Lass das Feld weg, wenn du keine Deduplizierung willst.
  • is_rework (Standard false): markiert das Deployment als Hotfix, Revert oder Nacharbeit. Zählt zur Änderungsfehlerrate, auch wenn success=true. Speist die fünfte Metrik (Rework Rate) gemäß dem DORA-Report 2025.

Benötigter Scope des Tokens: findings:write, derselbe Scope, den CI-Workflows für Abhängigkeitsscans und SBOM-Erfassung nutzen. Erstelle ihn unter Organisationsverwaltung → API-Token (oder nutze den Token-Austausch mit dem IdP deines Unternehmens für einen kurzlebigen Token).

Form der Antwort (201 beim ersten Eintrag, 200 bei einem Treffer der Deduplizierung):

{
  "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
}

Beispiele für die Einbindung in Workflows

Actions-Workflow im GitHub-Stil auf 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 }}"
            }'

PostSync-Hook in Argo CD

# 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\"
                }"

Ein Deployment als Rollback markieren

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"
  }'

Diese Zeile geht in die Änderungsfehlerrate ein UND startet die MTTR-Uhr. Das nächste Deployment mit success=true nach (acme/web, production) stoppt sie.

Das Dashboard lesen

Die Verwaltungsseite zeigt die zuletzt berechneten Werte für das aktuelle Fenster und pro Metrik eine Sparkline über 30 Tage. Fahre mit der Maus über einen Datenpunkt, um die zugrunde liegenden Deployments zu sehen. Klicke auf eine Metrik, um die Aufschlüsselung pro Repository zu öffnen.

Die DORA-Kategorien (Elite / High / Medium / Low) jeder Metrik werden live gegen die Schwellenwerte aus Accelerate berechnet, dieselben Bänder, die der DORA-Report von Google Cloud verwendet.

Was wir bewusst nicht tun

  • Keine Aggregation auf Teamebene. Die Team-Achse von DORA braucht eine Zuordnung jedes Deployments zu einem Team, die sich bei Monorepos und mandantenübergreifenden Deployments nicht zuverlässig aus repo_full_name allein ableiten lässt. Heute über die Aufschlüsselung pro Repository verfügbar; eine echte Team-Aggregation ist geplant.
  • Kein Vergleich über deine Organisation hinaus. Branchen-Benchmarks werden nicht angezeigt: Ein Vergleich würde erfordern, deine Zahlen an einen Aggregator eines Drittanbieters zu senden, was dem Vertrag zur EU-Datenresidenz widerspricht. Für die Frage „Wo stehen wir im Branchenvergleich?“ nimm den öffentlichen DORA-Report.
  • Keine automatische Verknüpfung mit Vorfällen. Die MTTR wird aus deinem Paar success=false → nächstes success=true berechnet. Wir versuchen nicht, Vorfallszeiträume aus PagerDuty, Statuspage oder Issue-Aktivität in Forgejo abzuleiten: Maßgeblich ist das Erfolgs- bzw. Fehlersignal deiner eigenen Deployments.

Verwandte Themen

  • Was in jeder Umgebung live ist: das aktuelle und das vorherige Deployment je Umgebung, aus dem Deploy-Gate gelesen, auch als GET /_app/api/v1/orgs/<org>/deployments/live.
  • Audit-Log: Jede DORA-Erfassung erzeugt ein Audit-Ereignis (api.dora.deployments.ingested), sodass ein Operator die Herkunft jeder angezeigten Zahl nachprüfen kann.
  • Agenten-native Authentifizierung: Tausche ein JWT vom IdP deines Unternehmens gegen einen kurzlebigen Token mit findings:write, wenn du keinen langlebigen PAT pflegen willst.
  • API-Token: Erstelle langlebige PATs mit findings:write für CI-Workflows unter Benutzereinstellungen → API-Token; Höchstlaufzeit und Rotationsregeln für die ganze Organisation stehen unter Authentifizierungsrichtlinie.