JIRAのAPIを利用する

こんにちは。[mediba advent calendar 2016](http://qiita.com/advent-calendar/2016/mediba)の17日目担当 メディアシステム開発部の松本です。

medibaでは、複数のチームがプロジェクト管理にatlassianのJIRAを利用しています。
定期的に発生するタスクの管理にも使用しているのですが、毎度ストーリーを発行して、サブタスクをメンバー分発行して・・・
というのが地味に面倒でうっかり忘れることもあるので、APIを利用して作業を簡略化してみました。

# やりたいこと
- JIRAのAPIを利用して毎週発生する定期報告のissueを作成し、メンバーの数だけサブタスクのissueを作成する
- issueの作成日は毎週月曜日、報告期限は同じ週の木曜日


# 環境・準備
- [Python3.5.2](https://www.python.org/downloads/release/python-352/)
- [JIRA REST API](https://docs.atlassian.com/jira/REST/cloud/)
- [requests](http://docs.python-requests.org/en/master/)

# 実装
## import

```py3:import
import requests
import json
import datetime
```

## APIの認証
JIRAのAPIを利用するための認証方法は2つあり、今回はBasic HTTPを使用します。

- [OAuth](https://developer.atlassian.com/cloud/jira/platform/jira-rest-api-oauth-authentication/)
- [Basic HTTP](https://developer.atlassian.com/cloud/jira/platform/jira-rest-api-basic-authentication/)

BASE64エンコードを用いて認証キーを作成します。

```py3:認証
import base64
auth_str = 'JIRAアカウント:JIRAパスワード'
authkey = base64.encodestring(auth_str.encode("utf8")).decode("ascii")
```
## issueを取得する
課題タイプなどのパラメータ解析のため、既存のissueを取得して参考にします。

```py3:issueの取得
issue_data = requests.get(
    'https://JIRAのURL/rest/api/2/issue/取得したいissueID',
    headers={'Content-Type': 'application/json',
             'Authorization': 'Basic 上で作製した認証キー}'})
```

header情報に認証キーを含めることでAPIへのアクセスが可能になります。
レスポンスから、issue作成で必要になる情報を取得します。

- 優先度=priority　３はミディアム
- 課題タイプ=issuetype 　5はサブタスク

この辺りはJIRAの設定でも変わってくると思います。
## issueを追加する
まず、リクエスト内で使用するパラメータを用意しておきます。

```py3:パラメータ
# 子issueの担当者
assignee = ['担当者1のID', '担当者2のID', '担当者3のID']
# 報告期限
duedate = str(datetime.date.today() + datetime.timedelta(3))
```

issueを追加するリクエストです。

```py3:issueの追加
addissue = requests.post(
    'https://JIRAのURL/rest/api/2/issue/',
    json.dumps({
        "fields": {
            'project': {
                'key': 'プロジェクトキー'
            },
            'assignee': {
                'name': '親issueの担当者'
            },
            'reporter': {
                'name': '親issueの報告者'
            },
            'priority': {
                'id': '3'
            },
            'issuetype': {
                'id': '10001'
            },
　　　　　　　'labels': 'ラベル名',
            'summary':'要約文',
            'description': description,
            'duedate': duedate,
        }
    }),
    headers={'Content-Type': 'application/json',
             'Authorization': 'Basic 認証キー}'}
)
```

これで親issueが追加されるので、サブタスクとして子issueを追加します。
parentに親issueのIDが必要な為、先のリクエスト結果から取得したものを使用します。

```py3:issueの追加
for name in assignee:
  addsub = requests.post(
      'https://JIRAのURL/rest/api/2/issue/',
      json.dumps({
          "fields": {
              'project': {'key': 'プロジェクトキー'},
              'summary': summary + '_' + name,
              'assignee': {
                  'name': name
              },
              'reporter': {
                  'name': '親チケットの報告者'
              },
              'priority': {
                  'id': '3'
              },
              'parent': {
                  'id': addissue.json()['id']
              },
              'issuetype': {
                  'id': '5'
              },
              'labels': 'ラベル名',
              'description': description,
              'duedate': duedate,
          }
      }),
      headers={'Content-Type': 'application/json',
               'Authorization': 'Basic 認証キー}'}
  )
```

## 実行結果

上記、実行結果のレスポンス。

``` py3:レスポンス
{'id': '42601',
 'key': 'プロジェクトキー-452',
 'self': 'https://JIRAのURL/rest/api/2/issue/42601'}
'42601'
{'id': '42602',
 'key': 'プロジェクトキー-453',
 'self': 'https://JIRAのURL/rest/api/2/issue/42602'}
{'id': '42603',
 'key': 'プロジェクトキー-454',
 'self': 'https://JIRAのURL/rest/api/2/issue/42603'}
{'id': '42604',
 'key': 'プロジェクトキー-455',
 'self': 'https://JIRAのURL/rest/api/2/issue/42604'}
```

実際にJIRAにアクセスし、親issue、子issueが正常に追加されていることを確認して終了です。

# まとめ
パラメータの把握さえできてしまえばAPIにリクエストするだけで簡単に動作するので、JIRAを利用している方は検討してみるのはいかがでしょうか。
もちろん、curlでも代用できます。
明日18日は、[曽根さん](http://qiita.com/HiroyukiSone)による「リモート開発の取り組み」です。