【SAPUI5】SAP Continuous Integration and Deliveryを使ってみる

##1. はじめに
この記事では、[SAP Continuous Integration and Delivery](https://help.sap.com/viewer/99c72101f7ee40d0b2deb4df72ba1ad3/Cloud/en-US/03814e24e992470cbda2b066a221d239.html)というSAP Business Technology Platform(BTP)のサービスを使って、SAPUI5アプリのCI/CDパイプラインを構築してみたいと思います。

SAPが提供するCI/CDに関するツール、ガイドには以下の3種類があります。右上にいくほど適用の難易度が上がるとともに、自由度も上がります。このうち、CI/CD service(**SAP Continuous Integration and Delivery**)はBTPでの設定だけでパイプラインが作成できるため、最も手軽にCI/CDを始めることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/8e7a939c-588b-5f1b-6741-0ced8ddba328.png)
[DevOps with SAP: Holistic Overview and Latest News [DEV100]](https://static.rainfocus.com/sap/sapteched2020/sess/1602555751805001utlG/sessionppt/DEV100_V3_1604711079260001W1if.pdf)より引用

##2. SAP Continuous Integration and Deliveryとは
SAP Continuous Integration and DeliveryはBTPのCloud Foundry環境で提供されるサービスで、Cloud Foundryにデプロイするアプリケーション向けのパイプラインを作成することができます。以下で説明する3種類のパイプラインのテンプレートが用意されています。テンプレートを使用して簡単にパイプラインを作成できる一方、目的に合ったテンプレートがない場合は使えないので自由度はそれほど高くないということになります。

###2.1. サポートされているパイプライン
3つのパイプラインがサポートされています。今回は**SAP Fiori in the Cloud Foundry environment**を使います。

- SAP Cloud Application Programming Model: CAP用（Cloud Foundry環境）
- SAP Fiori in the Cloud Foundry environment: SAP Fiori用（Cloud Foundry環境）
- SAP Fiori in the Neo environment: SAP Fiori用（Neo環境）

###2.2. SAP Fiori in the Cloud Foundry environmentのジョブ設定方法
ジョブの設定方法は2通りあります。
①Job Editorで設定
②ソースレポジトリのconfig.ymlファイルで設定

①は設定画面から入力する方式で、②はプロジェクトの中に設定ファイルを置く方法です。どちらも設定できる内容は同じなので、今回は①の方法で行います。

####ジョブの設定内容
SAP Fiori in the Cloud Foundry environmentのジョブは5つのステージで構成されており、各ステージを実行するかどうかをState（ON/OFF）で指定します。なお、Buildステップは必ず実行されます。

|ステージ    |パラメータ      |設定値      |
|:----------|:---------------|:---------------|
|Build|Application Name（任意）|アプリケーション名。指定しない場合はデフォルトの"ui5application"が使われる。※ここで指定した名前よりもmta.yamlで指定したapplication nameが優先される|
|Test|State|ONにした場合、テストステージが実行される。テストを実行するためにはFioriプロジェクト側に[テスト用の設定](https://help.sap.com/viewer/99c72101f7ee40d0b2deb4df72ba1ad3/Cloud/en-US/201ef608e14c4ca483b2184b42e17e7f.html)が必要|
|Malware Scan|State|ONにした場合、Malware Scanが実行される|
|Deploy|State|ONにした場合、Cloud Foundryへのデプロイが行われる。以下のパラメータの設定が必要|
||API Endpoint|Cloud FoundryのAPIエンドポイントを指定（例：https://api.cf.eu10.hana.ondemand.com）|
||Org Name|Cloud FoundryのOrg Nameを指定（サブアカウントのOverviewで確認できる）|
||Space|デプロイ先のSpaceを指定|
||Credentials|Cloud FoundryにログインするためCredentials（自分のユーザ、パスワードのセット）を作成しておき、それを指定する|
|Upload to Transport Management Service|State|ONにした場合、Buildの結果をTransport Management Serviceにアップロードする。以下のパラメータの設定が必要|
||Node Name|アップロード先のTransport Managementのノード名を指定|
||Service Key|Transport Management用のCredentials（サービスキー）を作成しておき、それを指定する|

##3. やってみた内容
今回は、シンプルにSAP Fioriのパイプラインを実行することを目的とします。
実行するステップは①Build、②Test、③Malware Scan、④Deployです。
Transport Management Serviceへのアップロードについては、[kanamen10](https://qiita.com/tnmrknm)さんの以下の記事で説明されています。
[誰かSAP CP界隈の購買事情をなんとかしてくれ。](https://qiita.com/tnmrknm/items/a01ebc877ecb5f2373c1)

＜ステップ＞
[1. 初期設定](https://qiita.com/tami/items/a9d9c8f6b79d7139099c#1-%E5%88%9D%E6%9C%9F%E8%A8%AD%E5%AE%9A)
[2. Credentialsを作成](https://qiita.com/tami/items/a9d9c8f6b79d7139099c#2-credentials%E3%82%92%E4%BD%9C%E6%88%90)
[3. Fioriアプリを作成してGitHubにPush](https://qiita.com/tami/items/a9d9c8f6b79d7139099c#3-fiori%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%81%A6git%E3%81%ABpush)
[4. リポジトリと接続](https://qiita.com/tami/items/a9d9c8f6b79d7139099c#4-%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%A8%E6%8E%A5%E7%B6%9A)
[5. ジョブを作成して実行](https://qiita.com/tami/items/a9d9c8f6b79d7139099c#5-%E3%82%B8%E3%83%A7%E3%83%96%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%81%A6%E5%AE%9F%E8%A1%8C)
[6. Webhookの設定](https://qiita.com/tami/items/a9d9c8f6b79d7139099c#6-webhook%E3%81%AE%E8%A8%AD%E5%AE%9A)

###1. 初期設定
####1.1. サービスの有効化
サブアカウントのSubscriptionsから、Continuous Integration & Deliveryをサブスクライブします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/ee052ccc-04e8-4a53-c208-d37035a39a34.png)

####1.2. ロールの割り当て
Trust Configurationより、**CICD Service Administrator**のロールコレクションを自分に割り当てます。
（ロールの種類については[こちら](https://help.sap.com/viewer/99c72101f7ee40d0b2deb4df72ba1ad3/Cloud/en-US/c679ebdbe76142bd9fb1071e5e53511d.html)を参照）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/f1df6f86-5e2c-16e5-1706-ab314c21bf49.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/e0428c1c-448e-7e5f-3480-faefe65e08d6.png)

####1.3. サービスを実行
Go to Applicationのリンクからサービスを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/564711e9-8d45-c319-d846-42b2c1330dc5.png)

###2. Credentialsを作成
Cloud Foundryにログインするための認証情報を作成します。Credentialsのタブで+ボタンを押して新規作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/5198c8e8-d70d-3579-134d-c3aec3202adb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/2936f212-5e26-e0a5-2fa9-f6e2f133852f.png)

###3. Fioriアプリを作成してGitにPush
####3.1. Fioriアプリを作成
以下のチュートリアルのステップ4（Buildの手前）まで実行します。
[Deploy Your First SAPUI5 App to Cloud Foundry](https://developers.sap.com/tutorials/appstudio-sapui5-create.html)

この結果、Build、Test、Deployに必要な設定がすでに入った状態のアプリが完成します。参考までに、CI/CDがどの設定を見て動いているのかについて説明します。

**①Test**
Testステージでは、UI5アプリのフォルダのpackage.jsonで指定されたtestスクリプトが実行されます。ここでは[Karma](https://karma-runner.github.io/6.1/index.html)というプラグインを使ってテストを実行するように設定されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/4fe01d02-0747-4f4c-28a7-a6b9da02d394.png)
Karmaはkarma.conf.jsというファイルを見に行き、テストに必要な設定を取得します。frameworksにui5が設定されているので、[karma-ui5](https://github.com/SAP/karma-ui5)というUI5に特化したプラグインが使用されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/9cca37ed-3f98-2c37-a17d-37c0875dc182.png)
karma-ui5は、特に指定がなければ[testsuite.qunit.htmlというファイルをテストページとして実行します](https://github.com/SAP/karma-ui5#testpage)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/b1470dfc-d468-8776-a716-3cef3c2116b0.png)
testsuite.qunit.htmlから参照されているtestsuite.qunit.jsファイルの中で、unit/unitTests.qunit.htmlとintegration/opaTests.qunit.htmlをテストページとして追加しています。これにより、unitフォルダ配下のQUnitテストと、integrationフォルダ配下のOPA5テストが実行されます。
Qunit、OPA5について詳しくは[こちら](https://sapui5.hana.ondemand.com/#/topic/7cdee404cac441888539ed7bfe076e57)をご参照ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/255c0de1-a2d7-6c1b-29bc-4eb38077c69f.png)

テンプレートを使わず作成したプロジェクトなどで一からテストの設定が必要な場合は、以下のページの**Configure the Test Stage**のセクションを参考にしてください。
[Configure an SAP Fiori in the Cloud Foundry Environment Job with the Job Editor](https://help.sap.com/viewer/99c72101f7ee40d0b2deb4df72ba1ad3/Cloud/en-US/201ef608e14c4ca483b2184b42e17e7f.html)

**②Build**
Buildステージではプロジェクトのルートを指定して`mbt build`コマンドが実行されます。このために必要なのはプロジェクトのルートにあるmta.yamlです。ここに、このプロジェクトに必要なモジュールやビルド時のパラメータ、使用するリソースなどが記載されています。`mbt build`を実行すると各モジュールがビルドされ、Cloud Foundryにデプロイ可能なmtarファイルが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/ac5dfdda-f7bb-a3e9-e37c-294a4e7fc84e.png)

**③Deploy**
DeployステージではBuildの結果できたmtarファイルをCloud Foundryにアップロードします。デプロイの前にDeployステージで指定したCredentialsを使ってCloud Foundryのスペースにログインが行われます。

####3.2. ローカルでテスト
ローカルでCI/CDで実行されるのと同じテストを実行してみます。ターミナルを開き、UI5アプリのフォルダに移動してテストを実行します。

```
cd <UI5アプリのフォルダ名>
npm test
```
ターミナルにテストの結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/1e18641b-43ab-2a4d-80af-9c41daeb1593.png)

テストの結果、coverageというフォルダが作られます。このなかのindex.htmlファイルを右クリックし、Open with>Previewを選択すると、テストのカバレージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/45250534-60a8-3db6-dfae-f40c6541c764.png)

####3.3. GitHubにPush
作成したプロジェクトをGitHubに上げます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/fb6da259-403c-274e-a2d2-70f0badd163f.png)

###4. リポジトリと接続
Repositoriesのタブで+ボタンを押して新規作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/d8ba248f-4a1a-8f7b-b171-2b9f4c346907.png)
Name, Clone URL（GitリポジトリのURL）を入力してAddをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/3887304d-1b9a-3e90-74ca-e4e672d606c1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/5ddca49b-5105-90fb-9714-e18f2187b203.png)

###5. ジョブを作成して実行
####5.1. ジョブを作成
Jobsのタブで+ボタンを押して新規作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/68c33867-ed2d-765a-35ef-4fe182a1a954.png)
以下の内容を設定し、保存します。下記以外はデフォルトのままとしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/2104d0c2-a37f-158d-489c-217249ef88b6.png)


|項目   |設定値      |
|:----------|:---------------|
|Job Name|任意の名前|
|Repository|ステップ4で作成したリポジトリを選択|
|Branch|master（対象とするブランチを指定）|
|Pipeline|SAP Fiori in the Cloud Foundry environment|
|Test|ON|
|Deploy|ON（Org Name, Space, Credentialsも設定）|
|Upload to Cloud Transport Management|OFF|

####5.2. 実行
▷ボタンを押して実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/915bbbb5-abae-3934-3f1d-d79dea53f582.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/c6c1cc6a-2af6-810d-20c2-bf7c29865eed.png)
すべてのステージが正常終了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/ad82ee65-1dc2-73ac-2998-087dec616c43.png)
※途中のステージでエラーになった場合は、後続のステージは実行されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/a0eacbad-6b73-1009-5e90-55fb6262e9f2.png)

####5.3. デプロイされたアプリケーションを確認
アプリケーションがデプロイされ、起動しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/c87098dc-0d97-9d39-4d10-0e75dadc0397.png)
中に入ってApplication RouteのURLをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/1682b3da-fc3e-ace3-c8e5-fd0234f20ec2.png)
UI5アプリケーションが起動しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/6727d427-2a3e-db36-effc-241804093cb5.png)


