背景描述
最近有個需求是獲取某些符合條件的jira數據,在統計後使用echarts可視化度量出來。後端代碼打算用 Python實現
問題解決
這裏着重說下後臺獲取jira數據的代碼。python有一個非常好用的jira操作庫jira-python。這裏有其非常友好的文檔說明。下面權當是對文檔的摘抄複述吧!
安裝
如果Python環境中集成了pip的話,可以直接使用如下命令安裝:
pip install jira
或者直接下載其離線包安裝(注意,jira包在安裝的時候可能有其他依賴包。其他依賴包也需要安裝)這種安裝比較麻煩,更推薦上面pip命令安裝。
使用
我們知道jira裏有相應的project、project下是對應的一些issues(我是這樣理解的,一個jira是一個issue,issue也分類,project是同一類issues的統稱。不知道這樣說對不對,_)。要想獲取jira對應的project或者issues,就得先建立一個jira的鏈接對象。即:
from jira import JIRA
# 即通過jira的主網址、一個jira網站的用戶名和密碼即可獲取該jira網站的鏈接對象
test_jira = JIRA('https://jirahost.com.cn', basic_auth=('username', 'password'))
下面就可以調用它來查詢jira對應的projet與issues了。
查詢projet
# 獲取所有的projets
projects = test_jira.projects()
# 獲取指定的project, JRA
test_proj = test_jira.project('JRA')
查詢issues
獲取或查詢指定條件的issues一般是用的最多也是最常用的。一般我們需要獲取到issue,並對issue的數據進行統計度量。這裏主要用到了這個包的search_issues()方法(該方法返回的是一個列表,裏面都是符合對應條件的issue對象),這個方法的參數是jira的JQL語句。JQL語句是一種用來查詢jira數據的查詢語句,類似於數據庫的sql語句(例如mySQL的查詢語句),但它不是數據庫查詢語句。jira官網文檔有更加詳盡的說明。比如要查詢名爲“TEST”的project的issues,則其JQL語句爲:
project = "TEST"
要查詢指派人爲“小明”,並且project名爲“TEST”的issues,則其JQL語句爲:
project = "TEST" AND assignee = "小明"
上面兩句對應的Python代碼分別爲:
search_str = 'project = "TEST"'
issues = test_jira.search_issues(search_str)
search_str = 'project = "TEST" AND assignee = "小明"'
issues = test_jira.search_issues(search_str)
可以看到,要獲取指定的jira或issues,只要寫好對應的JQL語句即可。關於JQL的關鍵字的用法說明jira官網文檔都有。可以把符合條件的JQL語句寫好,然後在自己或公司搭建的JIRA網站(即在首頁導航欄的Issues—>Search for issues)中調試,如果可行,再放入代碼中運行。
需要注意的是search_issues()默認查詢的issues最多爲50個。如果你查詢的jira或issues數量超過50個,則需要添加maxResults參數來指定更大的值。例如獲取project名爲“TEST”的issues有100個,則Python中的代碼爲:
# 指定獲取的issues總數最多10000個
search_str = 'project = "TEST"'
issues = test_jira.search_issues(search_str, maxResults=10000)
獲取到指定條件的issue列表,我們就可以用它來得到對應issue的詳細信息了,比如最簡單的我們想獲取每個issue的名字,即:
search_str = 'project = "TEST" AND assignee = "小明"'
# 得到issue的列表
issues = test_jira.search_issues(search_str)
# 獲取issue的名字
name_list = [issue.key for issue in issues]
若是獲取到對應的issue列表後,想獲取issue的某一個信息,但我們又不知道其對應的是issue的哪個字段(有時候我們會給jira自定義某些字段),我們可以將獲取到的issues轉爲ison數據,通過查看json數據,從而找到對應的字段。即:
import json
search_str = 'project = "PROJ" AND Created="2019-3-18 8:12"'
# 用於json_result=True來返回對應的字典。
issue = test_jira.search_issues(search_str, json_result=True)
寫入到json文件中
issue = json.dumps(issue, ensure_ascii=False)
with open('jira.json', 'w', encoding='utf-8') as f:
f.write(issue)
f.close()
之後將該json文件中的數據進行代碼格式化,找到自己想要的字段,進行後續的jira數據查詢操作。
刪除、更新issues
方便起見,下面已將一些常用的功能進行了封裝,代碼如下:
from jira import JIRA, JIRAError
server = JIRA(server='https://jirahost.com.cn',
basic_auth=('username', 'password'))
# 查詢issues
def search_issue(jql: str) -> list:
"""
查詢jira
:param jql:
:return:
"""
issue_key_list = []
try:
issues = server.search_issues(jql, maxResults=10000)
if len(issues) > 0:
issue_key_list = [issue.key for issue in issues]
except JIRAError as e:
print(f'search issue failed: {e}')
finally:
return issue_key_list
# 驗收issues.只有當issue的狀態爲待驗收或驗收中時纔會驗收
def close_jira(issue_key):
"""
:param issue_key:
:return:
"""
status_list = ['待驗收', '驗收中']
closed = False
try:
issue = server.issue(issue_key)
issue_status = issue.fields.status.name
if issue_status == '完成':
return True
if issue_status not in status_list:
return False
transitions = server.transitions(issue)
# print(transitions)
issue_id = transitions[0]['id']
# print(issue_id)
server.transition_issue(issue, issue_id)
# 如果爲待驗收則遞歸一次
if issue_status == '待驗收':
close_jira(issue_key)
closed = True
except JIRAError as e:
print(f'close issue failed: {e}')
finally:
return closed
# 創建issue
def create_issue(issue_dict: dict):
"""
創建一個issue,並返回其key
:param issue_dict:
:return: issue_key
"""
issue_key = ''
try:
issue = server.create_issue(fields=issue_dict)
issue_key = issue.key
except JIRAError as e:
print(f'create issue failed:{e}')
finally:
return issue_key
# 更新issue指派人
def modify_jira_assignee(issue_key: str, modify_usr: str):
try:
issue = server.issue(issue_key)
issue.update(assignee=modify_usr)
except JIRAError as e:
print(e)
# 刪除issue
def delete_jira(issue_key: str):
try:
issue = server.issue(issue_key)
issue.delete()
except JIRAError as e:
print(e)
# 更改issue的截至日期
def modify_jira_duration(issue_key: str, duration: str):
try:
issue = server.issue(issue_key)
issue.update(duedate=duration)
except JIRAError as e:
print(e)