Octokit.rbとGitHub Appを使ってGitHub Releasesを作成する
2022-12-24
はじめに
この記事は、🎅GMO ペパボエンジニア Advent Calendar 2022の 24 日目の記事です。 前回は、ryuichi1208 による、1TB をネットワーク経由でコピーするのに 5 秒くらいで終わらせることは出来るのかでした。
以前ブログに書いたのですが、Octokit.rbという GitHub の Api をいい感じに触る事ができる Ruby ライブラリがあります。このライブラリは認証にユーザ ID やパスワード、OAuth Application を使う方法など、様々な認証方式に対応しています。これ以外にも GitHub App を使った認証にも対応しています。今回は GitHub App と Octokit.rb を使って GitHub Releases を作成するまでをやってみます。
検証に使ったコードは、こちらのリポジトリにあります。
GitHub App の作成とインストール
まずは、GitHub App を作成します。作成方法はGitHub 公式にあるのでざっくりでいきます。
Developer settingsより GitHub App を作成します。この時、作成したアプリのApp IDと、秘密鍵のダウンロードを忘れないようにして下さい。権限設定も忘れないようにして下さい。
作成したら、リポジトリにインストールします。
動かすコード
実際に GitHub Releases にデプロイしていきます。大まかな処理の流れは以下のとおりです。
- JWT を生成
- JWT をセットし GitHub App をインストールすると設定される installation_id を取得
- GitHub App をインストールするとそのオーガナイゼーション(もしくはユーザ)に(おそらく)一意の ID が振り分けれます。この ID を installation_id と呼んでいて、これをもとにアクセストークンをリクエストする必要が あります。
- 取得した installation_id をもとにアクセストークンをリクエスト
- アクセストークンをセットし、GitHub Releases を作成
まずは、必要なライブラリをGemfile
に定義します。
source "https://rubygems.org"
gem "octokit"
gem "jwt"
gem "openssl"
bundle install
実際にコードを書いていきます。GitHub App から JWT を生成するコードは公式のコードをそのまま持ってきています。秘密鍵のファイル名や、App ID は個人のものに書き換えてください。
require 'jwt'
require 'octokit'
class GitHubApp
def initialize(repository_name)
@client = Octokit::Client.new
@repository_name = repository_name
create_jwt_token
end
# JWT TOKENを生成する
def create_jwt_token
# ダウンロードした秘密鍵
private_pem = File.read("./XXX.pem")
private_key = OpenSSL::PKey::RSA.new(private_pem)
# Generate the JWT
payload = {
# issued at time, 60 seconds in the past to allow for clock drift
iat: Time.now.to_i - 60,
# JWT expiration time (10 minute maximum)
exp: Time.now.to_i + (10 * 60),
# 今回作成したGitHub AppのID
# https://git.pepabo.com/organizations/colorme/settings/apps/colorme-token-app
iss: "YYY"
}
jwt = JWT.encode(payload, private_key, "RS256")
@client.bearer_token = jwt
end
private :create_jwt_token
# installation_idを取得
def get_installation_id_from_github_api
installation_id = @client.find_repository_installation(@repository_name).id
return installation_id
end
# アクセストークンを生成
def create_access_token(installation_id)
access_token = @client.create_app_installation_access_token(installation_id).token
return access_token
end
# アクセストークンを生成
def set_access_token(access_token)
@client.bearer_token = access_token
end
# GitHub Releasesを作成
def create_github_release(tag_name)
@client.create_release(@repository_name, tag_name)
end
end
作成したクラスを呼び出します。リポジトリ名やタグ名は適宜置き換えて下さい。
require_relative 'github_app'
if __FILE__ == $0
github_app = GitHubApp.new('Tatsumi0000/github-app-practice')
installation_id = github_app.get_installation_id_from_github_api
access_token = github_app.create_access_token(installation_id)
github_app.set_access_token(access_token)
github_app.create_github_release("v3.0.0")
end
実行します。
bundle exec ruby main.rb
これで、実際に GitHub Releases に作成されると思います。今回は、Releases 時のリリースノートなどはパラメータに含めていませんが、実際には含めることもできます。
最後に
GitHub App と Octokit.rb を使い、GitHub Releases にデプロイするまでをやってみました。Ruby は fastlane を触る以外で全く触らないのでちょっと苦労しました。可視性の書き方とかこんなかんじだったな〜と新卒研修で受けた Rails Tutorial の記憶がほんのり蘇ってきました。
Octokit.rb を使いこなせると、GitHub 上の自動化などもかなり楽になると思うので使っていきたいなと思いました。また、セキュリティ面や、利便性でも GitHub App は便利なのでどんどん使っていきたいなと思います。