GitHubのProjectsのDraftIssueを一括でIssueに変換するツール作った
作ったもの
GitHubのProjectsのDraftIssueをまとめてIssueに変換するCLIツール作ってみました。Ruby製です。
実行すると、これが
こうなります。(DraftIssueがIssueになる)
使い方
Rubyが実行できる環境が必要です。(開発時は3.2系で動作確認)
インストール
% gem install gh_draft_issues_converter
事前準備
- 変更元DraftIssueのあるProjectsの番号 (
-p
で指定 ) - 変更先のIssueのリポジトリ名(owner/repositoy)(
-r
で指定) - GitHub のPersonal Token( GITHUB_KEY に登録しておくこと)
コマンド例
% gh_draft_issues_converter -p 1 -r kuredev/gh-draft-issues-converter
主な制約
- カスタムフィールドでは単一選択の物のみ移行されます
- 標準のフィールドは、assignのみ移行されます
- Projectsとリポジトリは同じオーナーの物が対象となります
作った動機
業務で、開発案件のタスク管理をGitHubのProjectsを使用しており、テンプレート機能を用いています。テンプレート内のアイテムはDraftIssueとして管理されるため、実プロジェクトに展開したとき、大量のDraftIssueが生成されることとなります。実際のタスクとしてはIssueで管理するため、DraftIssueからIssueへの変換が必要でした。
Webからは1個1個コンバートする機能はあるのですが、まとめてコンバートする機能が見当たらなかったので、勉強がてら作ってみました。
技術的なメモ
GitHubではREST APIとGraphQL APIが提供されていますが、GitHubのProjectsはGraphQLからしか操作できないようだったので、今回GraphQLを全面的に用いました。
APIでは「コンバートする」という操作が無いようだったので、以下の流れを実装しました。
- DraftIssueのデータを取得
- Issueを作成
- DraftIssueを削除
今回もっともハマったのはフィールドオブジェクトのID周りです。フィールドとはアイテムの属性値です。コンバート処理ではアイテムごとのDraftIssueのフィールド値を取得した後、Issueにも同じフィールド値を設定する必要があります。
上記リンクをみると分かるように属性値には「ID」と「optionId」の2つの識別子のようなものがあります。説明を読んでもいまいち分からなかったのですが、どうやら前者は今のアイテムに紐づいている状態としてのID、optionIdはこのフィールド値そのもののIDということになるようです。
したがって、作成後のIssueにフィールド値を紐づけるときは後者のIDを指定する必要があります。
ちなみに後者のフィールド値自体のIDは以下のフィールドのオブジェクトからも参照できます。
その他備考
以下のコメントを参考に、レートリミットを避けるために、CreateIssueAPIの実行間隔として、デフォルトで25秒間のインターバルを設けています。
本ツール内では、この間隔は -i オプションで変更可能としています。
感想
最初はGraphQLの指定方法が分からず、ChatGPTと公式ドキュメントをにらめっこしながら調整していきましたが、いくつもサンプルのクエリを書いていくうちに徐々に書き方のコツが掴めて来た気がします。書き方は少しむずかしいものの、オブジェクト型が定義されているのがRESTと比べて表現力が大きいので、面白いところだなと思いました。
Discussion