/go-jira

simple jira command line client in Go

Primary LanguageGoApache License 2.0Apache-2.0

Join the chat at https://gitter.im/go-jira-cli/help Build Status GoDoc

go-jira

simple command line client for Atlassian's Jira service written in Go

Synopsis

jira ls -p GOJIRA                       # list all unresolved issues for project GOJIRA
jira ls -p GOJIRA -a mothra             # as above also assigned to user mothra
jira ls -p GOJIRA -w mothra             # lists GOJIRA unresolved issues watched by user mothra
jira ls -p GOJIRA -r mothra             # list GOJIRA unresolved issues reported by user mothra
jira ls -t table -p GOJIRA              # list all unresolved issues in pretty table output

jira view GOJIRA-321                    # print Issue using "view" template
jira GOJIRA-321                         # same as above

jira edit GOJIRA-321                    # open up the issue in an editor, when you exit the
                                        # editor the issue will post the updates to the server

# edit the issue, using the overrides on the command line, skip the interactive editor:
jira edit GOJIRA-321 --noedit \
     -o assignee=mothra \
     -o comment="mothra, please take care of this." \
     -o priority=Major

jira create -p GOJIRA                   # create new "Bug" type issue for project GOJIRA
jira create -p GOJIRA -i Task           # create new Task type issue

jira trans close GOJIRA-321             # close issue, with interactive editor to set fields
jira close GOJIRA-321 --edit            # same as above

# close the issue, set the resolution, and skip interactive editor:
jira trans close GOJIRA-321 -o resolution="Won't Fix" --noedit
# same as above
jira close GOJIRA-321 -o resolution="Won't Fix"

jira reopen GOJIRA-321 -m "reopening"  # reopen issue

jira watch GOJIRA-321                   # add self as watcher to the issue

jira comment GOJIRA-321 -m "done yet?"  # add comment to the issue

jira take GOJIRA-321                    # assign issue to self

jira give GOJIRA-321 mothra             # assign issue to user mothra

# create local project config to set defaults
mkdir .jira.d
echo "project: GOJIRA" > .jira.d/config.yml

jira ls                                 # list all unresolved issues for project GOJRIA
jira ls -a mothra                       # as above also assigned to user mothra
jira ls -w mothra                       # lists GOJIRA unresolved issues watched by user mothra
jira ls -r mothra                       # list GOJIRA unresolved issues reported by user mothra
jira ls -t table                        # list all unresolved issues in pretty table output

jira create                             # create new "Bug" type issue for project GOJIRA
jira create -i Task                     # create new Task type issue

# make the table template your default "list" template:
jira export-templates -t table
mv $HOME/.jira.d/templates/table $HOME/.jira.d/templates/list

Download

You can download one of the pre-built binaries for go-jira here.

Build

  • NOTE You will need go-1.4.1 minimum

  • To build the jira binary the current directory just run:

make
  • To install the binary to you ~/bin directory you can run:
make install

Configuration

go-jira uses a configuration hierarchy. When loading the configuration from disk it will recursively look through all parent directories in your current path looking for a .jira.d directory. If your current directory is not a child directory of your homedir, then your homedir will also be inspected for a .jira.d directory. From all of .jira.d directories discovered go-jira will load a config.yml if found. The configuration properties found in a file closests to your current working directory will have precedence. Properties overriden with command line options will have final precedence.

The complicated configuration hierarchy is used because go-jira attempts to be context aware. For example, if you are working on a "foo" project and you cd into your project workspace, wouldn't it be nice if jira ls automatically knew to list only issues related to the "foo" project? Likewise when you cd to the "bar" project then jira ls should only list issues related to "bar" project. You can do this with by creating a configuration under your project workspace at ./.jira.d/config.yml that looks like:

project: foo

You will need to specify your local jira endpoint first, typically in your homedir like:

mkdir ~/.jira.d

cat <<EOM >~/.jira.d/config.yml
endpoint: https://jira.mycompany.com
EOM

Then use jira login to authenticate yourself as $USER. To change your username, use the -u CLI flag or set user: in your config.yml