###6. Webhookの設定
Webhookを使うと、GitリポジトリにPushしたタイミングでCI/CDに連携され、自動的にジョブが起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/2c0623e1-81c6-8a51-f8b4-2d2f80ab0ae5.png)

####6.1. Webhookの呼び出し情報を確認
Gitリポジトリから呼び出すWebhookのURLは、RepositoriesのWebhook Dataから確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/6060a2dd-ad4e-3424-ce43-f6d9dc352a3a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/0d5b3d2b-3ddf-f692-8490-d3162f2d37d8.png)

####6.2. Webhook連携の設定
GitリポジトリのSettingsタブから、新しいWebhookを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/6cb7b40f-14a2-42cb-d0ca-bcd0043721fa.png)
以下の項目を設定し、**Add webhook**をクリックします。

|項目   |設定値      |
|:----------|:---------------|
|Payload URL|6.1.で確認したPayload URL|
|Content type|6.1.で確認したContent type|
|Secret|6.1.で確認したSecret|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/4f04ec20-e3bc-faf7-5e4f-e8053e9b4b5a.png)

####6.3. アプリケーションを変更してPush
アプリケーションに少し変更を加えてGitにPushします。すると、すぐにJobが開始します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/ccdccce0-cd6a-3ff1-4cae-6798a65e2eb5.png)

##4. おわりに
以前Jenkinsを使って[一からパイプラインを構築](https://qiita.com/tami/items/509a7a792143e529fb4a)した際は、トライアル&エラーで大変苦労したのですが、今回は一発でうまくいきました。テンプレートさえ合えば、CD/CDを始めるハードルとしてはこの上なく低いといえそうです。
一方で、例えば「FioriアプリをABAPサーバにデプロイしたい」など他の要求が出てきたときには、現状だと複数のツールを使いわけることになります。今後テンプレートの種類が拡充されていくことに期待したいです。