issue-metricsというGitHub Actionsの紹介
背景
ここ最近,issue-metricsというGitHub Actionsに定期的にパッチを送っています.
パッチを送っている関係から内部実装をある程度把握しており,このCIについてある程度詳しくなったという自負があるので,少し紹介したいと思います.公式なリリース記事は以下になります[1].
どんなGitHub Actions??
GitHub RepositoryのIssueやPull Requestのメトリクスを取得するGitHub Actionsです.
収集結果は,以下の画像のように,Issueとして作成されます[2].MEND Renovateが生成するdependency dashboardと近しいものを感じます.
デフォルトの状態では,次のようなメトリクスが取得されます.
- Issue/PRが作成されてから最初のコメントがつくまでの平均時間
- Issue/PRが作成されてからCloseされるまでの平均時間
- discussionの回答がつくまでの平均時間
- いまだにCloseされていないIssue/PRの数
- 期間内にCloseされたIssue/PRの数
- 期間内に作成されたIssue/PRの数
合わせて,上記の画像では少し見づらいですが,各Issue/PRへのURL,作成者などが記された表も生成されていることがわかります.
エンジニア組織であれば,例えば「最初のコメントは平均n時間以内につけるようにする」「月の最後にCloseされていないIssue/PRはn個以下にする」のように,これらの値を元にしたKPIを設定することができるのではないでしょうか.もちろん,個人運用のリポジトリやOSSプロジェクトなどでも,同じような指標として利用することができます.
また,生成されたIssueのタイトルが,Monthly issue metrics report
となっていることからもわかるように,ここでは月次でメトリクスを取得するようにしています.これは,CIの実行頻度を月次に設定しているためであり,もちろん任意に設定することができます.
使い方
ここでは簡単に使い方を紹介します.より詳しい使い方は,READMEを参照してください.
以下のようなマニュフェストを,.github/workflows/<お好きな名前>.yml
のように配置することで,月次でメトリクスを取得することができます.ただし,SEARCH_QUERY: 'repo:<repo-name> ...
の部分は,メトリクスを取得したいリポジトリを指定する必要があります.これは例えば,https://github.com/Okabe-Junya/sandbox というリポジトリであれば,repo:Okabe-Junya/sandbox
と指定することになります.
(以下のマニュフェストは,公式リリース: Metrics for issues, pull requests, and discussions#setup-and-workflow-integration を元に一部改変したものです)
name: Monthly issue metrics
on:
workflow_dispatch:
schedule:
- cron: '3 2 1 * *'
permissions:
issues: write
pull-requests: read
jobs:
build:
name: issue metrics
runs-on: ubuntu-latest
steps:
- name: Get dates for last month
shell: bash
run: |
# Calculate the first day of the previous month
first_day=$(date -d "last month" +%Y-%m-01)
# Calculate the last day of the previous month
last_day=$(date -d "$first_day +1 month -1 day" +%Y-%m-%d)
#Set an environment variable with the date range
echo "$first_day..$last_day"
echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
- name: Run issue-metrics tool
uses: github/issue-metrics@v2
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SEARCH_QUERY: 'repo:<repo-name> is:"issue pr" created:${{ env.last_month }} -reason:"not planned"'
- name: Create issue
uses: peter-evans/create-issue-from-file@v4
with:
title: Monthly issue metrics report
token: ${{ secrets.GITHUB_TOKEN }}
content-filepath: ./issue_metrics.md
assignees: <YOUR_GITHUB_HANDLE_HERE>
このマニュフェストから察する方もいるかと思いますが, SEARCH_QUERY
でGitHubの検索クエリを指定しています.ここをよしなに設定することで,収集対象のリポジトリや期間,Issue/PRの種類などを指定することができます.
また,GitHub Actionsのcronは,UTCで実行されることに注意してください.この記事を執筆している 2023/10/05 時点ではタイムゾーンの指定ができないため,9時間の時差を考慮する必要があります.より詳しくは,公式ドキュメントのEvents that trigger workflows#scheduleの項目などを参照してください.
tips
複数のリポジトリに跨ってメトリクスを取得する
複数のリポジトリに跨ったメトリクスを取得したいというユースケースもあると思います.その場合は,以下のように,SEARCH_QUERY
に複数のリポジトリを指定することで,メトリクスを取得することができます.
SEARCH_QUERY: 'repo:owner/repo1 repo:owner/repo2 is:issue'
複数のリポジトリを指定する場合,全てのリポジトリがPublicである,あるいは同一の個人・組織が所有しているリポジトリであれば上記の通りで設定でき非常に簡単ですが,そうでない場合は複雑になります.具体的には,各個人・組織からissue, prのread権限がついているアクセストークンを作成し,それらをシークレットとして登録する必要があります.少し複雑な手順を踏むことになるので,この記事では割愛します.
ラベルを用いたメトリクスの取得
いくつかのエンジニア組織やOSSプロジェクトなどでは,PRのレビューに関して以下のような運用をしていると思います.
- PRがレビュー可能になったタイミングで,PRの作成者が
ready for review
のようなラベルを付与する - レビュー,修正のサイクルを繰り返す
- 全てのレビュープロセスが完了し,PRがマージ可能となった段階(LGTMをつける段階)で,レビュワーが
ready for review
のラベルを削除し,ready for merge
のようなラベルを付与する
これらのプロセスを人力,botのどちらが行っているのかといった問題はあるものの,ラベルの付け外しのタイミングが正しく行われていると仮定すれば,ready for review
のラベルがついていた期間が,レビューに要した時間と考えることができます.
このようなユースケースに対応するために,「特定のラベルが付けられていた期間」をメトリクスとして取得することができます.もちろん,対象とするラベルは任意に設定することができ,複数のラベルを指定することもできます.
LABELS_TO_MEASURE: 'ready for review'
最後に
個人的にコントリビュートしているGitHub Actionsについて少し紹介させて頂きました.多くの個人・組織が導入しやすいような様々な機能が用意されているので,ぜひ使ってみてください.
各種リンク
- リポジトリ: github/issue-metrics
- リリース記事: Metrics for issues, pull requests, and discussions
- Events that trigger workflows#schedule
- 個人検証用のワークフロー: Okabe-Junya/sandbox/.github/workflows/issue-metrics.yml
Discussion