Code Monkey home page Code Monkey logo

go-jira's Introduction

๐Ÿ‘‹ Hi, I'm Andy Grunwald

I am a Software Engineer and Engineering Manager from Germany with a focus on Backend-Systems and Infrastructure, Engineering Culture and People.

๐Ÿ‘ท Check out what I'm currently working on

๐Ÿ”ญ Latest releases I've contributed to

๐Ÿ”จ Latest Pull Requests I published

๐Ÿ“ My recent blog posts

๐Ÿ“ซ How to reach me

Twitter Follow

go-jira's People

Contributors

ahmadsalimi avatar andygrunwald avatar attack7 avatar babarot avatar benjivesterby avatar chilicheech avatar condensedtea avatar dependabot-preview[bot] avatar dependabot[bot] avatar dougefresh avatar fank avatar fffinkel avatar fkrauthan-hyperwallet avatar ghostsquad avatar guywithnose avatar hirakiuc avatar jasonobroin avatar johanmeiring avatar macpijan avatar manuelbcd avatar nebril avatar oroshnivskyy avatar phille97 avatar rbriski avatar shawncatz avatar thiht avatar vladimir-ch avatar vovka667 avatar xjs avatar zenixls2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-jira's Issues

Improve error handling to manage unexpected JIRA responses

The JIRA client library supports making arbitrary REST API calls to JIRA. This is great. However, not all of JIRA expresses errors as ErrorResponse JSON objects. Innocently missing parameters in some requests can make JIRA fail ungracefully with an XML response containing a Java stack trace. This would be fine, if it weren't for

go-jira/jira.go

Line 119 in 22e1989

// Any other response body will be silently ignored.

As a result of this, the response body, which contains vital information when trying to wrangle JIRA's REST API, is lost to the caller. This is made even worse by the fact that the caller cannot manually read the response body because it has already been read and closed.

Given the API contract for this is to return a generic error and callers are expected to type assert for ErrorResponse, I would be tempted to add either an UnhandledErrorResponse type, or just shove the response body into Go's default error type. This then allows the caller to at least debug problems with their REST API calls.

Getting an Issue's linked epic returns nil pointer

When trying to get a linked Epic for a Story a nil pointer is returned even when the story has a linked epic.

func main() {
	jiraClient, _ := jira.NewClient(nil, "https://issues.apache.org/jira/")
	issue, _, _ := jiraClient.Issue.Get("MESOS-3078")

	fmt.Printf(issue.Fields.Epic.Name)
}

This returns:
panic: runtime error: invalid memory address or nil pointer dereference

Even though there is an epic link:
MESOS-3078

BUG: requests fail if baseUrl contains extra path

For Jira Server instances the base urls can contain extra path params (like https://example.com/jira) and NewRequest calls end up losing the last path param due to the way the request urls are built using ResolveReference.

https://github.com/andygrunwald/go-jira/blob/master/jira.go#L82
https://github.com/andygrunwald/go-jira/blob/master/jira.go#L119
https://github.com/andygrunwald/go-jira/blob/master/jira.go#L187

I think it should be if we help users overcome these 2 pitfalls:

  1. baseURL must contain a trailing /
  2. any of the urls passed into NewRequest calls above need to not include the preceding /, unless they are an absolute url

Expose the base JIRA URL

It's frustrating that the very base URL passed into the constructor for a jira.Client doesn't get exposed in some way. The URL is extremely useful when forming HTML links, and I'm continually having to pass a wrapper struct of { Client, BaseURL }.

I fully understand why you don't want it to be modified from under you, but exposing a getter like Client.BaseURL() would be incredibly helpful for me.

Data is not an array, custom field create jira issue

I'm trying to create a new issue in Jira using a custom field and continue to receive this error:

{"errorMessages":[],"errors":{"This Field":"data was not an array"}}
This: Request failed. Please analyze the request body for more details. Status code: 400

The test code:

func main() {                                                       
    client, err := connectJira()                                    
    if err != nil {                                                 
        fmt.Println("error:", err)                                  
        return                                                      
    }                                                               
                                                                    
    i := jira.Issue{                                                
        Fields: &jira.IssueFields{                                  
            Assignee: &jira.User{                                   
                Name: "username",                                   
            },                                                      
            Description: "SOME_DESCRIPTION",                        
            Type: jira.IssueType{                                   
                Self: "http://jiraisthebest/rest/api/2/issuetype/3",
                Name: "Task",                                       
            },                                                      
            Unknowns: tcontainer.MarshalMap{                        
                "customfield_11882": "SOMEVALUE",                   
            },                                                      
            Project: jira.Project{                                  
                Key: "ITW",                                         
            },                                                      
            Summary: "Just a demo issue",                           
        },                                                          
    }                                                               
    issue, response, err := client.Issue.Create(&i)                 
    body, readErr := ioutil.ReadAll(response.Body)                  
    if readErr != nil {                                             
        fmt.Println("Body error:", readErr)                         
        return                                                      
    }                                                               
    fmt.Println(string(body))                                       
    if err != nil {                                                 
        fmt.Println("This: ", err)                                  
        return                                                      
    }                                                               
                                                                    
    fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary)        
}                                                                   

