JIRA integration to Emacs org-mode
This library is still in early beta phase, but I use it already for most of my daily JIRA usage.
Differences to org-jira-mode
- New api implementation, jiralib2.el.
- Syncing data from remote does not clear marker’s (most notably clock marker) from the org file.
- Support for Epics. Refiling tickets automatically when epics change.
- Support for Sprints.
- Parsing to (with
ox-jira) and from (with own parser) JIRA markup to and from org-markup.
- Custom agenda command.
- Usage of org-capture to add comments.
- Exporting org-clock data to Tempo with a separate interface to edit clock values before committing.
ejira implements a new client for JIRA’s REST API. It uses cookie auth instead of basic auth for performance reasons. JIRA limits the amount of queries per second with basic auth queries but not cookie auth queries. Downside for cookie auth is that it expires in a few hours which requires a new login every now and then. Ejira will automatically ask for credentials when the session has expired and some API command is performed. If desired, the password can be easily cached by e.g. advicing
Each project gets it’s dedicated file. The file will contain all of the epics and tickets in that project. The file will be created automatically in
ejira-my-org-directory if it does not exist yet.
Tickets will be automatically refiled in the correct project file under the epic ticket in that file when synced from remote. Actions that user can perform on tickets:
- Add comment
- Update title
ejira provides a new agenda command, which shows the issues in the active sprint, highlighting those that are assigned to you.
Clocking hours with Tempo
Clocking hours to JIRA Tempo is done normally with org-clock. Then, at the end of the day those entries can be synced to Tempo. One can clock the hours of a regular org-header into a specific ticekt by just refiling it under the ticket headline. Ejira will traverse up the tree until it finds a heading with an ID tag. The Title of the heading containing the clock entry will be used as the comment of the clock entry. This is useful with for example meetings: just use regular org-capture to capture the meeting and collect notes, and then in the end of the meeting (or later) refile the meeting under a ticket where the hours from that meeting should be logged.
This package depends on:
request. Also, if
helm-ejira is used,
helm-org are also required.
This package is not yet in melpa, manual installation only. With use-package:
(use-package ejira :load-path "/path/to/cloned/ejira/repo" :ensure nil)
First, configure required variables for the package:
(use-package ejira :load-path "/path/to/cloned/ejira/repo" :ensure nil :init (setq jiralib2-url "https://jira.mycorp.com" jiralib2-user-login-name "my-jira-username" ejira-projects '("PROJECT1" "PROJECT2" "PROJECT3") ejira-main-project "PROJECT1" ejira-my-org-directory "/Users/username/projects/org" ejira-done-states '("Done") ejira-in-progress-states '("In Progress" "In Review" "Testing") ejira-high-priorities '("High" "Highest") ejira-low-priorities '("Low" "Lowest") ;; Customize these based on your JIRA server configuration ejira-sprint-field 'customfield_10001 ejira-epic-field 'customfield_10002 ejira-epic-summary-field 'customfield_10004)
|The full URL of your JIRA server, without ’rest/api’ part|
|Project IDs you want to sync from JIRA server|
|The project which is tied to the sprint (the sprint name should have the same code in it)|
|The directory where the JRA project files will be created (must exist)|
To sync the server state to your local files, run
M-x ejira-update-issues-in-active-sprint. The sync will take a few seconds.
You can interact with the tickets by opening them from the agenda (mapped to
helm-ejira-sprint, or by manually browsing the org files.
Ejira provides following commands that can be mapped to bindings preferred by the user.
|Resync the data from remote||Point inside an issue|
|Assign the issue to a JIRA user (use prefix argument C-u to assign to yourself)||Point inside an issue|
|Change the state of the issue with actions provided by the server.||Point inside an issue|
|Add a comment to the issue with ||Point inside an issue|
|Deletes the current comment from the server||Point inside a comment|
|Add a link to a username into an org-document (e.g. a comment)||Anywhere|
|Insert a web link to the issue you are currently clocked in into the current buffer||Anywhere when clock is active|
|Update the local changes made to the summary and description of the issue to the server||Point inside an issue|
Example configuration (with use-package):
(use-package ejira :init (setq jiralib2-url "https://jira.mycorp.com" jiralib2-user-login-name "my-jira-username" ejira-projects '("PROJECT1" "PROJECT2" "PROJECT3") ejira-main-project "PROJECT1" ejira-my-org-directory "/Users/username/projects/org" ejira-done-states '("Done") ejira-in-progress-states '("In Progress" "In Review" "Testing") ejira-high-priorities '("High" "Highest") ejira-low-priorities '("Low" "Lowest") ejira-coding-system 'utf-8 ;; Customize these based on your JIRA server configuration ejira-sprint-field 'customfield_10001 ejira-epic-field 'customfield_10002 ejira-epic-summary-field 'customfield_10004 ;; Org-customization, adjust to your liking epa-pinentry-mode 'loopback org-tags-column -100 org-clock-history-length 23 org-agenda-restore-windows-after-quit t org-clock-in-resume t org-drawers '("PROPERTIES" "LOGBOOK") org-clock-into-drawer t org-clock-out-remove-zero-time-clocks t org-clock-out-when-done t org-clock-persist t org-clock-persist-query-resume nil org-clock-auto-clock-resolution 'when-no-clock-is-running org-clock-report-include-clocking-task t org-time-stamp-rounding-minutes '(1 1) org-indirect-buffer-display 'other-window org-agenda-files '("~/projects/org") org-refile-targets '((nil :maxlevel . 9) (org-agenda-files :maxlevel . 9)) org-use-fast-todo-selection t) :config (require 'ejira) (require 'org-agenda) (org-add-agenda-custom-command ejira-sprint-agenda))
- Login with
jiralib2-session-loginworks, but all session calls return 401.
- Try setting
request--curl-cookie-jarto an empty string
(setq request--curl-cookie-jar ""). This solved the issue for me with a Linux laptop running curl 7.62.0. My Macbook Pro running curl 7.54.0 did not require this. Maybe a bug in curl?
- Try setting