3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CircleCIAdvent Calendar 2023

Day 23

Salesforce CLI で CircleCIの自動テストを実行する

Posted at

こんにちは、こちらはCircleCI Advent Calendar 2023の23日目、Perfumeはかしゆかの生誕祭をお祝いする記事になります。
悲しいことに1日遅れになってしまいました。よよよ。それでもゆかちゃん誕生日おめでとう🎉良い35歳を過ごしてください。

ということでSalesforceの開発をCircleCIで自動化していきます。

なぜ今更?

CircleCI + Salesforce の自動化記事は世に沢山あります。しかし残念ながら、どれもこれも古いsfdxコマンドを使ったもので、やがてなくなっていくコマンドを使って自動化しています。
ここはやはり、Salesforceの中の人として、salesforce cliを使った自動化を実現しなければならないと今回の記事を生成しました。が、結構大変でゆかちゃんの誕生日に間に合いませんでした。ホント残念です。

が、Salesforce CLIを使った自動化方法は完全にできあがりましたので、1日遅れで公開していきます。

事前準備

Salesforce CLIを使って自動化したバッチ処理を行う場合には、JWTを使った認証が必要となります。
まず、こちらの記事を元にして証明書の作成と、Salesforce組織側の設定を行っておく必要があります。

Salesforce CLIをJWTで使う場合の設定

暗号化した証明書の準備

下地ができあがりましたら、今度は外部に公開してぶちまけてしまっても安全な証明書を準備して、CircleCIを設定していきます。

事前に準備したserver.keyが必要です。

パスフレーズを暗号化する

まず証明書を暗号化するために必要なパスフレーズを準備します。そのパスフレーズでしか復号化できないようにするためです。とは言え、パスフレーズをそのままどこかに記してしまったら不安全で仕方ありません。念には念を入れて、このパスフレーズをまず暗号化していきます。

<パスフレーズ>には、好きなパスフレーズを指定してください。なんでも良いです。
実行するとkeyivが出力されます。このパスフレーズを暗号化した情報源です。やったぜ。

パスフレーズを元に暗号化情報を取得する
> openssl enc -aes-256-cbc -k <パスフレーズ> -P -md sha1 -nosalt -iter 10000
key=7F045E41781E5E49A48AE86716375E4ED5FB9D4325F39CB3D2385C007755F945
iv =11650FF4873F3A391729991E53FD588C

この暗号化されたパスフレーズ情報を元にして、server.keyを暗号化します。

暗号化コマンド
> openssl enc -nosalt -aes-256-cbc -in ./foo/server.key -out server.key.enc -base64 -K 7F045E41781E5E49A48AE86716375E4ED5FB9D4325F39CB3D2385C007755F945 -iv 11650FF4873F3A391729991E53FD588C

これで、先ほどの暗号化されたパスフレーズ情報を元に、証明書を暗号化した外部に公開されちゃっても安全な証明書ファイルができました。実際に利用するときは、この暗号化された証明書を復号化して利用します。このままでは利用できません。

参考: forcedotcom/sfdx-circleci

Salesforce DXプロジェクトに、暗号化された証明書を配置する

今回はYUKAちゃん誕生日おめでとうFY23ソースコードサンプルをベースに進めていきます。

今回は、Salesforce DXプロジェクトのルートディレクトリに assetsというフォルダを準備して進めます。その配下に、先ほど準備した暗号化された証明書server.key.encを配置します。それ以外の証明書関係のファイルはプロジェクトディレクトリには配置しないでください。ヤバイです。情報漏洩です。

暗号化されたパスフレーズなどもファイルに残したりしないでください。なお、上記のkeyiv情報は私は使っていないので、これを使ってもなりすましは不可能です。フフフ。

と言うことで、ファイルを配置できたら、準備は完了です。あとはCircleCI側の設定です。

CircleCIを設定する

該当のGitHubリポジトリとCircleCIを連携してプロジェクトを準備してください。ここでは割愛します

環境変数を設定する

プロジェクトを準備したら、次の4項目の環境変数を作成してください。Project SettingsからEnvironment Variablesを辿ってください。
そこからAdd Environment Variableで4つの環境変数を作成します。

  1. CONSUMER_KEY ... Salesforce組織の接続アプリケーションで作成された「コンシューマー鍵」を定義します
  2. DECRYPTION_IV ... 先ほど作成した暗号化されたパスフレーズのiv情報をここに記します
  3. DECRYPTION_KEY ... 先ほど作成した暗号化されたパスフレーズのkey情報をここに記します
  4. USERNAME ... Salesforce組織へ接続するときのユーザー名(メールアドレス形式のアレ)を指定します

CleanShot 2023-12-24 at 11.48.54@2x.png

これらを環境変数として持つことで、外部に公開されているソースコードも安全に運用が可能というわけです。

config.yml を準備する

全体像はこちらです。ゆかちゃんの誕生日にあわせてyuka-birthdayというジョブとワークフローを設定しました。名前は好きにしてください。

特徴としては、Salesforceが提供するSalesforce CLIおよびnpmパッケージを含むDockerイメージを利用しています。これにより古いsfdxコマンドを使わずに、常に最新のsalesforce cliが利用できます。

