Reusable GitHub Composite Action to calculate DORA metrics and upload CSV artifacts.
DoraPulse calculates the four key metrics defined by the DORA (DevOps Research and Assessment) team.
- How often an organization successfully releases to production
- Elite performers: Multiple deployments per day
- Metric shows: Release cadence and batch size
- Time taken from code commit to code running in production
- Elite performers: Less than one hour
- Metric shows: Process efficiency and deployment pipeline health
- How long it takes to restore service after an incident
- Elite performers: Less than one hour
- Metric shows: Incident response effectiveness
- Percentage of changes that lead to degraded service
- Elite performers: 0-15%
- Metric shows: Quality of testing and review processes
- Official DORA Research Program
- Google Cloud's DORA Metrics
- DORA's State of DevOps Reports
- DORA Metrics in GitHub
- Accelerate: The Science of Lean Software - The book that introduced DORA metrics
dora_metrics.csv: per-repository metricsdora_metrics_summary.csv: aggregate summary
token(required): GitHub token with read access to target repositoriesowner(optional): repository owner for single repository mode, or optional owner/org filter in topic moderepo(optional): repository name for single repository modetopic(optional): GitHub topic for discovery modedays(optional, default30)artifact_name(optional, defaultdora-metrics-csv)
Provide either:
owner+repo(single repository mode), ortopic(topic mode, optionalownerfilter)
Metrics are calculated from closed pull requests with merged_at inside the selected rolling window (days).
- Deployment Frequency:
merged_prs_in_window / days - Lead Time for Changes (hours):
Average of
(merged_at - created_at)for merged PRs in window - MTTR (hours):
Average of
(merged_at - created_at)only for merged PRs whose title/body contains recovery keywords:fix,hotfix,revert,rollback - Change Failure Rate (%):
(failed_prs / merged_prs_in_window) * 100A PR is treated as failed if title/body contains any failure keyword:fix,hotfix,revert,rollback,emergency
CSV files:
dora_metrics.csv: One row per repository with columns:repository,period_days,merged_prs,failed_prs,deployment_frequency_per_day,lead_time_hours,mttr_hours,change_failure_rate_pctdora_metrics_summary.csv: Columns:repositories_analyzed,period_days,total_merged_prs,total_failed_prs,avg_deployment_frequency_per_day,avg_lead_time_hours,avg_mttr_hoursWeighted failure rate formula:weighted_change_failure_rate_pct = (total_failed_prs / total_merged_prs) * 100
Notes:
- Unmerged PRs are ignored for all four metrics.
- If no merged PRs are found in window, rate/time metrics are emitted as
0.0.
name: DORA Metrics
on:
workflow_dispatch:
jobs:
dora:
runs-on: ubuntu-latest
steps:
- name: Run DoraPulse
uses: chandanrattan/DoraPulse@v1
with:
token: ${{ secrets.TOKEN }}
owner: my-org
repo: my-service
days: 30
artifact_name: my-service-doraname: DORA Topic Metrics
on:
workflow_dispatch:
jobs:
dora-topic:
runs-on: ubuntu-latest
steps:
- name: Run DoraPulse
uses: chandanrattan/DoraPulse@v1
with:
token: ${{ secrets.TOKEN }}
topic: microservice
owner: my-org
days: 30The action uses scripts/dora_metrics_csv.py.
- Install dependencies:
pip install .- Copy env template and set values:
cp .env.example .env- Edit
.envand choose one mode:
- Single repository mode: set
TOKEN,DORA_OWNER,DORA_REPOand keepDORA_TOPICempty - Topic mode: set
TOKEN,DORA_TOPICand optionallyDORA_OWNERas filter; keepDORA_REPOempty
- Run:
python scripts/dora_metrics_csv.pyOptional examples:
# Estimate only (no CSV generation)
python scripts/dora_metrics_csv.py --estimate-only
# CLI override example
python scripts/dora_metrics_csv.py --owner my-org --repo my-service --token <token>Install with dev tooling:
pip install ".[dev]"For local execution:
python scripts/dora_metrics_csv.pyUse .env / .env.example variables:
TOKENDORA_OWNER+DORA_REPO, orDORA_TOPICDORA_DAYSDORA_OUT_DIR