GitHub CLI + jqで特定タイトルのイシュー番号だけ取得する
はじめに
こんにちは、がんがんです。
普段 GitHub CLI + GitHub Actions で良しなに自動化しているのですが、たまに GitHub CLI だけだと痒いところに手が届かないことがあります。
そんな時は GitHub CLI に備わっている-q
オプションで jq を利用することができます。
CLI のオプションとして jq コマンドが利用できる点は AWS CLI と似ていますね。AWS CLI と jq については以前下記記事で実験しています。
本記事では GitHub CLI と jq の力を存分に使って問題解決していきたいと思います。
ゴール:解決したい課題
今回の要件は以下のとおりです。
- 達成したい課題:毎日作成している日報イシューを自動でクローズしたい。クローズ対象は前日のイシュー
- 環境:GitHub Actions で動作させる
- 利用するツール:GitHub CLI、jq で完結させる
本課題を解決するため順番に実験していきます。
イシュー一覧を取得する
まずはイシュー一覧を取得してみます。GitHub CLI にはlist
コマンドが存在しており、こちらで簡単に取得できます。
$ gh issue list
特定タイトルのイシューをイシュー番号だけ取得したい
例えば、タイトルが 2024/08/09 のイシュー番号を取得したいとします。GitHub CLI には-S, --search
オプションが備わっており、こちらを用いることで解決できます。
$ gh issue list -S '2024/08/09' --json number -q '.[].number'
679
ただ、この場合は類似タイトルだった場合に複数個が取得されます。例えば、2024/08/10 と 2024/08/10 TODO がイシューにあった場合は以下のように 2 つ取得されます。困りました。
$ gh issue list -S '2024/08/10' --json number -q '.[].number'
680
681
特定タイトルのイシューを(タイトル完全一致で取得し)イシュー番号だけ取得したい
-S
オプションだと取得が不十分な結果になりました。そのため、jq
コマンド側で絞ります。いい感じです。
$ gh issue list --json number -q '.[] | select(.title == "2024/08/09") | .number'
679
変数を利用する場合は?
ワークフロー作成おじさんは気づいたはずです。「毎回変わるタイトルはどうやって可変させれば良いのか」
shell / jq 大好き芸人は気づいたはずです。「jq の--arg オプションは利用できるのか」
実際に試してみましたが予想通りダメでした。--arg
オプションが GitHub CLI に存在していないのでエラーが発生します。
$ gh issue list --json number,title -q --arg target '2024/08/09' '.[] | select(.title == $target) | .number'
unknown arguments ["target" "2024/08/09" ".[] | select(.title == $target) | .number"]; please quote all values that have spaces
Usage: gh issue list [flags]
Flags:
--app string Filter by GitHub App author
-a, --assignee string Filter by assignee--search
-A, --author string Filter by author
-q, --jq expression Filter JSON output using a jq expression
--json fields Output JSON with the specified fields
-l, --label strings Filter by label
-L, --limit int Maximum number of issues to fetch (default 30)
--mention string Filter by mention
-m, --milestone string Filter by milestone number or title
-S, --search query Search issues with query
-s, --state string Filter by state: {open|closed|all} (default "open")
-t, --template string Format JSON output using a Go template; see "gh help formatting"
-w, --web List issues in the web browser
-q
オプションだけだと jq の力を最大限利用することはできなそうですね。大人しくjq
を使っていきます。jq 利用する場合は以下のコマンドでいけます。
$ gh issue list -R 'shinGangan/dairy-report' --json number,title | jq --arg target "2024/08/09" '.[] | select(.title == $target) | .number'
680
特定タイトルのイシューのイシュー番号を取得し、そのイシューをクローズする
では、一番やりたかった「特定イシュー番号を特定しクローズする」というワンライナーを書きます(別にワンライナーである必要はないです。Shell 芸をワンライナーで書けると気持ちいいだけです)。
number=$(gh issue list --json number,title | jq --arg target "2024/08/05" '.[] | select(.title == $target) | .number') \
&& gh issue close $number -c "期限が切れたのでクローズします"
本項ではクローズしていますが、例えば
- 特定イシューを紐付けたい
- 特定イシューに対してコメントを残したい
などの GitHub CLI で行えることは可能となります。また、jq の柔軟性を活かして柔軟な条件分岐が書けるのも良い点です。
参考
おわりに
今回は GitHub CLI と jq を用いて特定イシューの操作を行いました。
jq は非常に柔軟性に優れており、ユーザーがやりたい Shell 芸を補助してくれます。
また本記事では登場していませんが yq という yaml 版 jq も存在しています。
こちらも便利ですので是非触ってみてください。
Discussion
参考程度に別解的な。