#TL;DR
Github上でv1.2.3のようなreleaseタグを作るだけで、
あとはCircleCIが自動で
version.rbの更新→Gemビルド→RubyGemsへリリースする仕組みを作りました。
サンプルはこちらにあります。
https://github.com/NA070/release_test
RubyGems公開手順
RubyGems公開には以下の手順が必要です。
- RubyGems APIキーを~/.gem/credentialsへ書き込む
- ./lib/{package_name}/version.rbの更新( 更新箇所:
VERSION = '1.2.3'
) - gemのパッケージ化 ( コマンド例:
gem build package_name.gemspec
) - RubyGemsでの公開 ( コマンド例:
gem push package_name-1.2.3.gem
)
運用の要求
releaseタグを使って管理したいという要求がありました。
理由としては以下の要点があります
- 更新内容を明記したい
- masterブランチが更新されるたびにリリースすることもできるがそれだと更新内容がわかりづらい
- releaseごとの更新情報を管理できない
- コード実装完了=リリースしてOKではない
- ドキュメント更新がある場合もあるので、それも整備し終えてからリリースしたい
- masterブランチ更新でリリースだと↑は満たされない
自動化したフロー
releaseタグ作成を入れて、自動化した公開手順は以下です。
※ 1だけ手動であとは自動実行されます。
- 新しいreleaseタグをgithub上で作成
- ./lib/{package_name}/version.rbのバージョンナンバー更新
- masterブランチへpush
- gemのパッケージ化
- RubyGemsでの公開
次にどのように自動化しているかを説明していきます
設定方法
CircleCIを使って自動化しました。
設定を進める前に空のジョブでいいので、リポジトリとCircleCIを連携させておく必要があります。
① RubyGemsのAPIキーをCircleCIプロジェクトの環境変数に設定する
CicleCIのプロジェクトセッティングから環境変数を設定します。
サンプルではRUBYGEMS_API_KEYとしました。
APIキーはRubygemsのプロフィール編集ページで確認できます。(要ログイン)
② Checkout SSH keysに鍵を追加する
version.rbを更新したあとにリポジトリへpushsする必要があります。
そのためにwrite権限が必要です。
- Githubの認証を許可します
- 鍵を作成します
③ CircleCIの設定ファイルを追加
リポジトリへpushするための設定は add_ssh_keys
で設定します。
先程追加したsshキーのfinger printを記述します。
version: 2
jobs:
publish:
docker:
- image: circleci/ruby:2.4.1
steps:
- add_ssh_keys:
finerprints:
- "b8:3b:3a:5b:4b:0b:50:73:bf:92:e0:e3:ac:00:01:c1"
- checkout
- run:
name: Setup Rubygems
command: bash .circleci/setup_rubygems.sh
- run:
name: Update vresion.rb and publish on RubyGems
command: bash .circleci/deploy_to_rubygems.sh
workflows:
version: 2
deploy:
jobs:
- publish:
filters:
tags:
only: /^v[0-9]{1,}(\.[0-9]{1,}){2}$/
branches:
ignore: /.*/
④ ジョブで使うshellスクリプトを追加
1. RubyGemsのcredentialファイル作成処理
環境変数 $RUBYGEMS_API_KEY に設定されたAPIキーをファイルへ書き込みます。
https://github.com/NA070/release_test/blob/master/.circleci/setup_rubygems.sh
mkdir ~/.gem
echo -e "---\r\n:rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials
chmod 0600 /home/circleci/.gem/credentials
2. version.rb更新→gemビルド→gem pushする処理
役割が多いですが、1ファイルにしています。(責任が多いので分けるのが良いかもです。)
↓では説明のために分割しています。
タグを取得します。
また、git操作するための設定を行います。
メールアドレスにはgithubが用意しているダミーアドレスを使いました。
(参考:https://help.github.com/en/articles/about-commit-email-addresses)
VERSION=$(git describe --tags | sed -e 's/^v//')
git config user.email "2687752+NA070@users.noreply.github.com"
git config user.name "2687752+NA070"
version.rbを更新し、commitします。
# Update version.rb
sed -i '' -e "s/VERSION = '[0-9]\{1,\}.[0-9]\{1,\}.[0-9]\{1,\}'/VERSION = '$VERSION'/" lib/release_test_nao/version.rb
git diff
git checkout master
git add lib/release_test_nao/version.rb
git commit -m "Version $VERSION"
ビルドし、gem push(RubyGemsへリリース)します
# Build and release gem
gem build release_test_nao.gemspec
gem push "release_test_nao-$VERSION.gem"
最後にリポジトリへpushします。
最後に行うのはそれまでの処理で何らかのエラーがあった場合に誤った状態でのpushを防ぐためです。
# Push to master
git push origin master
設定は以上です。
リリースしてみる
リリースタグを作ります。
v0.1.32 でリリースします。
無事うまくいきました。
要求を満たした自動化が実現できました
実現はできたもののの、OSSの経験が少ないので、何が最適なのかは探求する必要がありそうです。
アドバイスなどがありましたらコメントいただけると嬉しいです。