support for oauth2 used by Jira Add-Ons

In order to support REST API calls from Jira Add-Ons created through the Atlassian Connect framework, we need to:

  1. create a JSON Web Token (JWT) assertion
  2. use the JWT assertion + secret to get an access token
  3. include the access token in the request headers

I've got a working standalone example and I'll create a PR in a bit.

Comments are not unmarshalled

Using go-jira for a CLI, I found that comments are not being unmarshalled for any Issue.
I did the following try on your code, and got issue_test doesn't pass. In https://github.com/andygrunwald/go-jira/blob/master/issue_test.go#L140, I added:

if len(issue.Fields.Comments) != 1 {
  t.Error("Expected one comment, %v found", len(issue.Fields.Comments))
}

I'm not very experienced in Go programming and even most not sure of understanding JSON Unmarshalling anyway, so I might be wrong. I might like to contribute a fix for this, but I'm uncertain about this actually being a bug, or how to diagnose and fix... I also found another issue, trying to see the response body, but this should probably be another issue.

I apologize if this is not the correct way to contribute, or help; I'm just trying to use this :)

NewClient() seems to be returning nil without throwing an error

Hi all,

I have a problem where attempting to get an issue's info throws a nil pointer exception. The error is the following:
runtime error: invalid memory address or nil pointer dereference: errorString

Here's where I'm accessing the jiraClient, inside the OnIntent method:

log.Println("OpenTicketIntent triggered")

issue, issueResponse, err := jiraClient.Issue.Get("DUN-455", nil)
fmt.Println(issue)
fmt.Println(issueResponse)
if err != nil {
	log.Println(err.Error())
}
i := fmt.Sprintf("%s: %+v\n", issue.Key, issue.Fields.Summary)

speechText := fmt.Sprintf("i = %s", i)

It is on this line that I'm getting the error:
issue, issueResponse, err := jiraClient.Issue.Get("DUN-455", nil)

Here is where I'm initializing jiraClient, in main:

jiraClient, err := jira.NewClient(nil, "https://xxxxxx.atlassian.net/")
if err != nil {
	fmt.Println(err.Error())
	panic(err)
}
fmt.Print("jiraClient: ")
fmt.Println(jiraClient)
jiraClient.Authentication.SetBasicAuth("xxxxx", "xxxxx")
lambda.Start(Handle)

I'm sure that the line log.Println("OpenTicketIntent triggered") is getting triggered because I see that in the console output. What I don't see in the console is where I'm printing the jiraClient with a prefix string:

fmt.Print("jiraClient: ")
fmt.Println(jiraClient)

But in addition, I'm not getting an error thrown in main! My program goes all the way into OnIntent and into OpenTicketIntent before trying to access the jiraClient, which was initialized in main.

This is making me think that NewClient() is returning a nil response for the client without throwing an error. Am I missing something here?

GET request removes path

When passing a URL with a path, the path is not included in the request.

fmt.Println(*jiraURL)
req, _ := jiraClient.NewRequest("GET", "/rest/api/2/user/search?username=.&maxResults=1000", nil)
fmt.Println(req)

returns

