Automating JIRA operations via wget

As JIRA is a web application, it is generally possible to construct a URL which will trigger an operation, such as creating or commenting on an issue. This is often a simple alternative to SOAP or XML-RPC.

For example, To create a Bug in the 'TST' project on jira.atlassian.com, click on:

http://jira.atlassian.com/secure/CreateIssueDetails.jspa?pid=10420&issuetype=1&summary=My+Test+Issue&os_username=soaptester&os_password=soaptester

This URL contains various parameters (pid, issuetype, summary) that are either hidden or submitted in HTML forms. Here is another variant, setting a custom field, but not submitting the form (ie. prepopulating a field):

http://jira.atlassian.com/secure/CreateIssueDetails.jspa?pid=10420&issuetype=1&customfield_10010=hooray

So the task is to discover exactly what parameters are required for a particular operation.

Discovering HTTP parameters

HTTP parameters are most easily discovered with the LiveHTTPHeaders plugin for Firefox.
Install this plugin, and then navigate to the point before the operation you're interested in (eg. Step 2 in the issue creation process). Now open the LiveHTTPHeaders window, and submit the JIRA form to proceed with the operation. In the LiveHTTPHeaders window you will see the HTTP POST operation:

POST /secure/CreateIssueDetails.jspa HTTP/1.1
Host: jira.atlassian.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20060918 Firefox/2.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://jira.atlassian.com/secure/CreateIssue.jspa
Cookie: jira.conglomerate.cookie=navigator.filter.subheading.workratio=0; jira.conglomerate.cookie=;JSESSIONID=aWtQgyV8UTO9JioJG-; s_cc=true; s_sq=%5B%5BB%5D%5D
Content-Type: multipart/form-data; boundary=---------------------------20848862422003718001775908787
Content-Length: 2665
-----------------------------20848862422003718001775908787
Content-Disposition: form-data; name="summary"

My test issue
-----------------------------20848862422003718001775908787
Content-Disposition: form-data; name="description"

Test description
.....
-----------------------------2084886242200378001775908787

Content-Disposition: form-data; name="customfield_10061:1"

10104
-----------------------------20848862422003718001775908787
Content-Disposition: form-data; name="customfield_10170"


-----------------------------20848862422003718001775908787
Content-Disposition: form-data; name="pid"

10420
-----------------------------20848862422003718001775908787
Content-Disposition: form-data; name="issuetype"

1
-----------------------------20848862422003718001775908787
Content-Disposition: form-data; name="Create"

Create
-----------------------------20848862422003718001775908787--

From this, get the POST header URL:

/secure/CreateIssueDetails.jspa

then find the section for each field you're interested in, and construct a name:value pair for it, eg:

pid=10420
issuetype=1
summary=My test issue
description=Test description

Now construct a full URL, separating the URL from the parameters with '?', and each parameter from others with '&':

http://jira.atlassian.com/secure/CreateIssueDetails.jspa?pid=10420&issuetype=1&summary=My test issue&description=Test description

Finally, append the special os_username and os_password
parameters, which will log you in as a user to perform the operation:

http://jira.atlassian.com/secure/CreateIssueDetails.jspa?pid=10420&issuetype=1&summary=My test issue&description=Test description&os_username=soaptester&os_password=soaptester

You can automate the submission of a URL like this with command-line
tools like wget or curl.

Scripting multi-stage operations