Dynamic Configuration

If the .jira.d/config.yml file is executable, then go-jira will attempt to execute the file and use the stdout for configuration. You can use this to customize templates or other overrides depending on what type of operation you are running. For example if you would like to use the "table" template when ever you run jira ls, then you can create a template like this:

#!/bin/sh

echo "endpoint: https://jira.mycompany.com"
echo "editor: emacs -nw"

case $JIRA_OPERATION in 
    list)
      echo "template: table";;
esac

Or if you always set the same overrides when you create an issue for your project you can do something like this:

#!/bin/sh
echo "project: GOJIRA"

case $JIRA_OPERATION in
    create)
        echo "assignee: $USER"
        echo "watchers: mothra"
        ;;
esac

Editing

When you run command like jira edit it will open up your favorite editor with the templatized output so you can quickly edit. When the editor closes go-jira will submit the completed form. The order which go-jira attempts to determine your prefered editor is:

  • editor property in any config.yml file
  • JIRA_EDITOR environment variable
  • EDITOR environment variable
  • vim

Templates

go-jira has the ability to customize most output (and editor input) via templates. There are default templates available for all operations, which may or may not work for your actual jira implementation. Jira is endlessly customizable, so it is hard to provide default templates that will work for all issue types.

When running a command like jira edit it will look through the current directory hierarchy trying to find a file that matches .jira.d/templates/edit, if found it will use that file as the template, otherwise it will use the default edit template hard-coded into go-jira. You can export the default hard-coded templates with jira export-templates which will write them to ~/.jira.d/templates/.

Writing/Editing Templates

First the basic templating functionality is defined by the Go language 'text/template' library. The library reference documentation can be found here, and there is a good primer document here. go-jira also provides a few extra helper functions to make it a bit easlier to format the data, those functions are defined here.

Knowing what data and fields are available to any given template is not obvious. The easiest approach to determine what is available is to use the debug template on any given operation. For eample to find out what is available to the "view" templates, you can use:

jira view GOJIRA-321 -t debug

This will print out the data in JSON format that is available to the template. You can do this for any other operation, like "list":

jira list -t debug

Figuring out what is available to input templates (like for the create operation) is a bit more tricky, but similar. To find the data available for a create template you can run:

jira create --dryrun -t debug --editor /bin/cat

This will attempt to fetch metadata for your default project (you can provide any options that you would normally specify for the create operation). It uses the --dryrun option to prevent any actual updates being sent to Jira. The -t debug is like before to cause the input to be serialized to JSON and printed for your inspection. Finally the --editor /bin/cat will cause go-jira to just print the template rather than open up an editor and wait for you to edit/save it.

Authentication

By default go-jira will prompt for a password automatically when we receive an 403 http response. Then after authentication we cache the JSESSSION cookie returned by the service and reuse that on subsequent requests. Typically this cookie will be valid for several hours (depending on the service configuration). Many deployments of Jira (like the cloud services on atlassian.net) have "websudo" enabled which will prevent the cookie based authentcation from working. On these deployments you have a few options with go-jira. You can enable a password-source via .jira.d/config.yml with possible values of keyring or pass.

keyring password source

Note: Version 0.1.9 required. On OSX and Linux there are a few keyring providers that go-jira can use (via this golang module). To integrate go-jira with a supported keyring just add this configuration to $HOME/.jira.d/config.yml:

password-source: keyring

After setting this and issuing a jira login, your credentials will be stored in your platform's backend (e.g. Keychain for Mac OS X) automatically. Subsequent operations, like a jira ls, should "just work" from there.

pass password source

Note: Version 0.1.9 required. An alternative to the keyring password source is the pass tool (documentation here). This uses gpg to encrypt/decrypt passwords on demand and by using gpg-agent you can cache the gpg credentials for a period of time so you will not be prompted repeatedly for decrypting the passwords. The advantage over the keyring integration is that pass can be used on more platforms than OSX and Linux, although it does require more setup. To use pass for password storage and retrieval via go-jira just add this configuration to $HOME/.jira.d/config.yml:

password-source: pass