http://localhost:2990/jira
&{GET http://localhost:2990/rest/api/2/user/search?username=.&maxResults=1000

Any ideas?

Documentation with Time

Hi, thanks for this lib. ๐Ÿ˜„

However, I would like to get updated field from a Jira issue, but I don't know how to get it.

if err = issue.Fields.Updated.UnmarshalJSON(???????????)); err != nil {
    log.Fatalf(err.Error())
}

What do we need to use as UnmarshalJSON arg ?
Thanks !

Oauth

I'm trying to implement Oauth authentification with our jira cloud platform and I see on the README.md that this library support it but I have trouble to wrap my head around this feature.

Does anybody have a working example ?

Thanks a lot !

Error: unknown field 'BaseURL' in struct literal of type jira.CookieAuthTransport

In README.md the examples for Create an issue and Call a not implemented API endpoint, the type CookieAuthTransport is being passed the field BaseURL and then used by calling tp.BaseUrl.

When I try to do this I get the following error:
unknown field 'BaseURL' in struct literal of type jira.CookieAuthTransport
Checking type CookieAuthTransport struct in jira.go, I don't see the field BaseURL, was this removed at some point?

Is this by design and has the README just not being updated? Or is this something else?
Thank you!

Snippet of code example below highlighting the use case:

tp := jira.CookieAuthTransport{
	Username: "username",
	Password: "password",
	BaseURL:  "https://my.jira.com",
}

jiraClient, err := jira.NewClient(tp.Client(), tp.BaseURL)

Problems unmarshaling JSON for JIRA v6.4

Here's my sample code:

client, _ := jira.NewClient(nil, "http://my.jira.url")

if i, _, err := client.Issue.Get("DAR-1"); err != nil {
    logger.Error(err)
} else {
    logger.Info(i.Fields.Project.ID)
}

The errors I see are:

json: cannot unmarshal object into Go value of type []*jira.Worklog
json: cannot unmarshal string into Go value of type int (This is probably for issue.Fields.Updated)
json: cannot unmarshal object into Go value of type []*jira.Comment

The JIRA version I am using is v6.4.10#64025-sha1:5b8b740

Using JIRA http://hostname/rest/api/2/issue/DAR-1, I see that the worklog JSON looks like this:

worklog: {
  startAt: 0,
  maxResults: 20,
  total: 0,
  worklogs: [ ]
},

New to Go

I know this isn't the right place to ask this question as it isn't an issue.

However, i hope you guys can assist me.

How do i create a component to be tagged to a createissue?

