Salesforce
SFDX

旧形式のsalesforceプロジェクトをHeroku CI上でテストを回す

はじめに

Heroku CIはHerokuが提供するCIのためのテスト自動化サービスで、世に出て半年くらい経ちますでしょうか。
様々な言語に対応しており、さらには自分でbuildpackを用意すれば公式で対応してない言語でも利用できるようになる、ということでsalesforceのプロジェクトでも利用できるようにしたいと思って、試してみたところになります。

なお、今回はsfdx形式のプロジェクトではなく、Metadata APIを使った形式(ひとまず、"旧形式"と呼びます 他意はありませんw)のプロジェクトを対象にしています。

なぜか?
単にまだまだsfdxに移行できてない、という大人ではない子供の事情です...

さておき、構成の概要はこんな感じです。

summary.png

Sandbox環境の準備

最近ではSandbox環境を20個くらいは作れるようになったので(一昔前はデフォルトで1個だけ作れて買い足すなどの(以下ry))、dev環境、CI環境、Staging環境などお好きに準備しましょう。

通常は、以下のパターンが多いと思いますが、開発規模や開発プロセスによっては変わることもあるかもしれません。

種別 個数
dev 複数
CI 1
Staging 1

Heroku CIの準備

Heroku CIは、Herokuのアプリケーションライフサイクル管理機能であるHeroku Pipelinesと組み合わせて使用します。
HerokuのダッシュボードからPipelineを作成します。

heroku_dashuboard_menu.png

Pipeline内のメニュータブにTestsというメニューがありますので、そこからHeroku CI機能を参照できます。

heroku_pipeline_menutab.png

その他、基本的な流れは、Heroku CIを使ってみたという中の方が投稿した記事が参考になると思います。
併せて、公式の記事Pipelinesも確認してみてください。

今回はGithubとの連携も設定していますので、こちらの公式記事GitHub Integration(Heroku GitHub Deploys)も確認されると良いと思います。

テスト実行に向けた設定(app.jsonによる設定)

buildpackを指定する

Heroku CIによるテスト実行は、2種類の方法で定義できるようです。

  1. BuildPack内でtestコマンドとして記述する
  2. app.jsonファイル内にテストスクリプトを記述する

もともと用意されている言語は、以下の10種類でsalesforce向けには用意がありません。

  • Go
  • Node
  • Java
  • PHP
  • Python
  • Ruby
  • Gradle
  • Scala
  • Clojure
  • Elixir

したがって、app.jsonを用意することになります。

今回は、sfdxを使うことにしていますので、sfdxが使えるように設定が必要となります。
ということで、@WadeWegnerさんが作成したsalesforce-cli-buildpackを使うことにします。
(github上のリポジトリはこちら)

heruoku_buildpack_search_salesforce.png

このbuildpackの中身を見てみると/bin/compileにてsfdxをインストールしているようなので、これを追加のbuildpackとして指定すればsfdxが使えるようになる模様です。
あわせて読みたい: buildpack API

ここまでで、app.jsonの中身はこんな感じになります。

app.json
{
  "buildpacks": [
    {
      "url": "https://github.com/wadewegner/salesforce-cli-buildpack"
    }
  ]
}

テストスクリプトを用意する

sfdxを使って、テスト実行するまでの処理手順としては以下の流れを想定します。

  1. 特定のSandbox環境へのアクセストークンを取得する
  2. 旧形式のプロジェクトを、そのSandbox環境にMetadataAPI経由でデプロイする
  3. Sandbox環境上で全ローカルテストを実行させる

sfdxコマンドにもMetadata APIを使うためのコマンドが用意されています。
今回は、Metadata API経由でデプロイ&ローカルテスト実行ということで、force:mdapi:deployコマンドを利用します。

また、デプロイ先を指定する上で、上記コマンド実行前にforce:auth Commandsでアクセストークンを取得しておきます。
今回は、3種類あるうちのforce:auth:sfdxurl:storeを利用してみます。(force:auth:jwt:grantでも問題ありません。こちらを使う場合は、こちらの記事を参考にしてください。)

上記コマンドを利用する場合には、refresh tokenが必要になります。取得方法については、jsforce: Access Token Requestか、REST API開発者ガイド:認証についてを参考にすると良いかと思います。(すみませんが割愛します...)
取得したrefresh tokenをリファレンスにある通り、

force://<clientId>:<clientSecret>:<refreshToken>@<instanceUrl>

という文字列だけのファイル(今回はsfdxAuthUrlというファイル名にしています)を作成します。

一応、念のためにローカルで問題なくトークンが取得できるかどうか確認してみましょう。

$ sfdx force:auth:sfdxurl:store -f ./sfdxAuthUrl -a herokuci
Successfully authorized (ユーザID) with org ID (組織ID)

が返ってくれば成功です。

最終的に、app.jsonへの設定としては以下のようになります。

  1. test-setup にてアクセストークンを取得する
  2. test にてデプロイ&テスト実行する
app.json
{
    "buildpacks": [
      {
        "url": "https://github.com/wadewegner/salesforce-cli-buildpack"
      }
    ],
  "environments": {
    "test": {
      "scripts": {
        "test-setup": "./.local/share/sfdx/cli/bin/sfdx force:auth:sfdxurl:store -f ./sfdxAuthUrl -a herokuci",
        "test": "./.local/share/sfdx/cli/bin/sfdx force:mdapi:deploy -d ./src/ -u herokuci -l RunLocalTests -w 60"
      }
    }
  }
}

テストを回す

ひとまず、app.jsonや、refresh tokenを格納したファイルをgithubにpushします。
すると、Heroku CIが反応してtest-setup->testと実行されていきます。
(テスト自体は落ちてますが...テストセットアップは正常に完了し、デプロイ&ローカルテスト実行していることが確認できます)

heroku_ci_test.png

後記

  • refresh tokenの保管方法としては、Herokuの環境変数にセットしておいて利用するなど、もう少し工夫したいところです。
  • CI環境でのテストが成功したら、Staging環境にデプロイするような設定も加えたいところです。
  • パッケージをインストールした上でのカスタマイズなど、ScracthOrgを作成するだけだと、デプロイしにくい...という事情がある場合で、1つのSandbox環境を使い回すようなパターンについて、今回考えてみた次第でした。
  • Herokuからもsalesforce-buildpackというbuildpackが用意されていますが、/bin/detectをみるとsfdx-workspace.jsonというファイルが存在するかどうかでbuildpackに対応したプロジェクトかどうか判定しています。sfdx形式のプロジェクトではsfdx-project.jsonを作成するので、正しく判定できないし、うまく動かなかったところもあるので今のところは使えなかったです...
  • Metadata API経由だと、Apexクラスの削除にも対応するには、なかなか複雑になりそうですが、旧形式のプロジェクトからCI回す上での課題ですね。

より良いsfdxを使った開発ライフをお楽しみください。