📈

issue-metricsというGitHub Actionsの紹介

2023/10/05に公開

背景

ここ最近,issue-metricsというGitHub Actionsに定期的にパッチを送っています.

https://github.com/github/issue-metrics

contributionの画像

パッチを送っている関係から内部実装をある程度把握しており,このCIについてある程度詳しくなったという自負があるので,少し紹介したいと思います.公式なリリース記事は以下になります[1]

https://github.blog/2023-07-19-metrics-for-issues-pull-requests-and-discussions/

どんなGitHub Actions??

GitHub RepositoryのIssueやPull Requestのメトリクスを取得するGitHub Actionsです.
収集結果は,以下の画像のように,Issueとして作成されます[2]MEND Renovateが生成するdependency dashboardと近しいものを感じます.

実際に作成されるメトリクスissueの画像

デフォルトの状態では,次のようなメトリクスが取得されます.

  • 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のレビューに関して以下のような運用をしていると思います.

  1. PRがレビュー可能になったタイミングで,PRの作成者が ready for review のようなラベルを付与する
  2. レビュー,修正のサイクルを繰り返す
  3. 全てのレビュープロセスが完了し,PRがマージ可能となった段階(LGTMをつける段階)で,レビュワーがready for review のラベルを削除し,ready for merge のようなラベルを付与する

これらのプロセスを人力,botのどちらが行っているのかといった問題はあるものの,ラベルの付け外しのタイミングが正しく行われていると仮定すれば,ready for review のラベルがついていた期間が,レビューに要した時間と考えることができます.

このようなユースケースに対応するために,「特定のラベルが付けられていた期間」をメトリクスとして取得することができます.もちろん,対象とするラベルは任意に設定することができ,複数のラベルを指定することもできます.

LABELS_TO_MEASURE: 'ready for review'

最後に

個人的にコントリビュートしているGitHub Actionsについて少し紹介させて頂きました.多くの個人・組織が導入しやすいような様々な機能が用意されているので,ぜひ使ってみてください.

各種リンク

脚注
  1. この記事がリリースされてからいくつかの変更,特にv2へのアップデートが行われています.また,2023/10/05時点ではv2.10.0が最新リリースとなっていることに注意してください ↩︎

  2. 厳密には,Issueの作成には別のactionを用いています.当該actionでは,結果をマークダウン形式でエクスポートするところまでを扱っており,それを元に別のactionを利用してIssueを作成しています ↩︎

Discussion