Compare commits

...

45 Commits

Author SHA1 Message Date
Cory Bennett 1f33400288 Updated Changelog 2016-08-12 13:32:13 -07:00
Cory Bennett 37332354b7 ignore t/.jira.d/templates which are exported in 000setup.t 2016-08-12 13:31:16 -07:00
Cory Bennett 7530b309e2 add tests for "Task Management" type projects 2016-08-12 13:30:24 -07:00
Cory Bennett e93bf71fea add tests for "Process Management" type projects 2016-08-12 13:29:56 -07:00
Cory Bennett d022f0ad70 add tests for "Project Management" type projects 2016-08-12 13:29:01 -07:00
Cory Bennett 4d5076230c when running "dups" on a Process Management Project type, you have to start/stop the task to resolve it 2016-08-12 13:27:51 -07:00
Cory Bennett 3cbd2f85a4 allow for defaultResolution option for transition command 2016-08-12 12:13:37 -07:00
Cory Bennett 970876851b add tests for Kanban Software Project type issues 2016-08-10 10:52:45 -07:00
Cory Bennett f74c45d7d7 add tests for Scrum Software Project type issues 2016-08-10 10:52:17 -07:00
Cory Bennett 4e7e52288d add test for Basic Software Project type issues 2016-08-10 10:51:55 -07:00
Cory Bennett 63f41e5e88 add comments 2016-08-10 10:50:04 -07:00
Cory Bennett dbf6a5a265 add extra "mojira" user for testing voting and ownership reassignment 2016-08-10 10:49:11 -07:00
Cory Bennett b2056be287 add "backlog" command for Kanban related Issues 2016-08-10 10:48:02 -07:00
Cory Bennett 6beb941d82 fix --noedit flag with "dups" command 2016-08-09 23:51:04 -07:00
Cory Bennett b297d5a4ef add "votes" and "labels" to default view template 2016-08-09 23:48:28 -07:00
Cory Bennett bf7f38de87 gofmt 2016-08-09 23:16:41 -07:00
Cory Bennett f7ed1ed8d8 gofmt 2016-08-09 23:16:20 -07:00
Cory Bennett 280c0f24b3 add "blockerType" config param, for issueLinkType use for "blocks" command 2016-08-09 23:09:31 -07:00
Cory Bennett 6e296052f5 add "debug" make target 2016-08-09 23:06:46 -07:00
Cory Bennett 189b0d252c update gitter room 2016-08-08 00:10:04 -07:00
Cory Bennett 0e453a45d3 fix typo 2016-08-05 13:11:31 -07:00
Cory Bennett 179596ff12 add gitter badge 2016-08-05 13:09:17 -07:00
Cory Bennett 50bac02419 make the bootstrapping simpler, move more setup to 000setup.t 2016-08-04 11:11:03 -07:00
Cory Bennett 4b7e24a199 fix links 2016-08-03 09:58:00 -07:00
Cory Bennett b9bf8455bd mention osht for testing 2016-08-03 09:56:54 -07:00
Cory Bennett 9111231545 start adding some basic integration tests 2016-08-03 00:13:53 -07:00
Cory Bennett 986528d4ea default issuetype to "Bug" for project that have Bug, otherwise try "Task" 2016-08-03 00:09:09 -07:00
Cory Bennett 9c1f028be2 make view template only show fields that have values 2016-08-02 23:16:08 -07:00
Cory Bennett e3c5051e5e make default create template only display fields if they are valid fields for the project 2016-08-02 22:44:24 -07:00
Cory Bennett 580ea50b37 ignore empty json fields when processing templates 2016-08-02 22:36:51 -07:00
Cory Bennett be31acde65 allow JIRA_LOG_FORMAT env variable to control log output format 2016-08-02 20:12:30 -07:00
Cory Bennett a2f8b7ef65 remove extraneous debug 2016-08-02 20:06:40 -07:00
Cory Bennett c28d46fe8f add logout command
modify password prompt to echo masked password
2016-08-02 20:04:11 -07:00
Cory Bennett 108a5b4976 tweak cookies to store hostname
dump all http request/response with --verbose
2016-08-02 19:23:24 -07:00
Cory Bennett e3d11357e1 load configs in order of closest to cwd (/etc/go-jira.yml is last) 2016-08-02 19:20:23 -07:00
Cory Bennett dfb10740f5 [#48] fix quoting for "make install" so it actually installs to homedir 2016-08-01 11:31:06 -07:00
Cory Bennett adc08935b4 Updated Changelog 2016-07-30 20:13:00 -07:00
Cory Bennett 073c8a3694 [#43] add support for jira done|todo|prog commands 2016-07-30 20:05:13 -07:00
Cory Bennett c4a31a498e [issue #46] add documentation for how to create/edit templates 2016-07-08 12:12:02 -07:00
coryb bcad37089a Merge pull request #24 from mikepea/edit_template_common
Reporter is not generally editable.
2016-06-30 08:53:34 -07:00
Cory Bennett b2ba8de15d Updated Changelog 2016-06-29 23:11:04 -07:00
Cory Bennett 6016bda571 [#44] Close tmpfile before rename to work around "The process cannot access the file because it is being used by another process" error on windows. 2016-06-29 23:09:27 -07:00
Cory Bennett 34ca09cf1a trim out unused platforms, we can add then back in on request
publish windows binaries as .exe
2016-06-29 23:08:54 -07:00
Cory Bennett d7fb88ee41 fix for versions with 'v' prefix 2016-06-28 23:07:06 -07:00
Mike Pountney e58625b00c Reporter is not generally editable.
Support the lowest common denominator for default_edit_template, as per #23

`reporter` is not usually editable by unprivileged users. Even if it is left as-is,
the PUT request is trying to update it, resulting in the following error:

    {"errorMessages":[],"errors":{"reporter":"Field 'reporter' cannot be set. It is not on the appropriate screen, or unknown."}}

Commenting out the field leaves the information visible, so is a reasonable compromise.
2016-01-03 22:25:05 -08:00
22 changed files with 3565 additions and 85 deletions
+4 -1
View File
@@ -6,4 +6,7 @@ src/github.com/mgutz/
src/github.com/op/
src/gopkg.in/
jira
jira.exe
jira.exe
schemas/*.json
t/issue.props
t/.jira.d/templates
+28
View File
@@ -1,5 +1,33 @@
# Changelog
## 0.1.4 - 2016-08-12
* when running "dups" on a Process Management Project type, you have to start/stop the task to resolve it [Cory Bennett] [[2c91905](https://github.com/Netflix-Skunkworks/go-jira/commit/2c91905)]
* allow for defaultResolution option for transition command [Cory Bennett] [[a328c2d](https://github.com/Netflix-Skunkworks/go-jira/commit/a328c2d)]
* add "backlog" command for Kanban related Issues [Cory Bennett] [[5d39b23](https://github.com/Netflix-Skunkworks/go-jira/commit/5d39b23)]
* fix --noedit flag with "dups" command [Cory Bennett] [[37c07fa](https://github.com/Netflix-Skunkworks/go-jira/commit/37c07fa)]
* add "votes" and "labels" to default view template [Cory Bennett] [[6f73b8c](https://github.com/Netflix-Skunkworks/go-jira/commit/6f73b8c)]
* add "blockerType" config param, for issueLinkType use for "blocks" command [Cory Bennett] [[30fd301](https://github.com/Netflix-Skunkworks/go-jira/commit/30fd301)]
* update gitter room [Cory Bennett] [[4b822b1](https://github.com/Netflix-Skunkworks/go-jira/commit/4b822b1)]
* default issuetype to "Bug" for project that have Bug, otherwise try "Task" [Cory Bennett] [[0c807b4](https://github.com/Netflix-Skunkworks/go-jira/commit/0c807b4)]
* make view template only show fields that have values [Cory Bennett] [[8238fe8](https://github.com/Netflix-Skunkworks/go-jira/commit/8238fe8)]
* make default create template only display fields if they are valid fields for the project [Cory Bennett] [[adc2ace](https://github.com/Netflix-Skunkworks/go-jira/commit/adc2ace)]
* ignore empty json fields when processing templates [Cory Bennett] [[f5f3e28](https://github.com/Netflix-Skunkworks/go-jira/commit/f5f3e28)]
* allow JIRA_LOG_FORMAT env variable to control log output format [Cory Bennett] [[469def0](https://github.com/Netflix-Skunkworks/go-jira/commit/469def0)]
* remove extraneous debug [Cory Bennett] [[752a94d](https://github.com/Netflix-Skunkworks/go-jira/commit/752a94d)]
* add logout command modify password prompt to echo masked password [Cory Bennett] [[8ad91be](https://github.com/Netflix-Skunkworks/go-jira/commit/8ad91be)]
* tweak cookies to store hostname dump all http request/response with --verbose [Cory Bennett] [[f93fe79](https://github.com/Netflix-Skunkworks/go-jira/commit/f93fe79)]
* load configs in order of closest to cwd (/etc/go-jira.yml is last) [Cory Bennett] [[f54267b](https://github.com/Netflix-Skunkworks/go-jira/commit/f54267b)]
## 0.1.3 - 2016-07-30
* [[#43](https://github.com/Netflix-Skunkworks/go-jira/issues/43)] add support for jira done|todo|prog commands [Cory Bennett] [[dd7d1cc](https://github.com/Netflix-Skunkworks/go-jira/commit/dd7d1cc)]
* Reporter is not generally editable. [Mike Pountney] [[a637b43](https://github.com/Netflix-Skunkworks/go-jira/commit/a637b43)]
## 0.1.2 - 2016-06-29
* [[#44](https://github.com/Netflix-Skunkworks/go-jira/issues/44)] Close tmpfile before rename to work around "The process cannot access the file because it is being used by another process" error on windows. [Cory Bennett] [[0980f8e](https://github.com/Netflix-Skunkworks/go-jira/commit/0980f8e)]
## 0.1.1 - 2016-06-28
* use USERPROFILE instead of HOME for windows, rework paths to use filepath.Join for better cross platform support [Cory Bennett] [[adcedc4](https://github.com/Netflix-Skunkworks/go-jira/commit/adcedc4)]
+16 -11
View File
@@ -1,18 +1,19 @@
PLATFORMS= \
freebsd-386 \
freebsd-amd64 \
freebsd-arm \
linux-386 \
linux-amd64 \
linux-arm \
openbsd-386 \
openbsd-amd64 \
windows-386 \
windows-amd64 \
darwin-386 \
darwin-amd64 \
$(NULL)
# freebsd-386 \
# freebsd-arm \
# linux-arm \
# openbsd-386 \
# openbsd-amd64 \
# darwin-386
NAME=jira
OS=$(shell uname -s)
@@ -33,8 +34,8 @@ DIST=$(CWD)$(SEP)dist
GOBIN ?= $(CWD)
CURVER ?= $(shell [ -d .git ] && git describe --abbrev=0 --tags || grep ^\#\# CHANGELOG.md | awk '{print $$2; exit}')
LDFLAGS:=-X jira.VERSION=$(patsubst v%,%,$(CURVER)) -w
CURVER ?= $(patsubst v%,%,$(shell [ -d .git ] && git describe --abbrev=0 --tags || grep ^\#\# CHANGELOG.md | awk '{print $$2; exit}'))
LDFLAGS:=-X jira.VERSION=$(CURVER) -w
# use make DEBUG=1 and you can get a debuggable golang binary
# see https://github.com/mailgun/godebug
@@ -47,6 +48,9 @@ endif
build: src/github.com/Netflix-Skunkworks/go-jira
$(GOBUILD) -o '$(BIN)' main/main.go
debug:
$(MAKE) DEBUG=1
src/%:
mkdir -p $(@D)
test -L $@ || ln -sf '$(GOPATH)' $@
@@ -65,18 +69,19 @@ all:
echo "Building for $$p"; \
${MAKE} build GOOS=$${p/-*/} GOARCH=$${p/*-/} BIN=$(DIST)/$(NAME)-$$p; \
done
for x in $(DIST)/jira-windows-*; do mv $$x $$x.exe; done
fmt:
gofmt -s -w main/*.go *.go
install:
${MAKE} GOBIN=~/bin build
${MAKE} GOBIN=$$HOME/bin build
NEWVER ?= $(shell echo $(CURVER) | awk -F. '{print $$1"."$$2"."$$3+1}')
TODAY := $(shell date +%Y-%m-%d)
changes:
@git log --pretty=format:"* %s [%cn] [%h]" --no-merges ^$(CURVER) HEAD main/*.go *.go | grep -vE 'gofmt|go fmt'
@git log --pretty=format:"* %s [%cn] [%h]" --no-merges ^v$(CURVER) HEAD main/*.go *.go | grep -vE 'gofmt|go fmt'
update-changelog:
@echo "# Changelog" > CHANGELOG.md.new; \
@@ -92,7 +97,7 @@ update-changelog:
git tag v$(NEWVER)
version:
@echo $(patsubst v%,%,$(CURVER))
@echo $(CURVER)
clean:
rm -rf pkg dist bin src ./$(NAME)
+22
View File
@@ -1,3 +1,5 @@
[![Join the chat at https://gitter.im/go-jira-cli/help](https://badges.gitter.im/go-jira-cli/help.svg)](https://gitter.im/go-jira-cli/help?utm_source=badge&utm_medium=badge&utm_content=badge)
# go-jira
simple command line client for Atlassian's Jira service written in Go
@@ -157,6 +159,26 @@ When running a command like `jira edit` it will look through the current directo
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.
## Usage
```
+58 -19
View File
@@ -11,6 +11,7 @@ import (
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/http/httputil"
"net/url"
"os"
"os/exec"
@@ -66,7 +67,22 @@ func New(opts map[string]interface{}) *Cli {
return cli
}
func (c *Cli) saveCookies(cookies []*http.Cookie) {
func (c *Cli) saveCookies(resp *http.Response) {
if _, ok := resp.Header["Set-Cookie"]; !ok {
return
}
cookies := resp.Cookies()
for _, cookie := range cookies {
if cookie.Domain == "" {
// if it is host:port then we need to split off port
parts := strings.Split(resp.Request.URL.Host, ":")
host := parts[0]
log.Debugf("Setting DOMAIN to %s for Cookie: %s", host, cookie)
cookie.Domain = host
}
}
// expiry in one week from now
expiry := time.Now().Add(24 * 7 * time.Hour)
for _, cookie := range cookies {
@@ -76,11 +92,11 @@ func (c *Cli) saveCookies(cookies []*http.Cookie) {
if currentCookies := c.loadCookies(); currentCookies != nil {
currentCookiesByName := make(map[string]*http.Cookie)
for _, cookie := range currentCookies {
currentCookiesByName[cookie.Name] = cookie
currentCookiesByName[cookie.Name+cookie.Domain] = cookie
}
for _, cookie := range cookies {
currentCookiesByName[cookie.Name] = cookie
currentCookiesByName[cookie.Name+cookie.Domain] = cookie
}
mergedCookies := make([]*http.Cookie, 0, len(currentCookiesByName))
@@ -102,14 +118,17 @@ func (c *Cli) loadCookies() []*http.Cookie {
}
if err != nil {
log.Errorf("Failed to open %s: %s", c.cookieFile, err)
os.Exit(1)
panic(err)
}
cookies := make([]*http.Cookie, 0)
err = json.Unmarshal(bytes, &cookies)
if err != nil {
log.Errorf("Failed to parse json from file %s: %s", c.cookieFile, err)
}
log.Debugf("Loading Cookies: %s", cookies)
if os.Getenv("LOG_TRACE") != "" && log.IsEnabledFor(logging.DEBUG) {
log.Debugf("Loading Cookies: %s", cookies)
}
return cookies
}
@@ -144,15 +163,6 @@ func (c *Cli) makeRequestWithContent(method string, uri string, content string)
req, _ := http.NewRequest(method, uri, buffer)
log.Infof("%s %s", req.Method, req.URL.String())
if log.IsEnabledFor(logging.DEBUG) {
logBuffer := bytes.NewBuffer(make([]byte, 0, len(content)))
req.Write(logBuffer)
log.Debugf("%s", logBuffer)
// need to recreate the buffer since the offset is now at the end
// need to be able to rewind the buffer offset, dont know how yet
req, _ = http.NewRequest(method, uri, bytes.NewBufferString(content))
}
if resp, err := c.makeRequest(req); err != nil {
return nil, err
} else {
@@ -190,7 +200,20 @@ func (c *Cli) get(uri string) (*http.Response, error) {
}
func (c *Cli) makeRequest(req *http.Request) (resp *http.Response, err error) {
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
// this is actually done in http.send but doing it
// here so we can log it in DumpRequest for debugging
for _, cookie := range c.ua.Jar.Cookies(req.URL) {
req.AddCookie(cookie)
}
if log.IsEnabledFor(logging.DEBUG) {
out, _ := httputil.DumpRequest(req, true)
log.Debugf("Request: %s", out)
}
if resp, err = c.ua.Do(req); err != nil {
log.Errorf("Failed to %s %s: %s", req.Method, req.URL.String(), err)
return nil, err
@@ -204,9 +227,13 @@ func (c *Cli) makeRequest(req *http.Request) (resp *http.Response, err error) {
})
if _, ok := resp.Header["Set-Cookie"]; ok {
c.saveCookies(resp.Cookies())
c.saveCookies(resp)
}
}
if log.IsEnabledFor(logging.DEBUG) {
out, _ := httputil.DumpResponse(resp, true)
log.Debugf("Response: %s", out)
}
return resp, nil
}
@@ -261,13 +288,25 @@ func (c *Cli) editTemplate(template string, tmpFilePrefix string, templateData m
log.Errorf("Failed to make temp file in %s: %s", tmpdir, err)
return err
}
defer fh.Close()
tmpFileName := fmt.Sprintf("%s.yml", fh.Name())
if err := os.Rename(fh.Name(), tmpFileName); err != nil {
log.Errorf("Failed to rename %s to %s: %s", fh.Name(), fmt.Sprintf("%s.yml", fh.Name()), err)
oldFileName := fh.Name()
tmpFileName := fmt.Sprintf("%s.yml", oldFileName)
// close tmpfile so we can rename on windows
fh.Close()
if err := os.Rename(oldFileName, tmpFileName); err != nil {
log.Errorf("Failed to rename %s to %s: %s", oldFileName, tmpFileName, err)
return err
}
fh, err = os.OpenFile(tmpFileName, os.O_RDWR|os.O_EXCL, 0600)
if err != nil {
log.Errorf("Failed to reopen temp file file in %s: %s", tmpFileName, err)
return err
}
defer fh.Close()
defer func() {
os.Remove(tmpFileName)
}()
+107 -19
View File
@@ -2,11 +2,13 @@ package jira
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"golang.org/x/crypto/ssh/terminal"
"github.com/Netflix-Skunkworks/go-jira/data"
"github.com/howeyc/gopass"
"io/ioutil"
"net/http"
"net/http/httputil"
"net/url"
"os"
"strings"
@@ -19,17 +21,17 @@ func (c *Cli) CmdLogin() error {
req, _ := http.NewRequest("GET", uri, nil)
user, _ := c.opts["user"].(string)
fmt.Printf("Enter Password for %s: ", user)
pwbytes, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
passwd := string(pwbytes)
fmt.Printf("Jira Password [%s]: ", user)
pw, err := gopass.GetPasswdMasked()
if err != nil {
return err
}
passwd := string(pw)
req.SetBasicAuth(user, passwd)
log.Infof("%s %s", req.Method, req.URL.String())
if resp, err := c.makeRequest(req); err != nil {
return err
} else {
out, _ := httputil.DumpResponse(resp, true)
log.Debugf("%s", out)
if resp.StatusCode == 403 {
// probably got this, need to redirect the user to login manually
// X-Authentication-Denied-Reason: CAPTCHA_CHALLENGE; login-url=https://jira/login.jsp
@@ -59,6 +61,24 @@ func (c *Cli) CmdLogin() error {
return nil
}
func (c *Cli) CmdLogout() error {
uri := fmt.Sprintf("%s/rest/auth/1/session", c.endpoint)
req, _ := http.NewRequest("DELETE", uri, nil)
if resp, err := c.makeRequest(req); err != nil {
return err
} else {
if resp.StatusCode == 401 || resp.StatusCode == 204 {
// 401 == no active session
// 204 == successfully logged out
} else {
err := fmt.Errorf("Failed to Logout: %s", err)
return err
}
}
log.Notice("OK")
return nil
}
func (c *Cli) CmdFields() error {
log.Debugf("fields called")
uri := fmt.Sprintf("%s/rest/api/2/field", c.endpoint)
@@ -177,9 +197,41 @@ func (c *Cli) CmdIssueTypes() error {
return runTemplate(c.getTemplate("issuetypes"), data, nil)
}
func (c *Cli) defaultIssueType() string {
project := c.opts["project"].(string)
uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s", c.endpoint, project)
data, _ := responseToJson(c.get(uri))
issueTypeNames := make(map[string]bool)
if data, ok := data.(map[string]interface{}); ok {
if projects, ok := data["projects"].([]interface{}); ok {
for _, project := range projects {
if project, ok := project.(map[string]interface{}); ok {
if issuetypes, ok := project["issuetypes"].([]interface{}); ok {
if len(issuetypes) > 0 {
for _, issuetype := range issuetypes {
issueTypeNames[issuetype.(map[string]interface{})["name"].(string)] = true
}
}
}
}
}
}
}
if _, ok := issueTypeNames["Bug"]; ok {
return "Bug"
} else if _, ok := issueTypeNames["Task"]; ok {
return "Task"
}
return ""
}
func (c *Cli) CmdCreateMeta() error {
project := c.opts["project"].(string)
issuetype := c.getOptString("issuetype", "Bug")
issuetype := c.getOptString("issuetype", "")
if issuetype == "" {
issuetype = c.defaultIssueType()
}
log.Debugf("createMeta called")
uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s&issuetypeNames=%s&expand=projects.issuetypes.fields", c.endpoint, project, url.QueryEscape(issuetype))
@@ -212,8 +264,29 @@ func (c *Cli) CmdComponents(project string) error {
return runTemplate(c.getTemplate("components"), data, nil)
}
func (c *Cli) ValidTransitions(issue string) (jiradata.Transitions, error) {
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/transitions?expand=transitions.fields", c.endpoint, issue)
resp, err := c.get(uri)
if err != nil {
return nil, err
}
transMeta := &jiradata.TransitionsMeta{}
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
err = json.Unmarshal(content, transMeta)
if err != nil {
return nil, err
}
return transMeta.Transitions, nil
}
func (c *Cli) CmdTransitions(issue string) error {
log.Debugf("Transitions called")
// FIXME this should just call ValidTransitions then pass that data to templates
c.Browse(issue)
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/transitions", c.endpoint, issue)
data, err := responseToJson(c.get(uri))
@@ -224,9 +297,12 @@ func (c *Cli) CmdTransitions(issue string) error {
}
func (c *Cli) CmdCreate() error {
project := c.opts["project"].(string)
issuetype := c.getOptString("issuetype", "Bug")
log.Debugf("create called")
project := c.opts["project"].(string)
issuetype := c.getOptString("issuetype", "")
if issuetype == "" {
issuetype = c.defaultIssueType()
}
uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s&issuetypeNames=%s&expand=projects.issuetypes.fields", c.endpoint, project, url.QueryEscape(issuetype))
data, err := responseToJson(c.get(uri))
@@ -260,7 +336,6 @@ func (c *Cli) CmdCreate() error {
fmt.Sprintf("create-%s-", sanitizedType),
issueData,
func(json string) error {
log.Debugf("JSON: %s", json)
uri := fmt.Sprintf("%s/rest/api/2/issue", c.endpoint)
if c.getOptBool("dryrun", false) {
log.Debugf("POST: %s", json)
@@ -316,7 +391,7 @@ func (c *Cli) CmdBlocks(blocker string, issue string) error {
json, err := jsonEncode(map[string]interface{}{
"type": map[string]string{
"name": "Depends", // TODO This is probably not constant across Jira installs
"name": c.GetOptString("blockerType", "Blocks"),
},
"inwardIssue": map[string]string{
"key": issue,
@@ -514,13 +589,11 @@ func (c *Cli) CmdTransition(issue string, trans string) error {
}
if transId == "" {
err := fmt.Errorf("Invalid Transition '%s', Available: %s", trans, strings.Join(found, ", "))
log.Errorf("%s", err)
log.Debugf("%s", err)
return err
}
handlePost := func(json string) error {
log.Debugf("POST: %s", json)
// os.Exit(0)
uri = fmt.Sprintf("%s/rest/api/2/issue/%s/transitions", c.endpoint, issue)
if c.getOptBool("dryrun", false) {
log.Debugf("POST: %s", json)
@@ -554,12 +627,29 @@ func (c *Cli) CmdTransition(issue string, trans string) error {
issueData = data.(map[string]interface{})
}
issueData["meta"] = transMeta
if c.GetOptString("defaultResolution", "") == "" {
// .meta.fields.resolution.allowedValues
if fields, ok := transMeta["fields"].(map[string]interface{}); ok {
if resolution, ok := fields["resolution"].(map[string]interface{}); ok {
if allowedValues, ok := resolution["allowedValues"].([]interface{}); ok {
for _, allowedValueRaw := range allowedValues {
if allowedValues, ok := allowedValueRaw.(map[string]interface{}); ok {
if allowedValues["name"] == "Fixed" {
c.opts["defaultResolution"] = "Fixed"
} else if allowedValues["name"] == "Done" {
c.opts["defaultResolution"] = "Done"
}
}
}
}
}
}
}
issueData["overrides"] = c.opts
issueData["transition"] = map[string]interface{}{
"name": transName,
"id": transId,
}
return c.editTemplate(
c.getTemplate("transition"),
fmt.Sprintf("%s-trans-%s-", issue, trans),
@@ -572,7 +662,6 @@ func (c *Cli) CmdComment(issue string) error {
log.Debugf("comment called")
handlePost := func(json string) error {
log.Debugf("JSON: %s", json)
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/comment", c.endpoint, issue)
if c.getOptBool("dryrun", false) {
log.Debugf("POST: %s", json)
@@ -669,7 +758,6 @@ func (c *Cli) CmdLabels(action string, issue string, labels []string) error {
}
handlePut := func(json string) error {
log.Debugf("JSON: %s", json)
uri := fmt.Sprintf("%s/rest/api/2/issue/%s", c.endpoint, issue)
if c.getOptBool("dryrun", false) {
log.Debugf("PUT: %s", json)
+59 -7
View File
@@ -14,12 +14,16 @@ import (
)
var (
log = logging.MustGetLogger("jira")
format = "%{color}%{time:2006-01-02T15:04:05.000Z07:00} %{level:-5s} [%{shortfile}]%{color:reset} %{message}"
log = logging.MustGetLogger("jira")
defaultFormat = "%{color}%{time:2006-01-02T15:04:05.000Z07:00} %{level:-5s} [%{shortfile}]%{color:reset} %{message}"
)
func main() {
logBackend := logging.NewLogBackend(os.Stderr, "", 0)
format := os.Getenv("JIRA_LOG_FORMAT")
if format == "" {
format = defaultFormat
}
logging.SetBackend(
logging.NewBackendFormatter(
logBackend,
@@ -31,7 +35,7 @@ func main() {
user := os.Getenv("USER")
home := os.Getenv("HOME")
defaultQueryFields := "summary,created,updated,priority,status,reporter,assignee"
defaultSort := "priority asc, created"
defaultSort := "priority asc, key"
defaultMaxResults := 500
usage := func(ok bool) {
@@ -65,6 +69,10 @@ Usage:
jira reopen ISSUE [--edit] <Edit Options>
jira start ISSUE [--edit] <Edit Options>
jira stop ISSUE [--edit] <Edit Options>
jira todo ISSUE [--edit] <Edit Options>
jira backlog ISSUE [--edit] <Edit Options>
jira done ISSUE [--edit] <Edit Options>
jira prog|progress|in-progress [--edit] <Edit Options>
jira comment ISSUE [--noedit] <Edit Options>
jira (set,add,remove) labels ISSUE [LABEL] ...
jira take ISSUE
@@ -81,6 +89,7 @@ Usage:
jira export-templates [-d DIR] [-t template]
jira (b|browse) ISSUE
jira login
jira logout
jira request [-M METHOD] URI [DATA]
jira ISSUE
@@ -140,6 +149,12 @@ Command Options:
"reopen": "reopen",
"start": "start",
"stop": "stop",
"todo": "todo",
"backlog": "backlog",
"done": "done",
"prog": "in-progress",
"progress": "in-progress",
"in-progress": "in-progress",
"comment": "comment",
"label": "labels",
"labels": "labels",
@@ -158,6 +173,7 @@ Command Options:
"export-templates": "export-templates",
"browse": "browse",
"login": "login",
"logout": "logout",
"req": "request",
"request": "request",
"vote": "vote",
@@ -305,6 +321,8 @@ Command Options:
switch command {
case "login":
err = c.CmdLogin()
case "logout":
err = c.CmdLogout()
case "fields":
err = c.CmdFields()
case "list":
@@ -352,10 +370,26 @@ Command Options:
requireArgs(2)
err = c.CmdBlocks(args[0], args[1])
case "dups":
setEditing(true)
requireArgs(2)
if err = c.CmdDups(args[0], args[1]); err == nil {
opts["resolution"] = "Duplicate"
err = c.CmdTransition(args[0], "close")
trans, err := c.ValidTransitions(args[0])
if err == nil {
if trans.Find("close") != nil {
err = c.CmdTransition(args[0], "close")
} else if trans.Find("done") != nil {
// for now just assume if there is no "close", then
// there is a "done" state
err = c.CmdTransition(args[0], "done")
} else if trans.Find("start") != nil {
err = c.CmdTransition(args[0], "start")
if err == nil {
err = c.CmdTransition(args[0], "stop")
}
}
}
}
case "watch":
requireArgs(1)
@@ -390,6 +424,22 @@ Command Options:
requireArgs(1)
setEditing(false)
err = c.CmdTransition(args[0], "stop")
case "todo":
requireArgs(1)
setEditing(false)
err = c.CmdTransition(args[0], "To Do")
case "backlog":
requireArgs(1)
setEditing(false)
err = c.CmdTransition(args[0], "Backlog")
case "done":
requireArgs(1)
setEditing(false)
err = c.CmdTransition(args[0], "Done")
case "in-progress":
requireArgs(1)
setEditing(false)
err = c.CmdTransition(args[0], "Progress")
case "comment":
requireArgs(1)
setEditing(true)
@@ -461,7 +511,9 @@ Command Options:
func parseYaml(file string, opts map[string]interface{}) {
if fh, err := ioutil.ReadFile(file); err == nil {
log.Debugf("Found Config file: %s", file)
yaml.Unmarshal(fh, &opts)
if err := yaml.Unmarshal(fh, &opts); err != nil {
log.Errorf("Unable to parse %s: %s", file, err)
}
}
}
@@ -489,10 +541,10 @@ func loadConfigs(opts map[string]interface{}) {
populateEnv(opts)
paths := jira.FindParentPaths(".jira.d/config.yml")
// prepend
paths = append([]string{"/etc/go-jira.yml"}, paths...)
paths = append(paths, "/etc/go-jira.yml")
// iterate paths in reverse
for i := len(paths) - 1; i >= 0; i-- {
for i := 0; i < len(paths); i++ {
file := paths[i]
if stat, err := os.Stat(file); err == nil {
tmp := make(map[string]interface{})
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env python
from lxml import html
import requests
import json
page = requests.get('https://docs.atlassian.com/jira/REST/cloud')
tree = html.fromstring(page.content)
schemas = tree.xpath("//div[@class='representation-doc-block']//code/text()")
for schema in schemas:
try:
data = json.loads(schema)
if "title" in data:
title = data["title"].replace(" ", "")
print "Writing {}.json".format(title)
with open("{}.json".format(title), 'w') as f:
f.write(schema)
except:
True
+2
View File
@@ -0,0 +1,2 @@
endpoint: http://localhost:8080
user: gojira
Executable
+51
View File
@@ -0,0 +1,51 @@
#!/bin/bash
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira --user admin"
PLAN 15
# clean out any old containers
RUNS sh -c "docker rm -f go-jira-test || true"
# start newt jira service
RUNS docker run --detach --name go-jira-test --publish 8080:8080 go-jira-test:latest
# wait a few seconds for it to bind to port 8080
RUNS sleep 10
# wait for healthchecks to pass, curl will retry 60 times over 1 min waiting
RUNS curl -q -L --retry 60 --retry-delay 1 -f -s "http://localhost:8080/rest/api/2/serverInfo?doHealthCheck=1"
# login to jira as admin user
echo "admin123" | RUNS $jira login
# create gojira user
RUNS $jira req -M POST /rest/api/2/user '{"name":"gojira","password":"gojira123","emailAddress":"gojira@example.com","displayName":"Go Jira"}'
# create mojira user (need secondary user for voting)
RUNS $jira req -M POST /rest/api/2/user '{"name":"mojira","password":"mojira123","emailAddress":"mojira@example.com","displayName":"Mo Jira"}'
# create SCRUM softwareproject
RUNS $jira req -M POST /rest/api/2/project '{"key":"SCRUM","name":"Scrum","projectTypeKey":"software","projectTemplateKey":"com.pyxis.greenhopper.jira:gh-scrum-template","lead":"gojira"}'
# create KANBAN software project
RUNS $jira req -M POST /rest/api/2/project '{"key":"KANBAN","name":"Kanban","projectTypeKey":"software","projectTemplateKey":"com.pyxis.greenhopper.jira:gh-kanban-template","lead":"gojira"}'
# create BAISC software project
RUNS $jira req -M POST /rest/api/2/project '{"key":"BASIC","name":"Basic","projectTypeKey":"software","projectTemplateKey":"com.pyxis.greenhopper.jira:basic-software-development-template","lead":"gojira"}'
# create PROJECT business project
RUNS $jira req -M POST /rest/api/2/project '{"key":"PROJECT","name":"Project","projectTypeKey":"business","projectTemplateKey":"com.atlassian.jira-core-project-templates:jira-core-project-management","lead":"gojira"}'
# create PROCESS business project
RUNS $jira req -M POST /rest/api/2/project '{"key":"PROCESS","name":"Process","projectTypeKey":"business","projectTemplateKey":"com.atlassian.jira-core-project-templates:jira-core-process-management","lead":"gojira"}'
# create TASK business project
RUNS $jira req -M POST /rest/api/2/project '{"key":"TASK","name":"Task","projectTypeKey":"business","projectTemplateKey":"com.atlassian.jira-core-project-templates:jira-core-task-management","lead":"gojira"}'
RUNS $jira logout
# export new templates so we are always using whatever is latest
# and not whatever is in the test-runners homedir
RUNS $jira export-templates -d .jira.d/templates
Executable
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira=../jira
PLAN 7
###############################################################################
## Verify logout works, we expect when we call the session api
## that we will get a 401 and prompt user for password
################################################################################
RUNS $jira logout
NRUNS $jira req /rest/auth/1/session </dev/null
ODIFF <<EOF
Jira Password [gojira]:
EOF
###############################################################################
## Verify login works (password read from stdin) and verify that the
## sesion api no longer prompts
###############################################################################
echo "gojira123" | RUNS $jira login
RUNS $jira req /rest/auth/1/session </dev/null
GREP '"name": "gojira"'
GREP '"self": "http://localhost:8080/rest/api/latest/user?username=gojira"'
Executable
+508
View File
@@ -0,0 +1,508 @@
#!/bin/bash
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira --project BASIC"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
PLAN 84
# cleanup from previous failed test executions
($jira ls | awk -F: '{print $1}' | while read issue; do ../jira done $issue; done) | sed 's/^/# CLEANUP: /g'
# reset login
RUNS $jira logout
echo "gojira123" | RUNS $jira login
###############################################################################
## Create an issue
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## View the issue we just created
###############################################################################
RUNS $jira view $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## List all issues, should be just the one we created
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Try to close the issue, bug Basic projects do not allow that state
###############################################################################
NRUNS $jira close $issue
EDIFF <<EOF
ERROR Invalid Transition 'close', Available: To Do, In Progress, In Review, Done
EOF
###############################################################################
## put the issue into Done state, resolving it.
###############################################################################
RUNS $jira done $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## Verify there are no unresolved issues
###############################################################################
RUNS $jira ls
DIFF <<EOF
EOF
###############################################################################
## Setup 2 more issues so we can test duping
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira create -o summary=dup -o description=dup --noedit --saveFile issue.props
dup=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $dup http://localhost:8080/browse/$dup
EOF
###############################################################################
## Mark issue as duplicate, expect both issues to be updated and when viewing
## the main issue there should be a "depends" line showing the dup'd issue, and
## that issue should be resolved
###############################################################################
RUNS $jira $dup dups $issue --noedit
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
OK $dup http://localhost:8080/browse/$dup
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## We should see only one unresolved issue, the Dup should be resolved
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Setup for testing blocking issues
###############################################################################
RUNS $jira create -o summary=blocks -o description=blocks --noedit --saveFile issue.props
blocker=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set blocker and verify it shows up when viewing the main issue
###############################################################################
RUNS $jira $blocker blocks $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Both issues are unresolved now
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
$(printf %-12s $blocker:) blocks
EOF
###############################################################################
# reset login for mojira for voting
###############################################################################
jira="$jira --user mojira"
RUNS $jira logout
echo "mojira123" | RUNS $jira login
###############################################################################
## vote for main issue, verify it shows when viewing the issue
###############################################################################
RUNS $jira vote $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 1
description: |
description
EOF
###############################################################################
## downvote the main issue, verify the vote count goes back to 0
###############################################################################
RUNS $jira vote $issue --down
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## set mojira user as watcher to issue and verify from REST api
###############################################################################
RUNS $jira watch $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
# FIXME we probably need a watchers command to wrap this?
RUNS sh -c "$jira req /rest/api/2/issue/$issue/watchers | jq -r .watchers[].name"
DIFF <<EOF
gojira
mojira
EOF
###############################################################################
## set issue to In Progress state
###############################################################################
RUNS $jira trans "In Progress" $blocker --noedit
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## set it back to "To Do"
###############################################################################
RUNS $jira todo $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set issue to "In Review" state
###############################################################################
RUNS $jira trans "review" $blocker --noedit
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set it back to "To Do"
###############################################################################
RUNS $jira todo $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set it to "In Progress"
###############################################################################
RUNS $jira prog $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set it to "Done"
###############################################################################
RUNS $jira done $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Verify issue is now in Done state (the "blocker" issue is now Done)
###############################################################################
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[Done]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Verify we can add a comment
###############################################################################
RUNS $jira comment $issue --noedit -m "Yo, Comment"
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[Done]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
comments:
- | # mojira, a minute ago
Yo, Comment
EOF
###############################################################################
## Verify we can add labels to an issue
###############################################################################
RUNS $jira add labels $blocker test-label another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: another-label, test-label
description: |
blocks
EOF
###############################################################################
## Verify we can remove a label
###############################################################################
RUNS $jira remove labels $blocker another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: test-label
description: |
blocks
EOF
###############################################################################
## Verify we can replace the labels with a new set
###############################################################################
RUNS $jira set labels $blocker more-label better-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify that "mojira" user can take the issue (reassign to self)
###############################################################################
RUNS $jira take $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: BASIC
issuetype: Bug
assignee: mojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify we can give the issue back go "gojira" user
###############################################################################
RUNS $jira give $blocker gojira
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: BASIC
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
Executable
+508
View File
@@ -0,0 +1,508 @@
#!/bin/bash
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira --project SCRUM"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
PLAN 84
# cleanup from previous failed test executions
($jira ls | awk -F: '{print $1}' | while read issue; do ../jira done $issue; done) | sed 's/^/# CLEANUP: /g'
# reset login
RUNS $jira logout
echo "gojira123" | RUNS $jira login
###############################################################################
## Create an issue
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## View the issue we just created
###############################################################################
RUNS $jira view $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## List all issues, should be just the one we created
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Try to close the issue, bug Basic projects do not allow that state
###############################################################################
NRUNS $jira close $issue
EDIFF <<EOF
ERROR Invalid Transition 'close', Available: To Do, In Progress, Done
EOF
###############################################################################
## put the issue into Done state, resolving it.
###############################################################################
RUNS $jira done $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## Verify there are no unresolved issues
###############################################################################
RUNS $jira ls
DIFF <<EOF
EOF
###############################################################################
## Setup 2 more issues so we can test duping
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira create -o summary=dup -o description=dup --noedit --saveFile issue.props
dup=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $dup http://localhost:8080/browse/$dup
EOF
###############################################################################
## Mark issue as duplicate, expect both issues to be updated and when viewing
## the main issue there should be a "depends" line showing the dup'd issue, and
## that issue should be resolved
###############################################################################
RUNS $jira $dup dups $issue --noedit
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
OK $dup http://localhost:8080/browse/$dup
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## We should see only one unresolved issue, the Dup should be resolved
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Setup for testing blocking issues
###############################################################################
RUNS $jira create -o summary=blocks -o description=blocks --noedit --saveFile issue.props
blocker=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set blocker and verify it shows up when viewing the main issue
###############################################################################
RUNS $jira $blocker blocks $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Both issues are unresolved now
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
$(printf %-12s $blocker:) blocks
EOF
###############################################################################
# reset login for mojira for voting
###############################################################################
jira="$jira --user mojira"
RUNS $jira logout
echo "mojira123" | RUNS $jira login
###############################################################################
## vote for main issue, verify it shows when viewing the issue
###############################################################################
RUNS $jira vote $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 1
description: |
description
EOF
###############################################################################
## downvote the main issue, verify the vote count goes back to 0
###############################################################################
RUNS $jira vote $issue --down
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## set mojira user as watcher to issue and verify from REST api
###############################################################################
RUNS $jira watch $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
# FIXME we probably need a watchers command to wrap this?
RUNS sh -c "$jira req /rest/api/2/issue/$issue/watchers | jq -r .watchers[].name"
DIFF <<EOF
gojira
mojira
EOF
###############################################################################
## set issue to In Progress state
###############################################################################
RUNS $jira trans "In Progress" $blocker --noedit
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## set it back to "To Do"
###############################################################################
RUNS $jira todo $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set issue to "In Review" state, which is an invalid state for SCRUM
###############################################################################
NRUNS $jira trans "review" $blocker --noedit
DIFF <<EOF
ERROR Invalid Transition 'review', Available: To Do, In Progress, Done
EOF
###############################################################################
## Set it back to "To Do"
###############################################################################
RUNS $jira todo $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set it to "In Progress"
###############################################################################
RUNS $jira prog $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set it to "Done"
###############################################################################
RUNS $jira done $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Verify issue is now in Done state (the "blocker" issue is now Done)
###############################################################################
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[Done]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Verify we can add a comment
###############################################################################
RUNS $jira comment $issue --noedit -m "Yo, Comment"
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[Done]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
comments:
- | # mojira, a minute ago
Yo, Comment
EOF
###############################################################################
## Verify we can add labels to an issue
###############################################################################
RUNS $jira add labels $blocker test-label another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: another-label, test-label
description: |
blocks
EOF
###############################################################################
## Verify we can remove a label
###############################################################################
RUNS $jira remove labels $blocker another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: test-label
description: |
blocks
EOF
###############################################################################
## Verify we can replace the labels with a new set
###############################################################################
RUNS $jira set labels $blocker more-label better-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify that "mojira" user can take the issue (reassign to self)
###############################################################################
RUNS $jira take $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: SCRUM
issuetype: Bug
assignee: mojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify we can give the issue back go "gojira" user
###############################################################################
RUNS $jira give $blocker gojira
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: SCRUM
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
Executable
+517
View File
@@ -0,0 +1,517 @@
#!/bin/bash
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira --project KANBAN"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
PLAN 86
# cleanup from previous failed test executions
($jira ls | awk -F: '{print $1}' | while read issue; do ../jira done $issue; done) | sed 's/^/# CLEANUP: /g'
# reset login
RUNS $jira logout
echo "gojira123" | RUNS $jira login
###############################################################################
## Create an issue
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## View the issue we just created
###############################################################################
RUNS $jira view $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Backlog
summary: summary
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## List all issues, should be just the one we created
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Try to close the issue, bug Basic projects do not allow that state
###############################################################################
NRUNS $jira close $issue
EDIFF <<EOF
ERROR Invalid Transition 'close', Available: Backlog, Selected for Development, In Progress, Done
EOF
###############################################################################
## put the issue into Done state, resolving it.
###############################################################################
RUNS $jira done $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## Verify there are no unresolved issues
###############################################################################
RUNS $jira ls
DIFF <<EOF
EOF
###############################################################################
## Setup 2 more issues so we can test duping
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira create -o summary=dup -o description=dup --noedit --saveFile issue.props
dup=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $dup http://localhost:8080/browse/$dup
EOF
###############################################################################
## Mark issue as duplicate, expect both issues to be updated and when viewing
## the main issue there should be a "depends" line showing the dup'd issue, and
## that issue should be resolved
###############################################################################
RUNS $jira $dup dups $issue --noedit
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
OK $dup http://localhost:8080/browse/$dup
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Backlog
summary: summary
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## We should see only one unresolved issue, the Dup should be resolved
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Setup for testing blocking issues
###############################################################################
RUNS $jira create -o summary=blocks -o description=blocks --noedit --saveFile issue.props
blocker=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set blocker and verify it shows up when viewing the main issue
###############################################################################
RUNS $jira $blocker blocks $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Backlog
summary: summary
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[Backlog]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Both issues are unresolved now
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
$(printf %-12s $blocker:) blocks
EOF
###############################################################################
# reset login for mojira for voting
###############################################################################
jira="$jira --user mojira"
RUNS $jira logout
echo "mojira123" | RUNS $jira login
###############################################################################
## vote for main issue, verify it shows when viewing the issue
###############################################################################
RUNS $jira vote $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Backlog
summary: summary
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[Backlog]
depends: $dup[Done]
priority: Medium
votes: 1
description: |
description
EOF
###############################################################################
## downvote the main issue, verify the vote count goes back to 0
###############################################################################
RUNS $jira vote $issue --down
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Backlog
summary: summary
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[Backlog]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## set mojira user as watcher to issue and verify from REST api
###############################################################################
RUNS $jira watch $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
# FIXME we probably need a watchers command to wrap this?
RUNS sh -c "$jira req /rest/api/2/issue/$issue/watchers | jq -r .watchers[].name"
DIFF <<EOF
gojira
mojira
EOF
###############################################################################
## set issue to In Progress state
###############################################################################
RUNS $jira trans "In Progress" $blocker --noedit
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## set it to "To Do", which is not a valid state for KANBAN issues
###############################################################################
NRUNS $jira todo $blocker
DIFF <<EOF
ERROR Invalid Transition 'To Do', Available: Backlog, Selected for Development, In Progress, Done
EOF
###############################################################################
## set issue back to backlog state
###############################################################################
RUNS $jira backlog $blocker --noedit
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set issue to "In Review" state, which is an invalid state for KANBAN
###############################################################################
NRUNS $jira trans "review" $blocker --noedit
DIFF <<EOF
ERROR Invalid Transition 'review', Available: Backlog, Selected for Development, In Progress, Done
EOF
###############################################################################
## Set it back to "Backlog"
###############################################################################
RUNS $jira backlog $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set it to "In Progress"
###############################################################################
RUNS $jira prog $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set it to "Done"
###############################################################################
RUNS $jira done $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Verify issue is now in Done state (the "blocker" issue is now Done)
###############################################################################
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Backlog
summary: summary
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[Done]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Verify we can add a comment
###############################################################################
RUNS $jira comment $issue --noedit -m "Yo, Comment"
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Backlog
summary: summary
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
blockers: $blocker[Done]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
comments:
- | # mojira, a minute ago
Yo, Comment
EOF
###############################################################################
## Verify we can add labels to an issue
###############################################################################
RUNS $jira add labels $blocker test-label another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[Backlog]
priority: Medium
votes: 0
labels: another-label, test-label
description: |
blocks
EOF
###############################################################################
## Verify we can remove a label
###############################################################################
RUNS $jira remove labels $blocker another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[Backlog]
priority: Medium
votes: 0
labels: test-label
description: |
blocks
EOF
###############################################################################
## Verify we can replace the labels with a new set
###############################################################################
RUNS $jira set labels $blocker more-label better-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[Backlog]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify that "mojira" user can take the issue (reassign to self)
###############################################################################
RUNS $jira take $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: KANBAN
issuetype: Bug
assignee: mojira
reporter: gojira
blockers:
depends: $issue[Backlog]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify we can give the issue back go "gojira" user
###############################################################################
RUNS $jira give $blocker gojira
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: KANBAN
issuetype: Bug
assignee: gojira
reporter: gojira
blockers:
depends: $issue[Backlog]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
Executable
+520
View File
@@ -0,0 +1,520 @@
#!/bin/bash
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira --project PROJECT"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
PLAN 84
# cleanup from previous failed test executions
($jira ls | awk -F: '{print $1}' | while read issue; do ../jira done $issue; done) | sed 's/^/# CLEANUP: /g'
# reset login
RUNS $jira logout
echo "gojira123" | RUNS $jira login
###############################################################################
## Create an issue
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## View the issue we just created
###############################################################################
RUNS $jira view $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: PROJECT
issuetype: Task
assignee: gojira
reporter: gojira
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## List all issues, should be just the one we created
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Try to close the issue, bug Basic projects do not allow that state
###############################################################################
NRUNS $jira close $issue
EDIFF <<EOF
ERROR Invalid Transition 'close', Available: Start Progress, Done
EOF
###############################################################################
## put the issue into Done state, resolving it.
###############################################################################
RUNS $jira done $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## Verify there are no unresolved issues
###############################################################################
RUNS $jira ls
DIFF <<EOF
EOF
###############################################################################
## Setup 2 more issues so we can test duping
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira create -o summary=dup -o description=dup --noedit --saveFile issue.props
dup=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $dup http://localhost:8080/browse/$dup
EOF
###############################################################################
## Mark issue as duplicate, expect both issues to be updated and when viewing
## the main issue there should be a "depends" line showing the dup'd issue, and
## that issue should be resolved
###############################################################################
RUNS $jira $dup dups $issue --noedit
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
OK $dup http://localhost:8080/browse/$dup
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: PROJECT
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## We should see only one unresolved issue, the Dup should be resolved
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Setup for testing blocking issues
###############################################################################
RUNS $jira create -o summary=blocks -o description=blocks --noedit --saveFile issue.props
blocker=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set blocker and verify it shows up when viewing the main issue
###############################################################################
RUNS $jira $blocker blocks $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: PROJECT
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Both issues are unresolved now
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
$(printf %-12s $blocker:) blocks
EOF
###############################################################################
# reset login for mojira for voting
###############################################################################
jira="$jira --user mojira"
RUNS $jira logout
echo "mojira123" | RUNS $jira login
###############################################################################
## vote for main issue, verify it shows when viewing the issue
###############################################################################
RUNS $jira vote $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: PROJECT
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 1
description: |
description
EOF
###############################################################################
## downvote the main issue, verify the vote count goes back to 0
###############################################################################
RUNS $jira vote $issue --down
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: PROJECT
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## set mojira user as watcher to issue and verify from REST api
###############################################################################
RUNS $jira watch $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
# FIXME we probably need a watchers command to wrap this?
RUNS sh -c "$jira req /rest/api/2/issue/$issue/watchers | jq -r .watchers[].name"
DIFF <<EOF
gojira
mojira
EOF
###############################################################################
## set issue to In Progress state, which is an invalid state for PROJECT
###############################################################################
NRUNS $jira trans "In Progress" $blocker --noedit
DIFF <<EOF
ERROR Invalid Transition 'In Progress', Available: Start Progress, Done
EOF
###############################################################################
## Set issue to "In Review" state, which is an invalid state for PROJECT
###############################################################################
NRUNS $jira trans "review" $blocker --noedit
DIFF <<EOF
ERROR Invalid Transition 'review', Available: Start Progress, Done
EOF
###############################################################################
## Set it to "Start Progress" and verify that assignee is set to mojira
###############################################################################
RUNS $jira start $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: In Progress
summary: blocks
project: PROJECT
issuetype: Task
assignee: mojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
description: |
blocks
EOF
###############################################################################
## Set it back to "Stop Progress"
###############################################################################
RUNS $jira stop $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set it to "Done"
###############################################################################
RUNS $jira done $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Verify issue is now in Done state (the "blocker" issue is now Done)
###############################################################################
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: PROJECT
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[Done]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Verify we can add a comment
###############################################################################
RUNS $jira comment $issue --noedit -m "Yo, Comment"
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: PROJECT
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[Done]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
comments:
- | # mojira, a minute ago
Yo, Comment
EOF
###############################################################################
## Verify we can add labels to an issue
###############################################################################
RUNS $jira add labels $blocker test-label another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: PROJECT
issuetype: Task
assignee: mojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: another-label, test-label
description: |
blocks
EOF
###############################################################################
## Verify we can remove a label
###############################################################################
RUNS $jira remove labels $blocker another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: PROJECT
issuetype: Task
assignee: mojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: test-label
description: |
blocks
EOF
###############################################################################
## Verify we can replace the labels with a new set
###############################################################################
RUNS $jira set labels $blocker more-label better-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: PROJECT
issuetype: Task
assignee: mojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify we can give the issue back go "gojira" user
###############################################################################
RUNS $jira give $blocker gojira
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: PROJECT
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify that "mojira" user can take the issue (reassign to self)
###############################################################################
RUNS $jira take $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: PROJECT
issuetype: Task
assignee: mojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
Executable
+513
View File
@@ -0,0 +1,513 @@
#!/bin/bash
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira --project PROCESS"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
PLAN 84
# cleanup from previous failed test executions
($jira ls | awk -F: '{print $1}' | while read issue; do ../jira start $issue; done) | sed 's/^/# CLEANUP: /g'
($jira ls | awk -F: '{print $1}' | while read issue; do ../jira stop $issue; done) | sed 's/^/# CLEANUP: /g'
# reset login
RUNS $jira logout
echo "gojira123" | RUNS $jira login
###############################################################################
## Create an issue
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## View the issue we just created
###############################################################################
RUNS $jira view $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Open
summary: summary
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## List all issues, should be just the one we created
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Try to close the issue, but PROCESS projects do not allow that state
###############################################################################
NRUNS $jira close $issue
EDIFF <<EOF
ERROR Invalid Transition 'close', Available: Start Progress
EOF
###############################################################################
## put the issue into Start Progress state, then Stop Progress state
## which will resolve the issue
###############################################################################
RUNS $jira start $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira stop $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## Verify there are no unresolved issues
###############################################################################
RUNS $jira ls
DIFF <<EOF
EOF
###############################################################################
## Setup 2 more issues so we can test duping
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira create -o summary=dup -o description=dup --noedit --saveFile issue.props
dup=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $dup http://localhost:8080/browse/$dup
EOF
###############################################################################
## Mark issue as duplicate, expect both issues to be updated and when viewing
## the main issue there should be a "depends" line showing the dup'd issue, and
## that issue should be resolved. For PROCESSS projects it has to go through
## 2 steps to resolve, one is "Start Progress" then resolved with "Stop
## Progress", so we see 3 updates in total
###############################################################################
RUNS $jira $dup dups $issue --noedit
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
OK $dup http://localhost:8080/browse/$dup
OK $dup http://localhost:8080/browse/$dup
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Open
summary: summary
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $dup[Cancelled]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## We should see only one unresolved issue, the Dup should be resolved
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Setup for testing blocking issues
###############################################################################
RUNS $jira create -o summary=blocks -o description=blocks --noedit --saveFile issue.props
blocker=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set blocker and verify it shows up when viewing the main issue
###############################################################################
RUNS $jira $blocker blocks $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Open
summary: summary
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[Open]
depends: $dup[Cancelled]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Both issues are unresolved now
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
$(printf %-12s $blocker:) blocks
EOF
###############################################################################
# reset login for mojira for voting
###############################################################################
jira="$jira --user mojira"
RUNS $jira logout
echo "mojira123" | RUNS $jira login
###############################################################################
## vote for main issue, verify it shows when viewing the issue
###############################################################################
RUNS $jira vote $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Open
summary: summary
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[Open]
depends: $dup[Cancelled]
priority: Medium
votes: 1
description: |
description
EOF
###############################################################################
## downvote the main issue, verify the vote count goes back to 0
###############################################################################
RUNS $jira vote $issue --down
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Open
summary: summary
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[Open]
depends: $dup[Cancelled]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## set mojira user as watcher to issue and verify from REST api
###############################################################################
RUNS $jira watch $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
# FIXME we probably need a watchers command to wrap this?
RUNS sh -c "$jira req /rest/api/2/issue/$issue/watchers | jq -r .watchers[].name"
DIFF <<EOF
gojira
mojira
EOF
###############################################################################
## set issue to In Progress state, which is an invalid state for PROCESS
###############################################################################
NRUNS $jira trans "In Progress" $blocker --noedit
DIFF <<EOF
ERROR Invalid Transition 'In Progress', Available: Start Progress
EOF
###############################################################################
## Set issue to "In Review" state, which is an invalid state for PROCESS
###############################################################################
NRUNS $jira trans "review" $blocker --noedit
DIFF <<EOF
ERROR Invalid Transition 'review', Available: Start Progress
EOF
###############################################################################
## Set it to "Start Progress"
###############################################################################
RUNS $jira start $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set it back to "Stop Progress"
###############################################################################
RUNS $jira stop $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set it to "Done"
###############################################################################
RUNS $jira reopen $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Verify issue is now in Done state (the "blocker" issue is now Done)
###############################################################################
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Open
summary: summary
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[Open]
depends: $dup[Cancelled]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Verify we can add a comment
###############################################################################
RUNS $jira comment $issue --noedit -m "Yo, Comment"
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: Open
summary: summary
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[Open]
depends: $dup[Cancelled]
priority: Medium
votes: 0
description: |
description
comments:
- | # mojira, a minute ago
Yo, Comment
EOF
###############################################################################
## Verify we can add labels to an issue
###############################################################################
RUNS $jira add labels $blocker test-label another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Open
summary: blocks
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $issue[Open]
priority: Medium
votes: 0
labels: another-label, test-label
description: |
blocks
EOF
###############################################################################
## Verify we can remove a label
###############################################################################
RUNS $jira remove labels $blocker another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Open
summary: blocks
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $issue[Open]
priority: Medium
votes: 0
labels: test-label
description: |
blocks
EOF
###############################################################################
## Verify we can replace the labels with a new set
###############################################################################
RUNS $jira set labels $blocker more-label better-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Open
summary: blocks
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $issue[Open]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify that "mojira" user can take the issue (reassign to self)
###############################################################################
RUNS $jira take $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Open
summary: blocks
project: PROCESS
issuetype: Task
assignee: mojira
reporter: gojira
blockers:
depends: $issue[Open]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify we can give the issue back go "gojira" user
###############################################################################
RUNS $jira give $blocker gojira
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Open
summary: blocks
project: PROCESS
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $issue[Open]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
Executable
+504
View File
@@ -0,0 +1,504 @@
#!/bin/bash
eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)"
cd $(dirname $0)
jira="../jira --project TASK"
export JIRA_LOG_FORMAT="%{level:-5s} %{message}"
PLAN 82
# cleanup from previous failed test executions
($jira ls | awk -F: '{print $1}' | while read issue; do ../jira done $issue; done) | sed 's/^/# CLEANUP: /g'
# reset login
RUNS $jira logout
echo "gojira123" | RUNS $jira login
###############################################################################
## Create an issue
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## View the issue we just created
###############################################################################
RUNS $jira view $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## List all issues, should be just the one we created
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Try to close the issue, but TASK projects do not allow that state
###############################################################################
NRUNS $jira close $issue
EDIFF <<EOF
ERROR Invalid Transition 'close', Available: Done
EOF
###############################################################################
## put the issue into Done state, which will resolve the issue
###############################################################################
RUNS $jira done $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
###############################################################################
## Verify there are no unresolved issues
###############################################################################
RUNS $jira ls
DIFF <<EOF
EOF
###############################################################################
## Setup 2 more issues so we can test duping
###############################################################################
RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props
issue=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira create -o summary=dup -o description=dup --noedit --saveFile issue.props
dup=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $dup http://localhost:8080/browse/$dup
EOF
###############################################################################
## Mark issue as duplicate, expect both issues to be updated and when viewing
## the main issue there should be a "depends" line showing the dup'd issue, and
## that issue should be resolved. For TASKS projects it has to go through
## 2 steps to resolve, one is "Start Progress" then resolved with "Stop
## Progress", so we see 3 updates in total
###############################################################################
RUNS $jira $dup dups $issue --noedit
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
OK $dup http://localhost:8080/browse/$dup
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## We should see only one unresolved issue, the Dup should be resolved
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
EOF
###############################################################################
## Setup for testing blocking issues
###############################################################################
RUNS $jira create -o summary=blocks -o description=blocks --noedit --saveFile issue.props
blocker=$(awk '/issue/{print $2}' issue.props)
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Set blocker and verify it shows up when viewing the main issue
###############################################################################
RUNS $jira $blocker blocks $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Both issues are unresolved now
###############################################################################
RUNS $jira ls
DIFF <<EOF
$(printf %-12s $issue:) summary
$(printf %-12s $blocker:) blocks
EOF
###############################################################################
# reset login for mojira for voting
###############################################################################
jira="$jira --user mojira"
RUNS $jira logout
echo "mojira123" | RUNS $jira login
###############################################################################
## vote for main issue, verify it shows when viewing the issue
###############################################################################
RUNS $jira vote $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 1
description: |
description
EOF
###############################################################################
## downvote the main issue, verify the vote count goes back to 0
###############################################################################
RUNS $jira vote $issue --down
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[To Do]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## set mojira user as watcher to issue and verify from REST api
###############################################################################
RUNS $jira watch $issue
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
# FIXME we probably need a watchers command to wrap this?
RUNS sh -c "$jira req /rest/api/2/issue/$issue/watchers | jq -r .watchers[].name"
DIFF <<EOF
gojira
mojira
EOF
###############################################################################
## set issue to In Progress state, which is an invalid state for TASK
###############################################################################
NRUNS $jira trans "In Progress" $blocker --noedit
DIFF <<EOF
ERROR Invalid Transition 'In Progress', Available: Done
EOF
###############################################################################
## Set issue to "In Review" state, which is an invalid state for TASK
###############################################################################
NRUNS $jira trans "review" $blocker --noedit
DIFF <<EOF
ERROR Invalid Transition 'review', Available: Done
EOF
###############################################################################
## Set it to "Start Progress", which is an invalid state for TASK
###############################################################################
NRUNS $jira start $blocker
DIFF <<EOF
ERROR Invalid Transition 'start', Available: Done
EOF
###############################################################################
## Set it back to "Stop Progress", which is an invalid state for TASK
###############################################################################
NRUNS $jira stop $blocker
DIFF <<EOF
ERROR Invalid Transition 'stop', Available: Done
EOF
###############################################################################
## Set it to "Done"
###############################################################################
RUNS $jira done $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
###############################################################################
## Verify issue is now in Done state (the "blocker" issue is now Done)
###############################################################################
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[Done]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
EOF
###############################################################################
## Verify we can add a comment
###############################################################################
RUNS $jira comment $issue --noedit -m "Yo, Comment"
DIFF <<EOF
OK $issue http://localhost:8080/browse/$issue
EOF
RUNS $jira $issue
DIFF <<EOF
issue: $issue
created: a minute ago
status: To Do
summary: summary
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
blockers: $blocker[Done]
depends: $dup[Done]
priority: Medium
votes: 0
description: |
description
comments:
- | # mojira, a minute ago
Yo, Comment
EOF
###############################################################################
## Verify we can add labels to an issue
###############################################################################
RUNS $jira add labels $blocker test-label another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: another-label, test-label
description: |
blocks
EOF
###############################################################################
## Verify we can remove a label
###############################################################################
RUNS $jira remove labels $blocker another-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: test-label
description: |
blocks
EOF
###############################################################################
## Verify we can replace the labels with a new set
###############################################################################
RUNS $jira set labels $blocker more-label better-label
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify that "mojira" user can take the issue (reassign to self)
###############################################################################
RUNS $jira take $blocker
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: TASK
issuetype: Task
assignee: mojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
###############################################################################
## Verify we can give the issue back go "gojira" user
###############################################################################
RUNS $jira give $blocker gojira
DIFF <<EOF
OK $blocker http://localhost:8080/browse/$blocker
EOF
RUNS $jira $blocker
DIFF <<EOF
issue: $blocker
created: a minute ago
status: Done
summary: blocks
project: TASK
issuetype: Task
assignee: gojira
reporter: gojira
blockers:
depends: $issue[To Do]
priority: Medium
votes: 0
labels: better-label, more-label
description: |
blocks
EOF
+3
View File
@@ -0,0 +1,3 @@
RUN curl -Ls https://raw.githubusercontent.com/cptactionhank/docker-atlassian-jira-software/master/docker-entrypoint.sh -o /docker-entrypoint.sh \
&& chmod 755 /docker-entrypoint.sh \
&& echo jira.websudo.is.disabled = true >> /var/atlassian/jira/jira-config.properties
+3
View File
@@ -0,0 +1,3 @@
INCLUDE MERGE -VOLUME -COPY \
https://raw.githubusercontent.com/cptactionhank/docker-atlassian-jira-software/master/Dockerfile \
Dockerfile.inc
+54
View File
@@ -0,0 +1,54 @@
## Tests
The test are written using the `osht` bash testing framework. Please read the [documentation](https://github.com/coryb/osht/blob/master/README.md) for `osht`.
## Setup
These tests assume there is a jira service running at 127.0.0.1:8080 with user "gojira" and password "gojira123".
There should also be a poweruser "admin" with password "admin123"
The test Jira was setup following the instructions [here](https://github.com/cptactionhank/docker-atlassian-jira).
### build base docker image
```
docker run --rm -i -v $(pwd):/root:ro coryb/dfpp:1.0.2 Dockerfile.pre | docker build -t go-jira-base:latest -
```
### Initialize container
```
docker run --detach --name go-jira-test --publish 8080:8080 go-jira-base:latest
```
### create admin user
```
open http://localhost:8080
```
Then follow UI workflow to create "admin" user, skip intro and project creation.
### snapshot docker container
```
docker commit go-jira-test go-jira-test:latest
```
### Destroy base container
```
docker rm -f go-jira-test
```
## Running Test:
From the top level of the project you can run:
```
# this creates a local "jira" binary
make
# this runs the integration tests in the "t" directory
prove
```
## API Documentation:
https://docs.atlassian.com/jira/REST/cloud/
## projectTempalteKey missing documentation
https://answers.atlassian.com/questions/36176301/jira-api-7.1.0-create-project
+29 -28
View File
@@ -31,26 +31,28 @@ const default_table_template = `+{{ "-" | rep 16 }}+{{ "-" | rep 57 }}+{{ "-" |
{{ end }}+{{ "-" | rep 16 }}+{{ "-" | rep 57 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+{{ "-" | rep 12 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+
`
const default_view_template = `issue: {{ .key }}
created: {{ .fields.created }}
status: {{ .fields.status.name }}
const default_view_template = `issue: {{ .key }}{{if .fields.created}}
created: {{ .fields.created | age }} ago{{end}}{{if .fields.status}}
status: {{ .fields.status.name }}{{end}}
summary: {{ .fields.summary }}
project: {{ .fields.project.key }}
components: {{ range .fields.components }}{{ .name }} {{end}}
issuetype: {{ .fields.issuetype.name }}
assignee: {{ if .fields.assignee }}{{ .fields.assignee.name }}{{end}}
reporter: {{ if .fields.reporter }}{{ .fields.reporter.name }}{{end}}
watchers: {{ range .fields.customfield_10110 }}{{ .name }} {{end}}
project: {{ .fields.project.key }}{{if .fields.components}}
components: {{ range .fields.components }}{{ .name }} {{end}}{{end}}{{if .fields.issuetype}}
issuetype: {{ .fields.issuetype.name }}{{end}}{{if .fields.assignee}}
assignee: {{ .fields.assignee.name }}{{end}}
reporter: {{ if .fields.reporter }}{{ .fields.reporter.name }}{{end}}{{if .fields.customfield_10110}}
watchers: {{ range .fields.customfield_10110 }}{{ .name }} {{end}}{{end}}{{if .fields.issuelinks}}
blockers: {{ range .fields.issuelinks }}{{if .outwardIssue}}{{ .outwardIssue.key }}[{{.outwardIssue.fields.status.name}}]{{end}}{{end}}
depends: {{ range .fields.issuelinks }}{{if .inwardIssue}}{{ .inwardIssue.key }}[{{.inwardIssue.fields.status.name}}]{{end}}{{end}}
priority: {{ .fields.priority.name }}
depends: {{ range .fields.issuelinks }}{{if .inwardIssue}}{{ .inwardIssue.key }}[{{.inwardIssue.fields.status.name}}]{{end}}{{end}}{{end}}{{if .fields.priority}}
priority: {{ .fields.priority.name }}{{end}}{{if .fields.votes}}
votes: {{ .fields.votes.votes}}{{end}}{{if .fields.labels}}
labels: {{ join ", " .fields.labels }}{{end}}
description: |
{{ or .fields.description "" | indent 2 }}
{{ or .fields.description "" | indent 2 }}{{if .fields.comment.comments}}
comments:
{{ range .fields.comment.comments }} - | # {{.author.name}} at {{.created}}
{{ range .fields.comment.comments }} - | # {{.author.name}}, {{.created | age}} ago
{{ or .body "" | indent 4}}
{{end}}
{{end}}{{end}}
`
const default_edit_template = `# issue: {{ .key }}
update:
@@ -65,8 +67,8 @@ fields:
- name: {{ .name }}{{end}}{{end}}
assignee:
name: {{ if .overrides.assignee }}{{.overrides.assignee}}{{else}}{{if .fields.assignee }}{{ .fields.assignee.name }}{{end}}{{end}}
reporter:
name: {{ if .overrides.reporter }}{{ .overrides.reporter }}{{else if .fields.reporter}}{{ .fields.reporter.name }}{{end}}
# reporter:
# name: {{ if .overrides.reporter }}{{ .overrides.reporter }}{{else if .fields.reporter}}{{ .fields.reporter.name }}{{end}}
# watchers
customfield_10110: {{ range .fields.customfield_10110 }}
- name: {{ .name }}{{end}}{{if .overrides.watcher}}
@@ -76,7 +78,7 @@ fields:
description: |~
{{ or .overrides.description (or .fields.description "") | indent 4 }}
# comments:
# {{ range .fields.comment.comments }} - | # {{.author.name}} at {{.created}}
# {{ range .fields.comment.comments }} - | # {{.author.name}}, {{.created | age}} ago
# {{ or .body "" | indent 4 | comment}}
# {{end}}
`
@@ -91,25 +93,24 @@ const default_issuetypes_template = `{{ range .projects }}{{ range .issuetypes }
const default_create_template = `fields:
project:
key: {{ .overrides.project }}
key: {{ or .overrides.project "" }}
issuetype:
name: {{ .overrides.issuetype }}
summary: {{ or .overrides.summary "" }}
name: {{ or .overrides.issuetype "" }}
summary: {{ or .overrides.summary "" }}{{if .meta.fields.priority.allowedValues}}
priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
name: {{ or .overrides.priority "unassigned" }}
name: {{ or .overrides.priority ""}}{{end}}{{if .meta.fields.components.allowedValues}}
components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{ range split "," (or .overrides.components "")}}
- name: {{ . }}{{end}}
- name: {{ . }}{{end}}{{end}}
description: |~
{{ or .overrides.description "" | indent 4 }}
{{ or .overrides.description "" | indent 4 }}{{if .meta.fields.assignee}}
assignee:
name: {{ or .overrides.assignee "" }}
name: {{ or .overrides.assignee "" }}{{end}}{{if .meta.fields.reporter}}
reporter:
name: {{ or .overrides.reporter .overrides.user }}
name: {{ or .overrides.reporter .overrides.user }}{{end}}{{if .meta.fields.customfield_10110}}
# watchers
customfield_10110: {{ range split "," (or .overrides.watchers "")}}
- name: {{.}}{{end}}
- name:
`
- name:{{end}}`
const default_comment_template = `body: |~
{{ or .overrides.comment "" | indent 2 }}
@@ -140,7 +141,7 @@ fields:{{if .meta.fields.assignee}}
reporter:
name: {{if .overrides.reporter}}{{.overrides.reporter}}{{else}}{{if .fields.reporter}}{{.fields.reporter.name}}{{end}}{{end}}{{end}}{{if .meta.fields.resolution}}
resolution: # Values: {{ range .meta.fields.resolution.allowedValues }}{{.name}}, {{end}}
name: {{if .overrides.resolution}}{{.overrides.resolution}}{{else if .fields.resolution}}{{.fields.resolution.name}}{{else}}Fixed{{end}}{{end}}{{if .meta.fields.summary}}
name: {{if .overrides.resolution}}{{.overrides.resolution}}{{else if .fields.resolution}}{{.fields.resolution.name}}{{else}}{{or .overrides.defaultResolution "Fixed"}}{{end}}{{end}}{{if .meta.fields.summary}}
summary: {{or .overrides.summary .fields.summary}}{{end}}{{if .meta.fields.versions.allowedValues}}
versions: # Values: {{ range .meta.fields.versions.allowedValues }}{{.name}}, {{end}}{{if .overrides.versions}}{{ range (split "," .overrides.versions)}}
- name: {{.}}{{end}}{{else}}{{range .fields.versions}}
+9
View File
@@ -322,6 +322,9 @@ func yamlFixup(data interface{}) (interface{}, error) {
return nil, err
}
}
if len(copy) == 0 {
return nil, nil
}
return copy, nil
case map[string]interface{}:
copy := make(map[string]interface{})
@@ -332,6 +335,9 @@ func yamlFixup(data interface{}) (interface{}, error) {
copy[k] = fixed
}
}
if len(copy) == 0 {
return nil, nil
}
return copy, nil
case []interface{}:
copy := make([]interface{}, 0, len(d))
@@ -342,6 +348,9 @@ func yamlFixup(data interface{}) (interface{}, error) {
copy = append(copy, fixed)
}
}
if len(copy) == 0 {
return nil, nil
}
return copy, nil
case string:
if d == "" || d == "\n" {