This assumes you have already setup pass correctly on your system. Specifically you will need to have created a gpg key like this:

$ gpg --gen-key

Then you will need the GPG Key ID you want associated with pass. First list the available keys:

$ gpg --list-keys
/home/gojira/.gnupg/pubring.gpg
-------------------------------------------------
pub   2048R/A307D709 2016-12-18
uid                  Go Jira <gojira@example.com>
sub   2048R/F9A047B8 2016-12-18

Then initialize the pass tool to use the correct key:

$ pass init "Go Jira <gojira@example.com>"

You probably want to setup gpg-agent so that you dont have to type in your gpg passphrase all the time. You can get gpg-agent to automatically start by adding something like this to your $HOME/.bashrc

if [ -f $HOME/.gpg-agent-info ]; then
    . $HOME/.gpg-agent-info
    export GPG_AGENT_INFO
fi
# verify sock file from GPG_AGENT_INFO is actually present
if [ ! -S "${GPG_AGENT_INFO%%:*}" ]; then
    # set passphrase cache so I only have to type my passphrase once a day
    eval $(gpg-agent --default-cache-ttl 604800 --daemon --write-env-file $HOME/.gpg-agent-info)
fi
export GPG_TTY=$(tty)

Usage

Usage:
  jira (ls|list) <Query Options> 
  jira view ISSUE
  jira edit [--noedit] <Edit Options> [ISSUE | <Query Options>]
  jira create [--noedit] [-p PROJECT] <Create Options>
  jira DUPLICATE dups ISSUE
  jira BLOCKER blocks ISSUE
  jira watch ISSUE [-w WATCHER]
  jira (trans|transition) TRANSITION ISSUE [--noedit] <Edit Options>
  jira ack ISSUE [--edit] <Edit Options>
  jira close ISSUE [--edit] <Edit Options>
  jira resolve ISSUE [--edit] <Edit Options>
  jira reopen ISSUE [--edit] <Edit Options>
  jira start ISSUE [--edit] <Edit Options>
  jira stop ISSUE [--edit] <Edit Options>
  jira comment ISSUE [--noedit] <Edit Options>
  jira take ISSUE
  jira (assign|give) ISSUE ASSIGNEE
  jira fields
  jira issuelinktypes
  jira transmeta ISSUE
  jira editmeta ISSUE
  jira issuetypes [-p PROJECT] 
  jira createmeta [-p PROJECT] [-i ISSUETYPE] 
  jira transitions ISSUE
  jira export-templates [-d DIR] [-t template]
  jira (b|browse) ISSUE
  jira login
  jira ISSUE

General Options:
  -b --browse         Open your browser to the Jira issue
  -e --endpoint=URI   URI to use for jira
  -h --help           Show this usage
  -t --template=FILE  Template file to use for output/editing
  -u --user=USER      Username to use for authentication (default: $USER)
  -v --verbose        Increase output logging

Query Options:
  -a --assignee=USER        Username assigned the issue
  -c --component=COMPONENT  Component to Search for
  -f --queryfields=FIELDS   Fields that are used in "list" template: (default: summary,created,updated,priority,status,reporter,assignee)
  -i --issuetype=ISSUETYPE  The Issue Type
  -l --limit=VAL            Maximum number of results to return in query (default: 500)
  -p --project=PROJECT      Project to Search for
  -q --query=JQL            Jira Query Language expression for the search
  -r --reporter=USER        Reporter to search for
  -s --sort=ORDER           For list operations, sort issues (default: priority asc, created)
  -w --watcher=USER         Watcher to add to issue (default: $USER)
                            or Watcher to search for

Edit Options:
  -m --comment=COMMENT      Comment message for transition
  -o --override=KEY=VAL     Set custom key/value pairs

Create Options:
  -i --issuetype=ISSUETYPE  Jira Issue Type (default: Bug)
  -m --comment=COMMENT      Comment message for transition
  -o --override=KEY=VAL     Set custom key/value pairs

Command Options:
  -d --directory=DIR        Directory to export templates to (default: $HOME/.jira.d/templates)