包丁一本さらしに巻いて

Pythonライブラリを最新に保つ為に(hubot-piptools)

休みの日を使ってhubot-piptoolsというツールを作った。初OSSなので作った経緯やらを書く。

hubot-piptools

前提

  • 提供しているサービスのバックエンドはPython
  • 開発チーム構成
    • 企画(ideyuta)
    • フロント/デザイン(moqada, ideyuta)
    • バックエンド(moqada, achiku)
    • インフラ/データ分析(achiku)
  • GitHub使って開発してる
  • CircleCI使ってCIまわしてる
  • 大体HipChat使ってコミュニケーションしてる
  • 社内のコミュニケーションでメールは使ってない
  • サービスモニタリング、ノーティフィケーションの類もHipChatに集約されてる

解決しようとした課題

  • 現在利用しているPythonのライブラリ更新確認、更新実施に使うコストがかかる

集約すると上記になるが、もう少し背景を書く。外部のライブラリはどんどん新しくなり、安定していき、機能が磨かれていっている。サービスを提供する側としては、ユーザが受け取る直接的価値である新規機能や機能改善に掛ける時間を最大化した上で、なおかつ眼に触れない部分の安定性も確保していきたい。

この「ユーザの眼に触れない部分の安定化/最新化」は、自分たちが作るサービスが直接ユーザに届けれる価値といったものからは若干の距離があり、コスト的に手をかけてやる事が難しい部分だ。前提に書いたように少人数で運営している場合などは特に難しいと感じる。とはいえ、中期的に、ふと気づいたら返済できないくらい溜まった負債を抱えない為に(大量且つ一度に実行されるライブラリアップデートはエラーの切り分けがダルい)、細かく簡単に返済していく何がしかの仕組みがあると便利だなと考えた。

解決しようとした課題を分割した

  • ライブラリ更新実施/コード修正/テスト修正のコスト
  • ライブラリ更新確認のコスト

ライブラリ更新実施/コード修正/テスト修正のコスト

ライブラリを更新したらAPIが変更になってたり、新規に潜り込んだバグの為にこっちのコード修正したり、テスト直したりしなければならないコストは、正直不可避だなと思う。互換性は壊れる時は壊れるし、バグは無くならない。それをもってして余りあるメリットを外部ライブラリからは受けているので、この部分は受け入れるもんだと思ってる。寧ろ感謝の気持ちを込めて再現性のあるIssueを上げたりPR出したりしていきたい。

ライブラリ更新確認のコスト

なので、達成すべきは「チームが簡単に更新を知って各自動き始める事」なのではないかと考えた。ポイントは「個人が簡単に更新を知って動き始める事」では無いところだと思う。チームメンバー内でも忙しさの波ってのは変わり得て、誰かが忙しいから更新が滞るってなってしまうと結局上手くいかない。

課題に対する解決策

それ、pip-toolsで

これ結構便利なんだけど、結局自分のローカルでしか動かせない。だから「チームが簡単に更新を知って動き始める事」ってのはちょっと達成できそうにないなと思った。これ実行してHipChatに毎日張るってのもありといえばありだけど俄然やりたくない。

それ、外部サービスで

これ使えば普通にイケそうだなって思った。特にrequires.ioは複数のrequirements.txtにも対応してるし、見栄えも良い上に、Security updateをちゃんと知らせてくれる。ただチームの状況には若干マッチしないのではないかと思った。

  • Privateリポジトリに対応させる時に課金する必要がある
  • ノーティフィケーションはメール

外部サービスに対してお金は全然払っても良いと思うしチームでは幾つかのサービスに課金もしている。ただ、これは別にちょっと落ちててもあまり大きな問題にはなんないんじゃないかと思いと、GitHubから指定ファイル取ってきてパースしてPyPiに問い合わせるだけっしょっていう思いから、いきなりお金払ってサービスを受けるのには若干抵抗があった。あと、極力社内の会話はチャットツールに寄せたいってのも大きく、一旦採用を見送った。

それ、Botで

結局フィットするものが無かったので作った。弊社のチャットツールにはKanmukunというボットが住んでいる。コイツに以下の要件で機能を追加してみたら何となくいい感じになった。

  • 毎朝決まった時間に指定リポジトリのrequirementsファイルをパースしてPyPiに問い合わせ
  • 問い合わせた結果、最新じゃないライブラリが分かるようにルームに通知

チャットツール内でライブラリのアップデートが通知されて、そこから自然発生的に「あーこれいつアップグレードする?」「ChangeLogどうなってんの?」「これは俺やっとくわ」とかの会話が発生し、何となく細々と時間空いてる時にアップグレードして行くことはできるんじゃないかなと。

人間じゃないヤツから毎日通知されるのであれば嫌味も無いし、空いてる時に一つずつでもいいからサクッとアップグレードしてCI回せば良い。CI落ちたらChangeLog確認してテストとコード修正するなり、CI落ちてチャットツールに通知されて「やっぱ駄目だったから後回し」ってするなり、状況に合わせてチームで判断していけばいい。

おわり

もっとチーム人数増えたりしたらもちろんこの解決策が有効じゃなくなってくることはあると思うけど、そんときはそんときで最適な形を考えます。実装に使った技術は全く新しくもなんともないですが、サーバサイドのCoffeeScript初めて書いたし、node周辺技術よく分かってないし、正直目的達成最優先でクッソ雑に書いてるのでマサカリ歓迎。

おまけ

kanmukunは色々できるいい子です。

kusokora