メドピアにおけるライブラリアップデート

村上大和氏:こんばんは。「メドピアにおけるライブラリアップデート」というテーマで、メドピア株式会社・エンジニアの村上大和が発表させていただきます。

まず最初に簡単に自己紹介させてください。村上大和と申します。

年齢が26歳で、GitHub上では「pipopotamasu」という名前で活動してます。RubyやPHP、Vue.js、Reactだったりを触ってきました。趣味は野球と映画になります。

重ねて会社紹介させてください(笑)。

(会場笑)

メドピア株式会社は「MedPeer」と言って、日本の医師の3人に1人にあたる10万人が参加している、医師限定のコミュニティサイトを運営しています。

サイト内では会員の先生たちが薬の口コミとか、あと患者さんの症例について相談し合ったり。そんな医師同士がナレッジを集合知として共有するプラットフォームになっていて、僕らはこんなものを開発したりしてます。

たまにVue.jsの公式リファレンスの翻訳などもやってます。

というわけで、発表テーマに移っていきます。ただその前にラッキーなことに、前の2人が「技術的負債とは?」ということをやっていなかったので、ここでちょっとやらせてください。

Wikipediaさんから拾ってきました。

「(技術的負債とは)行き当たりばったりのソフトウェアアーキテクチャと、余裕のないソフトウェア開発が引き起こす結果のことを指す新しい比喩」と。「新しい比喩」の部分がよくわからないんですが、要はこういうことです。

「行き当たりばったりのソフトウェアアーキテクチャ」と、「余裕のないソフトウェア開発」。僕はこっち(後者)に着目しました。

つまりこういうことかな、と思ってます。

こちら、Rails 4.2.7のGemfile.lockになります。たぶんだいたい3年くらい、時代に取り残されてるものです。

ということで発表テーマとしては、メドピアにおけるライブラリのアップデートについて話していきます。

Gemをアップデートしなかった結果

メドピアのメインのRailsプロダクトは、2016年の5月6日に最初のコミットがなされました。

当時はRails 4.2.6でした。それから1年くらいですかね……Ruby on Rails 5.1がリリースされました。その3~4ヶ月後くらいに、「そろそろ俺らも5.1に上げるか……」と。ただ、依存Gemが古すぎました。

というのも初期リリースからほとんどGemのバージョン上げていなくて、bundle updateコマンドを打とうものなら、アップデートがかなりいっぱいありました。

ただ、こいつらを上げていかないとRails 5.1にできないので、Rails 5.1に必要なGemをアップデートしていきました。これは(1)です。(1)があるということは(2)もあります。

こんな感じで「やっと5.1が見えてきたぞ」と。

「せっかくなのでほかのGemたちもアップデートしようぜ」……一部抜粋なんですが、こんな感じで上げてます。

最後にRails 5.1.2にアップグレードしました。これはさすがにちょっときつかったです。

何がきつかったかと言うと、1年と数ヶ月の時代の流れの重みとですかね。なのでこの反省を踏まえて、「ちゃんとGemのアップデートはやっていこう」と社内で決めました。

Bundle Update Flowの導入

そこでやったのが、Bundle Update Flowの導入です。こいつは何か。要するにbundle updateを定期的にやるための仕組みです。

こんな感じで、6つのステップに分かれております。まず1つ目から。毎月1日に、自動的にbundle updateのプルリクを作成します。基本的にこういうbundle updateって、どの会社でもメインタスクじゃなくてサブタスクになると思います。

メインで開発しているものがけっこう忙しくて、なかなかbundle updateに手が回らないということが多々あると思います。なので極力その負担は減らしてあげたいです。

そこで、こちらですね。「circleci-bundle-update-pr」というGemを使って、勝手にCircleCIでbundle updateのプルリクを作ってくれる便利なものです。こちらを使ってます。

こちらはCronで毎月1日……ここに15日も入ってるんですが、最初は月2回bundle updateしようとして、「それじゃ回らん」ということで月1回に変更して、今に至ってます。毎月1日、このGemを叩いてます。

ちょっと見にくいんですが、これがタスクです。

CIで「circleci-bundle-update-pr」をインストールして、それを叩くというタスクです。

その結果、こんなプルリクができます。

これでアップデートするGemの一覧と、プラス、ビフォーアフターのバージョン。これで簡単にアップデートのプルリクを作ることができます。

