はじめに
開発が一区切りついてリリースする際に、バージョン番号を上げる操作を「bumpする」って呼んだりしますよね。番号を上げるだけと言えばだけなのですが、この記事では以下の様な観点に着目して、bumpの方法を考えてみます。
- monorepoのプロジェクトの場合、各パッケージのバージョンをさっと上げるには
- React Nativeアプリのパッケージを含んでいる場合、iOS/Android固有のファイルに書かれているバージョン番号を上げるには
JavaScriptのエコシステムにある色々なコマンドやライブラリを紹介していくのですが、色々整理した末に、「結局、このRuby gemでよくないですか・・・」というところに行き着く記事です。
npmには、package.jsonのversionフィールドをbumpするコマンドがある
npm version
というコマンドがあって、単体のpackage.jsonのbumpならばこのコマンドでできます。
npm version patch # パッチバージョンを上げる
npm version minor # マイナーバージョンを上げる
npm version major # メジャーバージョンを上げる
npm version 1.2.3 # 指定したバージョンにする
実行すると、package.jsonのversionフィールドが更新されます。
デフォルトではこの時、Gitにコミットしつつ、タグを打つところまでいっぺんに行われます。
そこまではしたくない場合もあるでしょう。 --no-git-tag-version
オプションをつければ抑制できます。
npm --no-git-tag-version version patch
Lernaを使っているmonorepoでは、Lernaのコマンドで子パッケージをbumpできる
monorepoのプロジェクトにおいては、子パッケージのpackage.jsonも一度にbumpしたい場面もあるでしょう。
Lernaを使っているプロジェクト固有の方法にはなるのですが、 lerna version
というコマンドを使うと、子パッケージのbumpができます。
対象は子パッケージだけであり、ルートのpackage.jsonは変更されない点には注意です。
コマンドの使い方は npm version
に似ています(詳細は公式ドキュメントを参照)。
lerna version patch # パッチバージョンを上げる。同時にGitのコミットやタグ打ちもする。更に、pushもする。
lerna version patch --no-git-tag-version # npm versionのオプションと同様に、コミット以降を抑制する。
# lerna versionの実行時には、確認のプロンプトが表示される。--yesオプションをつけるとスキップできる。
lerna version patch --yes
lerna version patch --no-git-tag-version --yes
React Nativeアプリでは、"react-native-version"を使うとiOS/Android固有のファイルをbumpできる
React Nativeアプリの場合、 ios/
や android/
に含まれるファイルの中にも、バージョン番号が書かれる箇所があります(Info.plistとか、app/build.gradleとか)。
react-native-version
というライブラリを使うと、それらのファイルに対して、package.jsonにおけるversionの値を反映できます。
READMEに書かれている通り、下記の様な呼び出し方が典型的です。package.jsonのscriptsのところに version
または postversion
として指定します。
{
"scripts": {
"postversion": "react-native-version"
}
}
npm version
とセットで使うことを念頭に置かれているライブラリであり、デフォルトでは、直前のコミットにamendする形でInfo.plistなどが変更されます。 --never-amend
オプションを使うと、amendはしないようにできます。
react-native-version --never-amend
しかし、これらを組み合わせて使おうとすると、次第にややこしくなっていく
色々な道具が把握できてきたので、これらを組み合わせれば一通りのbumpが実現できそうです。しかし、細かい留意点が積み重なってきて、次第にややこしくなってきます。
- lerna versionでは子パッケージしかbumpできない。
- ルートパッケージのscriptsに
"postversion": "lerna version patch ...
って書こう。そして、ルートパッケージでnpm --no-git-tag-version version patch
って実行するようにしよう。 - patchでなく、minorやmajorを上げたい時はどうする?
とか、
- React Nativeアプリのパッケージにpostversionを書いて、react-native-versionを呼ぶようにしよう。これで、lerna versionによるbumpと繋がる。
- なお、lerna versionのところで--no-git-tag-versionオプションを付けていると、各パッケージのpostversionもスキップされるらしい(公式ドキュメント)
- そしたら、React Nativeアプリのパッケージに書くのは、postversionでなくversionにしておこう。
などなど・・・。
結局、このRuby gemに行き着いた
巡り巡って、以下のRuby gemがシンプルで分かりやすい気がしてきました。
- https://github.com/kt3k/ruby-bmp
- Denoに移植された版もあります。 https://github.com/kt3k/bmp
# gemをインストールする。
gem install bmp
# 以下のいずれかで実行する。
bmp -p|--patch
bmp -m|--minor
bmp -j|--major
以下の様な設定ファイルを用意しておくことで、bump対象を指定します。
---
version: 1.0.0
files:
lerna.json: '"version": "%.%.%"'
package.json: '"version": "%.%.%"'
packages/my-mobile-app/package.json: '"version": "%.%.%"'
packages/my-mobile-app/android/app/build.gradle: versionName "%.%.%"
packages/my-mobile-app/ios/MyMobileApp/Info.plist: "<string>%.%.%</string>"
Ruby製ツールの唐突な登場にはなりますが、これ単体で完結することと、設定ファイルを見ればbump対象が俯瞰しやすいことが利点です。必要な知識が少なく、READMEに「うちのプロジェクトではこのgemを使っています」と書いておけば、初見のメンバーもすぐキャッチアップできるでしょう。
npmやLernaのコマンドがあるだけに、それらを駆使して実現したくもなるのですが、Ruby製ツールを使うことに抵抗がなければ、十分おすすめです。