dora-metrics について
dora-metrics は、設定済みプロジェクトのデプロイ頻度と変更のリードタイムを取得し、リポジトリごとに報告します。GitHub、GitLab、Bitbucket、Azure のプロバイダー API を読み取り、デプロイマーカーを設定でき、任意で Markdown レポートを作成します。
主な機能
- 01デプロイ頻度と変更リードタイムの測定
- 024 種類のリポジトリプロバイダーに対応
- 03リリース、タグ、マージのマーカー設定
- 04リポジトリ単位での個別レポート
- 05サマリー表示と任意の Markdown レポート保存
活用シーン
- 01プロジェクトのデプロイ指標の調整
- 02複数プロバイダーにまたがるリポジトリの測定
- 03マージを基準とするデプロイ頻度の追跡
- 04リポジトリ別指標レポートの保存
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ somnio-software/ somnio-ai-tools --skill dora-metricsインストール後、Claude Code で/dora-metricsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdagents/report-writer.mdassets/report-template.mdconfig/projects.jsonevals/evals.jsonreferences/deployment-frequency.mdlead-time-for-changes.mdpractice-guidance.mdtroubleshooting.mdscripts/dora_metrics.pypractice_guidance.pytroubleshooting.pytests/test_dora_metrics.pytest_practice_guidance.pytest_troubleshooting.pytests/e2e/run_e2e.py詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
DORA 指標 — デプロイ頻度と変更のリードタイム
このスキルはデータの取得と集計のみを行います。人やプロジェクトを相互に解釈、順位付け、比較することはありません。それは別の後続ステップであり、このスキルの範囲外です。
コンテキスト
プロジェクトごとに、2 つの DORA 指標を測定します。デプロイ頻度(本番環境にどのくらいの頻度でデプロイするか)と、変更のリードタイム(変更が本番環境に到達するまでにどのくらいかかるか)です。これは調整の段階です。目標は、チームが自ら活用できる一貫した数値を得ることであり、人の評価に使う数値を得ることではありません。データの取得と解釈は意図的に別のステップに分けられています。指標を人の評価に使った時点で、それは優れた指標ではなくなります(グッドハートの法則)。
CI は統一されています(GitHub Actions)が、CD は一様ではありません(モバイル/ウェブ/バックエンドでデプロイ方法が異なります)。そのため、実際の CD を測定する代わりに、統一された目印を使用します。各リポジトリの本番ブランチにある、semver タグ vX.Y.Z が付いたリリースです(プロバイダーに Releases API がない場合は通常のタグを使います)。すべてのデータはリポジトリのプロバイダー APIから取得します。ローカルの git クローンから取得することはありません。リードタイムは各 PR/MR の実際の最初のコミットに依存し、それを確実に読み取れるのはプロバイダーの PR/MR オブジェクトからのみだからです(マージが squash であっても正しい値を保てます。main の git log ではそれが保証されません)。
各リポジトリは、サポート対象の 3 つのプロバイダーのいずれかに属し、config/projects.json でリポジトリごとに宣言します(provider、デフォルトは "github")。
| プロバイダー | リポジトリ識別子の形式 | デプロイの目印 |
|---|---|---|
github(デフォルト) | org/repo | GitHub Release、または通常のタグ |
gitlab | プロジェクトパス。例:group/project または group/subgroup/project | GitLab Release、または通常のタグ |
bitbucket | workspace/repo_slug | 通常のタグのみ — Bitbucket Cloud には Releases API がありません |
1 つのプロジェクト内、さらには 1 回の実行内でも、リポジトリごとに異なるプロバイダーを組み合わせられます。プロジェクトのフロントエンドは GitHub、バックエンドは GitLab に置き、それぞれを個別の認証情報で測定できます。api_base によるオーバーライドを除き、Bitbucket Server/Data Center および GitHub Enterprise は対象外です。このツールは GitHub.com、GitLab.com(または api_base を使ったセルフホストインスタンス)、Bitbucket Cloud に接続します。
プロジェクトはモノレポにもマルチレポにもできます。マルチレポの場合、各リポジトリは個別に測定・報告し、決して統合しません。プロジェクトがフロントエンドとバックエンドを別々の時期、あるいは別々のプロバイダーにデプロイする場合、それらを 1 つの数値にまとめると、調整によって明らかにするべきシグナルが隠れてしまいます。
各指標の正式な定義(属性、対象母集団、正確な計算方法)は、references/deployment-frequency.md と references/lead-time-for-changes.md を参照してください。
入力
- プロジェクト名(例:「Example Project」)。ユーザーが指定しない場合は、
config/projects.json内のすべてのプロジェクトを実行します。 - 測定期間:デフォルトは固定の 14 日間(設定
window_days)です。ユーザーが別の期間を明示的に希望しない限り、確認しないでください。
出力
-
プロジェクトごと、リポジトリごとに、デプロイ頻度、リードタイムの中央値、エッジケースに関する警告をまとめた、コンソール向けの読みやすい概要。
-
結果の保存を求められた場合は、
--out-dirで指定したフォルダーにファイルを出力します。リポジトリごとに 1 ファイルの Markdown レポート(YYYY-MM-DD-<repo>-dora-metrics.md)で、同じ概要を記載します。単独で簡単に開いて読める形式です。測定単位はリポジトリであり、同じプロジェクト内の他のリポジトリと統合することはありません。そのため、保存単位もリポジトリになります。マルチレポプロジェクトではリポジトリごとに 1 ファイルが作成され、そのリポジトリの数値のみが記載されます。
<repo>にはリポジトリ名を kebab-case に変換したものを使います。example-org/example-frontendはexample-frontendとなり、同じ実行内で同名のリポジトリが複数ある場合のみ、組織名を含むexample-org-example-frontendにフォールバックします。
ワークフロー
ステップ 1 — プロジェクトを特定する
config/projects.json を読み込みます。名前で対象のプロジェクトを検索します
(大文字と小文字は区別しません)。
プロジェクトが設定ファイルにない場合:リポジトリを作り上げたり、対応関係を推測したりしないでください。そこで処理を中断してユーザーに別ファイルの編集を求めるのではなく、不足している情報を直接尋ね、config/projects.json に自分で追加してください。
- プロジェクト名。
- プロジェクトを構成するリポジトリ(1 つまたは複数(マルチリポジトリ))と、各リポジトリが属するプロバイダー(
github、gitlab、bitbucketのいずれか。デフォルトはgithubですが、ユーザーが明示していない場合は推測せず確認してください)。識別子の形式はプロバイダーによって異なります。GitHub はorg/repo、GitLab はプロジェクトパス、Bitbucket はworkspace/repo_slugです。 - 各リポジトリの種類(web/mobile/backend)。
- 各リポジトリの本番ブランチ(妥当なデフォルトは
mainですが、推測せず確認してください)。 - 任意:リポジトリで Releases ではなくプレーンなタグを使用しているかどうか(
deploy_source: "tag")、またはグローバル設定とは異なるtag_patternを使用しているかどうか。デフォルトではグローバルのtag_patternを継承し、github/gitlab ではdeploy_source: "release"です。ただし Bitbucket には Releases API がなく、デフォルトで常にdeploy_source: "tag"になります(実際にはこれが必須です)。 - 任意:リポジトリが github.com/gitlab.com 上にない場合、セルフホストの GitHub Enterprise または GitLab インスタンスの
api_base。Bitbucket ではサポートされません(Cloud のみ)。 - 任意:プロジェクトについて、特記事項がある場合は短いメモ(例:異なる組織にまたがるマルチリポジトリ、リポジトリ間でデプロイが分離されている、複数のプロバイダーにリポジトリが分かれている)。プロジェクトの
"notes"フィールドに記載します。特に記載することがなければ不要です。
保存する前に、作成した JSON を表示して確認を求めてください(チーム全体で共有するファイルです)。保存したら、通常どおりステップ 2 に進みます。
ステップ 2 — 確認テーブルを表示する
API を呼び出す前に、測定対象をまとめたテーブルを表示します。ドキュメントを生成するスキルでは、取り消しにくいものを作成する前の必須確認事項としてテーブルを提示しますが、ここでは情報提供が目的です。スキルはデータを読み取ってレポートを作成するだけなので、気になる点(含めるべきでないリポジトリ、想定外のブランチなど)がなければ、そのまま進められます。実行するユーザーが測定対象を一目で確認できるよう、いずれの場合もテーブルを表示してください。Provider 列は必ず含めてください。すべてのリポジトリが GitHub の場合でも手間はかからず、プロジェクト内で複数のプロバイダーが混在する場合には特に重要です。
| プロジェクト | リポジトリ | プロバイダー | 種類 | 本番ブランチ | 期間 |
|---|---|---|---|---|---|
| Example Project | example-org/example-frontend | github | web, mobile | main | 過去 14 日間 |
| Example Project | example-partner-org/example-backend | github | backend | main | 過去 14 日間 |
テーブルの内容にユーザーの想定と異なる点があれば、スクリプトを実行する前に停止して確認してください。
ステップ 3 — 認証を確認する
スクリプト(scripts/dora_metrics.py)には、確認テーブルに記載されているすべてのプロバイダーについて認証情報が必要です。それぞれの認証情報には、プロジェクト内にある該当プロバイダーのリポジトリが属するすべての組織/グループ/ワークスペースへの読み取りアクセス権が必要です(例:GitHub が複数の組織にまたがる場合は、example-org と example-partner-org)。プロバイダーごとの優先順位は以下のとおりで、自動的に適用されます。
| プロバイダー | 1 番目 | 2 番目 |
|---|---|---|
github | GITHUB_TOKEN 環境変数 | gh auth token(GitHub CLI にログイン済みの場合) |
gitlab | GITLAB_TOKEN 環境変数 | glab auth token(GitLab CLI にログイン済みの場合) |
bitbucket | BITBUCKET_TOKEN 環境変数(ベアラー) | BITBUCKET_USERNAME + BITBUCKET_APP_PASSWORD の組み合わせ(CLI へのフォールバックなし) |
1 回の実行で複数のプロバイダーを組み合わせることができます。認証情報を解決できないプロバイダーのリポジトリは、no_credential 問題を伴う measured: false として報告されます(測定できない他のリポジトリと同じ形式です)。一方、認証情報があるプロバイダーのリポジトリはすべて通常どおり測定されます。テーブル内のどのプロバイダーにも認証情報がない場合に限り、スクリプトは測定全体をスキップし、その問題を 1 件だけ含むレポートを生成します。その場合も終了コードは 1 で、出力は生成されます(--out-dir が指定されていれば保存もされます)。
認証情報の不足は、他の問題と同じように報告してください。フローが Cowork の場合は、チャットにトークンを貼り付けるようユーザーに求めないでください。ローカルの Claude Code では、まだログインしていない場合は gh auth login / glab auth login を提案してください(Bitbucket には提案できる CLI ログイン手段がないため、代わりに環境変数を案内してください)。
ステップ 4 — スクリプトを実行する
pip install requests --break-system-packages # if needed
python3 scripts/dora_metrics.py --project "Example Project" --out-dir reports
使用できるフラグ:
--config:設定ファイルへのパス(デフォルト:config/projects.json)。--project:プロジェクト名を完全一致で指定します(デフォルト:設定内のすべてのプロジェクトを実行します)。--out-dir:指定すると、標準出力への表示に加えて、各リポジトリにつき 1 つのファイルを指定先に保存します —YYYY-MM-DD-<repo>-dora-metrics.md(読みやすい形式の同じサマリーです)。これは保存先の場所を指定するもので、--projectは測定する対象を指定します。ファイル名はプロジェクトではなく、リポジトリに基づきます。--branch <branch>:今回の実行に限り、prod_branchを上書きします(--projectが必要です)。設定は変更されません — 設定されたブランチとは異なるブランチを一度だけテストする場合に使用します。--deploy-source {release,tag}:今回の実行に限り、deploy_sourceを上書きします(--projectが必要です)。設定は変更されません。--provider {github,gitlab,bitbucket}:今回の実行に限り、providerを上書きします(--projectが必要です)。設定は変更されません — プロジェクト内のすべてのリポジトリに適用されるため、単一プロバイダーのプロジェクトでのみ有用です。--window-days N:今回の実行に限り、期間を日数で上書きします。設定は変更されません。
終了コード 1 は、実行の失敗を意味しません。測定できなかった項目(impact: blocked)があったという意味で、レポートは出力されています — Step 5 の説明どおり、標準出力(または保存されたファイル)から読み取り、ほかの問題と同様に、その内容を正確にユーザーへ報告してください。Bash の終了コードが 0 以外であることを理由に出力を破棄したり、実行が失敗したとユーザーに伝えたりしないでください。レポートがまったく出力されないのは、使用方法に誤りがある場合のみです — 不明な--project、--projectなしでの--branch/--deploy-source/--providerの指定、無効なdeploy_sourceまたはprovider、bitbucket リポジトリでのdeploy_source: "release"、あるいは bitbucket リポジトリでのapi_baseの指定です。この場合は、測定が始まる前に標準エラー出力へエラーが表示され、終了コード 1 で終了します。
config/projects.jsonのフィールドリファレンス(フォルダーを開いた人向けにREADME.mdにも記載されていますが、インストール時にSKILL.mdのみが含まれている場合でも、このスキルだけで完結するよう、ここに要約しています):
| フィールド | 階層 | 省略時のデフォルト | 内容 |
|---|---|---|---|
tag_pattern | グローバル | —(必須) | デプロイとしてカウントするタグが一致する必要のある正規表現です。 |
window_days | グローバル | —(必須) | 測定期間(日数)です。 |
projects[].name | プロジェクト | —(必須) | プロジェクトを検索する際に使用する名前です(大文字と小文字を区別しません)。 |
projects[].notes | プロジェクト | なし | このプロジェクト固有の理由や補足説明を自由記述します。 |
repos[].repo | リポジトリ | —(必須) | リポジトリ識別子です。形式はproviderによって異なります:org/repo(github)、プロジェクトパス(gitlab)、workspace/repo_slug(bitbucket)。 |
repos[].provider | リポジトリ | "github" | "github"、"gitlab"、または"bitbucket"です。 |
repos[].type | リポジトリ | [] | 情報表示用のリスト(web/mobile/backend)で、出力での表示にのみ使用します。 |
repos[].prod_branch | リポジトリ | —(必須) | そのリポジトリの本番ブランチです。 |
repos[].deploy_source | リポジトリ | "release"(github/gitlab)、"tag"(bitbucket) | "release"=semver タグを持つリリース(Bitbucket では利用できません)。"tag"=リリースを伴わない通常のタグで、タグは付けるがリリースを公開しないプロジェクト向けです。 |
repos[].tag_pattern | リポジトリ | グローバルのtag_pattern | 特定のリポジトリで異なるタグ形式(例:ビルド番号付き)が使われている場合に上書きします。 |
repos[].api_base | リポジトリ | プロバイダーの公開 API ルート | セルフホストの GitHub Enterprise または GitLab インスタンスの API ルートです。bitbucket ではサポートされていません(Cloud のみ)。 |
ステップ 5 — レポート
人が読むための要約を自分で即興で作成しないでください。report-writer サブエージェントを(Agent ツール経由で)呼び出し、スクリプトが標準出力に出力した JSON(および --out-dir が使用された場合は保存先のファイルパス)を渡して、assets/report-template.md に従って回答を作成させます。
呼び出すモデル(パラメーター指定可能): デフォルトでは、model: sonnet で report-writer を呼び出します。ユーザーが明示的に、より高速または低コストなものを求めた場合は、model: haiku を使用します。より詳細なものを明示的に求めた場合は、model: opus を使用します。明示的なリクエストがあった場合に限り、モデルを切り替えてください。独自に切り替えてはいけません。
report-writer は数値を整形するだけで、プロジェクト、リポジトリ、人を解釈、順位付け、採点、比較することはありません。従うべきルール(このステップで保証される内容)は次のとおりです。
- JSON も保存されている場合であっても、各リポジトリの 2 つの値(デプロイ頻度とリードタイムの中央値)をチャットで必ず直接回答してください。「ファイルを保存しました。そちらを確認してください」というだけの回答に置き換えてはいけません。
- 数値はスクリプトが出力したとおりに表示してください。解釈したり、順位付けしたりしてはいけません。それはこのスキルの範囲外であり、後続のステップで行います。
- スクリプトは測定中にリポジトリの設定を診断します。認証情報でリポジトリを確認できるか、
prod_branchが存在するか、デプロイマーカーがあるか、またそれらがtag_patternまたは設定済みのdeploy_sourceと一致するかを確認します。見つかった問題はすべてissuesに含まれ、references/troubleshooting.mdから読み込まれた修正手順がすでに付与されています。report-writerは各messageを一字一句そのまま表示し、その下に手順を記載します。問題(影響度がblocked/partial)と注記(影響度がnone)は、別々の見出しの下に記載します。追加の情報を調べたり、独自に手順を記述したりしてはいけません。guidance: nullの問題は、ガイダンスがないものとして報告します。これらは、この調整段階で明らかにすることを目的としたプロセス上のギャップを示すもので、隠すべきノイズではありません。手順の範囲は測定設定に厳密に限定し、数値の良し悪しについては決してコメントしません。 - スクリプトでまったく測定できなかったリポジトリは、
measured: falseで返され、メトリクスのフィールドは含まれません。その旨と問題を報告してください。リポジトリを省略したり、値をゼロに置き換えたりしてはいけません。 - ファイルが保存された場合は、値の報告に加えて、保存先(各リポジトリの
.mdファイル)を伝えてください。 - 結果には、ルートレベルに固定の
practice_guidanceカタログも含まれています。これは、一般的にリードタイムまたはデプロイ頻度に影響するエンジニアリングプラクティスであり、今回の実行結果に対する評価ではありません(references/practice-guidance.mdが信頼できる情報源です。スクリプトは絞り込みを行わずカタログ全体を添付するため、毎回同じ項目が含まれます)。report-writerは、これを必須の「これらのメトリクスを改善する方法」セクションとして、レポート全体で 1 回だけ(リポジトリごとには記載せず)、最後のプロジェクトセクションの後に配置し、dimensionごとにグループ化して、各項目を JSON のとおりに記載します。今回の実行で何も測定できなかった場合でも、このセクションは表示します。今回の実行データについて述べるものではないためです。測定結果に基づいて項目を選択、絞り込み、並べ替え、省略してはいけません。また、独自のプラクティスに関する助言を追加してはいけません。practice_guidanceが存在しないか空の場合でも、見出しを表示し、ガイダンスを利用できなかった旨とreferences/practice-guidance.mdを明記してください。項目を創作してはいけません。
設定の管理
config/projects.json はプロジェクトからリポジトリへの対応付けに関する唯一の信頼できる情報源であり、同期して更新すべき別のドキュメントはありません。新しいプロジェクトは、このワークフローのステップ 1(ユーザーとの会話)で追加するか、JSON を直接編集して追加します。このスキルが対応付けを独自に推測することはありません。対応付けがない場合は、ユーザーに尋ねます。
既知の制限事項(パイロット)
- リポジトリの最初の過去のリリース:Lead Time の計算対象から除外されます (その前の PR/MR の母集団を特定する方法がありません)。
- GitHub のみ:Search API を使用します(通常の REST API よりレート制限が厳しいです)。プロジェクトが 1~2 件であれば問題にならないはずですが、プロジェクト数を増やす場合は、バッチ処理やキャッシュが必要になる可能性があります。GitLab と Bitbucket にはこの特有の非対称性はありませんが、Bitbucket には以下に示す別のコストがあります。
- 初回実行では Lead Time の値が高くなります。これは調整期間中には想定されることであり、3~4 回の正常な測定期間が経過するまでは、パフォーマンスの指標として解釈しないでください。
deploy_source: "tag":タグ/リリースがマージの 1~2 秒後に作成された場合(自動でタグを付けるパイプラインなど)、PR/MR が除外されたり、次の期間に誤って割り当てられたりすることがあります。詳しくはscripts/dora_metrics.pyの docstring を参照してください。実際の頻度が数日~数週間であれば問題になりません。- セットアップ診断では、リポジトリごとに REST API を 2 回追加で呼び出します(リポジトリとブランチの存在確認)。また、リポジトリからデプロイマーカーが取得できず、その理由を説明するための証拠が必要な場合に限り、さらに 2 回呼び出します。これらは負荷の小さい REST API 呼び出しであり、レート制限の厳しい Search API の呼び出しではありません(GitHub のみ)。
- GitLab のセルフホスト環境:マージリクエスト一覧での
merged_after/merged_beforeフィルタリングには GitLab >= 13.1 が必要です。それより古いインスタンスでは、Lead Time を正確に測定するためにアップグレードが必要になる場合があります。 - GitLab のタグ:API で取得できるのは対象コミットの日付のみで、「タグ作成日」は別に取得できません(GitHub では注釈付きタグ自体の作成日とコミットの日付を区別できますが、GitLab では区別できません)。
- Bitbucket:Releases API がないため、すべての Bitbucket リポジトリは通常のタグを使って測定されます(
deploy_sourceは"tag"に固定されます)。また、プルリクエストのオブジェクトには「マージ日時」が直接含まれていません。スクリプトは可能な場合はマージコミットの日付を使用し、取得できない場合は PR のupdated_onを使用します。これは妥当な代替値ですが、GitHub/GitLab より正確性は劣ります。また、サーバー側で「この日付の間にマージされた項目」を絞り込んで測定期間をプロバイダーに指定するフィルターがないため、Bitbucket での Lead Time の測定には GitHub/GitLab より多くの API 呼び出しが必要です。 - Bitbucket Server/Data Center と GitHub Enterprise は、GitHub Enterprise の
api_base上書き設定を除き、対象外です。Bitbucket は Cloud のみが対象です。 - E2E テスト(
tests/e2e/)では現在、GitHub の経路のみをカバーしています。GitLab と Bitbucket は、実際のエンドツーエンド実行ではなく、HTTP レスポンスをモックしたユニットテストでカバーしています。
重要な注意事項
- このスキルは取得と報告のみを行います。人を評価、順位付け、比較することはありません。データの取得と評価を混在させると、データが歪められます(グッドハートの法則)。
- 複数のリポジトリがある場合も、それぞれを個別に測定して報告し、統合することはありません。リポジトリが異なるプロバイダー上にある場合も同様です。
- データソースはリポジトリのプロバイダー API(GitHub、GitLab、または Bitbucket)のみです。クローンしたリポジトリのローカルな
.gitは読み取りません。 - 要求されたプロジェクトが
config/projects.jsonにない場合は、推測で追加しないでください。詳細を尋ねて追加してください(ステップ 1)。リポジトリ、ブランチ、プロバイダーを決めつけないでください。 - プロバイダーに対して解決可能な認証情報がないリポジトリは、
measured: falseとno_credentialの問題を報告します。ほかのリポジトリが認証情報のあるプロバイダー上にある場合、処理全体を妨げることはありません。