[Salesforce][sfdx][CircleCI] sfdx + CircleCI で CI 環境を作る

[Trailblazer Advent Calendar 2018](https://adventar.org/calendars/3195)の12/22日の投稿になります。[株式会社ファンドレックス](http://fundrex.co.jp/)でシステムディレクターをやっている @shinchit です。よろしくお願いします♪

# この記事は

sfdx と CircleCI を使って CI環境を作る手順について記したものです。
基本的な情報は公式の [CircleCI を使用した継続的インテグレーション](https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_ci_circle.htm) に書いてありますが、全体の流れが**わかりづらかったので**自分へのメモを兼ねてやったことを書いておきます。
なお、CircleCI は git ホスティングサービスに GitHub と Bitbucket に対応していますが、ここでは GitHub を採用して話を進めます。

# CircleCI のサインアップ

英語ですが、迷うことはないと思いますので端折ります。
次の記事がとってもわかりやすいです。

[CircleCI2入門② CirlceCIとGitHubを連携させる](http://yuu.1000quu.com/circleci2_introduction_2)

# Salesforce CLI のインストール

[Install the Salesforce CLI](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli.htm) に従って Salesforce CLI をインストールします。
ここも迷うことはないと思いますので端折ります。

# JWTベースフローを使用した組織の認証

CircleCI が Salesforce CGI を使って組織をゴニョゴニョできるように組織を認証します。

## 組織の DevHub を有効化

組織の [設定] の [クイック検索] ボックスに 「Dev Hub」 と入力し、 [Dev Hub] を選択します。
Dev Hub 画面で Dev Hub を有効化します。

## 自己署名 SSL 証明書および非公開鍵の作成 と 接続アプリケーションの作成

[接続アプリケーションの作成 単元 | Salesforce Trailhead](https://trailhead.salesforce.com/ja/content/learn/modules/sfdx_travis_ci/sfdx_travis_ci_connected_app) に書いてある内容をそのまま実施します。
ただし、リンク先のトレイルは Travis CI 用の記述になっているので、接続アプリケーション名など「travis」という言葉が出てくる箇所は「cirlceci」に読み替えて設定します。　[^1]

## サーバキーの暗号化 

server.key ファイルがあるディレクトリで次のコマンドを実行します。<passphrase> 値には、一意の key を作成するために各自が選択した語を入力します。

```
$ openssl enc -aes-256-cbc -k <passphrase> -P -md sha1 -nosalt
```

key と iv の値が出力に表示されますので、記録しておきます。

```
key=****24B2
iv =****DA58
```

新しく生成された key と iv の値を使用してserver.key ファイルを暗号化します。 server.key ファイルがあるディレクトリで次のコマンドを実行します。<key> と <iv> は先の値に置き換えます。

```
openssl enc -nosalt -aes-256-cbc -in server.key -out server.key.enc -base64 -K <key> -iv <iv>
```

なお、 key と iv の値は 1 回だけ使用します。複数の server.key を暗号化することはできますが、それはセキュリティ違反とみなされます。

# sfdx-circleci リポジトリのフォーク

https://github.com/forcedotcom/sfdx-circleci をフォークし、ローカルにクローンします。

```
$ cd ~/
$ git clone https://github.com/<git_username>/sfdx-circleci.git
```

# CircleCI 設定

[CircleCI](https://circleci.com/) にアクセスして、sfdx-circleci というプロジェクトが表示されることを確認します。 CircleCI 上でこのプロジェクトを [Add Projects] > [Set Up Project] します。
すると、初回のビルドが走り、失敗します。

![スクリーンショット 2018-12-22 10.07.10.png](https://qiita-image-store.s3.amazonaws.com/0/69460/159a93a2-3f88-de99-9790-e91d793bbf1e.png)

## 環境変数を設定する

CircleCI の sfdx-circleci プロジェクトの設定（プロジェクトの歯車アイコン>[BUILD SETTINGS]>[Environment Variables])で次の4つの環境変数を設定します。[^2]

| 環境変数名       |値 |
|:-----------------|:------------------|
|HUB_CONSUMER_KEY|組織の接続アプリケーションのコンシューマ鍵|
|HUB_SFDC_USER|組織に接続するユーザ名(SFDXではないことに注意)|
|DECRYPTION_KEY|サーバキーの暗号化で生成した key|
|DECRYPTION_IV|サーバキーの暗号化で生成した iv|

設定すると次の様になります。

![スクリーンショット 2018-12-22 10.19.19.png](https://qiita-image-store.s3.amazonaws.com/0/69460/d9ac03e9-7cf9-c7da-3add-760c0c3758b5.png)

# 暗号化したサーバーキーの登録とCI実行

暗号化したサーバキー（server.key.enc)をリポジトリの `assets/`ディレクトリに登録します。

```
$ cd ~/sfdx-circleci
$ cp ~/certificates/server.key.enc ./assets/
$ git add ./assets/server.key.enc
$ git commit -m "change enc key" -v
$ git push
```

最後の　`git push` をトリガーにして CircleCI で CIプロセス（JOB）が走ります。
が、まだ fail します。

# sfdx-circleci の修正とCI再実行

`./circleci/config.yml` に対して次の２点の修正を行います。

- sfdx force:org:create　の wait は `3以上`である必要があるので修正 https://github.com/shinchit/sfdx-circleci/commit/2bef47b6806758cc50d7fd5c8711ed07df949c5e
- trail にしたがって Dev Hub 組織を作っていくと、組織のエイリアス（別名）は `DebHuv` になるので組織名を修正 https://github.com/shinchit/sfdx-circleci/commit/b8a9d34b3f35bb68ab8594bba4d4aa0431bf8b2d

修正を commit して　push します。
CIが再実行され、無事、「SUCCESS」になることを確認できます。

![スクリーンショット 2018-12-22 10.49.13.png](https://qiita-image-store.s3.amazonaws.com/0/69460/e2fc1656-22d1-086d-0fa5-ad1436fef332.png)

# まとめと今後

sfdx と CircleCI を使って CI環境を作る手順について記しました。
CircleCI の設定ファイル（ .circleci/config.yml ) を書くのが結構手間なので、雛形として [sfdx-circleci](https://github.com/forcedotcom/sfdx-circleci) プロジェクトをフォークして利用しました。
今後は、

- 実際に新規のプロジェクトを雛形をベースにCI（CircleCI）を使いつつ開発していく
- 複数メンバーとの共同開発を行なっていく

手順やノウハウを学んで共有できればと考えています。


[^1]: 実際は読み替えなくても動くんですけどもね。
[^2]: 詳細は、CircleCI のドキュメント[「Setting an Environment Variable in a Project」](https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-project)(プロジェクトの環境変数の設定) を参照してください。