i := jira.Issue{ Fields: &jira.IssueFields{ Assignee: &jira.User{ Name: "sample", }, Reporter: &jira.User{ Name: "samplereporter", }, Components: &[]jira.Component{{Name: "testcomponent"}}, Project: jira.Project{ Key: "PROJTEST", },

I'm lost as to how to initialise Components. Hope someone here can assist me.

Support of custom fields while creating issue

Hi , I am trying to create issue using custom fields ,

below JSON allows me to create issue through rest api
{
"fields":{
"project":{
"key":"ABC"
},
"summary":"TEST",
"description":"Story is created from TEST",
"issuetype":{
"name":"Story"
},
"customfield_10024" :{
"id" :"10036"
}
}
}

Could you please help in syntax of adding custom field to below code.


jiraClient, err := jira.NewClient(nil, "https://your.jira-instance.com/")
if err != nil {
panic(err)
}

res, err := jiraClient.Authentication.AcquireSessionCookie("username", "password")
if err != nil || res == false {
fmt.Printf("Result: %v\n", res)
panic(err)
}

customfield_10024 := tcontainer.NewMarshalMap()
customfield_10024["id"] = "10036"
i := jira.Issue{
Fields: &jira.IssueFields{
Assignee: &jira.User{
Name: "myuser",
},
Reporter: &jira.User{
Name: "youruser",
},
Description: "Test Issue",
Type: jira.IssueType{
Name: "Bug",
},
Project: jira.Project{
Key: "PROJ1",
},
Summary: "Just a demo issue",
Unknowns: customfield_10024,
},
}
issue, _, err := jiraClient.Issue.Create(&i)
if err != nil {
panic(err)
}


P.S : I referred #35 as well, but I could not understand.

Basic auth support

Hey,

I am relatively new to go but as I understand your library suppose to support basic auth connection with Jira. Your documentation for session cookie authentication even recommends to use basic auth. But I do not see any place to provide username and password to this library. I looked into go documentation but they say I would need to provide a username and password for each request object so I can't even set it globally on the http connection that I could pass in.

Can some one please advice?

how to update the given customfield value by programming ?

is anyone can give me an example?
e.g. i want to update the customfied_100010's value, and i try the following code, but not expected and got error .

`
payload := map[string]interface{}{
"fields":{
"customfield_100010":"update from programming",
},
}

jiraClient.Issue.DoTransitionWithPayload(issue.ID, payload)

`
and then , i try to use the jiraClient.Issue.Update(issue) function , but get error the same.

how should i do to update the given customfield value now ?

Basic Authentication Example?

Reading the docs I tried the following:

import (
	"strings"

	"github.com/urfave/cli"
	jira "gopkg.in/andygrunwald/go-jira.v1"
)

func NewJiraClientFromCliContext(c *cli.Context) (*jira.Client, error) {
	tp := jira.BasicAuthTransport{
		Username: c.GlobalString("jira_user"),
		Password: c.GlobalString("jira_password"),
	}

	client, err := jira.NewClient(tp.Client(), strings.TrimSpace(c.GlobalString("jira_url")))
	if err != nil {
		return nil, err
	}
	return client, nil
}

But this does not compile. it seems the jira.BasicAuthTransport does not exist. However, I see this test:

func TestClient_NewRequest_BasicAuth(t *testing.T) {
	c, err := NewClient(nil, testJIRAInstanceURL)
	if err != nil {
		t.Errorf("An error occurred. Expected nil. Got %+v.", err)
	}

	c.Authentication.SetBasicAuth("test-user", "test-password")

	inURL := "rest/api/2/issue/"
	inBody := &Issue{Key: "MESOS"}
	req, err := c.NewRequest("GET", inURL, inBody)

	if err != nil {
		t.Errorf("An error occurred. Expected nil. Got %+v.", err)
	}

	username, password, ok := req.BasicAuth()
	if !ok || username != "test-user" || password != "test-password" {
		t.Errorf("An error occurred. Expected basic auth username %s and password %s. Got username %s and password %s.", "test-user", "test-password", username, password)
	}
}

Which one is correct? Are docs out of date? Am I missing something here?

Runtime error when authentication error occurs

When I use an invalid host or the authentication details are incorrect, the errors printed back to the console are not best helpful when it fails to get an issue. See below for output currently:

_panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x6de982]

goroutine 1 [running]:
github.com/andygrunwald/go-jira.NewJiraError(0x0, 0x8a9160, 0xc4201182a0, 0x0, 0x0)
	.../go/src/github.com/andygrunwald/go-jira/error.go:22 +0x52
github.com/andygrunwald/go-jira.(*IssueService).Get(0xc42000e038, 0x779d93, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0)
	.../go/src/github.com/andygrunwald/go-jira/issue.go:499 +0x512
main.main()
	.../golang/src/github.com/jeynesrya/trial-go/jira.go:15 +0x19b_

Seems as though an error is occurring whilst the error is attempting to be built. I have to dig down into breakpointed code in order to find what the actual error was. For example, I have to dig down in the httpError variable in order to find that my issue was actually "no such host" but this is never returned back to the console.

Add changelog

It would be nice to have a way to provide "expand" parameter to get issue's changelog, i.e.
http://your-jira-server/rest/api/2/issue/ISSUE-11?expand=changelog

Minor misprint in README.md: JRIA -> JIRA

Great library, totally deserves misprint-free README :)
In README there is

For all possible API endpoints of JRIA

With "JIRA" being a key word in the context of this library, I think it ought to be fixed.

Get all project issues

Is it possible to get all the issues for a given project without providing a sprint id?

Add support for issue deletion

Thanks for writing this JIRA library. I noticed that issue deletion is not supported. It would be really nice to have this. Cheers.

PostAttachment auth issue

Hi.

Looks like there is some sort of issue with PostAttachment method. I'm getting 401 HTTP error code from the Jira service when trying to use it. Here is my example code:

https://gist.github.com/antekresic/4dda591c415d4a9dac5179efd1f7fd96
(I removed the credentials and other sensitive data)