Some operations in JIRA require the accumulation of server-side state (in the user's session), and span multiple page requests. For this, you will need to store and reuse a cookie to tie multiple requests together.

With wget, this can be done as follows:

justin@asahi ~
$ wget --save-cookies cookies.txt --post-data 'os_username=justin&os_password=XXXX&os_cookie=true' http://localhost:8090/jira/login.jsp

This command perform the initial request to log you into your JIRA instance and also create a file in your home directory called cookies.txt.

So for any further requests you just need to reference the cookies.txt file and use a normal URL without appending any user details:

justin@asahi ~
$ wget --load-cookies cookies.txt -p http://localhost:8090/jira/browse/WEB-3

Uploading file attachments

The simplest way to upload an attachment from the command-line is with curl (though I'm sure it's possible with wget too). Assuming you want to upload a file test.txt to JIRA at http://localhost:8080, you'd run:

curl 'http://localhost:8080/secure/AttachFile.jspa?id=10000&os_username=test&os_password=test' -F filename.1=@small.txt

The issue ID (10000) can be discovered by looking at the URLs for operations on the JIRA issue (comment, assign etc).

Bulk adding custom field options

If you need to add a lot of custom field options:

This operation can be easily scripted. Use LiveHTTPHeaders to analyse one submission:

POST /secure/admin/EditCustomFieldOptions!add.jspa HTTP/1.1

Host: localhost:8080

.....

Content-Type: application/x-www-form-urlencoded

Content-Length: 87

addValue=second&fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&Add=Add

So the URL is:

/secure/admin/EditCustomFieldOptions!add.jspa?
addValue=second&fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&Add=Add

Prepending the hostname, appending authentication parameters and moving the value to the end gives:

http://localhost:8080/secure/admin/EditCustomFieldOptions!add.jspa?fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&os_username=test&os_password=test&addValue=second

So now we can add a third value from the command-line:

$ wget -q 'http://localhost:8080/secure/admin/EditCustomFieldOptions!add.jspa?fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&os_username=test&os_password=test&addValue=third'

or even bulk add options from a file or script:

$ for user in `cat /etc/passwd | cut -d: -f1`; do
wget -q 'http://localhost:8080/secure/admin/EditCustomFieldOptions!add.jspa?fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&os_username=test&os_password=test&addValue='$user
done

Labels

 
(None)
  1. Jun 08, 2007

    Richard Sargent says:

    I see examples for creating an issue, but not for updating one. I have tried to ...

    I see examples for creating an issue, but not for updating one. I have tried to do so, based on what I can glean, but it just doesn't give the results I desire. Can anyone tell me what I have missed?

    Specifically, I use the following URL to attempt to set a custom field:

    http://someserver:8080/secure/EditIssue.jspa?Update=Update&customfield_10354=Waived&id=28831&os_username=rsargent&os_password=XXXXXXXX

    I get the EditIssue.jspa page back (some 400 Kb of HTML). Which shows my update to the custom field, but it has not been committed. Is this one of those tasks that require cookies and a two stage process?

    Any advice on making this work would be appreciated.

    BTW, I am not using a command line program like WGET. I am sending the HTTP request programmatically and reading the reply programmatically as well.

  2. Aug 07, 2007

    Eric Rawlins says:

    I was able to use this successfully to Add and Remove values from custom fields,...

    I was able to use this successfully to Add and Remove values from custom fields, as well as sort the new values alphabetically. This was implemented as part of a solution to synchronize a custom field list programatically with an external database. Code must still be written to determine additions/deletions between JIRA and the other values, and the jira database must be queried to get customfieldoption ID's, but if all those exist here are the commands I used, as an FYI:

    Adding a Value
    http://server/secure/admin/EditCustomFieldOptions!add.jspa?addValue=NEWVALUE_TEST&fieldConfigId=10270&os_username=username?os_password=password?Add=Add

    Delete a Value
    http://server/secure/admin/EditCustomFieldOptions!remove.jspa?fieldConfigId=10270&selectedValue=26460&confirm=true&Delete=Delete&os_username=username?os_password=password

    Sort Alphabetically
    http://server/secure/admin/EditCustomFieldOptions!sort.jspa?fieldConfigId=10270&os_username=username?os_password=password

  3. Dec 27, 2007

    Chris Kohlhardt says:

    Here is a php example for logging into jira and creating an issue: curl = cur...

    Here is a php example for logging into jira and creating an issue:

    curl = curl_init();
    $loginUrl = "http://localhost/login.jsp?os_username=" . $username . "&os_password=" . $password . "&os_cookie=true";;
    curl_setopt($curl,CURLOPT_URL, $loginUrl );
    curl_setopt($curl,CURLOPT_POST, true );
    curl_setopt($curl,CURLOPT_COOKIEFILE, '/tmp/cookie' );
    curl_setopt($curl,CURLOPT_COOKIEJAR, '/tmp/cookiejar' );
    curl_setopt($curl,CURLOPT_RETURNTRANSFER, true );
    curl_setopt($curl,CURLOPT_FOLLOWLOCATION, false );
    curl_setopt($curl,CURLOPT_NOBODY, true );         
    curl_setopt($curl,CURLOPT_MUTE,true );
    curl_exec( $curl );
    
    curl_setopt($curl,CURLOPT_RETURNTRANSFER, false );
    curl_setopt($curl,CURLOPT_URL, "http://localhost/secure/CreateIssueDetails.jspa?pid=12345&issuetype=1&summary=foo&assignee=" . $project->lead . "&reporter=" .$soapUsername . "&security=10003" ); 
    curl_exec( $curl );
    curl_close( $curl );