Python JIRA 라이브러리로 JIRA 이슈 생성하기
Language/Python

Python JIRA 라이브러리로 JIRA 이슈 생성하기

뉴비뉴 2021. 3. 20.

 글을 시작하기 전에 간단하게 JIRA가 무엇인지 왜 다른 모니터링 툴이 아닌 JIRA 라이브러리를 사용하였는지에 대해 알아보겠습니다.
먼저 JIRA란 무엇일까요? Atlassian 사에서 만든 이슈관리 및 프로젝트 관리 용도로 사용할 수 있는 툴 입니다. 왜 다른 Sentry 같은 에러 로깅 및 모니터링 툴을 사용하지 않고, JIRA 라이브러리를 사용한 이유는 비동기로 처리되는 로직에서 크리티컬한 에러를 JIRA 이슈로 관리할 수 있고, 해당 로직을 담당하고 있는 담당자를 멘션으로 호출하여 알림까지 제공이 되기 때문에 필요한 부분에 간단하게 사용할 수 있다 라고 판단되어 사용하게 되었습니다.

JIRA Python Library

Python(3.x)에서 JIRA REST API를 쉽게 사용할 수 있도록 만들어진 오픈소스 라이브러리입니다.

JQL이라는 쿼리언어를 지원하여 직접 쿼리를 작성하여 원하는 결과를 얻을 수 있습니다.

INSTALL

pip install jira

How to use?

1. Jira API 토큰 발행

우측 상단에 프로필 클릭 > 프로필 및 설정 > 보안 > API 토큰 > API 토큰 만들기

Jira API 토큰 발행 

다음으로 발행한 토큰으로 인증을 수행하고, 프로젝트 키reporter, 멘션 기능으로 호출 될 member들을 설정해주도록 하겠습니다.

from jira import JIRA


class Jira:
    def __init__(self):
        self.options = {'server': 'https://xxx.atlassian.net'}
        self.jira = JIRA(self.options, basic_auth=('<로그인 할 유저 E-mail>', '<JIRA_TOKEN>')
        self.proj = 'ABC'  # 프로젝트 키
        self.reporter = 'notification'  # reporter username
        self.member = {
            'notification': '<사용자 ID>'
            'tomas': '<사용자 ID>'
            'james': '<사용자 ID>'
        }

예시에 사용자 ID를 입력하는 부분은 팀원들에게 Jira에 접속하여 알려달라고 할 수 있겠지만 팀원들의 소중한 시간을 뺏을 수 없기 때문에 아래 사진에 있는 사용자 탭으로 이동하여 추가하고자 하는 사용자를 클릭하여 들어간 뒤 URL의 끝 부분이 사용자 ID 입니다.

ex) xxx.atlassian.net/jira/people/600117beb66825010e0dblah

member의 사용자 ID를 얻고싶은 사용자를 클릭

 

2. Jira 이슈 생성 및 검색 구현

이슈 생성 과정

from datetime import datetime
from pytz import timezone
import requests

from jira import JIRA


class Jira:
    def __init__(self):
        self.options = {'server': 'https://xxx.atlassian.net'}  # 사용중인 JIRA URL
        self.jira = JIRA(self.options, basic_auth=('<로그인 할 유저 E-mail>', '<JIRA_TOKEN>')
        self.proj = 'ABC'  # 프로젝트 키
        self.reporter = 'notification'  # reporter username
        self.member = {
            'notification': '<사용자 ID>'
            'tomas': '<사용자 ID>'
            'james': '<사용자 ID>'
        }
    def create_issue_comment(self, error):
        jira_issue = self._search_issue()
        text = f"발생 시간-{datetime.now(timezone('Asia/Seoul'))} [~accountid:{self.admin['tomas']}] \n*{error}*"
        
        if not jira_issue:
            jira_issue_form = {
                'project': {'key': f"{self.proj}"},
                'summary': '[긴급] 비정상 동작 감지 모니터링 필요 - AsyncError',
                'description': text,
                'issuetype': {'id': '10014'},  # 이슈 유형 - 버그
            }
            self.jira.create_issue(fields=jira_issue_form)
        else:
            for issue in jira_issue:
                self.jira.add_comment(issue, text)
        
    def _search_issue(self):
        search_issue_jql = f"summary~AsyncError and project={self.proj} and reporter={self.reporter} and status not in (closed, done)"
        jira_issue = self.jira.search_issues(search_issue_jql)
        
        return jira_issue
        
        
 if __name__ == '__main__':
     jira = Jira()
 
     a = "Hallo"
     if a != "Hello":
         error = "입력하신 문자열이 Hello와 같지 않습니다"
         jira.create_issue_comment(error)
     else:
         print("Have a nice day")
         
         

create_issue_comment 함수는 이슈가 생성되어있지 않으면 이슈를 생성시키고, 이슈가 생성되어있다면 생성되어있는 이슈에 comment를 추가하는 로직입니다. 이 과정에서 이슈 생성 유무를 확인할 때 _search_issue 함수에서 이슈가 있는지 검색하게 되는데 앞서 언급한 JQL 이라는 쿼리 언어를 사용하여 검색 할 조건을 설정할 수 있습니다. 

"summary~AsyncError and project={self.proj} and reporter={self.reporter} and status not in (closed, done)"

summary 의 끝에 AsyncError가 포함되어 있으며 project는 'ABC' 프로젝트이고, reporter는 'notification' 마지막으로 status는 이슈의 상태를 의미하는데 닫혀있거나 끝낸 상태가 아닌 것들만 가져오는 쿼리입니다. 

"발생 시간-{datetime.now(timezone('Asia/Seoul'))} [~accountid:{self.admin['tomas']}] \n*{error}*"

create_issue_comment 함수 안에 text에 저장되는 문자열을 풀어 설명해보면 [~accountid: {self.admin['tomas']] 는 tomas를 mention으로 언급한다는 것이고, Markdown을 지원하기 때문에 *{error}*는 error가 나오는 부분을 Bold 처리 한 것 입니다. 이 외에도 색깔을 입히거나 테이블을 만들거나 텍스트 박스를 만드는 등등 여러가지 기능을 지원하고 있습니다.

JIRA mention

마지막으로 jira_issue_form 안에 issuetype은 아래 첨부한 사진처럼 유형들이 있고, 유형마다 고유한 Key를 갖고 있어서 원하는 유형의 키를 입력해주시면 됩니다.

issuetype

마무리

오늘은 Python JIRA 라이브러리를 이용하여 이슈를 생성하는 방법에 대해 알아보았습니다. 프로젝트에서 임시로 사용하기 위해 만든 로직이기 때문에 에러 내용과 시간 담당자를 맨션하는 정도로 만들었습니다. 글을 작성하면서 이것저것 찾아보니 새로운 이슈가 등록 될 때 마다 comment를 작성하는 것이 아닌 이슈 본문에 테이블을 만들어놓고 ROW를 추가하는 방법도 괜찮아보이네요!

 

피드백은 언제나 환영입니다. 감사합니다.

Reference

- [Python JIRA Document]

- [JIRA REST API Document]

 

댓글

💲 추천 글