Jira 이슈 정보를 Emacs org-mode 문서에 삽입
로그인이 필요한 Confluence 페이지 타이틀을 API로 org-cliplink와 연동하는 작업을 진행했다. Confluence를 작업했으니 다음은 뭐다? Jira되겠다. 같은 회사 제품이니 인증 방법이 같고 API도 비슷하게 생겼다. org-cliplink를 연동하는 건 똑같다. Jira 연동에는 기능이 하나 추가된다. heading으로 Jira 정보를 추가하는 기능이다. 항상 이슈를 만들어서 일을 진행하기에 필요한 기능이다.
HTTP Basic Authentication 사용 테스트
Jira Cloud 버전을 사용하면서 인증 방법이 조금 바뀌었다. HTTP Basic Authentication을 사용하는 건 똑같다. 대신 password 대신 api token 을 사용한다.
본격적으로 코드를 짜기 전에 API 호출 테스트를 먼저 해본다. Restclient 패키지를 사용해서 테스트했다.
#+begin_src restclient
:auth := (format "Basic %s" (base64url-encode-string (format "%s:%s" "ohyecloudy@myoffice.com" "SUPERSECRET_API_TOKEN")))
GET https://myoffice.atlassian.net/rest/api/2/issue/MY-1234
Authorization: :auth
#+end_src
id:api_token
문자열을 Base64URL로 인코딩해서 헤더에 사용한다.
{
"id": "1234",
"self": "https://myoffice.atlassian.net/rest/api/2/issue/MY-1234",
"key": "MY-1234",
"fields": {
"description": "설명...",
"summary": "Jira 이슈 정보를 Emacs Org-mode 문서에 삽입",
...
}
}
잘 된다. $.fields.summary
정보를 가져오면 된다.
Jira Cloud REST API를 사용해 타이틀 가져오기
URL을 입력받아서 JIRA API로 이슈 정보를 가져온다. 거기서 summary 필드 정보를 추출한다. 예를 들어 URL이 https://myoffice.atlassian.net/browse/MY-1234
라면 이 정보에서 https://myoffice.atlassian.net/rest/api/2/issue/MY-1234
API URL을 만들어서 호출한다. 아래는 가져오는 함수다.
(defun my/jira--content (url)
(when-let* ((host-info (my/jira--find-host url my/jira-hosts))
(jira-id (my/jira--issue-id url))
(api-url (my/jira--build-issue-api-url (plist-get host-info :api-url) jira-id))
(auth-header (my/jira--auth (my/jira--remove-protocol (plist-get host-info :url))))
(content (my/jira--retrieve-content api-url auth-header)))
(plist-put content :id jira-id)))
my/jira--find-host
함수는 JIRA API를 사용해서 정보를 가져오는 URL인지 판단한다. my/jira--issue-id
함수로 URL에서 MY-1234
같은 이슈 id를 추출한다. my/jira--build-issue-api-url
함수로 API URL을 만든다. my/jira--auth
함수로 HTTP Basic Authentication 문자열을 만든다. 준비된 인증 헤더와 API URL로 my/jira--retrieve-content
함수를 호출해 이슈 정보를 가져온다. ohyecloudy/dotfiles/doom.d/lisp/my-jira.el에서 전체 구현을 볼 수 있다.
org-cliplink과 연동
’Confluence API로 가져온 제목으로 org-mode 마크업 링크 삽입 - org-cliplink 기능 확장’ 글에서 설명한 Confluence link처럼 Jira link도 org-cliplink와 연동한다. Doom Emacs에서 org-cliplink에 바인딩한 SPC m l c
키를 누르면 Jira URL일 때는 Jira API를 사용해서 타이틀을 가져와 링크를 만들게 한다.
’MY-1234 Jira 이슈 정보를 Emacs Org-mode 문서에 삽입’ 형식으로 타이틀을 만드는 my/jira-title
함수를 추가한다.
(defun my/jira-title (url)
(when-let* ((content (my/jira--content url)))
(format "%s %s" (plist-get content :id) (plist-get content :summary))))
’Confluence API로 가져온 제목으로 org-mode 마크업 링크 삽입 - org-cliplink 기능 확장’ 글에서 연결한 함수에 my/jira-title
함수를 호출해 타이틀을 가져오는 코드를 추가한다.
(setq my/org-cliplink-custom-retrieve-title-hook
(lambda (url)
(or (my/org-cliplink-confluence-title url)
(my/jira-title url))))
org-roam heading으로 추가
Confluence와 다르게 Jira는 타이틀을 가져와 링크뿐만 아니라 heading을 만들어주는 기능도 만들었다. 이슈에 글을 써서 중간보고를 하기에 heading으로 만들어야 관리가 쉽기 때문이다. org-cliplink처럼 클립보드에 복사한 URL이 있으면 그 정보를 사용하게 했다. org-cliplink를 쓰다 보니 이 방식이 편해졌다.
(defun my/jira-insert-heading-content ()
(interactive)
(let* ((url (my/jira--url-clipboard-or-prompt))
(content (my/jira--content url))
(summary (plist-get content :summary))
(id (plist-get content :id)))
(org-insert-heading)
(insert (format "%s %s [/]" id summary))
(org-update-statistics-cookies nil)
(org-set-property "URL" url)))
my/jira--url-clipboard-or-prompt
함수로 클립보드에서 가져오거나 없으면 prompt로 URL을 입력받는다. my/jira--content
함수로 Jira 이슈 정보를 가져와서 heading으로 추가한다.
** MY-1234 Jira 이슈 정보를 Emacs Org-mode 문서에 삽입 [0/0]
:PROPERTIES:
:URL: https://myoffice.atlassian.net/browse/MY-1234
:END:
이런 식으로 추가된다. C-c C-o
키를 누르면 꼭 링크 위가 아니라 대충 근처에서도 이슈 링크를 열어준다.
함수에 SPC m z j
키를 바인딩했다.
(map! :map org-mode-map
:localleader
(:prefix ("z" . "insert")
"j" #'my/jira-insert-heading-content))
세팅 방법
어떻게 Jira API를 사용해서 타이틀을 가져올 URL인지 구분할까? 코드에서 찾아보는 리스트에 사용하는 Jira 정보를 추가하게 해서 해결했다.
(add-to-list 'my/jira-hosts '(:url "https://some.atlassian.net/browse"
:api-url "https://some.atlassian.net/rest"
:api-version :cloud))
입력받은 URL을 my/jira-hosts
변수에서 찾으면 Jira API를 호출해서 이슈 정보를 가져온다.
마치며
org-cliplink와 연동한 건 좋은 선택이다. 구현한 함수를 직접 호출하거나 새로운 키바인딩을 추가해서 엔트로피를 높일 필요가 없다. 링크를 삽입하는 org-cliplink를 연동해 Jira URL이면 API를 사용해서 정보를 받아오게 연동했다. Jira는 heading을 추가하는 함수를 만들어서 Copy & Paste 노동을 줄였다.
C-x C-s C-x C-c
링크
- Base64URL - Base64 Standards - Base64 - base64.guru
- Basic auth for REST APIs - developer.atlassian.com
- Jira (software) - en.wikipedia.org
- ohyecloudy/dotfiles/blob/354302cca7d300665d71e2e0cc5e76c969be25c7/doom.d/lisp…
- REST 웹서비스를 테스트하고 싶다면 restclient 패키지를 - (emacsian ohyecloudy) - ohyecloudy.com
- org-cliplink 패키지로 title과 url을 편하게 삽입 - (emacsian ohyecloudy) - ohyecloudy.com
- Doom Emacs 전환 후기 - (emacsian ohyecloudy) - ohyecloudy.com
- Confluence API로 가져온 제목으로 org-mode 마크업 링크 삽입 - org-cliplink 기능 확장 - (emacsian …
- #훌륭한습관 중간보고 - ohyecloudy’s pnotes - ohyecloudy.com