By modifying jira.go file, the NewMultiPartRequest method on the Client, I was able to get it working. I changed the session cookie setting to be just like in the NewRequest method.

Let me know if you need more info regarding this issue.

Thanks!

Allow plug-ins to be added as a service

The PR at #133 is trying to add a plugin API. I like the idea of being able to harness go-jira with plug ins but I don't think it belongs in the core library. This issue is to discuss notation around how to import and add a new service into go-jira.

Cannot use IssueFields stuct as valid 'fields' object when performing a transition w/ payload

The fields Type/issuetype and Summary do not have omitempty in their stuct tags. This is certainly fine for a create, but when performing a transition, the presence of these fields without data in them confuses the JIRA API and error response of 400 is returned.

Example of a marshaled request using IssueFields for fields:

rest/api/2/issue/SAMPLE-123/transitions
{
	"update": {
		"comment": [{
			"add": {
				"body": "bug has been fixed."
			}
		}]
	},
	"fields": {
		"issuetype": {},
		"summary": ""
                "resolution": {
			"self": "",
			"id": "",
			"description": "",
			"name": "Done"
		},
		"customfield_14610": {
			"value": "Complete"
		}
	},
	"transition": {
		"id": "21",
		"name": "Close"
	}
}

Response:

{
    "errorMessages": [],
    "errors": {
        "summary": "Field 'summary' cannot be set. It is not on the appropriate screen, or unknown.",
        "issuetype": "Could not find issuetype by id or name.",
    }
}

Support renderedFields expand parameter

Hi,

Great library, but would be greater if it was supporting the renderedFields expand option. This would help for example to retrieve comments formatted as HTML, instead of formatted as Wiki markup, and having to transform them ;)

Basic Auth against 7.4.4 does not seem to be working

I have the following code:

package main

import (
	"fmt"
	"github.com/andygrunwald/go-jira"
	"io/ioutil"
	"strings"
)

func main() {
	var jiraAPIEndpoint = "https://my.jira.url"
	var jiraUsername = "abcd"
	var jiraPassword = "abcd123!"

	tp := jira.BasicAuthTransport{
		Username: jiraUsername,
		Password: jiraPassword,
	}

	jiraClient, err := jira.NewClient(tp.Client(), strings.TrimSpace(jiraAPIEndpoint))
	if err != nil {
		panic(err)
	}
	if jiraClient == nil {
		fmt.Println( "Cannot create JIRA client." )
		return
	}

	// Search for GDPR Issues
	searchOptions := &jira.SearchOptions{StartAt: 0, MaxResults: 100}
	issues, response, err := jiraClient.Issue.Search("\"Salesforce Bug ID\" is not EMPTY AND status = Closed AND attachments is not EMPTY AND status changed to Closed before -90d ", searchOptions )
	if err != nil {
		panic(err)
	}
	if response.StatusCode != 200 {
		fmt.Println( "Response Code: " + response.Status)
		bodyBytes, _ := ioutil.ReadAll(response.Body)
		fmt.Println( "Body: " + string(bodyBytes) )
		return
	}

	fmt.Println("Issues: ")

	for _, issue := range issues {
		fmt.Println("   " + issue.ID + ": " + issue.Key)
	}
}

It keeps giving me the following error:

panic: Request failed. Please analyze the request body for more details. Status code: 401: Could not parse JSON: invalid character '<' looking for beginning of value

goroutine 1 [running]:
main.main()
	/Users/cgz/go/src/jira-gdpr-cleanup/main.go:34 +0xcf4
exit status 2

It is not authentication properly (it is returning a 403), even though the username and password are the same. Postman works fine with the same credentials on the same machine.

Am I missing something? Do I need to do something special to the username or password?

Any help would be appreciated.

No Data Returned

Hello,

We're running this based on the examples provided but no data is being returned:

Here's the script

Thanks

Problem with example create

Im trying to Connect with the Example to Jira and creating an Issue.
Getting this as Response
{"errorMessages":[],"errors":{"project":"project is required"}}
panic: runtime error: invalid memory address or nil pointer dereference

go version go1.6.2 linux/amd64
Jira 7.3 & 7.1

Im new to golang so a little hint what to do would be nice :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.