参考:Docker イメージを使用した Salesforce CLI の実行 | Salesforce CLI 設定ガイド | Salesforce Developers

また、先ほど設定した「暗号化された証明書」を復号化してJWTの鍵として利用しています。

./circleci/config.yml
version: 2.1

jobs:
  yuka-birthday:
    docker:
      - image: salesforce/cli:latest-full
    steps:
      - checkout
      - run:
          name: "Create a server.key"
          command: |
            openssl enc -nosalt -aes-256-cbc -d -in assets/server.key.enc -out assets/server.key -base64 -K $DECRYPTION_KEY -iv $DECRYPTION_IV
      - run:
          name: "Authenticate and create Scratch org to Salesforce DevHub"
          command: |
            sf force auth jwt grant -i $CONSUMER_KEY -f assets/server.key --username $USERNAME -d
            sf org create scratch -f config/project-scratch-def.json -a circle_build_$CIRCLE_BUILD_NUM
            sf project deploy start -o circle_build_$CIRCLE_BUILD_NUM

      - run:
          name: "Run LWC tests"
          command: |
            npm install
            npm test
      - run:
          name: "Run Apex tests"
          command: |
            sf force apex test run --result-format human --code-coverage -o circle_build_$CIRCLE_BUILD_NUM

      - run:
          name: "Delete useless Scratch org"
          command: |
            sf org delete scratch -p -o circle_build_$CIRCLE_BUILD_NUM

workflows:
  version: 2
  yuka-birthday:
    jobs:
      - yuka-birthday

各所のポイントを説明します。

証明書の復号化

暗号化された証明書server.key.encDECRYPTION_KEYDECRYPTION_IVを利用して、証明書を復号化しています。複合に必要な情報を環境変数として定義していることで、ソースコード内に漏洩したら困るような情報の排除が可能となっています。やるじゃん。

openssl enc -nosalt -aes-256-cbc -d -in assets/server.key.enc -out assets/server.key -base64 -K $DECRYPTION_KEY -iv $DECRYPTION_IV

base64化した秘密鍵を環境変数に入れるという方法もとれるだろうと思いつつも、公式に従ってこの方法をとりました。興味がある方は次の記事を参考に頑張ってみてください。できたら教えてほしい。

[RS256] JWTでRSA秘密鍵を環境変数で処理したい [Javascript] #JavaScript - Qiita

JWT認証とスクラッチ組織作成とデプロイ

sf force auth jwt grantコマンドでCONSUMER_KEYと、復号化したserver.keyを使ってDevHub組織の認証を行っています。

sf org create scratchコマンドでスクラッチ組織を作成します。ここで-a circle_build_$CIRCLE_BUILD_NUMで別名を割り当てています。最後にスクラッチ組織を削除するために別名を割り当てています。

sf project deploy startで該当のスクラッチ組織へデプロイしています。

認証と組織の作成
sf force auth jwt grant -i $CONSUMER_KEY -f assets/server.key --username $USERNAME -d
sf org create scratch -f config/project-scratch-def.json -a circle_build_$CIRCLE_BUILD_NUM
sf project deploy start -o circle_build_$CIRCLE_BUILD_NUM

参考:CircleCI を DevHub に接続 | Salesforce DX 開発者ガイド | Salesforce Developers

Lightning Web Componentのテスト

Lightning Web Component(LWC)は、Jestを使ってテストをすることが推奨されています。Jest のインストールを参考にしてJestでテスト実行できる環境を設定しておく必要があります。

LWCのテストは、通常のJavaScriptのテストと同じです。npm installで必要なパッケージをインストールしてnpm testでテスト実行です。

LWCのテスト
npm install
npm test

参考:Lightning Web コンポーネントのテスト | Lightning Web Components 開発者ガイド | Salesforce Developers
参考: Jest のインストール | Lightning Web Components 開発者ガイド | Salesforce Developers

Apexのテスト

Salesforce Apexのテストも勿論実行可能です。
--result-format human--code-coverageを付けていますが、成功したときは何も表示されないので付ける意味はあまり感じていません。実際のテスト結果の詳細は、実行結果内で示唆されるsf apex get test -i 707H3000000xVjq -o test-xxxxxxxxxxx@example.comで確認が可能なので、これをうまく拾えたら良いんでしょうね。どうやったらいいんだろう。

sf force apex test run --result-format human --code-coverage -o circle_build_$CIRCLE_BUILD_NUM

スクラッチ組織の削除

最後にテストを実行したスクラッチ組織を削除します。作成可能な下図などに上限がありますので、一般的には削除運用が望ましいです。

sf org delete scratch -p -o circle_build_$CIRCLE_BUILD_NUM

スクラッチ組織を使い回すという考え方もあるでしょう。使い回しても良いかどうかは開発する内容にもよりますので一概には言えませんが、考慮しても良いかもしれません。

参考:sfdx-circleci/.circleci/config.yml at master · forcedotcom/sfdx-circleci

CircleCIで実行してみる。

YUKAちゃん誕生日おめでとうFY23ソースコードサンプルを元にCircleCIでテストを実行すると、次のような結果となります。ご参考に。

download.jpg

今年もお世話になりました🙏

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?