Edited at
ClassiDay 1

フロントエンド開発でパッケージのアップデートを継続的におこなう - Renovate

フロントエンド開発でパッケージのアップデートを継続的におこなう

これは Classi Advent Calendar 2018 1 日目の記事です。

フロントエンドエンジニアの @kasaharu です。


はじめに


  • 昨今のフロントエンド開発はフレームワークと呼ばれるものから便利なライブラリまで幅広いパッケージを使って行われている

  • しかし、これらは導入したときのままであることが多く、バージョンアップすることを怠ると後々問題の原因になったりする


    • バージョンを上げないとセキュリティ問題に対応できなくなったり、パッケージそのものがサポートされなくなったりする



  • また、逆にバージョンを上げることでパフォーマンス改善などの恩恵を受けられる場合もあるが、その機会を損失していたりする

  • 今回は、できるだけ負荷にならずに継続的なパッケージアップデートを習慣化するために Renovate というサービスを使用しているのでそのまとめをする


Renovate とは

renovate.png


  • Automated Dependency Updates と謳っている

  • 対象リポジトリの package.json を監視し、パッケージに更新があった場合に Pull Request(PR) を作成してくれる


    • package.json の他に .circleci/config.yml や Dockerfile なども監視対象になる



  • GitHub, GitLab に対応しており BitBucket にも対応予定

  • GitHub の public リポジトリなら無料で使える


導入



  • Marketplace から "Open Source" プランを選択しインストールをする
    renovate_install.png

  • インストールすると GitHub - settings - Applications にアプリが表示される

  • Renovate の Configure ボタンを押して "Repository access" から Renovate を使いたいリポジトリを選択し、保存する

  • 対象のリポジトリに Renovate から "Configure Renovate" というタイトルの PR が届くのでそれをマージして設定完了


    • renovate.json が追加される



  • 設定が完了すると "Pin dependencies" というタイトルの PR が届くので問題なければマージする


    • 今の package.json に記載されている各パッケージのバージョンを固定

    • バージョンアップを Renovate にゆだねるので固定してしまって問題ない




特徴


  • package.json の他に Dockerfile, .circleci/config.yml も監視する


    • Docker image で使っている Node.js のバージョンアップなどにも使える



  • アップデートするパッケージの PR が open の状態で次のバージョンが出た場合、古い PR を自動でクローズして次の PR が作られる


    • PR が無駄にたまらない



  • まとめてアップデートしたほうがいいパッケージを Monorepo としてグルーピングして PR を作る仕組みがある



  • コンフリクトした場合は自動で rebase してコンフリクトを解消する

  • PR を手動でマージした後にブランチを消し忘れても Renovate が自動で削除する
    delete_branch.png


便利なオプション

オプション
説明

schedule
Renovate が PR を作成する時間帯を指定できる

labels
PR にラベルが設定でき Renovate から来た PR かどうかを一覧ですぐに判別できる

automerge
「patch バージョンは auto merge」や「devDependencies は auto merge」などの設定が柔軟にできる

rebaseLabel
GitHub の PR に該当のラベルをつけると即時 rebase が行われる
デフォルトは "rebase"

enabled
特定のパッケージはバージョンアップの対象外にすることが可能

lockFileMaintenance
lock file のメンテナンスが可能


Classi での使い方


renovate.json

{

"extends": [
"config:base"
],
"timezone": "Asia/Tokyo",
"schedule": ["every weekend"],
"labels": ["renovate"],
"patch": { "automerge": true },
"lockFileMaintenance": {
"enabled": true,
"schedule": [
"before 3am on the first day of the month"
]
},
"packageRules": [
{
"groupName": "Unit test package",
"packagePatterns": ["^jasmine", "^karma"]
},
{
"groupName": "Angular DevKit",
"packagePatterns": ["^@angular-devkit/"]
},
{
"packagePatterns": ["^mysql"],
"enabled": false
}
]
}


  • assignees, reviewers にはチームメンバーを指定

  • スケジューリング : 毎週末


    • これにより月曜日にはアップデートが必要なパッケージの PR が作られている




  • patch バージョンアップは auto merge


    • PR を作成して、マージするまでを Renovate が自動でやるのでパッケージアップデートにかける時間を削減できる
      auto_merge.png



  • PR に "rebase" ラベルをつけることで即時 rebase するように設定

    rebase.png



  • グルーピング機能を使って angular-devkit などのパッケージを 1 つの PR で作成する


    • グルーピング設定するとそれぞれ作成されていた PR は自動でクローズされ、新規でグルーピングされた PR が作られる



angular-devkit/build-angular 単体
angular-devkit/build-ng-packagr 単体
Grouping 後

a.png
b.png
c.png


  • Docker image で使用している MySQL のバージョンは Renovate で変更したくないので "enabled": false にしている

  • 毎月 1 日 3 時に lock file(yarn.lock) のメンテナンスをするように設定


    • package.json に記載されているパッケージのアップデートをやっていても、依存しているパッケージのバージョンでハマったことがあったので lock file も定期的にメンテナンスするように設定




まとめ

実際に仕事で使い始めて 2 ヶ月以上経過しましたが、毎週月曜日の定期作業として習慣化してきました。

テストが通ることで動作保証するため、単体テストのコードカバレッジ 100% をルール化し、テストを書くモチベーションの一つにもなっています。

code_coverage.png

また、こまめに上げることで major バージョンアップ時もあまり時間がかからないのを実感しています。

これを読んだ人も是非試してみてください。

明日は @tetsuroito さんです。


参考