LoginSignup
3
1

特定のリポジトリのIssueを全てクローズするスクリプト

Posted at

GitHubでまとめてIssueを閉じたりする場合、数が少ないなら手動でポチポチ行えば良いです。
ただ、Issueが数百ある場合は面倒なので工夫をしたいです。
今回使われなくなった社内のリポジトリをアーカイブする作業があり、その前にIssueを全て閉じる作業を行うためのスクリプトを作成してみました。

アクセストークンの準備

まずスクリプトなどを利用してGitHubの操作を行う場合、アクセストークンを発行する必要があります。
GitHubにアクセス・ログインし、今回は右上の自分のアイコンをクリック -> Settings -> Developer Settings -> Personal access tokens -> Fine-grained tokens と辿っていきます。
Fine-grained personal access tokensのページに到達したら、Generate new tokenをクリックし、トークンの作成画面にジャンプします。

トークンの作成画面では、以下を記入・変更します。

  • Token name
    • 用途に適した名前を記入する
  • Expiration
    • お好みで選択
  • Description
    • 書きたいことがあれば記入
  • Repository access
    • All repositoriesOnly select repositoriesにする
    • Only select repositoriesにした場合は変更対象のリポジトリを選択する
  • Permissions
    • IssuesをRead and writeにする
      • Repository accessの設定がデフォルトのPublic Repositories (read-only)だと出ないので注意

作成されたアクセストークンは一旦保管しておきます。

gemのインストール

今回はGemfileを利用して2つのgemをインストールしています。

Gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'dotenv'
gem 'faraday-retry' # インストールしないと警告が出てうるさいので追加
gem 'octokit'

メインは.envファイルから環境変数を取得するためのdotenv、GitHubのAPIラッパーであるoctokit.rbです。faraday-retryは後述するプログラムを実行した際、以下のメッセージが出てしまうため素直に従っています。

To use retry middleware with Faraday v2.0+, install `faraday-retry` gem

環境変数の設定

.envファイルを作成し、環境変数を埋めていきます。
https://github.com/Umekawa/issue_closer には.env.sampleが存在するのでコピーするのが良いでしょう。

以下は https://github.com/Umekawa/issue_closer のissueを全てクローズする場合の例です。
リポジトリの設定やクエリは適宜変更してください。
ちなみにIssueの取得で使うPER_PAGEは、30がデフォルトなのでそのまま仮置きしています。(参考)

.env
GITHUB_TOKEN=先ほど取得したGitHubのアクセストークン
GITHUB_ID=Umekawa
REPOSITORY_NAME=issue_closer
SEARCH_QUERY='is:issue is:open'
PER_PAGE=30

スクリプトの作成

それでは実際にスクリプトを作成します。

main.rb
# frozen_string_literal: true

require 'octokit'
require 'dotenv'

Dotenv.load

client = Octokit::Client.new(access_token: ENV['GITHUB_TOKEN'])

per_page = ENV['PER_PAGE'] || 30

search_result = nil
while search_result.nil? || search_result.items.size.positive?
  search_result = client.search_issues("repo:#{ENV['GITHUB_ID']}/#{ENV['REPOSITORY_NAME']} #{ENV['SEARCH_QUERY']}",
                                       page: 1, per_page:)
  search_result.items.each do |issue|
    client.close_issue("#{ENV['GITHUB_ID']}/#{ENV['REPOSITORY_NAME']}", issue.number)
    puts "#{issue.title} (Issue ##{issue.number}) has been closed."
    sleep 1
  end
  sleep 1
end

構成としてはすごくシンプルで、以下のようになっています。

  • アクセストークンによる認証
  • Issueの取得
  • IssueのClose
    • リポジトリとIssueの番号(ID)を指定することでcloseすることができるので、第一引数にリポジトリ名、第二引数にissue.numberを引数に入れています
    • GitHubのサーバーに負荷をかけすぎないよう、1秒のsleepを挟むようにしています
  • Issueの再取得
    • 0件になるまでループさせています
    • pageが1固定なのは、1ページを全てcloseするので、それまでの2ページ目が1ページ目に変わるためです

このプログラムを実際にPER_PAGEを変えたりして、https://github.com/Umekawa/issue_closer/ で試した限り、問題なく動作することを確認できました。

スクリーンショット 2024-05-28 12.32.42.png

まとめ

今回、octokit gemを利用することで簡単にGitHubの操作を行うことができました。
GitHubのAPIラッパーは他の言語でも幅広く提供されているので、GUIだと辛いなという作業がある場合は好きな言語で挑戦してみるのはいかがでしょうか?

REF

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1