mirror of
https://github.com/Threnklyn/jira.git
synced 2026-05-19 20:53:27 +02:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f33400288 | |||
| 37332354b7 | |||
| 7530b309e2 | |||
| e93bf71fea | |||
| d022f0ad70 | |||
| 4d5076230c | |||
| 3cbd2f85a4 | |||
| 970876851b | |||
| f74c45d7d7 | |||
| 4e7e52288d | |||
| 63f41e5e88 | |||
| dbf6a5a265 | |||
| b2056be287 | |||
| 6beb941d82 | |||
| b297d5a4ef | |||
| bf7f38de87 | |||
| f7ed1ed8d8 | |||
| 280c0f24b3 | |||
| 6e296052f5 | |||
| 189b0d252c | |||
| 0e453a45d3 | |||
| 179596ff12 | |||
| 50bac02419 | |||
| 4b7e24a199 | |||
| b9bf8455bd | |||
| 9111231545 | |||
| 986528d4ea | |||
| 9c1f028be2 | |||
| e3c5051e5e | |||
| 580ea50b37 | |||
| be31acde65 | |||
| a2f8b7ef65 | |||
| c28d46fe8f | |||
| 108a5b4976 | |||
| e3d11357e1 | |||
| dfb10740f5 | |||
| adc08935b4 | |||
| 073c8a3694 | |||
| c4a31a498e | |||
| bcad37089a | |||
| b2ba8de15d | |||
| 6016bda571 | |||
| 34ca09cf1a | |||
| d7fb88ee41 | |||
| e58625b00c |
+4
-1
@@ -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
|
||||
@@ -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)]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
[](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
|
||||
|
||||
```
|
||||
|
||||
@@ -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
@@ -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
@@ -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{})
|
||||
|
||||
Executable
+21
@@ -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
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
endpoint: http://localhost:8080
|
||||
user: gojira
|
||||
Executable
+51
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
INCLUDE MERGE -VOLUME -COPY \
|
||||
https://raw.githubusercontent.com/cptactionhank/docker-atlassian-jira-software/master/Dockerfile \
|
||||
Dockerfile.inc
|
||||
+54
@@ -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
@@ -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}}
|
||||
|
||||
@@ -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" {
|
||||
|
||||
Reference in New Issue
Block a user