ククログ

株式会社クリアコード > ククログ > GitHub ProjectsにOrganizationを横断してIssueを集約し、トラッキングしやすくする方法

GitHub ProjectsにOrganizationを横断してIssueを集約し、トラッキングしやすくする方法

GitHubを利用して様々なプロジェクトに関わっている場合、関連するissueを一覧で確認できると便利な場合があります。 Notificationsのフィルタを活用すればある程度一覧性を担保できますが、その結果を複数人で共有、加工等したい場合には不向きです。 GitHub ProjectsではOrganization配下に作成されたリポジトリのissueを任意で追加できるので、トリアージが必要なissueを登録しておくと一覧できて有用です。

クリアコードではFluentdの開発にも深く関わっていることから、Fluentdのサポートサービスを提供しています。 Fluentdにはプラグインのエコシステムがありますが、関連するリポジトリはあちこちに分散しています。 それらのリポジトリで新規に起票されたissueをGitHub Projectsで一覧できると有用なのですが、そのようなしくみは整えられていませんでした。

そこで、GitHub ProjectsにOrganizationを横断して既存のissueを集約し、Fluentd Kanbanとしてトラッキングしやすくした方法について紹介します。

GitHub Projectsへの既存issueの登録方法はいくつかあります。

  • ProjectsのAdd itemからissueのURLを登録する
  • Projectsの組み込みのワークフローを作成して登録を自動化する
  • 既存のGitHub Actionを利用してissueの登録を自動化する
  • 独自にissueの登録を自動化する

以下それぞれ説明します。

GitHub ProjectsのAdd itemからissueのURLを登録する

GitHub Projectsにissueを集約するための、もっともシンプルなやりかたです。

project への項目の追加 - issue または pull request の URL の貼り付け に記載されているように、URLを貼り付けてEnterキーを押すことで異なるOrganizationのissueなども追加可能です。

(スクリーンショット:GitHub ProjectsのAdd Itemでissueを登録するときの画面)

ただし、毎回手作業なので随時発生するissueに追従していくのは非常に手間がかかります。

監視対象のリポジトリがとても少ないか、issueの登録頻度が少ない場合に向いています。 当然ながら、監視対象のリポジトリの活動が活発になるにつれて破綻するやりかたです。

GitHub Projectsの組み込みのワークフローを作成して登録を自動化する

GitHub Projectsでは組み込みのワークフローを作成して、条件にマッチするissueを自動的に登録できます。

組み込みの自動化の使用を参照すると どんな感じで設定できるかの感触がつかめることでしょう。

登録する条件はフィルタとして指定できます。 is:issue is:open label:"waiting-for-triage"といったように、特定のラベルの付いたissueが登録されたときに自動でそれをGitHub Projectsに登録できます。

ただし、組み込みのワークフローの登録数には上限があり、Fluentプロジェクトの場合は5つとなっています。 (組織のプランによってこの上限は変わります)

また、GitHub Projectsを作成したOrganization配下のリポジトリのissueしか対象にできません。 FluentプロジェクトのようにFluent Organization配下にないリポジトリのissueの登録を自動化したい場合には、他の手法と組み合わせる必要があります。

既存のGitHub Actionsを利用してissueの登録を自動化する

既存のGitHub Actionsにadd-to-projectというアクションがあります。 これを利用するとissueが新規作成されたときに、ラベルを付与したり、GitHub Projectsへのissueの登録を自動化できます。

なお、このアクションを利用する場合には、対象Organizationの設定権限もしくは各リポジトリごとの設定権限が必要です。 これは、GitHub Projectsへ書き込み権限をもたせたpersonal access token(PAT)をOrganization secretもしくはRepository secretとして設定する 必要があるからです。 前者のOrganization secretの場合、Organization配下のすべてのリポジトリで参照できるようになるのでPATの設定を集約できます。 後者のRepository secretの場合、該当リポジトリでのみ参照できるので、PATをあちこちに設定してまわる必要があります。

Fluentプロジェクトの場合、GitHub Projectsの組み込みのワークフローの設定の制限のためfluent配下でもワークフローを利用できないリポジトリがいくつかありました。

