mirror of
https://github.com/Threnklyn/jira.git
synced 2026-05-18 20:23:28 +02:00
301 lines
14 KiB
Markdown
301 lines
14 KiB
Markdown
[](https://gitter.im/go-jira-cli/help?utm_source=badge&utm_medium=badge&utm_content=badge)
|
|
[](https://travis-ci.org/Netflix-Skunkworks/go-jira)
|
|
[](https://godoc.org/gopkg.in/Netflix-Skunkworks/go-jira.v0)
|
|
|
|
|
|
# go-jira
|
|
simple command line client for Atlassian's Jira service written in Go
|
|
|
|
## Synopsis
|
|
|
|
```bash
|
|
jira ls -p GOJIRA # list all unresolved issues for project GOJRIA
|
|
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 overirdes 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](https://github.com/Netflix-Skunkworks/go-jira/releases).
|
|
|
|
## Build
|
|
|
|
* **NOTE** You will need **`go-1.4.1`** minimum
|
|
|
|
* To build the `jira` binary the current directory just run:
|
|
```bash
|
|
make
|
|
```
|
|
* To install the binary to you ~/bin directory you can run:
|
|
```bash
|
|
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 heirarchy 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:
|
|
|
|
```bash
|
|
mkdir ~/.jira.d
|
|
|
|
cat <<EOM >~/.jira.d/config.yml
|
|
endpoint: https://jira.mycompany.com
|
|
EOM
|
|
```
|
|
|
|
Then use `jira login` to authenticate yourself.
|
|
|
|
### 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:
|
|
|
|
```sh
|
|
#!/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:
|
|
|
|
```sh
|
|
#!/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](https://golang.org/pkg/text/template/), and there is a good primer document [here](https://gohugo.io/templates/go-templates/). `go-jira` also provides a few extra helper functions to make it a bit easlier to format the data, those functions are defined [here](https://github.com/Netflix-Skunkworks/go-jira/blob/master/util.go#L133).
|
|
|
|
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](https://github.com/tmc/keyring)). To integrate `go-jira` with a supported keyring just add this configuration to `$HOME/.jira.d/config.yml`:
|
|
```yaml
|
|
password-source: keyring
|
|
```
|
|
|
|
#### `pass` password source
|
|
**Note: Version 0.1.9 required.**
|
|
An alternative to the keyring password source is the `pass` tool (documentation [here](https://www.passwordstore.org/). 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 integrtaion is that `pass` can be used on more platforms than OSX and Linux. To use `pass` for password storage and retrieval via `go-jira` just add this configuration to `$HOME/.jira.d/config.yml`:
|
|
```yaml
|
|
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`
|
|
```bash
|
|
if [ ! -f $HOME/.gpg-agent-info ]; then
|
|
# set passphrase cache so I only have to type my passphrase once a day
|
|
gpg-agent --default-cache-ttl 86400 --daemon --write-env-file $HOME/.gpg-agent-info
|
|
fi
|
|
. $HOME/.gpg-agent-info
|
|
export GPG_AGENT_INFO
|
|
```
|
|
|
|
|
|
## 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)
|
|
```
|