【UiPath】CI/CD環境の構築その３（Jenkins編）

# 1. はじめに
* [前回](https://qiita.com/drafts)、[前々回](https://qiita.com/MasahiroHarada1105/items/fd549a56f60689bbe6d9)と2回に分けてUiPathのCI/CD環境をJenkins上に構築してきました。
* 今回は応用編として、UiPathのJenkinsプラグインで提供されていない機能の自動化方法について説明します。

https://qiita.com/MasahiroHarada1105/items/fd549a56f60689bbe6d9

https://qiita.com/MasahiroHarada1105/items/bf8d4c0b75b3a38e4e39

# 2. Orchestratorへのリリース作業について
* シンプルなリリースであればUiPathのJenkinsプラグインで提供されているタスクを組み合わせることで自動化を実現できるかと思いますが例えば以下の流れでリリースを行う場合、#3と#4（赤字部分）がプラグインのタスクとして提供されていないため手作業が残ってしまうことになります。

    1. プロジェクトのビルド
    1. プロジェクトパッケージのパブリッシュ
    1. <font color="Red">デプロイ先フォルダの作成</font>
    1. <font color="Red">作成したフォルダにユーザー、マシンを紐づける</font>
    1. プロジェクトパッケージのデプロイ

* 本記事では#3と#4の作業をCI/CDで自動化する方法について考えてみます。

# 3. どのようにCI/CDとして自動化するか
* 上述の#3、#4を実現するにはOrchestratorのAPIを呼び出す必要があり、JenkinsからOrchestratorのAPIを呼び出すためには以下の方法が考えられそうです。
    1. PowerShellから呼び出す
    1. UiPathのワークフローから呼び出す

* #1「PowerShellから呼び出す」は[Jenkins PowerShell Plugin](https://plugins.jenkins.io/powershell/)を使うことで実現できそうです。PowerShellからOrchestratorのAPIを呼び出す方法については弊社ナレッジベースで公開されている[外部アプリケーション機能(OAuth)によるOrchestrator APIコール実装方法](https://www.uipath.com/ja/community-blog/knowledge-base/implementing-orchestrator-api-with-oauth)にて詳細に解説されていますのでそちらを参照ください。

https://www.uipath.com/ja/community-blog/knowledge-base/implementing-orchestrator-api-with-oauth

* 本記事では#2「UiPathのワークフローから呼び出す」の方法を使ってフォルダ作成、フォルダへのユーザーとマシンの割り当てを実現してみます。

# 4. ワークフローを作成する
* ワークフローからのOrchestrator APIの呼び出しは、「[OrchestratorへのHTTP要求](https://docs.uipath.com/ja/activities/other/latest/workflow/orchestrator-http-request)」
アクテビティを使うことで比較的簡単に実現できます。このアクテビティは「UiPath.System.Activities」に含まれています。
* 「OrchestratorへのHTTP要求」アクテビティを使うメリットは、ワークフローの実行ユーザーにAPIを操作する適切な権限が付与されていればAPIの認証処理を実装することなく実行できることです。

https://docs.uipath.com/ja/activities/other/latest/workflow/orchestrator-http-request

* Orchestrator APIのレスポンスデータはJSON形式となっています。JSONデータから必要な項目にアクセスするために「JSONを逆シリアル化」アクテビティを使用しています。このアクテビティは「UiPath.WebAPI.Activities」に含まれています。パッケージ管理から「UiPath.WebAPI.Activities」をプロジェクトに追加してください。

https://docs.uipath.com/ja/activities/other/latest/developer/deserialize-json

* ワークフローの全体は以下となります。Jenkinsからユーザー名、フォルダ名、ロール名、マシン名を渡せるように引数を定義して、Orchestrator APIを利用して名称からIDを取得して最後にフォルダにユーザーとマシンを割り当てる処理となっています。
* このワークフローでは、引数で渡されたユーザー名を持つユーザーがOrchestratorに存在しない場合は例外をスローしてJenkinsに実行失敗を伝えるようにしています。サンプルのため便宜上ユーザー名のみのチェックとしていますが、他引数のチェックも行うことでより安定性の高いワークフローとすることができるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322296/5bd78bd3-ffd0-ab42-1512-8146c2b137c0.png)

引数の定義は以下となります。
| 名前          | 方向 | 型    |
|:-              |:----:|:-----:|
| in_userName    | 入力 | String |
| in_folderName  | 入力 | String |
| in_roleName    | 入力 | String |
| in_machineName | 入力 | String |

ワークフロー内で使用している変数は以下となります。
| 名前      |  型    |
|:-         |:-------:|
| response  | String  |
| jsonObj   | JObject |
| userId    | String  |
| folderId  | String  |
| roleId    | String  |
| machineId | String  |

ワークフローを作成したら、Orchestratorにパブリッシュ及びフォルダへのデプロイをして実行可能な状態としておいてください。

# 5. ジョブを登録してみる
* 準備ができたので実際にJenkinsにジョブを登録してみましょう。
* [前々回](https://qiita.com/MasahiroHarada1105/items/fd549a56f60689bbe6d9)作成したジョブをベースとして使用します。本記事では差分のみ紹介します。

長いですがジョブの全体は以下となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322296/040c8631-02fb-2519-5d2b-6da941faf581.png)


## パラメータの定義
Jenkinsジョブの実行時にパラメータを渡せるように「ビルドのパラメータ化」にチェック入れてパラメータを定義します。

* パラメータの型から文字列を選択して、「名前」にパラメータ名を入力します。
* よく使う値を「デフォルト値」に設定しておくことで、実行毎の入力の手間を省くことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322296/11ae029c-c719-214c-c528-571ae8f387d4.png)

