Jira Cloudの自動化機能で定期的にチケットを自動生成する

# 今回の目的

Jira Software/Jira Service Management/Jira Work Management などの Jira Cloud 製品には「自動化」機能があります。

<https://support.atlassian.com/ja/cloud-automation/docs/jira-cloud-automation/>

今回はこの「自動化」を使用して、指定した日時 (例えば「毎月15日の午前9:00」など) に定期的に Jira チケットを自動生成する方法を紹介します。

合わせて、「自動化」を使用して、条件 (例えば「期日を過ぎても完了していない」など) にマッチしたチケットに担当者宛てのコメントを自動追加する方法を紹介します。

# 背景

以前は定期的なタスクを自分の Google カレンダーに登録しておき、作業する時期になったら手動で Jira のチケットを作成し、管理していました。

このときは、

- チケットの作成を忘れることがある
- 毎回同じ内容のチケットを手動で作成するのが面倒。。。
- 特定の日(毎月○日)に行うタスクが休日だった場合に作業自体を忘れてしまう

などの課題がありました。
これらの課題を解決するため、手動でのチケット作成や担当者のアサインなどを自動化することにしました。

最初に導入したのが [Jira Cloud REST API](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-post "The Jira Cloud platform REST API - Atlassian Developer") を [Google Apps Script (GAS)] (https://script.google.com/home "Google Apps Script") から時間トリガーで実行し、必要なフィールドが設定された Jira チケットを自動生成する方法です。

:::note info
本ブログの「おまけ」の項で GAS のサンプルコードを紹介しています。
:::

この GAS でのチケット自動生成も便利だったのですが、 

- 他のメンバーが設定変更したいときにその人 (または私) が GAS を編集しなければならない
- メンバー全員が GAS を編集できるわけではない
- (システム管理者である) 自分の API トークンが見られてしまうので (悪用しないとは思うけど) 怖い。。。
- Jira チケットの [説明] フィールドに箇条書きリストなどが上手く設定できない
- チケット生成を自動化しても作業を忘れてしまうことがある
- できることならチケット自動生成の設定・管理を Jira Cloud 内で完結させたい

という課題や要望が出てきました。

これらを解決してくれたのが、今回紹介する Jira Cloud の「自動化」機能です。

```plantuml
@startuml
scale 1.25
skinparam activityBackgroundColor #ffffff
skinparam activityBarColor #666666
skinparam activityBorderColor #666666
skinparam activityArrowColor #666666
caption \nJira チケットの手動作成から自動化への変遷
:**第1段階**\n・Google カレンダーでスケジュール管理\n・手動で Jira チケット作成;
:**第2段階**\n・GAS の関数を時間トリガーで実行し Jira チケット生成;
:**第3段階**\nJira Cloudの「自動化」で\n・指定日時に Jira チケット生成\n・期日を過ぎても完了していない Jira チケットにアラート;
@enduml
```

現在は Jira Cloud の「自動化」でチケットを生成しています。
また、期日を過ぎても完了していないチケットには、同じく Jira Cloud の「自動化」で担当者宛のコメントを自動追加し、対応漏れの軽減を図っています。

# 自動化でチケットを生成する

今回は以下の条件で Jira チケットを自動生成したいと思います。

|項目|条件|補足|
|:--|:--|:--|
|生成日時|3月/6月/9月/12月の15日の午前9:00|3ヶ月の毎年4回|
|生成先プロジェクト名|`INVS`プロジェクト|私の検証用プロジェクト|
|課題タイプ|タスク|

また、自動化で設定するフィールドと値は以下の通りです。

|設定するフィールド|値|補足|
|:--|:--|:--|
|要約|定期タスク〇〇(`YYYYY`月`M`月)||
|説明|・タスク1<br>・タスク2<br><br>_This issue was created by Automation for Jira._|・「タスク1、2」は箇条書きリスト<br>・「This was ～」はイタリック体<br><br><br>|
|期日|生成日の5日後||
|担当者|自分||

## Jira Cloud 自動化を設定する

自動化を設定する方法を説明していきます。

### 自動化を設定する準備をする

1. 自動化を設定する Jira プロジェクトを開きます。
1. [プロジェクト設定] をクリックします。 ![プロジェクト設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/c2de7fff-876d-918f-a324-810db306285c.png "[プロジェクト設定]をクリックします")
1. [自動化] をクリックします。 ![自動化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/a43bc334-16cb-66f3-3e26-db4c721f5420.png "[自動化]をクリックします")
1. 初めて自動化を設定する場合は次の画像のような [推奨] 画面が表示されますので、[ルール] をクリックします。<br>※推奨する自動化ルールを追加したい場合は [オンにする] をクリックします。 ![自動化2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/f97c9970-70c2-699f-a496-861299a654c0.png "[ルール]をクリックします")
1. [ルールを作成] をクリックします。 ![自動化3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/4347495a-e0de-a496-27c2-78d34043b858.png "[ルールを作成]をクリックします")
1. 自動化設定画面が表示されます。 ![新しいトリガー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/0a4009cd-6f92-4fe4-8b09-42a56ef14b2c.png "新しいトリガーの設定")

続いて、実際に自動化を設定していきます。

### トリガーを設定する

まずはトリガーを設定します。
今回は指定した日時に Jira チケットを生成させたいので、トリガーとして [スケジュール時] を使用します。

1. すべてのコンポーネントで [スケジュール時] をクリックします。 ![コンポーネントの選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/46b9b1aa-2eb5-41d0-6a5a-e108f816f9be.png "[スケジュール時] をクリックします")
1. [スケジュール時] をクリックします。 ![スケジュール時.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/4d2ecfa5-675a-20df-ecb4-b9a6a48ad061.png "[スケジュール時] をクリックします")
1. スケジュールは [ベーシック] と [高度 (CRON 式)] で指定できます。<br>今回の生成日時は __3月/6月/9月/12月の15日の午前9:00__ なので [高度 (CRON 式)] をクリックします。 ![スケジュール時ベーシック画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/81106e38-beb8-ae5e-092d-e86bf9bc8dd8.png "[高度 (CRON 式)] をクリックします")
1. 日本標準時 (JST) の3月/6月/9月/12月の15日の午前9:00をトリガーにしたいので、[クローン表記] フィールドに `0 0 18 15 MAR,JUN,SEP,DEC ? *` と設定し、[保存] ボタンをクリックします。<br>※この画面にも記載がありますが、`「CRON 式を使用すると、ルールの頻度をより詳細にコントロールできるようになります。CRON 式は現在 UTC で予定されています」` とのことなので、+9時間して日本時間の午前9:00にトリガーされるようにしています (UTC 09:00 + 9h = UTC 18:00 = JST 09:00)。 ![CRONで設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/7559eb30-2f2a-5d40-5d0b-f26827645d3a.png "CRON 式で設定して保存します")

#### CRON 式について

日時を選ぶだけで CRON 式を生成してくれる以下のようなサイトもありますので、利用すると便利です。

<https://rakko.tools/tools/88/>

### アクションを設定する

続いて、アクションを設定していきます。

1. 前項のトリガー設定画面で [保存] ボタンをクリックすると [コンポーネントを追加] 画面になりますので、[新しいアクション] をクリックします。 ![新しいアクション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/2848bba3-f176-7828-20e0-f17b7718d042.png "[新しいアクションをクリックします")
1. [課題の作成] をクリックします。 ![課題の作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/7ea29f60-2154-8586-5b5b-629a85664b33.png "[課題の作成] をクリックします")
1. [プロジェクト] で課題を作成するプロジェクト (今回は `INVS`)、[課題タイプ]で `タスク` を選択します。 ![作成する課題の設定1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/40bd2703-e6b8-915b-8a45-c1cebe17f5b3.png "[プロジェクト]と[課題タイプ]を選択します")
1. [設定するフィールドを選択...] をクリックし、説明/担当者/期日 のチェックボックスをチェックします。 ![作成する課題の設定2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/8f351f7f-df9a-b040-a303-648f36578224.png "説明/担当者/期日 のチェックボックスをチェックします")
1. [要約] フィールドには「定期タスク〇〇(YYYYY月M月)」と設定したいので、Jira Cloud の __Smart Values__ を使用して `定期タスク〇〇({{now.format("yyyy年M月分")}})` と入力します。<br>※ __Smart Values__ の詳細については後述します。
1. [説明] フィールドには「<br>`* タスク1`<br>`* タスク2`<br><br>`_This issue was created by Automation for Jira._`<br>」と入力します。
1. [期日] フィールドには生成日の5日後を設定したいので、Jira Cloud の Smart Values を使用して `{{now.plusDays(5)}}` と入力します。
1. [担当者] フィールドには自分を設定したいので、自分のアカウントを選択します。
1. 設定値を確認し、[保存] ボタンをクリックします。 ![作成する課題の設定3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/d6a7e92b-19c3-4579-6d90-35379966a299.png "設定値を入力・選択して保存する")
1. 自動化の名前を入力(今回は「定期タスク〇〇の自動生成」)し、[オンにする] ボタンをクリックします。 ![自動化設定の保存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/0187ae5a-9252-0912-e605-da1d9b06a2ca.png "自動化に名前を付けてオンにします")
1. [ルール詳細] をクリックします。 ![ルール詳細の設定1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/a8e14ac8-9bd0-25a3-e6c1-652fd0119b10.png "[ルール詳細] をクリックします")
1. 必要に応じて [説明] にこの自動化に関する説明を入力します。
1. [アクター] に `Automation for Jira` が設定されていることを確認します。<br>※アクションの実行者を指定したい場合は変更してください。
1. [保存] ボタンをクリックします。 ![ルール詳細の設定2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/dc7acdff-1c39-ee60-e4e2-96434f5b046c.png "ルール詳細を設定し保存します")
1. [変更を公開] ボタンをクリックします。 ![ルールを公開.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/c536031c-86ee-4988-9914-4700418835ff.png)

以上で自動化の設定は完了です！

#### Smart Values について

`{{now.format("yyyy年M月分")}}` や `{{now.plusDays(5)}}` を Smart Values といいます。
Smart Values を使用すると、Jira 内の課題データにアクセスして操作できます。

- `{{now.format("yyyy年M月分")}}` は現在の時刻を参照し、フォーマットに「yyyy年M月分」を指定します。
- `{{now.plusDays(5)}}` は現在の時刻を参照してそれに 5 日を加算します。

Smart Values に関しては、こちらのドキュメントをご参照ください。

<https://support.atlassian.com/ja/cloud-automation/docs/smart-values-in-jira-automation/>

#### 補足：コンポーネントを指定して担当者を指定する

Jira Cloud ではプロジェクト毎に __コンポーネント__ を設定することが可能で、そのコンポーネントに __既定の担当者__ を設定することが可能です。
本ブログでは [担当者] フィールドを直接設定しましたが、チケットを作成するプロジェクトでコンポーネントと既定の担当者を設定しておき、自動化のアクション設定で [コンポーネント] フィールドを設定することでも、間接的に担当者を設定することができます。

コンポーネントに関しては、こちらのドキュメントをご参照ください。

<https://support.atlassian.com/ja/jira-software-cloud/docs/organize-work-with-components/>

## 手動実行して生成されるチケットを確認する

設定した自動化を手動実行し、実際にチケットを自動生成させ、内容を確認します。

### 自動化を手動実行する

1. [ルールを実行] ボタンをクリックします。 ![手動でルールを実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/32ebdec1-2d4b-2fac-471a-873d119292ef.png)
1. ルールが実行されます。

### 監査ログを確認する

1. [監査ログ] をクリックします。 ![監査ログを開く.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/d0437e03-f618-5948-0d4f-0958e0aabf1f.png "[監査ログ]をクリックします")
1. 手動実行した監査ログを確認します。今回の場合、`複数のエラー`になっていますので、詳細を確認するため、その監査ログの [さらに表示] をクリックします。 ![監査ログを開く2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/4e31a710-6b58-a668-a136-9543b2bb64f0.png)
1. 監査ログの内容を確認すると、課題の作成は成功していますが、INVSプロジェクトの課題タイプ `タスク` では `期日(duedate)` が利用できない(=課題タイプ `タスク` に `期日（dudate）` が追加されていない)ためエラーになったことがわかります。 ![監査ログの内容を確認する.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/6ef99b07-3fa1-69cb-ae48-e08122770f8b.png "監査ログの内容を確認します")
1. INVSプロジェクトの課題タイプ `タスク` で利用している画面に `期日` フィールドを追加します。 ![期日を追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/d8d1ac2a-5cf5-ce04-728e-a633c4a00e90.png "期日フィールドを追加します")
1. 再度、[ルールを実行] ボタンをクリックして自動化を手動実行します。
1. 手動実行した監査ログを確認します。今回は `成功` になりました。  ![監査ログの内容を確認2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/aee66281-d67b-5850-1a32-9adbbe564ea1.png "監査ログの内容を確認します")
1. 実際に作成した課題 `INVS-4` にアクセスし、要約/説明/期日/担当者の設定内容を確認します。 ![課題の内容を確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/c84f3fc7-6e6b-b4df-7d3d-12250e2ee093.png "作成した課題の内容を確認します")

以上で自動化の動作確認は完了です。

# 自動化でコメントを追加する

今回は指定した日時に期日を過ぎても完了していないチケットが存在するか検索し、検索結果のチケットに担当者宛のコメントを自動追加したいと思います。
コメント内で担当者にメンションすることで、担当者に通知が飛び、それにより期日が過ぎていることを気が付かせます。

今回の自動化したい内容を Jira Cloud の「自動化」用に分解すると以下のようになります。

- トリガー：指定した日時
- 検索条件：「期日を過ぎている」かつ「ステータスカテゴリーが Done ではない」
- アクション：検索結果のチケットに担当者宛てのコメントを追加

具体的には、以下の内容で自動化を設定します。

|項目|値|補足|
|:--|:--|:--|
|検索実行日時|平日の午後1:00||
|検索条件 (JQL)|`duedate < now() AND statusCategory != Done`||
|コメント|`@担当者`<br><b>[アラート]</b> この課題は期日を過ぎていますが、ステータスが完了になっていません。<br>確認や対応が必要です。|`@担当者`は担当者名が表示され、メンションされることで担当者に通知されます<br><br><br>|

検索条件の __JQL__ は Jira Query Language の略で、Jira で特定の課題を検索するための、強力で柔軟な方法です。

今回の場合、「期日を過ぎている」を JQL で表現したものが `duedate < now()`、「ステータスカテゴリーが Done ではない」を JQL で表現したものが `statusCategory != Done` になります。

JQL について詳しく知りたい方はこちらの Atlassian Blog をご参照ください。

<https://www.atlassian.com/ja/blog/jql-for-beginners-1>

## Jira Cloud 自動化を設定する

自動化を設定する準備は先ほどと同様ですので割愛し、実際の設定に進みます。

### トリガーを設定する

今回も__指定した日時__にチケットを検索させたいので、先ほどと同様に [スケジュール時] をトリガーとして使用します。

1. すべてのコンポーネントで [スケジュール時] をクリックします。
1. [スケジュール時] をクリックします。
1. 今回の平日の午後1:00をトリガーにしたいので [ベーシック] をクリックします。
1. [ルールを次の間隔で実行] で `1` `週` を入力・選択します。
1. [曜日] で `月` `火` `水` `木` `金` をクリックします。
1. [時刻] で `1:00 PM` `Asia/Tokyo` を選択します。 ![スケジュールの設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/2a28c933-9f05-ac66-12de-5340fd28a74e.png "スケジュールを設定します")
1. [JQL 検索を実行し、結果を後続の条件とアクションに渡します] のチェックボックスをチェックし、[JQL] に `duedate < now() AND statusCategory != Done` と入力し、[保存] ボタンをクリックします。 ![JQLの設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/b4d5632d-5b6c-93b3-1a88-7ebc04a78f58.png "JQLを設定して保存します")

### アクションを設定する

続いて、アクションを設定していきます。

1. 前項のトリガー設定画面で [保存] ボタンをクリックすると [コンポーネントを追加] 画面になりますので、[新しいアクション] をクリックします。
1. [課題へのコメント] をクリックします。 ![課題へのコメントをクリック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/6b7e2d99-a830-90e2-f150-394c6951ac07.png "[課題へのコメント] をクリックします")
1. [コメント] に「<br>`[~accountid:{{assignee.accountId}}]`<br>`*[アラート]* この課題は期日を過ぎていますが、ステータスが完了になっていません。`<br>`確認や対応が必要です。`<br>」と入力します。<br>※`{{assignee.accountId}}` は [担当者] のAtlassian アカウント ID を表現する Smart Values です。<br>※`[~accountid:` `]` で `{{assignee.accountId}}` を囲むことで担当者へメンションすることができます。
1. 期日を過ぎた後、自動化が実行された際に毎回コメント追加したい場合は [重複を避けるため、このコメントを特定の課題に追加するのは 1 回のみとしてください。] のチェックを外してください。<br>※今回はチェックされたままにします。
1. [保存] ボタンをクリックします。 ![課題へのコメントを設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/c7fc9b02-f222-580e-c239-83d6a5414b39.png "コメントを設定し保存します")
1. 自動化の名前を入力(今回は「期限切れ課題へのアラート」)し、[オンにする] ボタンをクリックします。
1. [ルール詳細] をクリックします。
1. 必要に応じて [説明] にこの自動化に関する説明を入力します。
1. [アクター] に Automation for Jira が設定されていることを確認します。<br>※アクションの実行者を指定したい場合は変更してください。
1. [保存] ボタンをクリックします。
1. [変更を公開] ボタンをクリックします。

以上で自動化の設定は完了です。

## 手動実行して通知や追加されるコメントを確認する

こちらも必要に応じて設定した自動化を手動実行し、動作を確認してください。

- 担当者に通知が届くことを確認 ![メンション通知.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/324525ae-c025-5cb5-1b9b-3537dbf6ffce.png)
- 通知内容を確認 ![通知内容.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/dfe3f1d2-fdef-83f1-b0f1-9b64699eae9e.png)
- コメントの内容と担当者にメンションされていることを確認 ![コメント内容.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/488bf633-5923-ad7b-d9cd-f45015f29c73.png)

# おまけ：GASでチケットを自動生成する

おまけとして、GAS で Jira チケットを生成するためのサンプルコードを紹介します。
サンプルコードには以下の設定値を指定しています。

|項目|設定値|
|:--|:--|
|プロジェクト キー|`INVS`|
|課題タイプ|タスク|
|要約フィールド|定期タスク〇〇(`YYYY`月`M`月)|
|説明フィールド|定期タスクに関する説明\n\nThis issue was created by Google Apps Script automatically.|
|担当者フィールド|担当者に設定するユーザーの Atlassian アカウント ID|

```javascript:sample.gs
var API_BASE_URL = 'https://your-instance.atlassian.net';

// Basic認証用文字列の生成
function create_auth_data(user_id, password) {
  return Utilities.base64Encode(user_id + ':' + password);
}

// ヘッダーの生成
function create_headers(auth_data) {
  return {
    'content-type'  : 'application/json',
    'Authorization' : 'Basic ' + auth_data
  };
}

// Jiraチケットの説明(description)フィールドの設定
function create_description(text) {
  const description = {
    "type": "doc",
    "version": 1,
    "content": [
      {
        "type": "paragraph",
        "content": [
          {
            "text": text,
            "type": "text"
          }
        ]
      }
    ]
  };
  return description;
}

// Jiraチケットの要約(summary)フィールドに設定する「YYYY年M月」の生成
function get_date() {
  var now   = new Date();
  var year  = now.getFullYear();
  var month = now.getMonth() + 1;
  var day   = now.getDate();
  
  var date = year + "年" + month + "月";
  return date; 
}

// POST処理
function post_content_jira(headers, accountId) {
  var date = get_date();
  var data = {
    project: {key: "INVS"},
    issuetype: {name: "タスク"},
    summary: "定期タスク〇〇(" + date + ")",
    description: create_description("定期タスクに関する説明\n\nThis issue was created by Google Apps Script automatically."),
    assignee: {accountId: accountId}
  };
  var fields = {fields: data};
  var payload = JSON.stringify(fields);
  
  var options = {
    'headers' : headers,
    'payload' : payload,
    'method' : 'post'
  };
  
  var api_url      = API_BASE_URL + '/rest/api/3/issue';
  var response     = UrlFetchApp.fetch(api_url, options);
  var content_json = JSON.parse(response);
  
  return content_json;
}

// メイン処理
function create_issue() {
  var now   = new Date();
  var month = now.getMonth() + 1;
  
  // 実行判定 (3月, 6月, 9月, 12月のみ実行する)
  if (month==3||month==6||month==9||month==12) {
    var accountId    = "担当者に設定するユーザーの Atlassian アカウント ID";
    var auth_data    = create_auth_data('自分の Atlassian アカウント','自分の API トークン');
    var headers      = create_headers(auth_data);
    var content_json = post_content_jira(headers, accountId);
    Logger.log(content_json);
  }
}
```

GAS の時間トリガーで `create_issue` を毎月特定の日時に実行するように設定すると、3月/6月/9月/12月に Jira チケットが生成されます。

# おわりに

Jira Cloud の自動化機能で定期的にチケットを自動生成する方法と、条件にマッチしたチケットにコメントを自動追加する方法を紹介させていただきました。

自動化のトリガーやアクションには他にもいろいろなものがあります。
例えばアクションの [Web リクエストを送信] を使用すると、REST API を実行することができます。

![Webリクエストを送信の設定画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234372/87c18f58-2419-48dd-08fb-a3d56db014d5.png "アクション[Web リクエストを送信]の設定画面")


自分に合った自動化を設定し、業務効率化に役立てていただければ幸いです。
最後まで読んでいただきありがとうございました！