これは 【その1】ドリコムAdventCalendar の1日目です *1
- 自己紹介
- 1日目:社内gemとOSSのgemのメンテについて
- 2日目
自己紹介
- HN
- sue445
- お仕事
- 社内ライブラリとか社内ツールのメンテ
- 最近はAmeba版ちょこっとファームの開発のお手伝いをしています *2
- 参考: ドリコム、農園育成ゲーム「ちょこっとファーム」を「Ameba」にて提供、10月29日(木)より事前登録開始!! | 株式会社ドリコム
- 事前登録よろしくお願いします!!!!
- あとはサーバサイドを浅く広く見守っています
- 主なコミュニティ
- 【警告】Twitter は上級者向けアカウントなので軽い気持ちでフォロー厳禁【注意】 *3
1日目:社内gemとOSSのgemのメンテについて
そういうポエムです
言葉の定義
- 社内gem : 社内など特定の環境でしか公開されていないgem
- OSSのgem : RubyGems.org など、OSSとして公開されていて誰でも自由にインストールできるgem
適当な説明ですが世の中のgemはだいたいこの2種類に分類されると思います。異論あると思いますが以降この2つの言葉を使います
OSSのgemのメンテで意識していること
他の人にリポジトリを見てもらい、その人が容易にPRを送れるように「おもてなしの心」を意識しています
どんなに小さいgemでも自動テストは必ず書く
- 自分以外の人が修正した時に既存機能を壊していないことを手軽に確認するためです
- リポジトリのトップにCIのバッジを貼ってテストが落ちてないことをアピールできればベストですね╭( ・ㅂ・)و ̑̑
バージョンごとにtagはpushする
- tagをpushしておくことで https://github.com/sue445/rubicure/compare/v0.2.9...v0.3.0 のようにバージョン間の差分をひと目で確認するためです
rake release
使ってればtagもpushされるので普段は気にすることないかと思います
読んでもらうREADMEを意識する
- READMEはリポジトリの顔なので、そこにどんな機能があるかが一目で分からないと本当に素晴らしいgemであっても誰にも使ってもらえないです
- サンプルコードやスクリーンショットなどがあると文章を読まなくても直感で分かるようになるのでベターですね
CHANGELOG(更新履歴)を書く
CHANGELOGがないとどのバージョンでどんな機能が入ったのか分からないのでgemの利用者は迂闊にアップデートできないので合った方がいいです
サンプル
https://github.com/sue445/rubicure/blob/master/CHANGELOG.md
粒度
- 基本的には1行 1 PullRequestくらいの粒度がベスト
- 逆に言うと1つのPullRequestに複数の変更が入ると変更が追いづらくなります
- 「PullRequestにも単一責任の原則」 (1つのPullRequestには1つの変更だけを入れる)を適用することを意識しています
- 各バージョンごとに前のバージョンとのcompareリンクを「full changelog」で書いていればバージョン間の差分がコミット単位で分かるので分かりやすいです
カテゴリ分け
量が少なければ羅列していてもいいのですが、量が多くなるとどれが重要な変更なのか分かりづらいので下記のようなカテゴリを使ってます
- Breaking change:下位互換をぶっ壊す変更
- Bugfix: バグ修正
- Enhancements: 機能追加
この書き方は RSpecのCHANGELOG を参考にしています。gemの利用者にとって重要な変更(Breaking change)は上に書いて目立たせるようにしています
細かいRefactoring系を書くかどうかは好みが分かれるところなのでどっちでもいいかなぁw
CHANGELOGの半自動生成
gemのバージョンアップの度に毎回上記に当てはめてCHANGELOGを書くのは大変なので、普段からPullRequestやMergeRequestのタイトルをそのままリリースノートに書けるような形式*4にすることを心がけておくことで、いざリリースの時には GitHub Changelog Generator や gitlab_awesome_release などでCHANGELOGのテンプレだけを自動生成し細かい文言修正やカテゴリ分けだけ手動で済むようになります
参考になるリポジトリ
たまに bundle update
おじさんをすることがあってアプリで使ってるgemのCHANGELOGを全部読んでたことがありますが、その中で一番参考になったのは Ruby on Rails, RSpec 辺りでした
gemを作ったら必ず宣伝する
- githubやrubygemsに公開しただけで満足すると自分以外誰も使わないのでブログや勉強会でどんどん宣伝した方がいいです。
- Twitterだけだと流れるので1回流すだけでは宣伝効果は弱いと感じてます。
社内gemのホスティングについて
- 弊社だと geminabox を立ててそこにgemをホスティングしています
drecon_gem
という社内gemを自分の社内gemに入れることで、rake drecom:release
コマンドでgeminaboxにgemのリリースを行ったり、 間違って https://rubygems.org/ へ社内gemをリリースできないようにrake release
コマンドを実行できなくしています- 詳しくは RubyKaigi2014で発表した - mitaku.log を御覧ください
- 今見たら社内gemが157個あった。すげえ。。。
社内gemのメンテで意識していること
だいたい上とかぶるので違う部分だけ書きます
サポートするRubyやRailsのバージョンなどは社内アプリ優先
当然ですね
- サポートが切れているRubyやRailsのバージョンであってもそれらを社内で使ってるのであれば社内gemでも基本的にサポートする
- acts_as_mysql_partitionという社内gem*5は2015年6月当時 (Ruby 1.9系, 2,0系, 2.1系, 2.2系) x (Rails 3.2系, 4.0系, 4.1系, 4.2系) の16パターンのビルドをしていたのですが、Ruby 2.2系とRails 3.2系を組み合わせるとビルドがこける問題がありました。*6 この組み合わせだけビルドを除外するでもよかったのですが、せっかくなのでRuby1.9系とRails 3.2系のサポートをきるためにこのgemを使ってるアプリを全部洗い出し、プロダクションでは使ってないことを確認したのでサポートをきりました
- ちなみに社内には Gemicom というGemnasium の社内クローンがあったのでどのアプリでgemを使ってるのか特定が容易に進みました
gemを作ったら社内gemとOSSのどっちにすべきか?
自分の場合下記を考えて社内と社外(OSS)のどっちに公開するかを考えています
OSSのgemのメリット
- OSSにした方が周辺のエコシステムを享受しやすい
- 社内gemにしたら仕事じゃない趣味のアプリでは使えないけど、最初からOSSにしておくと仕事と趣味の両方で同じgemを使えて便利かと
- 社内gemを勝手に社外で使うとインシデントだけど、既に社外で公開しているgemを社内のアプリで使う分には大抵の場合問題ないはず
- 「高級レストランのあの味をご家庭でも!」感w
社内gemのメリット
社内コンテキストに特化させることによるメリットが多いです
- OSSにしていろんなパターンを考慮して汎用化するとその分仕組が複雑になりますが、社内gemだと社内の利用用途に限定させることで仕組をシンプルにすることができます
- 外からのマサカリが飛んでこない *7
- とはいえ外のマサカリを全く受けない温室育ちだと外に出られないので適度に外のマサカリを受けることは大事だと思いますw
OSSのgem -> 社内gem or 社内gem -> OSSのgem
途中で公開形態を変えることもできますが、後者だと会社のメールアドレスやパスワードなどの機密情報をgit filter-branch
などで完全に書き換える必要があり面倒なので、個人的には可能なら最初からOSSにしてた方が楽なんじゃないかなーと思います
2日目
- id:onk さんです!