権限のあるOrganizationについてはOrganization secretを設定し、そうでないOrganization配下にリポジトリーに対してはRepository secretを適用することにしました。

注意事項として、add-to-projectを利用する場合、フィールドをきめ細かに設定することができません。 Adding status and start or end dateとして要望はでているので、もしかしたらいずれ実装されるかもしれません。

当然のことながら、リポジトリの設定変更権限がないとこのしくみは使えないので、別の手法を利用する必要があります。

GitHub Actionsで独自にissueの登録を自動化する

次のような場合に検討することになるかもしれないやりかたです。

  • GitHub Projectsのワークフローが利用できない(上限に引っかかっている)
  • 設定権限がないので、既存のGitHub Actionsを対象リポジトリで利用できない
  • より複雑な条件でフィルタした特定のissueの登録を自動化したい

Fluentプロジェクトの場合、サードパーティーの提供するリポジトリのissueの登録を自動化したい場面に検討していました。 実際には、対象となるプラグインをfluent-plugins-nurseryで引き取ったほうがよいのではということでボツになった方法です。

次のような手順を踏む必要があります。

  • GitHub ProjectのノードIDを特定する
  • 登録したいissueのノードIDを特定する
  • GitHub Projectに対象issueを登録する

GitHub ProjectのノードIDを特定する

Fluentプロジェクトで利用しているGitHub Project (https://github.com/orgs/fluent/projects/4) の番号は4なので、ノードのIDを特定するには次のようなクエリで実現できます。

curl --silent --request POST \
  --url https://api.github.com/graphql \
  --header "Authorization: Bearer (ここにPATを指定する)" \
  --data '{"query":"query{organization(login: \"fluent\") {projectV2(number: 4){id}}}"}' | jq .
{
  "data": {
    "organization": {
      "projectV2": {
        "id": "PVT_(省略)"
      }
    }
  }
}

レスポンスとして、プロジェクトのノードIDが得られます。

登録したいissueのノードIDを特定する

次に、登録したいissueのノードIDを特定する必要があります。 例えば、次のようなクエリーで、fluent/fluent-plugin-kafkaリポジトリに作成されたwaiting-for-triageラベルの付与されたissueを調べられます。

curl --silent --request POST \
  --url https://api.github.com/graphql \
  --header "Authorization: Bearer (ここにPATを指定する)"\
  --data '{"query": "{search(query: \"repo:fluent/fluent-plugin-kafka is:issue is:open label:waiting-for-triage\", type: ISSUE, last: 100) {issueCount nodes {... on Issue {id title createdAt updatedAt}}}}"' | jq . 
{
  "data": {
    "search": {
      "issueCount": 10,
      "nodes": [
        {
          "id": "I_(省略)",
          "title": "max_send_limit_bytes setting is not working as expected",
          "createdAt": "2024-12-23T13:31:17Z"
        },
		...

検索条件のところを工夫すれば、より高度なフィルタリングも実現できるでしょう。

GitHub Projectに対象issueを登録する

プロジェクトのidとissueのidが特定できたら、あとはプロジェクトのコンテンツとしてひもづけます。 次のようなクエリでGitHub Projectsにissueが登録でき、レスポンスとして、ひもづけられたアイテムのidが得られます。

curl --silent --request POST \
  --url https://api.github.com/graphql \
  --header "Authorization: Bearer (省略)"\
  --data '{"query": "mutation {addProjectV2ItemById(input: {projectId: \"PVT_(省略)\", contentId: \"I_(省略)\"}) {item {id}}}"}'
{"data":{"addProjectV2ItemById":{"item":{"id":"PVTI_(省略)"}}}}

ここまでできたら、あとは上記を自身が管理しているなんらかのリポジトリのGitHub Actionsワークフローへと組み込むとよいでしょう。

さいごに

今回は、GitHub ProjectsにOrganizationを横断してissueを集約し、トラッキングしやすくする方法について紹介しました。

似たようなトラッキングをしたいひとは「GitHub Projectsの組み込みのワークフローを作成して登録を自動化する」あたりから試してみるのが良いでしょう。 GitHub ProjectのWebインタフェースから簡単に設定できるので、とっつきやすいはずです。