今回のジョブでは以下の4つのパラメータを定義します。デフォルト値は皆さんの環境に応じて変更してください。
| 名前 | 型 | デフォルト値 |
|:-|:-:|:-|
| UserName    | 文字列 | robot01    |
| FolderName  | 文字列 | Shared     |
| RoleName    | 文字列 | Robot      |
| MachineName | 文字列 | Production |

## 既存のタスクにパラメータを渡す
* 「UiPathのNuGetパッケージをデプロイ」などにフォルダ名がハードコードされている場合、上記で定義したパラメータに置き換えます。
* 変数は、```$変数名```のように先頭に```$```を付けることで使用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322296/0921ddd1-6115-5740-488b-43a6dbf70eed.png)

## UiPathのジョブに渡すパラメータのJSONファイルを作成する
* 後述する「UiPathのジョブを実行」タスクではパラメータをJSONファイルで指定する必要があります。そのため、先ほど説明した4つのパラメータの値をもつJSONファイルを作成してUiPathのジョブに引数として渡します。
* 今回は[Groovy plugin for Jenkins](https://plugins.jenkins.io/groovy/)をインストールして、Groovyスクリプトを実行してJSONファイルを作成してみます。プラグインがインストールがされていない場合は、Jenkinsの管理 -> Pluginsからインストールしてください。

インストールしたら、「Execute system Groovy script」をBuild Stepsに追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322296/e67889ee-5220-e99d-43f4-fa980cd9ec49.png)

**Groovy Script** のテキストエリアに以下のコードを張り付けてください。
```groovy
import groovy.json.*

// パラメータの取得
env = build.getEnvironment(listener)
userName = env.get('userName')
folderName = env.get('folderName')
roleName = env.get('roleName')
machineName = env.get('machineName')

// JSON形式に変換
def builder = new JsonBuilder()
builder in_userName: userName, in_folderName: folderName, in_roleName: roleName, in_MachineName: machineName
json = builder.toPrettyString()

// JSONファイルの作成
new File(build.workspace.toString() + "\\input.json").write(json)
```

## UiPathのジョブを呼び出す
最後に「UiPathのジョブを実行」タスクを使用して作成したワークフローを呼び出してフォルダを作成してユーザーとマシンを割り当てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322296/ab57743d-0376-beea-9bbb-3a4489fb9c44.png)

「UiPathのテストを実行」タスクの設定項目は以下となります。タスクのみでテストプロジェクトのビルドからOrchestratorへのパブリッシュ、フォルダへのデプロイ及びテストケースの実行まで行います。
<table>
  <thead>
    <tr>
      <th>項目</th>
      <th>値</th>
    </tr>
  </thead>
  <tr>
    <td>処理</td>
    <td>PrepareDeployment（UiPathプロセス名）</td>
  </tr>
  <tr>
    <td>入力パラメータ</td>
    <td>${WORKSPACE}\input.json</td>
  </tr>
  <tr>
    <td>優先度</td>
    <td>Low</td>
  </tr>
  <tr>
    <td>ストラテジー</td>
    <td>「動的に割り当て」または「特定のロボット」</td>
  </tr>
  <tr>
    <td>JobType</td>
    <td>Unattended</td>
  </tr>
  <tr>
    <td>Orchestratorのアドレス</td>
    <td>https://cloud.uipath.com/</td>
  </tr>
  <tr>
    <td>Orchestratorテナント</td>
    <td>DefaultTenant</td>
  </tr>
  <tr>
    <td>Orchestratorのフォルダー</td>
    <td>Shared</td>
  </tr>
  <tr>
    <td>認証</td>
    <td>外部アプリケーションを使用してCloud Orchestratorに認証</td>
  </tr>
  <tr>
    <td>Identity Url</td>
    <td>入力なし</td>
  </tr>
  <tr>
    <td>Application Id</td>
    <td>Orchestrator外部アプリケーションの登録で取得したアプリID</td>
  </tr>
  <tr>
    <td>Account Name</td>
    <td>
      <code>https://cloud.uipath.com/[アカウント名]/[テナント名]</code><br />
      上記URLの[アカウント名]を入力
    </td>
  </tr>
  <tr>
    <td>Application Secret</td>
    <td>Jenkinsに登録したCredentialの説明が表示されているはずなのでそのままでOK</td>
  </tr>
  <tr>
    <td>Application Scope(s)</td>
    <td>OR.Jobs</td>
  </tr>
  <tr>
    <td>ジョブの失敗時に失敗</td>
    <td>チェック</td>
  </tr>
  <tr>
    <td>ジョブの完了まで待機</td>
    <td>チェック</td>
  </tr>
</table>

# 6. ジョブを実行してみよう
* 準備が出来たのでJenkinsのジョブを実行してみましょう。
* ジョブの実行はプロジェクトのトップページにある「パラメータ付きビルド」から行います。パラメータに間違いがないことを確認したら「ビルド」ボタンを押下して実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322296/26885d77-b593-0426-56a7-4c8e38205173.png)

* 正常終了した場合、Orchestratorにパッケージがパブリッシュされ指定したフォルダにデプロイされていることが確認できるかと思います。

# 7. おわりに
* UiPathのJenkinsプラグインで提供されていない機能も、UiPathのワークフローを呼び出すことで簡単に実現することができました。今回紹介した以外にも様々なことが出来るかと思いますので是非CI/CD環境の構築にトライしてみてください。