チームで fastlane と Ruby のバージョンを揃えるための環境構築（rbenv, rbenv-gemset, bundler）

お世話になります。@sutchanです。
何を書こうかなと今年を振り返っていると、そういえばこの夏、fastlaneを導入したのでした。
何にって、サービスローンチから4年が経過した**[CafeSnap](https://cafesnap.me)（Android版）**に。

せっかくなので、導入時に書いた`README.md`をベースに、**導入手順を公開しちゃいたいと思います！**
それでは、早速見ていきましょう。

# はじめに

導入手順までを書いていますので、fastlaneの具体的なlane（Fastfile）は登場しません。

## 前提

ここから読み進めるにあたり、技術的前提は以下の通りでございます :bow_tone1: 

- Mac
- Homebrewがインストールされていること
- ビルド対象となるAndroidプロジェクトがあること

そういえば、App Bundleはまだ対応していない。

## 導入の背景

- もともと Deploygate を使った配信をしていた（ShellScriptでgradlewを呼んでビルドし、apkをcurlでpost）
- Fabric(Crashlytics) も使っているから、Fabric Betaにまとめたほうが効率良いし
- 配信対象の端末も設定しやすい

もともとは、こんな感じのスクリプトで、Deploygateに配信していました。
これで全く問題ありませんでした。

```sh
#!/bin/sh

# 出力先
OUT_DIR="./app/build/outputs"
# apkディレクトリ
APK_DIR="apk"
# apk名称
APP="app-dev-debug.apk"
# DEPLOYGATEのAPIトークン
DEPLOYGATE_API_TOKEN="xxxxxxxxxx"

# リリースノート作成
vi "${OUT_DIR}/release.txt"

# 存在しない場合はとりあえず空ファイル用意しておく
if [ ! -f "${OUT_DIR}/release.txt" ]; then
    touch "${OUT_DIR}/release.txt"
fi

# リリースノートメッセージ
release_msg=`cat ${OUT_DIR}/release.txt` 

# ビルドする
./gradlew assembleDevDebug

# DeployGateに送信
curl "https://deploygate.com/api/users/my-user-name/apps" -F "file=@${OUT_DIR}/${APK_DIR}/${APP}" -F "token=${DEPLOYGATE_API_TOKEN}" -F "message=${release_msg}"
```

しかしながら、状況は変わってくるわけですね。
Fabric Betaにまとめてしまいたくなったわけです。
そこで、fastlaneの出番がやってまいりました。

## 要件

- チーム内でRubyとfastlaneのバージョンを揃えられる
- 別のPCに移行するときも、比較的簡単にセットアップしたい
- fastlaneのバージョンアップをするときに、既存の環境を汚さず動作確認したい

そう、これができるのが、**rbenv**と**rbenv-gemset**と**bundler**、3種の神器です。

# 環境構築

## rbenv, rbenv-gemsetのインストール

rbenvとrbenv-gemsetをインストールします。
この2つを導入することで、以下の2つを実現します。

- rbenv: Rubyをシステムに依存せず、開発ディレクトリでは指定したRubyバージョンを使用する
- rbenv-gemset: 依存するgemをセットとして管理することで、開発用セットやSandboxセットなどバージョンアップの検証等で効果を発揮する

```
$ brew install rbenv
$ brew install rbenv-gemset
```

ZSH を使用している場合、.zshrc に以下の文言を追加します。
追加後、シェルにログインし直すなどして、パスを有効化します。

```
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init - zsh)"
```

## rbenvのセットアップ

Rubyのバージョンを指定して、rbenvでインストールします。
ここでは、2.5.1を指定しました（当時最新）。

```
$ rbenv install 2.5.1
```

Androidアプリのプロジェクトのディレクトリに移動し、ディレクトリのRubyバージョンを2.5.1に設定します。

```
# 既に.ruby-version のファイルが存在する場合、実行しなくても良い
$ rbenv local 2.5.1
```

この、`rbenv local 2.5.1`を実行すると、`.ruby-version`ファイルにたった1行`2.5.1`と書かれたファイルが生成されます。

**`.ruby-version`は、git管理に入れてください（チーム内でRubyのバージョンを揃えるためです）**

上のコマンドを実行したら、プロジェクトのディレクトリで、Rubyのバージョンが2.5.1になることを確認します。

```
$ cd ~
$ ruby -v
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin17]

$ cd cafesnap-android
$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
```

↑ ちゃんと、プロジェクトのディレクトリでは、`2.5.1`になっていることを確認できました！

## gemsetのセットアップ

gemsetを使用することで、Gemのアップデートをテストしやすくします。
ここでは、デフォルトのgemset “cafesnap-android” を作成するプロセスを見てみます。

```
$ rbenv gemset create 2.5.1 cafesnap-android
```

コマンドのパラメータは、`rbenv gemset create <version> <setname>`です。
そのため、プロジェクトで使用するRubyのバージョンが上がったら、gemsetも作り直すことになります……。

上のコマンドで作成したgemsetを、有効化します。

```
$ echo cafesnap-android > .rbenv-gemsets
$ rbenv gemset active
cafeapp-android global
```

ここで、`.rbenv-gemsets`というファイルに、たった1行`cafesnap-android`というセット名を保存しました。
こうすることで、次回から`rbenv gemset active`のコマンドを打つだけで、gemsetが`cafesnap-android`のセットになります。
**`.rbenv-gemsets`は、git管理に入れてください。**
いや、チーム内でセット名を共通にするなら入れる必要があります。なので、入れなくても問題はありません。

## bundlerのインストール

チーム内でfastlaneのバージョンを揃えるため、パッケージマネージャをインストールします。
あとからジョインしたメンバーも、同じバージョンですぐ環境構築できるようになります。

```
gem install bundler
```

動作確認。
rbenvが有効なので、rbenvを経由しないとbundlerは実行できません。

```
$ cd ~
$ bundle -v
zsh: command not found: bundle
$ rbenv exec bundle -v
rbenv: bundle: command not found

$ cd cafesnap-android
$ rbenv exec bundle -v
Bundler version 1.16.3
$ bundle -v
zsh: command not found: bundle
```

上の通り確かに、rbenvを経由していないと、bundlerは実行できませんね。

## 依存パッケージのインストール

それでは、rbenv経由でbundlerを実行し、Gemfileに記述してあるパッケージをインストールします。これでほぼ終了です！

まず、fastlaneに依存していることをGemfileに記述します。

```:Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "fastlane", "~> 2.101"
```

保存したら、以下のコマンドを実行します。これでインストール完了 :thumbsup: 

```
$ rbenv exec bundle install
```

実行すると、fastlaneがインストールされ、さらに、インストールしたバージョンを管理する`Gemfile.lock`というファイルが生成されます。
**`Gemfile`と`Gemfile.lock`は、git管理に入れてください（チームメンバーのfastlaneのバージョンを揃えるためです）**

## fastlaneがインストールされていることを確認
Fastlaneはbundle経由で実行する必要があるので、以下のコマンドで確認する。（遠回りな気もしますが……）

```
$ rbenv exec bundle exec fastlane --help
```

これでfastlaneのインストールが完了！お疲れ様でした！

# 最後に、CafeSnapとは……

個性光るカフェを探せる、投稿型のカフェアプリ。
こだわりの検索機能で、電源のあるカフェ、Wi-Fiのあるカフェなど、好みのカフェを見つけられます。
Facebook、Twitter、LINEのアカウントがあればすぐ利用できます。
お気に入りのカフェを見つけたら、ぜひ投稿してくださいね！

<img width="225" alt="IMG_0130.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/75329/96d06843-d0af-4dcb-88dd-c25b0f5e2ae4.png">　<img width="225" alt="IMG_0131.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/75329/76502711-9856-4df3-2f36-3cf467515044.png">

iOS版 → https://itunes.apple.com/us/app/cafesnap/id910848942
Android版 → https://play.google.com/store/apps/details?id=jp.co.allabout.cafesnap

# まとめ

ここでは、プロジェクトで使用するRubyのバージョン、fastlaneのバージョンを揃えるための手法として、
`rbenv`・`rbenv-gemset`・`bundler`を用いた環境構築を紹介しました。
皆さんの開発環境がより良くなることを願っております。
そして、自分のプロジェクトももっと改善していきたいので、こんな方法もあるよなどアドバイスありましたら、教えていただけますと幸いです :bow: 
それでは皆さん、良いお年を。

あ、アドベントカレンダーだった。それでは、メリークリスマス！:christmas_tree::tada: