GitHub Projectsへ簡単にissueを作成、追加するGitHub CLI拡張を作った
はじめに
業務やプライベートで、少し特殊な方法でGitHub Projectsを運用しており、GitHub Projectsに直接issueを追加したいと思うことが多々ありました。
詳細は割愛しますが、運用を簡単に説明しますと、プランニングでGoogle Sheetsを用いてタスクや見積もりを整理/調整し、一括でissueを作成、GitHub Projectsへ追加を行っていました。これらの作業を簡単にするために、GitHub CLI拡張を作成しました。
GitHub CLIの拡張について
詳細は公式ドキュメントを参考にしてください。GitHub CLIには任意のユーザーが作成した拡張機能を導入することが可能です。
github extensions install {オーナー名}/{リポジトリ名}
拡張はGitHub CLIラッパーで、デフォルトでは足りない権限もGitHub CLIの設定で適宜scopeを追加することが可能です。
メリットとして、拡張導入側はツール毎に設定ファイルを管理する必要がなく、拡張作成側は、トークン設定周りの実装をGitHub CLI側に任せることが可能です。
動作イメージ
動作概要は以下の画像の通りです。issue及びdraft issue両方とも作成可能で、ProjectV2で導入されたカスタムフィールドも設定可能です。(※ iterationは未対応)

インストール方法
ツールは以下に公開しております。
GitHub CLIの導入
GitHub CLIを導入してない方は、公式ドキュメントを参考に導入してください。
projectsのscopeの追加
GitHub CLIのデフォルトのscopeだと権限が足りないため、権限を追加します。
gh auth login --scopes 'project'
gh-p2の導入
拡張を導入します。
gh extension install shuntaka9576/gh-p2
※ 初回実行時は、バイナリインストールため遅い場合はがあります。
使い方
必須オプション解説
詳細はREADMEを参考にしてください。本記事ではQuick start的な内容を書いていきます。
利用するGitHub Projectがuserに紐づくかorganizationに紐づくかを確認して頂き、どちらかを指定します。
# userに紐づく場合
gh p2 create -u "<user名>"
# organizationに紐づく場合
gh p2 create -o "<organization名>"
今回はuserに紐づくとし、ユーザー名はshuntaka9576とします。
次に作成するissue or draft issueタイトルを指定します。Fix bugとします。
gh p2 create -u "shuntaka9576" \
 -t "Fix bug"
次にプロジェクトタイトルを指定します。testProjectとします。
gh p2 create -u "shuntaka9576" \
 -t "Fix bug" \
 -p "testProject"
存在しないプロジェクトタイトルだった場合、以下のように利用可能なプロジェクトタイトル一覧が出力されるようにしています。タイトル名を拾うのが面倒な場合は、適当な文字列を指定するのもありです。
$ gh p2 create -u "shuntaka9576"
 -t "Fix bug" \
 -p "testProject"
Not found project name: testProject
The following project names are available and can be specified in the project-title(-p) flag.
  * test
実際に存在するプロジェクトタイトルがtestということがわかったので、プロジェクトタイトルにtestを指定します。
gh p2 create -u "shuntaka9576" \
 -t "Fix bug" \
 -p "test"
ここから先は、issueを作成するかdraft issueを作成するかで指定するオプションが異なります。
issueを作成する
issueを作成したいリポジトリを-rオプションで指定します。
gh p2 create -u "shuntaka9576" \
 -t "Fix bug" \
 -p "test" \
 -r "repoName"
これで一先ず、repoNameリポジトリへissue発行しつつProjectへ登録が可能です。
label Projectのカスタムフィールド assignees を設定する場合は以下の通りです。labelは、存在しない場合にランダムな色で新規作成します。カスタムフィールドはiteration以外は対応しています。date型のカスタムフィールドを設定する場合はISO 8601形式で指定するようにしてください。
gh p2 create -u "shuntaka9576" \
  -t "Fix bug" \
  -p "test" \
  -r "repoName" \
  -a "shuntaka9576" \
  -l "label1" \
  -l "label2" \
  -f "Status:Todo" \
  -f "Point:1" \
  -f "deadline:2022-08-11"
指定可能なオプションの詳細は、helpをご確認ください。
gh p2 create --help
Usage: p2 create --project-title=STRING --title=STRING
Option to create an issue or draft issue directly in Project V2.
Flags:
  -h, --help                       Show context-sensitive help.
  -o, --org=STRING                 Specify an organization name.
  -u, --user=STRING                Specify a user name.
  -v, --version                    print the version.
  -p, --project-title=STRING       Specify the title of ProjectV2.
  -t, --title=STRING               Specify issue title.
  -r, --repo=STRING                Specify the repository name. Owner name is not required. This flag is not available when creating draft issues.
  -f, --fields=FIELDS,...          Specify ProjectV2 custom fields in the format {keyName}:{valueName}. e.g. Status:Todo, Point:3, date:2022-08-29. See https://docs.github.com/ja/graphql/reference/input-objects#projectv2fieldvalue for data types. Iteration is not currently supported.
  -l, --labels=LABELS,...          Specify the label name to be set for the issue. If a label with the target name does not exist, a new one will be created with a random color. This flag is not available when creating draft issues.
  -d, --draft                      Due to GitHub specifications, the --label and --repo options cannot be used together.
  -a, --assignees=ASSIGNEES,...    Specify the GitHub account ID to be assigned.
draft issueを作成する
draft issueは、GitHubの仕様上labelを指定することが不可能です。また所属するのはProjectであるため、リポジトリの指定も不可能です。最後に-dオプションをつければ作成できます。需要はなさそうです。
gh p2 create -u "shuntaka9576" \
  -t "Fix bug" \
  -p "test" \
  -a "shuntaka9576" \
  -f "Status:In Progress" \
  -f "Point:4" \
  -f "deadline:2022-08-14" \
  -d
利用技術や参考にした内容
Go言語で書きました。CLIライブラリは、alecthomas/kongを利用しています。他にも気になるところがあればリポジトリの中身を参照してください。
yusukebe様のgh-markdown-previewのshell実装や配布周りをかなり参考にさせて頂きました。。ありがとうございます。。
ProjectV2のAPIがあることは知らなかったのですが、以下の記事で存在を知りました。ありがとうございます、、
Projects(classic)はTUIを作ったことがあるのですが、ProjectV2はカスタムフィールドのStausがカンバンの列に該当するため、かなり取り回しが楽でした。
今後
- issueのbodyを設定可能にする
- カスタムフィールドのiterationタイプ対応
- GitHub API呼び出し周りの最適化(少しissue作成が遅い)
開発時によく参照したドキュメント
GraphQL API仕様書
MutationやQueryの利用方法の確認に利用します。
REST API仕様書
GraphQL APIでは対応できないケースが多々存在するので、REST APIも併用するのが良いです。gh-p2では、labelの作成や取得はREST APIを利用しています。
GitHub CLI extensions作成方法
1回読めば良い感じだと思います。
最後に
ニッチなツールですが、同じような問題がある方がいれば使ってみてください。
この手のツールを作る際に、直接GitHub APIを叩くことは以後ないだろうと思えるくらいにGitHub CLI周りのエコシステムが整っていることが分かりました。基本的にはgh api gh api graphql コマンドで代用可能です。また、REST API仕様書には、GitHub CLIの実行方法が掲載されているので、調査しやすいです。



Discussion