ただ弊社はGitHub Enterpriseを使っていまして、その対応が実はこのGemではされてなくて。その対応に手間取ったんですけれども、なんとかすることができました。

3人担当者を決めて作業を分担

さて、これで毎月1回、自動的にbundle updateのプルリクを作ることができました。そうしたら今度は、bundle updateの担当者を3名割り当てます。見た感じ、アップデートされるGemが多いです。なのでこんなふうに、ばーっと一覧が出てきます。

これは正直1人でやるのはしんどいですよね。めっちゃ時間かかります。

なんですが、いい感じに3人で分担してあげれば、1人当たりの負担を減らして、心理的負担なくbundle updateの時間を確保できると考えております。こんな感じで、Slackのくじで適当に3人当てて、「よろしく」って感じですね。

先ほどのCIのCronで、Slack上で3人、適当にくじで当てようとしていたんですが、BOTだとSlackのくじが動かないらしいので今、対応中って感じです。

次です。全員で集まって、1~2時間で差分をすべてチェックします。最初は各自でやってたんですが、正直各自で「じゃあこの差分確認しといて」ってやると、やっぱりメインタスクのほうが忙しくてなかなかやれないんです。

なので各自で確認するんじゃなくて、こうやって1~2時間。3人で時間とって、その間に集中してやりましょう、ということで。3人で集まって差分チェックしてます。そして修正が必要なら修正を行います。

Bundle Update Flowをやってみて

次に、テスト環境に1週間漬けます。これはどういうことかと言うと、もちろんGemアップデートしているので、その中にはジョブ周りとか、Cron周りのアップデートもある場合もありますし、そこで使ってるGemもあります。

なのでCron周りの確認という意味で、1週間テスト環境に入れて確認してます。

そしてもう1つ。テスト環境なので、いろんな人が見に来たりします。そこで、もともと差分確認で想定してなかった不具合がなにかの拍子に見つかればいいな、という期待を込めて、こんな感じで1週間、テスト環境に入れるということをしてます。

それでOKならリリース、そしてまた1に戻る……というサイクルを回しております。

実際にこの「Bundle Update Flow」というのを2、3回まわしてみて、まぁ毎月アップデートだからそんなに重くないです。さすがに1年越しなんかよりは軽いです。

次に、1人でやるとGemの差分がけっこうたくさんあるので負担が大きいんですが、3人でやればそんなに苦じゃないです。

そうやって、いい感じでアップデートが回り始めました。結論、やっぱり仕組み化してやっていくというのは大事だなと思っています。

メドピアにおけるライブラリアップデート、npm編

「完」。

ただ、「待てよ……」と。これはRailsの話だ、「なんか忘れてないか?」……はい、こっちもありますね。

なのでこれからは「メドピアにおけるライブラリアップデート ~npm編~」が始まります。

ここらへんはだいたい一緒ですね。

npmが古すぎます、略します。アップグレードしたら、アップデートいっぱい。略します。そのへんの反省を踏まえて「npmのアップデートは定期的にやっていこう」と。

そこで考え出されたのが、「Yarn Update Flow」という「Bundle Update Flow」のパクリです。だいたい一緒ですね。BundleがYarnになってるだけです。

まず1つ目。毎月1日に自動的にyarn updateのプルリクを作成する。先ほどGemのほうを使ってたんですが、こちらは今度npmのパッケージということで。「ci-yarn-upgrade」というnpmのパッケージを使ってます。

先ほどと一緒なんですが、毎月1日にCron仕込んで.

タスク叩いて。

プルリク作るって感じですね。作られたプルリクはこんな感じです。

だいたいパッケージの名前と、アップデートの前後のバージョンと、最新バージョンと、dependenciesとdevdependenciesなどが表示されるって感じです。

だいたいGemのやつと一緒なように、GHE対応があんまりメンテされてなかったので、メンテしてできるようにしました。

次にyarn updateの担当者を3名割り当てます。

「Coming soon...」となってるんですけれども、実はまだ、ちゃんと回しきれていなくて。今がんばって回そうとしてるという最中です。そのうちGemのUpdate Flowと一緒に、ちゃんと回せるようにしたいなと思っております。

「アップデートは仕組み化して、負債を貯めないようにしていきましょう」というのがまとめになります。

ご清聴ありがとうございました。

(会場拍手)