Open Hans-Maulwurf opened 6 years ago
I'm sorry for the documentation, it really is not comprehensive enough...
So, the intended way ejira is used is not to enable ejira-mode
manually. Instead, you configure your JIRA server as shown in the README (essential settings are jiralib2-url
, jiralib2-user-login-name
, ejira-projects
and ejira-main-project
).
Then you run the command M-x ejira-update-issues-in-active-sprint
. That will fetch tickets from all projects listed in ejira-projects
which are in the currently ongoing sprint (of project ejira-main-project
, JIRA can have tickets from multiple projects in a sprint that is tied to a single project). This command can then be run to sync the state from the JIRA server.
Then, there are multiple ways to interact with the tickets.
(org-add-agenda-custom-command ejira-sprint-agenda)
binds the ejira agenda to the 's' agenda key (M-x org-agenda s
).helm-ejira
for filtering through all tickets, or helm-ejira-sprint
for filtering thtough only the tickets in the ongoing sprint.ejira-update-current-issue
, ejira-add-comment
, ejira-assign-issue
, ejira-progress-current-issue
etc.) work from an org-mode buffer without having ejira-mode
active as long as point is somewhere inside the ticket you want to interact with.if
org-clock` is clocking an issue focuses on that issue.The package does not have any default bindings yet, I use evil personally.
I do not expect everything to work out-of-the-box yet, since you are probably the first one after me who is taking the library to use. It has also never been tested with any other JIRA server, or any other workflow. But let's see if we can you up and running.
Feel free to send more comments if something does not work, something works weirdly or something is unclear.
When I execute M-x ejira-update-issues-in-active-sprint
I only get if: Wrong type argument: number-or-marker-p, nil
but i dont get in detail where the error occurs.
Can you enable debug-on-error M-x toggle-debug-on-error
, then run the command again and it should give you the stacktrace. I could then take a look at it.
the only part i understand is the 401 ^^ does it mean i have no access to the api?
`Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil) =(nil 401) (if (= (progn (or (and (memq (type-of response) cl-struct-request-response-tags) t) (signal 'wrong-type-argument (list 'request-response response))) (aref response 1)) 401) (progn (message "Session expired, retrying...") (jiralib2-session-login) (setq response (jiralib2--session-call path args)))) (let ((response (jiralib2--session-call path args))) (if (= (progn (or (and (memq (type-of response) cl-struct-request-response-tags) t) (signal 'wrong-type-argument (list 'request-response response))) (aref response 1)) 401) (progn (message "Session expired, retrying...") (jiralib2-session-login) (setq response (jiralib2--session-call path args)))) (progn (or (and (memq (type-of response) cl-struct-request-response-tags) t) (signal 'wrong-type-argument (list 'request-response response))) (aref response 3))) jiralib2-session-call("/rest/api/2/search" :type "POST" :data "{\"jql\":\"project in (DRS) and sprint in openSprints()\",\"maxResults\":100}") (assoc 'issues (jiralib2-session-call "/rest/api/2/search" :type "POST" :data (json-encode (list (cons 'jql jql) (cons 'maxResults limit))))) (cdr (assoc 'issues (jiralib2-session-call "/rest/api/2/search" :type "POST" :data (json-encode (list (cons 'jql jql) (cons 'maxResults limit)))))) (append (cdr (assoc 'issues (jiralib2-session-call "/rest/api/2/search" :type "POST" :data (json-encode (list (cons 'jql jql) (cons 'maxResults limit)))))) nil) jiralib2-do-jql-search("project in (DRS) and sprint in openSprints()") (first (jiralib2-do-jql-search (concat "project in (" ejira-main-project ") and sprint in openSprints()"))) (ejira-extract-value (first (jiralib2-do-jql-search (concat "project in (" ejira-main-project ") and sprint in openSprints()"))) 'fields ejira-sprint-field) (mapcar (function ejira-parse-sprint) (ejira-extract-value (first (jiralib2-do-jql-search (concat "project in (" ejira-main-project ") and sprint in openSprints()"))) 'fields ejira-sprint-field)) (mapc (function (lambda (s) (if (equal (progn (or (and (memq (type-of s) cl-struct-jira-sprint-tags) t) (signal 'wrong-type-argument (list 'jira-sprint s))) (aref s 3)) "ACTIVE") (progn (throw 'active-sprint (progn (or (and (memq (type-of s) cl-struct-jira-sprint-tags) t) (signal 'wrong-type-argument (list 'jira-sprint s))) (aref s 2))))))) (mapcar (function ejira-parse-sprint) (ejira-extract-value (first (jiralib2-do-jql-search (concat "project in (" ejira-main-project ") and sprint in openSprints()"))) 'fields ejira-sprint-field))) (catch 'active-sprint (mapc (function (lambda (s) (if (equal (progn (or (and (memq (type-of s) cl-struct-jira-sprint-tags) t) (signal 'wrong-type-argument (list 'jira-sprint s))) (aref s 3)) "ACTIVE") (progn (throw 'active-sprint (progn (or (and (memq (type-of s) cl-struct-jira-sprint-tags) t) (signal 'wrong-type-argument (list 'jira-sprint s))) (aref s 2))))))) (mapcar (function ejira-parse-sprint) (ejira-extract-value (first (jiralib2-do-jql-search (concat "project in (" ejira-main-project ") and sprint in openSprints()"))) 'fields ejira-sprint-field)))) (setq current-sprint (catch 'active-sprint (mapc (function (lambda (s) (if (equal (progn (or (and (memq (type-of s) cl-struct-jira-sprint-tags) t) (signal 'wrong-type-argument (list 'jira-sprint s))) (aref s 3)) "ACTIVE") (progn (throw 'active-sprint (progn (or (and (memq (type-of s) cl-struct-jira-sprint-tags) t) (signal 'wrong-type-argument (list 'jira-sprint s))) (aref s 2))))))) (mapcar (function ejira-parse-sprint) (ejira-extract-value (first (jiralib2-do-jql-search (concat "project in (" ejira-main-project ") and sprint in openSprints()"))) 'fields ejira-sprint-field))))) ejira-update-current-sprint() ejira-update-issues-in-active-sprint() funcall-interactively(ejira-update-issues-in-active-sprint) call-interactively(ejira-update-issues-in-active-sprint record nil) command-execute(ejira-update-issues-in-active-sprint record)
i have no idea how to make this code look pretty, sorry
i have no idea how to make this code look pretty, sorry
No problem, I can manage with this one.
The issue seems to be that the HTTP response does not have a status code (it gets set to nil and thus the comparison to 401 fails). So the 401 here is not the actual status code you receive, but one we compare it to.
Maybe it times out? How long does it take for the command to fail?
Double check that jiralib2-url
is set correctly. You can also check with a browser whether you can access http[s]://your.jira.url.com/rest/auth/1/session
(first login to JIRA normally so that you get an active session cookie). You should receive json similar to this:
{
"self": "https://your.jira.url.com/rest/api/latest/user?username=myusername",
"name": "myusername",
"loginInfo": {
"failedLoginCount": 53,
"loginCount": 4903,
"lastFailedLoginTime": "2018-08-21T13:28:42.504+0300",
"previousLoginTime": "2018-09-18T17:37:19.320+0300"
}
}
If that does not work, your JIRA instance might have REST api disabled, ask your administrator.
Edit: FYI, I was able to reproduce the same error by making my jiralib2-url
invalid. I will add a proper error message there. Also, it most likely rules out timeout, so my advice would be to get the rest call working with browser, then setting jiralib2-url
based on that. In this example the value would be "https://your.jira.url.com"
.
hmm ... strange ...
I login in my browser to jira and go to https://jiraurl.com/rest/auth/1/session
and i get
{
"self":"https://jiraurl.com/rest/api/latest/user?username=demo",
"name":"demo",
"loginInfo":{
"failedLoginCount":11,
"loginCount":216,
"lastFailedLoginTime":"2018-08-08T10:37:21.984+0200",
"previousLoginTime":"2018-09-19T08:54:54.522+0200"
}
}
but in my init.el jiralib2-url
is set to https://jiraurl.com
and jirallib2-user-login-name
is demo
(emacs asks me for the password when prompting (demo)
so i think it is correctly set. Does it help if I try the REST requests via an external tool (i have Postman) and look at the responses? Which requests are done in ejira-update-issues-in-active-sprint
?
The password is asked before the actual request is made so it is not a quarantee that the login was successful.
Easy way to check if the login works is to evaluate (jiralib2-session-login "demo" "demo's password")
. That should save a session token in *JIRA-SESSION*
-global variable. It's value is JSESSIONID=<the session cookie>
after a successful login.
ejira-update-issues-in-active-sprint
first does a login call if no session variable is found, then it fetches the active sprint information by doing a POST request to /rest/api/2/search
with the data:
{
"jql": "project in (<ejira-main-project>) and sprint in openSprints()",
"maxResults": 100
}
Parentesis around the <ejira-main-project>
are required, as it is a list.
If an active sprint is found and it is successfully parsed, then it tries to fetch the actual issue data.
You can also pull the newest changes I made yesterday, it should give a bit better error messages for failed API calls.
Well *JIRA-SESSION*
seems to be set to "JSESSIONID=46C...."
so this part is fine.
You can then try the /rest/api/2/search
with Postman.
The request is POST
and the headers you need are:
Content-Type: application/json
cookie: JSESSIONID=46C...
The cookie expires in a short while, so you most likely need to renew it by calling jiralib2-session-login
again.
You can try with several search queries: {"jql": "project in (DRS)", "maxResults": 30}
should just give you 30 tickets in the given project. Then, you can try adding the and sprint in openSprints()
-clause to see if that is the reason for the error.
Hi,
Also trying to get this working. I'm stucked with the installation. Followed the readme, however seems that the package cannot be loaded.
Simply cloned the repo and tried to initialize with the use-package
(use-package ejira :load-path "~/.emacs.d/local-pkg/ejira" :ensure nil)
And I'm getting the following error:
Error (use-package): ejira/:catch: Cannot open load file: No such file or directory, language-detection
language-detection.el is required by ejira. You can install it from melpa. Other dependencies are ox-jira, s, cl-lib and request.
Already solved. Was a bug on my configuration! Great work.
How does one find out what the custom fields should be?
The way I did it was to pull the json of one of the tickets from the rest api with Postman and then manually check what is the name of the field containing the desired information, for example the epic key.
I don't know if there is a way to extract this mapping directly from the API.
your project looks very promising, but i dont know if i did something wrong or just our jira is messed up.
i added cloned your repo under ~/.emacs.d and added to my init.el under ~/.emacs.d
(add-to-list 'load-path "https://ourjira.com")
Then i continued with the setq-part from your example config followed by require 'ejira and 'org-agenda
At the beginning there were some errors because of missing packages (e.g. language-detection) but now there are no errors at the start of emacs. With M-x i am able to enable ejira-mode (when i'm in an org-file) but then i dont see the point, how to start?