SFDX-Falconを使ったISVパッケージの開発

# SFDX-Falconとは

[SFDX-Falcon](https://sfdx-isv.github.io/sfdx-falcon/)はSalesforce本社のISVテクニカルエバンジェリストの方が作成したISVパートナーのためのSFDXプラグインです。

AppExchange Demo Kit (ADK) と AppExchange Package Kit (APK)の2つを含んでいます。

* ADK: パッケージを含むデモ組織を簡単に作成するためのキット
* APK: SFDXでのISVパッケージ開発をしやすくするためのツールおよびテンプレート

この中で今回はAPKを説明します。

# AppExchange Package Kit (APK)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/27267/ed5da19e-73f3-97c4-d5d8-4ae320e7b173.png)
（[ISVs Adopting Salesforce DX with Managed Packages - YouTube](https://www.youtube.com/watch?v=lTTbymAAtAg)）

現状、SFDXでISVパッケージを作成するにはこのやり方になります。これを実現するための雛形を作れるのがAPKです。

SFDXをそのまま使うとISVパッケージ開発はどうやったらいいのかけっこう悩むのですが、それをだいぶ解決してくれています。

## "Happy Soup"問題の解決

SFDXが出たときからISVパッケージ作るときにパッケージに入れないけどgitには入れたいリソースの管理ってどうやんの？って思っていたのですが、その問題は解決してくれます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/27267/740a7f11-db01-84f0-f10e-ae72391acd45.png)
（[Salesforce DX 201 - Advanced Implementation for ISVs](https://www.slideshare.net/VivekMChawla/salesforce-dx-201-advanced-implementation-for-isvs) P.24）

このようなディレクトリ構造になっていて、そういうリソースは`unpackaged`に入れておけば、パッケージに入りません。

普通のSalesforce組織には色んなモジュールが混ざっているので、DXでどう扱うか悩ましいのですが、これを"Happy Soup"問題と言うらしいです。初めて知りました。（[参考](http://www.crmscience.com/single-post/2018/04/04/Development-Takeaways-from-TrailheaDX-2018)）

## ディレクトリ構成のベストプラクティス？の提供

![image.png](https://qiita-image-store.s3.amazonaws.com/0/27267/508ca386-23ec-224d-034c-13cbe86cb334.png)
(https://www.slideshare.net/VivekMChawla/salesforce-dx-201-advanced-implementation-for-isvs) P.31）

objectはschemaで、layoutはdefaultだったりとちょっと方針がよくわからないところもありますが、けっこうこういうの決めるの大変なので、決めてもらえると助かりますよね。これをベースに気になるところを修正したルールを決めても良いと思います。

各ディレクトリの`.gitignore`に少しルールの説明が書いてありました。（[例](https://github.com/sfdx-isv/sfdx-falcon-appx-package-kit/blob/master/sfdx-source/my_ns_prefix/main/default/classes/.gitignore)）

`feature-two`, `feature-three`と機能別に別れているのは、[Packaging 2](https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_dev2gp.htm)に移行しやすようにだそうです。Packaging 2では、いくつかのパッケージを組み合わせて一つのパッケージみたいなことができるようになるそうなので、こうしておくと別パッケージにしやすくなるんでしょう。

## その他

その他にも以下のような機能があります。

* pushするとベータパッケージを作成するCircle CIの設定サンプル
* 便利スクリプト
 * `rebuild-scratch-org`: スクラッチ組織の再作成から、ソースコードのpushまで。
 * `deploy-mdapi-source`: Metadata API形式に変換してパッケージ化組織へのデプロイ
 * `setup-project-org-auth`: 必要な組織へ対話式で認証
 * `install-pkg-in-sandbox`: Sandbox組織へのパッケージインストール

## 詳しくは

以下のリソースを見てください。ドキュメントはあまりありません。

* スライド：[Salesforce DX 201 - Advanced Implementation for ISVs](https://www.slideshare.net/VivekMChawla/salesforce-dx-201-advanced-implementation-for-isvs)
* 動画：[Salesforce DX 201 - Advanced Implementation for ISVs - YouTube](https://www.youtube.com/watch?v=xLjY-j5pf6c)
* ほとんど何もない公式サイト：[SFDX-Falcon • Home](https://sfdx-isv.github.io/sfdx-falcon/)
* Gitリポジトリ：[sfdx-isv/sfdx-falcon](https://github.com/sfdx-isv/sfdx-falcon#)
* APKのリポジトリ：[sfdx-isv/sfdx-falcon-appx-package-kit](https://github.com/sfdx-isv/sfdx-falcon-appx-package-kit)

この辺はちょっと古そうでした。ディレクトリ名など変わっているところがありました。

* [sfdx-isv/sfdx-falcon-template](https://github.com/sfdx-isv/sfdx-falcon-template)
* [sfdx-isv/sfdx-falcon-demo](https://github.com/sfdx-isv/sfdx-falcon-demo)

# 使い方

インストールからベータパッケージを作成するところまでやってみたので、使い方を説明します。

## 前提

[SFDXの設定](https://trailhead.salesforce.com/ja/content/learn/modules/sfdx_app_dev/sfdx_app_dev_setup_dx)をしてください。

それからパッケージ化組織を作成し、以下の設定をしてください。

* 名前空間および管理パッケージ（空でよい）の作成（名前空間とパッケージIDを控える）
* [名前空間とDevHub組織のリンク](https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_reg_namespace.htm)

## sfdx-falconのインストール

```
sfdx plugins:install sfdx-falcon
```

## APKプロジェクト作成

適当にディレクトリを作る。

```
$ mkdir ~/sfdx-falcon-projects
$ cd ~/sfdx-falcon-projects
```

APKプロジェクト作成。

```
$ sfdx falcon:apk:create

     _-----_     ╭──────────────────────────╮
    |       |    │  AppExchange Package Kit │
    |--(o)--|    │  (APK) Project Generator │
   `---------´   │          v0.0.91         │
    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |     
   __'.___.'__   
 ´   `  |° ´ Y ` 

? What is the name of your project? my-first-falcon
? Where do you want to create your project? /Users/xxxx/sfdx-falcon-projects
? Are you building a managed package? Yes
? What is the namespace prefix for your managed package? my_first_falcon
? What is the name of your package? My First Falcon
? What is the Metadata Package ID (033) of your package? 033XXX000000000
? What is the Package Version ID (04t) of your most recent release? 04t000000000
000
? Would you like to initialize Git for this project? (RECOMMENDED) Yes
? Have you created a Git Remote (eg. GitHub/BitBucket repo) for this project? Ye
s
? What is the URI of your Git Remote? https://github.com/xxxx/my-first-falc
on.git
```

先程控えたパッケージIDなどを使って回答してください。ある程度設定ファイルを書き換えてくれます。

`the Package Version ID`はまだ決まらないので指定しなくてよいと思います。

GitHubのリポジトリをhttpsで指定しないと先に進めないのが大変微妙です。
しかし、ここの指定がoriginに指定される以外どこで使われるかわからないので、作成後に`git@github.com...`に書き換えちゃってもいい気がします。

なお、httpsの場合は2要素認証を有効にしているCLIでパスワードでログインできません。それで困ったら[こちら](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/)を見るとよいです。（私は困りました。）

## 個人設定を書き換える

プロジェクトディレクトリ内に移動しておきましょう。

```
cd my-first-falcon
```

組織のエイリアスは各個人によって違うのでgit管理外の`tools/lib/local-config.sh`ファイルで指定するようになっています。それを書き換えます。

```
DEV_HUB_ALIAS="NOT_SPECIFIED"
```

となっているところを自分の環境のDevHubのエイリアスを設定してください。


`./tools/setup-local-project`で書き換えるのがおそらく手順のようなのですが、まだこのスクリプトは未完成のようで書き換わらないので、手動で書き換えます。

## 必要な組織にログイン

後々パッケージ化組織にデプロイする際に必要になるので、以下のコマンドを実行して、パッケージ化組織のエイリアスを設定します。

```
./tools/setup-project-org-auth
```

DevHub組織はもう認証済みなので無視しましょう。`Subscriber Sandbox Org`も聞かれるが、ISVパッケージの作成でsandboxって使わないと思うので私は無視しました。

## スクラッチ組織の作成

以下コマンドで名前空間付きのスクラッチ組織を作成できます。

```
./tools/rebuild-scratch-org
```

データのインポートなどはコメントアウトされているので、必要であれば戻してください。（試してないので、動くかはわかりませんが、コメントアウトされてるなーと思っていました。）

## 開発

この状態でコードを変更して、pushするとスクラッチ組織に反映されます。

```
sfdx force:source:push -u myfirstfalcon-SCRATCH
```

相変わらずファイル変更を監視して保存はしてくれない（なんでSalesforce周りの人はそこを気にしないのだろうか？）ので、[nodemonなどで設定する](https://ntotten.com/2018/01/17/using-nodemon-to-autopush-sfdx-project-changes/)必要があるでしょう。

新規のリソースは`force:source:pull`すると、`sfdx-source/<namespace>/main/default`に落ちてきます。他のディレクトリに作成していた場合はそのファイルが更新されます。
他のフォルダへの移動は手動でするのでしょうかね？そもそもSalesforceの画面で設定することを想定していないのでしょうか？オブジェクトとかアプリケーションとかはさすがにコードってのは面倒なのだが。

## パッケージ化組織にデプロイ

```
./tools/deploy-mdapi-source
```

## ベータパッケージの作成

残念ながらスクリプトは用意されていません。以下のコマンドでベータパッケージを作成できます。

```
sfdx force:package1:version:create --packageid 03310000000g8vm --name "My First Falcon" -u myfirstfalcon-PACKAGE
```

`.circleci/config.yml`にベータパッケージを作る処理があるので、CIで作ることを想定しているようです。

# 終わりに

ちょっと未完成なところは散見されますが、自分でこれを自動化するプロジェクト設定を作るのは面倒なので雛形を提供してもらえると助かるなーとは思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/27267/ed5da19e-73f3-97c4-d5d8-4ae320e7b173.png)
（[ISVs Adopting Salesforce DX with Managed Packages - YouTube](https://www.youtube.com/watch?v=lTTbymAAtAg)）

新しいアプリを作ろうと思うので、これをベースに模索してみようかなと思います。