mirror of
https://github.com/interviewstreet/go-jira.git
synced 2025-03-05 14:55:19 +02:00
fix(product): Make product naming consistent, rename JIRA to Jira (#286)
Atlassian names the product "Jira". In this library, the product name is used different (JIRA) and inconsistent (sometimes JIRA, sometimes Jira). closes issue #284
This commit is contained in:
parent
f6b1dcafcf
commit
146229d2ab
26
README.md
26
README.md
@ -4,23 +4,23 @@
|
||||
[](https://travis-ci.org/andygrunwald/go-jira)
|
||||
[](https://goreportcard.com/report/github.com/andygrunwald/go-jira)
|
||||
|
||||
[Go](https://golang.org/) client library for [Atlassian JIRA](https://www.atlassian.com/software/jira).
|
||||
[Go](https://golang.org/) client library for [Atlassian Jira](https://www.atlassian.com/software/jira).
|
||||
|
||||

|
||||

|
||||
|
||||
## Features
|
||||
|
||||
* Authentication (HTTP Basic, OAuth, Session Cookie)
|
||||
* Create and retrieve issues
|
||||
* Create and retrieve issue transitions (status updates)
|
||||
* Call every API endpoint of the JIRA, even if it is not directly implemented in this library
|
||||
* Call every API endpoint of the Jira, even if it is not directly implemented in this library
|
||||
|
||||
This package is not JIRA API complete (yet), but you can call every API endpoint you want. See [Call a not implemented API endpoint](#call-a-not-implemented-api-endpoint) how to do this. For all possible API endpoints of JIRA have a look at [latest JIRA REST API documentation](https://docs.atlassian.com/jira/REST/latest/).
|
||||
This package is not Jira API complete (yet), but you can call every API endpoint you want. See [Call a not implemented API endpoint](#call-a-not-implemented-api-endpoint) how to do this. For all possible API endpoints of Jira have a look at [latest Jira REST API documentation](https://docs.atlassian.com/jira/REST/latest/).
|
||||
|
||||
## Requirements
|
||||
|
||||
* Go >= 1.8
|
||||
* JIRA v6.3.4 & v7.1.2.
|
||||
* Jira v6.3.4 & v7.1.2.
|
||||
|
||||
## Installation
|
||||
|
||||
@ -52,7 +52,7 @@ go test -v ./...
|
||||
|
||||
Please have a look at the [GoDoc documentation](https://godoc.org/github.com/andygrunwald/go-jira) for a detailed API description.
|
||||
|
||||
The [latest JIRA REST API documentation](https://docs.atlassian.com/jira/REST/latest/) was the base document for this package.
|
||||
The [latest Jira REST API documentation](https://docs.atlassian.com/jira/REST/latest/) was the base document for this package.
|
||||
|
||||
## Examples
|
||||
|
||||
@ -113,12 +113,12 @@ func main() {
|
||||
|
||||
#### Authenticate with session cookie [DEPRECATED]
|
||||
|
||||
JIRA [deprecated this authentication method.](https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-basic-auth-and-cookie-based-auth/) It's not longer available for use.
|
||||
Jira [deprecated this authentication method.](https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-basic-auth-and-cookie-based-auth/) It's not longer available for use.
|
||||
|
||||
|
||||
#### Authenticate with OAuth
|
||||
|
||||
If you want to connect via OAuth to your JIRA Cloud instance checkout the [example of using OAuth authentication with JIRA in Go](https://gist.github.com/Lupus/edafe9a7c5c6b13407293d795442fe67) by [@Lupus](https://github.com/Lupus).
|
||||
If you want to connect via OAuth to your Jira Cloud instance checkout the [example of using OAuth authentication with Jira in Go](https://gist.github.com/Lupus/edafe9a7c5c6b13407293d795442fe67) by [@Lupus](https://github.com/Lupus).
|
||||
|
||||
For more details have a look at the [issue #56](https://github.com/andygrunwald/go-jira/issues/56).
|
||||
|
||||
@ -175,9 +175,9 @@ func main() {
|
||||
|
||||
### Call a not implemented API endpoint
|
||||
|
||||
Not all API endpoints of the JIRA API are implemented into *go-jira*.
|
||||
Not all API endpoints of the Jira API are implemented into *go-jira*.
|
||||
But you can call them anyway:
|
||||
Lets get all public projects of [Atlassian`s JIRA instance](https://jira.atlassian.com/).
|
||||
Lets get all public projects of [Atlassian`s Jira instance](https://jira.atlassian.com/).
|
||||
|
||||
```go
|
||||
package main
|
||||
@ -209,7 +209,7 @@ func main() {
|
||||
|
||||
// ...
|
||||
// BAM: Bamboo
|
||||
// BAMJ: Bamboo JIRA Plugin
|
||||
// BAMJ: Bamboo Jira Plugin
|
||||
// CLOV: Clover
|
||||
// CONF: Confluence
|
||||
// ...
|
||||
@ -218,7 +218,7 @@ func main() {
|
||||
|
||||
## Implementations
|
||||
|
||||
* [andygrunwald/jitic](https://github.com/andygrunwald/jitic) - The JIRA Ticket Checker
|
||||
* [andygrunwald/jitic](https://github.com/andygrunwald/jitic) - The Jira Ticket Checker
|
||||
|
||||
## Code structure
|
||||
|
||||
@ -226,7 +226,7 @@ The code structure of this package was inspired by [google/go-github](https://gi
|
||||
|
||||
There is one main part (the client).
|
||||
Based on this main client the other endpoints, like Issues or Authentication are extracted in services. E.g. `IssueService` or `AuthenticationService`.
|
||||
These services own a responsibility of the single endpoints / usecases of JIRA.
|
||||
These services own a responsibility of the single endpoints / usecases of Jira.
|
||||
|
||||
## Contribution
|
||||
|
||||
|
@ -15,9 +15,9 @@ const (
|
||||
authTypeSession = 2
|
||||
)
|
||||
|
||||
// AuthenticationService handles authentication for the JIRA instance / API.
|
||||
// AuthenticationService handles authentication for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#authentication
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#authentication
|
||||
type AuthenticationService struct {
|
||||
client *Client
|
||||
|
||||
@ -31,7 +31,7 @@ type AuthenticationService struct {
|
||||
password string
|
||||
}
|
||||
|
||||
// Session represents a Session JSON response by the JIRA API.
|
||||
// Session represents a Session JSON response by the Jira API.
|
||||
type Session struct {
|
||||
Self string `json:"self,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
@ -48,13 +48,13 @@ type Session struct {
|
||||
Cookies []*http.Cookie
|
||||
}
|
||||
|
||||
// AcquireSessionCookieWithContext creates a new session for a user in JIRA.
|
||||
// Once a session has been successfully created it can be used to access any of JIRA's remote APIs and also the web UI by passing the appropriate HTTP Cookie header.
|
||||
// AcquireSessionCookieWithContext creates a new session for a user in Jira.
|
||||
// Once a session has been successfully created it can be used to access any of Jira's remote APIs and also the web UI by passing the appropriate HTTP Cookie header.
|
||||
// The header will by automatically applied to every API request.
|
||||
// Note that it is generally preferrable to use HTTP BASIC authentication with the REST API.
|
||||
// However, this resource may be used to mimic the behaviour of JIRA's log-in page (e.g. to display log-in errors to a user).
|
||||
// However, this resource may be used to mimic the behaviour of Jira's log-in page (e.g. to display log-in errors to a user).
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
//
|
||||
// Deprecated: Use CookieAuthTransport instead
|
||||
func (s *AuthenticationService) AcquireSessionCookieWithContext(ctx context.Context, username, password string) (bool, error) {
|
||||
@ -99,7 +99,7 @@ func (s *AuthenticationService) AcquireSessionCookie(username, password string)
|
||||
return s.AcquireSessionCookieWithContext(context.Background(), username, password)
|
||||
}
|
||||
|
||||
// SetBasicAuth sets username and password for the basic auth against the JIRA instance.
|
||||
// SetBasicAuth sets username and password for the basic auth against the Jira instance.
|
||||
//
|
||||
// Deprecated: Use BasicAuthTransport instead
|
||||
func (s *AuthenticationService) SetBasicAuth(username, password string) {
|
||||
@ -108,7 +108,7 @@ func (s *AuthenticationService) SetBasicAuth(username, password string) {
|
||||
s.authType = authTypeBasic
|
||||
}
|
||||
|
||||
// Authenticated reports if the current Client has authentication details for JIRA
|
||||
// Authenticated reports if the current Client has authentication details for Jira
|
||||
func (s *AuthenticationService) Authenticated() bool {
|
||||
if s != nil {
|
||||
if s.authType == authTypeSession {
|
||||
@ -123,7 +123,7 @@ func (s *AuthenticationService) Authenticated() bool {
|
||||
|
||||
// LogoutWithContext logs out the current user that has been authenticated and the session in the client is destroyed.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
//
|
||||
// Deprecated: Use CookieAuthTransport to create base client. Logging out is as simple as not using the
|
||||
// client anymore
|
||||
@ -163,7 +163,7 @@ func (s *AuthenticationService) Logout() error {
|
||||
|
||||
// GetCurrentUserWithContext gets the details of the current user.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
func (s *AuthenticationService) GetCurrentUserWithContext(ctx context.Context) (*Session, error) {
|
||||
if s == nil {
|
||||
return nil, fmt.Errorf("authentication Service is not instantiated")
|
||||
|
20
board.go
20
board.go
@ -7,9 +7,9 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// BoardService handles Agile Boards for the JIRA instance / API.
|
||||
// BoardService handles Agile Boards for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/server/
|
||||
// Jira API docs: https://docs.atlassian.com/jira-software/REST/server/
|
||||
type BoardService struct {
|
||||
client *Client
|
||||
}
|
||||
@ -23,7 +23,7 @@ type BoardsList struct {
|
||||
Values []Board `json:"values" structs:"values"`
|
||||
}
|
||||
|
||||
// Board represents a JIRA agile board
|
||||
// Board represents a Jira agile board
|
||||
type Board struct {
|
||||
ID int `json:"id,omitempty" structs:"id,omitempty"`
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
@ -63,7 +63,7 @@ type SprintsList struct {
|
||||
Values []Sprint `json:"values" structs:"values"`
|
||||
}
|
||||
|
||||
// Sprint represents a sprint on JIRA agile board
|
||||
// Sprint represents a sprint on Jira agile board
|
||||
type Sprint struct {
|
||||
ID int `json:"id" structs:"id"`
|
||||
Name string `json:"name" structs:"name"`
|
||||
@ -127,7 +127,7 @@ type BoardConfigurationColumnStatus struct {
|
||||
|
||||
// GetAllBoardsWithContext will returns all boards. This only includes boards that the user has permission to view.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-getAllBoards
|
||||
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-getAllBoards
|
||||
func (s *BoardService) GetAllBoardsWithContext(ctx context.Context, opt *BoardListOptions) (*BoardsList, *Response, error) {
|
||||
apiEndpoint := "rest/agile/1.0/board"
|
||||
url, err := addOptions(apiEndpoint, opt)
|
||||
@ -157,7 +157,7 @@ func (s *BoardService) GetAllBoards(opt *BoardListOptions) (*BoardsList, *Respon
|
||||
// GetBoardWithContext will returns the board for the given boardID.
|
||||
// This board will only be returned if the user has permission to view it.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-getBoard
|
||||
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-getBoard
|
||||
func (s *BoardService) GetBoardWithContext(ctx context.Context, boardID int) (*Board, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%v", boardID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -187,7 +187,7 @@ func (s *BoardService) GetBoard(boardID int) (*Board, *Response, error) {
|
||||
// Note, if the user does not have the 'Create shared objects' permission and tries to create a shared board, a private
|
||||
// board will be created instead (remember that board sharing depends on the filter sharing).
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-createBoard
|
||||
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-createBoard
|
||||
func (s *BoardService) CreateBoardWithContext(ctx context.Context, board *Board) (*Board, *Response, error) {
|
||||
apiEndpoint := "rest/agile/1.0/board"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, board)
|
||||
@ -212,7 +212,7 @@ func (s *BoardService) CreateBoard(board *Board) (*Board, *Response, error) {
|
||||
|
||||
// DeleteBoardWithContext will delete an agile board.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-deleteBoard
|
||||
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-deleteBoard
|
||||
func (s *BoardService) DeleteBoardWithContext(ctx context.Context, boardID int) (*Board, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%v", boardID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "DELETE", apiEndpoint, nil)
|
||||
@ -235,7 +235,7 @@ func (s *BoardService) DeleteBoard(boardID int) (*Board, *Response, error) {
|
||||
// GetAllSprintsWithContext will return all sprints from a board, for a given board Id.
|
||||
// This only includes sprints that the user has permission to view.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board/{boardId}/sprint
|
||||
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board/{boardId}/sprint
|
||||
func (s *BoardService) GetAllSprintsWithContext(ctx context.Context, boardID string) ([]Sprint, *Response, error) {
|
||||
id, err := strconv.Atoi(boardID)
|
||||
if err != nil {
|
||||
@ -258,7 +258,7 @@ func (s *BoardService) GetAllSprints(boardID string) ([]Sprint, *Response, error
|
||||
// GetAllSprintsWithOptionsWithContext will return sprints from a board, for a given board Id and filtering options
|
||||
// This only includes sprints that the user has permission to view.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board/{boardId}/sprint
|
||||
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board/{boardId}/sprint
|
||||
func (s *BoardService) GetAllSprintsWithOptionsWithContext(ctx context.Context, boardID int, options *GetAllSprintsOptions) (*SprintsList, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%d/sprint", boardID)
|
||||
url, err := addOptions(apiEndpoint, options)
|
||||
|
@ -2,14 +2,13 @@ package jira
|
||||
|
||||
import "context"
|
||||
|
||||
// ComponentService handles components for the JIRA instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/software/jira/docs/api/REST/7.10.1/#api/2/component
|
||||
// ComponentService handles components for the Jira instance / API.//
|
||||
// Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/7.10.1/#api/2/component
|
||||
type ComponentService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// CreateComponentOptions are passed to the ComponentService.Create function to create a new JIRA component
|
||||
// CreateComponentOptions are passed to the ComponentService.Create function to create a new Jira component
|
||||
type CreateComponentOptions struct {
|
||||
Name string `json:"name,omitempty" structs:"name,omitempty"`
|
||||
Description string `json:"description,omitempty" structs:"description,omitempty"`
|
||||
@ -21,7 +20,7 @@ type CreateComponentOptions struct {
|
||||
ProjectID int `json:"projectId,omitempty" structs:"projectId,omitempty"`
|
||||
}
|
||||
|
||||
// CreateWithContext creates a new JIRA component based on the given options.
|
||||
// CreateWithContext creates a new Jira component based on the given options.
|
||||
func (s *ComponentService) CreateWithContext(ctx context.Context, options *CreateComponentOptions) (*ProjectComponent, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/component"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, options)
|
||||
|
@ -14,7 +14,7 @@ func TestComponentService_Create_Success(t *testing.T) {
|
||||
testRequestURL(t, r, "/rest/api/2/component")
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
fmt.Fprint(w, `{ "self": "http://www.example.com/jira/rest/api/2/component/10000", "id": "10000", "name": "Component 1", "description": "This is a JIRA component", "lead": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "assigneeType": "PROJECT_LEAD", "assignee": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "realAssigneeType": "PROJECT_LEAD", "realAssignee": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "isAssigneeTypeValid": false, "project": "HSP", "projectId": 10000 }`)
|
||||
fmt.Fprint(w, `{ "self": "http://www.example.com/jira/rest/api/2/component/10000", "id": "10000", "name": "Component 1", "description": "This is a Jira component", "lead": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "assigneeType": "PROJECT_LEAD", "assignee": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "realAssigneeType": "PROJECT_LEAD", "realAssignee": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "isAssigneeTypeValid": false, "project": "HSP", "projectId": 10000 }`)
|
||||
})
|
||||
|
||||
component, _, err := testClient.Component.Create(&CreateComponentOptions{
|
||||
|
2
error.go
2
error.go
@ -10,7 +10,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Error message from JIRA
|
||||
// Error message from Jira
|
||||
// See https://docs.atlassian.com/jira/REST/cloud/#error-responses
|
||||
type Error struct {
|
||||
HTTPError error
|
||||
|
10
field.go
10
field.go
@ -2,14 +2,14 @@ package jira
|
||||
|
||||
import "context"
|
||||
|
||||
// FieldService handles fields for the JIRA instance / API.
|
||||
// FieldService handles fields for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Field
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Field
|
||||
type FieldService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Field represents a field of a JIRA issue.
|
||||
// Field represents a field of a Jira issue.
|
||||
type Field struct {
|
||||
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
||||
Key string `json:"key,omitempty" structs:"key,omitempty"`
|
||||
@ -26,9 +26,9 @@ type FieldSchema struct {
|
||||
System string `json:"system,omitempty" structs:"system,omitempty"`
|
||||
}
|
||||
|
||||
// GetListWithContext gets all fields from JIRA
|
||||
// GetListWithContext gets all fields from Jira
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-field-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-field-get
|
||||
func (s *FieldService) GetListWithContext(ctx context.Context) ([]Field, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/field"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
|
@ -2,13 +2,14 @@ package jira
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
import "fmt"
|
||||
|
||||
// FilterService handles fields for the JIRA instance / API.
|
||||
// FilterService handles fields for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Filter
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Filter
|
||||
type FilterService struct {
|
||||
client *Client
|
||||
}
|
||||
@ -224,7 +225,7 @@ func (fs *FilterService) GetMyFilters(opts *GetMyFiltersQueryOptions) ([]*Filter
|
||||
|
||||
// SearchWithContext will search for filter according to the search options
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-rest-api-3-filter-search-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-rest-api-3-filter-search-get
|
||||
func (fs *FilterService) SearchWithContext(ctx context.Context, opt *FilterSearchOptions) (*FiltersList, *Response, error) {
|
||||
apiEndpoint := "rest/api/3/filter/search"
|
||||
url, err := addOptions(apiEndpoint, opt)
|
||||
|
14
group.go
14
group.go
@ -6,9 +6,9 @@ import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// GroupService handles Groups for the JIRA instance / API.
|
||||
// GroupService handles Groups for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group
|
||||
type GroupService struct {
|
||||
client *Client
|
||||
}
|
||||
@ -22,7 +22,7 @@ type groupMembersResult struct {
|
||||
Members []GroupMember `json:"values"`
|
||||
}
|
||||
|
||||
// Group represents a JIRA group
|
||||
// Group represents a Jira group
|
||||
type Group struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
@ -63,7 +63,7 @@ type GroupSearchOptions struct {
|
||||
// Users in the page are ordered by user names.
|
||||
// User of this resource is required to have sysadmin or admin permissions.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group-getUsersFromGroup
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group-getUsersFromGroup
|
||||
//
|
||||
// WARNING: This API only returns the first page of group members
|
||||
func (s *GroupService) GetWithContext(ctx context.Context, name string) ([]GroupMember, *Response, error) {
|
||||
@ -91,7 +91,7 @@ func (s *GroupService) Get(name string) ([]GroupMember, *Response, error) {
|
||||
// Users in the page are ordered by user names.
|
||||
// User of this resource is required to have sysadmin or admin permissions.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group-getUsersFromGroup
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group-getUsersFromGroup
|
||||
func (s *GroupService) GetWithOptionsWithContext(ctx context.Context, name string, options *GroupSearchOptions) ([]GroupMember, *Response, error) {
|
||||
var apiEndpoint string
|
||||
if options == nil {
|
||||
@ -125,7 +125,7 @@ func (s *GroupService) GetWithOptions(name string, options *GroupSearchOptions)
|
||||
|
||||
// AddWithContext adds user to group
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/group-addUserToGroup
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/group-addUserToGroup
|
||||
func (s *GroupService) AddWithContext(ctx context.Context, groupname string, username string) (*Group, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/group/user?groupname=%s", groupname)
|
||||
var user struct {
|
||||
@ -154,7 +154,7 @@ func (s *GroupService) Add(groupname string, username string) (*Group, *Response
|
||||
|
||||
// RemoveWithContext removes user from group
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/group-removeUserFromGroup
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/group-removeUserFromGroup
|
||||
func (s *GroupService) RemoveWithContext(ctx context.Context, groupname string, username string) (*Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/group/user?groupname=%s&username=%s", groupname, username)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "DELETE", apiEndpoint, nil)
|
||||
|
115
issue.go
115
issue.go
@ -21,13 +21,13 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// AssigneeAutomatic represents the value of the "Assignee: Automatic" of JIRA
|
||||
// AssigneeAutomatic represents the value of the "Assignee: Automatic" of Jira
|
||||
AssigneeAutomatic = "-1"
|
||||
)
|
||||
|
||||
// IssueService handles Issues for the JIRA instance / API.
|
||||
// IssueService handles Issues for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue
|
||||
type IssueService struct {
|
||||
client *Client
|
||||
}
|
||||
@ -39,7 +39,7 @@ type UpdateQueryOptions struct {
|
||||
OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"`
|
||||
}
|
||||
|
||||
// Issue represents a JIRA issue.
|
||||
// Issue represents a Jira issue.
|
||||
type Issue struct {
|
||||
Expand string `json:"expand,omitempty" structs:"expand,omitempty"`
|
||||
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
||||
@ -75,7 +75,7 @@ type Changelog struct {
|
||||
Histories []ChangelogHistory `json:"histories,omitempty"`
|
||||
}
|
||||
|
||||
// Attachment represents a JIRA attachment
|
||||
// Attachment represents a Jira attachment
|
||||
type Attachment struct {
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
||||
@ -99,8 +99,8 @@ type Epic struct {
|
||||
Done bool `json:"done" structs:"done"`
|
||||
}
|
||||
|
||||
// IssueFields represents single fields of a JIRA issue.
|
||||
// Every JIRA issue has several fields attached.
|
||||
// IssueFields represents single fields of a Jira issue.
|
||||
// Every Jira issue has several fields attached.
|
||||
type IssueFields struct {
|
||||
// TODO Missing fields
|
||||
// * "workratio": -1,
|
||||
@ -147,7 +147,7 @@ type IssueFields struct {
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom JSON marshal function for the IssueFields structs.
|
||||
// It handles JIRA custom fields and maps those from / to "Unknowns" key.
|
||||
// It handles Jira custom fields and maps those from / to "Unknowns" key.
|
||||
func (i *IssueFields) MarshalJSON() ([]byte, error) {
|
||||
m := structs.Map(i)
|
||||
unknowns, okay := m["Unknowns"]
|
||||
@ -162,7 +162,7 @@ func (i *IssueFields) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a custom JSON marshal function for the IssueFields structs.
|
||||
// It handles JIRA custom fields and maps those from / to "Unknowns" key.
|
||||
// It handles Jira custom fields and maps those from / to "Unknowns" key.
|
||||
func (i *IssueFields) UnmarshalJSON(data []byte) error {
|
||||
|
||||
// Do the normal unmarshalling first
|
||||
@ -210,7 +210,7 @@ func (i *IssueFields) UnmarshalJSON(data []byte) error {
|
||||
|
||||
}
|
||||
|
||||
// IssueRenderedFields represents rendered fields of a JIRA issue.
|
||||
// IssueRenderedFields represents rendered fields of a Jira issue.
|
||||
// Not all IssueFields are rendered.
|
||||
type IssueRenderedFields struct {
|
||||
// TODO Missing fields
|
||||
@ -228,7 +228,7 @@ type IssueRenderedFields struct {
|
||||
Description string `json:"description,omitempty" structs:"description,omitempty"`
|
||||
}
|
||||
|
||||
// IssueType represents a type of a JIRA issue.
|
||||
// IssueType represents a type of a Jira issue.
|
||||
// Typical types are "Request", "Bug", "Story", ...
|
||||
type IssueType struct {
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
@ -240,7 +240,7 @@ type IssueType struct {
|
||||
AvatarID int `json:"avatarId,omitempty" structs:"avatarId,omitempty"`
|
||||
}
|
||||
|
||||
// Watches represents a type of how many and which user are "observing" a JIRA issue to track the status / updates.
|
||||
// Watches represents a type of how many and which user are "observing" a Jira issue to track the status / updates.
|
||||
type Watches struct {
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
WatchCount int `json:"watchCount,omitempty" structs:"watchCount,omitempty"`
|
||||
@ -265,35 +265,35 @@ type AvatarUrls struct {
|
||||
Three2X32 string `json:"32x32,omitempty" structs:"32x32,omitempty"`
|
||||
}
|
||||
|
||||
// Component represents a "component" of a JIRA issue.
|
||||
// Components can be user defined in every JIRA instance.
|
||||
// Component represents a "component" of a Jira issue.
|
||||
// Components can be user defined in every Jira instance.
|
||||
type Component struct {
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
||||
Name string `json:"name,omitempty" structs:"name,omitempty"`
|
||||
}
|
||||
|
||||
// Progress represents the progress of a JIRA issue.
|
||||
// Progress represents the progress of a Jira issue.
|
||||
type Progress struct {
|
||||
Progress int `json:"progress" structs:"progress"`
|
||||
Total int `json:"total" structs:"total"`
|
||||
Percent int `json:"percent" structs:"percent"`
|
||||
}
|
||||
|
||||
// Parent represents the parent of a JIRA issue, to be used with subtask issue types.
|
||||
// Parent represents the parent of a Jira issue, to be used with subtask issue types.
|
||||
type Parent struct {
|
||||
ID string `json:"id,omitempty" structs:"id"`
|
||||
Key string `json:"key,omitempty" structs:"key"`
|
||||
}
|
||||
|
||||
// Time represents the Time definition of JIRA as a time.Time of go
|
||||
// Time represents the Time definition of Jira as a time.Time of go
|
||||
type Time time.Time
|
||||
|
||||
func (t Time) Equal(u Time) bool {
|
||||
return time.Time(t).Equal(time.Time(u))
|
||||
}
|
||||
|
||||
// Date represents the Date definition of JIRA as a time.Time of go
|
||||
// Date represents the Date definition of Jira as a time.Time of go
|
||||
type Date time.Time
|
||||
|
||||
// Wrapper struct for search result
|
||||
@ -301,7 +301,7 @@ type transitionResult struct {
|
||||
Transitions []Transition `json:"transitions" structs:"transitions"`
|
||||
}
|
||||
|
||||
// Transition represents an issue transition in JIRA
|
||||
// Transition represents an issue transition in Jira
|
||||
type Transition struct {
|
||||
ID string `json:"id" structs:"id"`
|
||||
Name string `json:"name" structs:"name"`
|
||||
@ -336,8 +336,8 @@ type Option struct {
|
||||
Value string `json:"value" structs:"value"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON will transform the JIRA time into a time.Time
|
||||
// during the transformation of the JIRA JSON response
|
||||
// UnmarshalJSON will transform the Jira time into a time.Time
|
||||
// during the transformation of the Jira JSON response
|
||||
func (t *Time) UnmarshalJSON(b []byte) error {
|
||||
// Ignore null, like in the main JSON package.
|
||||
if string(b) == "null" {
|
||||
@ -351,14 +351,14 @@ func (t *Time) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON will transform the time.Time into a JIRA time
|
||||
// during the creation of a JIRA request
|
||||
// MarshalJSON will transform the time.Time into a Jira time
|
||||
// during the creation of a Jira request
|
||||
func (t Time) MarshalJSON() ([]byte, error) {
|
||||
return []byte(time.Time(t).Format("\"2006-01-02T15:04:05.000-0700\"")), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON will transform the JIRA date into a time.Time
|
||||
// during the transformation of the JIRA JSON response
|
||||
// UnmarshalJSON will transform the Jira date into a time.Time
|
||||
// during the transformation of the Jira JSON response
|
||||
func (t *Date) UnmarshalJSON(b []byte) error {
|
||||
// Ignore null, like in the main JSON package.
|
||||
if string(b) == "null" {
|
||||
@ -373,16 +373,16 @@ func (t *Date) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
// MarshalJSON will transform the Date object into a short
|
||||
// date string as JIRA expects during the creation of a
|
||||
// JIRA request
|
||||
// date string as Jira expects during the creation of a
|
||||
// Jira request
|
||||
func (t Date) MarshalJSON() ([]byte, error) {
|
||||
time := time.Time(t)
|
||||
return []byte(time.Format("\"2006-01-02\"")), nil
|
||||
}
|
||||
|
||||
// Worklog represents the work log of a JIRA issue.
|
||||
// Worklog represents the work log of a Jira issue.
|
||||
// One Worklog contains zero or n WorklogRecords
|
||||
// JIRA Wiki: https://confluence.atlassian.com/jira/logging-work-on-an-issue-185729605.html
|
||||
// Jira Wiki: https://confluence.atlassian.com/jira/logging-work-on-an-issue-185729605.html
|
||||
type Worklog struct {
|
||||
StartAt int `json:"startAt" structs:"startAt"`
|
||||
MaxResults int `json:"maxResults" structs:"maxResults"`
|
||||
@ -411,7 +411,7 @@ type EntityProperty struct {
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
// TimeTracking represents the timetracking fields of a JIRA issue.
|
||||
// TimeTracking represents the timetracking fields of a Jira issue.
|
||||
type TimeTracking struct {
|
||||
OriginalEstimate string `json:"originalEstimate,omitempty" structs:"originalEstimate,omitempty"`
|
||||
RemainingEstimate string `json:"remainingEstimate,omitempty" structs:"remainingEstimate,omitempty"`
|
||||
@ -429,7 +429,7 @@ type Subtasks struct {
|
||||
Fields IssueFields `json:"fields" structs:"fields"`
|
||||
}
|
||||
|
||||
// IssueLink represents a link between two issues in JIRA.
|
||||
// IssueLink represents a link between two issues in Jira.
|
||||
type IssueLink struct {
|
||||
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
@ -439,7 +439,7 @@ type IssueLink struct {
|
||||
Comment *Comment `json:"comment,omitempty" structs:"comment,omitempty"`
|
||||
}
|
||||
|
||||
// IssueLinkType represents a type of a link between to issues in JIRA.
|
||||
// IssueLinkType represents a type of a link between to issues in Jira.
|
||||
// Typical issue link types are "Related to", "Duplicate", "Is blocked by", etc.
|
||||
type IssueLinkType struct {
|
||||
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
||||
@ -454,7 +454,7 @@ type Comments struct {
|
||||
Comments []*Comment `json:"comments,omitempty" structs:"comments,omitempty"`
|
||||
}
|
||||
|
||||
// Comment represents a comment by a person to an issue in JIRA.
|
||||
// Comment represents a comment by a person to an issue in Jira.
|
||||
type Comment struct {
|
||||
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
@ -493,7 +493,7 @@ type CommentVisibility struct {
|
||||
|
||||
// SearchOptions specifies the optional parameters to various List methods that
|
||||
// support pagination.
|
||||
// Pagination is used for the JIRA REST APIs to conserve server resources and limit
|
||||
// Pagination is used for the Jira REST APIs to conserve server resources and limit
|
||||
// response size for resources that return potentially large collection of items.
|
||||
// A request to a pages API will result in a values array wrapped in a JSON object with some paging metadata
|
||||
// Default Pagination options
|
||||
@ -547,8 +547,8 @@ type AddWorklogQueryOptions struct {
|
||||
OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"`
|
||||
}
|
||||
|
||||
// CustomFields represents custom fields of JIRA
|
||||
// This can heavily differ between JIRA instances
|
||||
// CustomFields represents custom fields of Jira
|
||||
// This can heavily differ between Jira instances
|
||||
type CustomFields map[string]string
|
||||
|
||||
// RemoteLink represents remote links which linked to issues
|
||||
@ -590,13 +590,13 @@ type RemoteLinkStatus struct {
|
||||
}
|
||||
|
||||
// GetWithContext returns a full representation of the issue for the given issue key.
|
||||
// JIRA will attempt to identify the issue by the issueIdOrKey path parameter.
|
||||
// Jira will attempt to identify the issue by the issueIdOrKey path parameter.
|
||||
// This can be an issue id, or an issue key.
|
||||
// If the issue cannot be found via an exact match, JIRA will also look for the issue in a case-insensitive way, or by looking to see if the issue was moved.
|
||||
// If the issue cannot be found via an exact match, Jira will also look for the issue in a case-insensitive way, or by looking to see if the issue was moved.
|
||||
//
|
||||
// The given options will be appended to the query string
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getIssue
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getIssue
|
||||
func (s *IssueService) GetWithContext(ctx context.Context, issueID string, options *GetQueryOptions) (*Issue, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s", issueID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -767,7 +767,7 @@ func WithQueryOptions(options interface{}) func(*http.Request) error {
|
||||
// Creating a sub-task is similar to creating a regular issue, with two important differences:
|
||||
// The issueType field must correspond to a sub-task issue type and you must provide a parent field in the issue create request containing the id or key of the parent issue.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-createIssues
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-createIssues
|
||||
func (s *IssueService) CreateWithContext(ctx context.Context, issue *Issue) (*Issue, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/issue"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, issue)
|
||||
@ -801,7 +801,7 @@ func (s *IssueService) Create(issue *Issue) (*Issue, *Response, error) {
|
||||
// UpdateWithOptionsWithContext updates an issue from a JSON representation,
|
||||
// while also specifying query params. The issue is found by key.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue
|
||||
func (s *IssueService) UpdateWithOptionsWithContext(ctx context.Context, issue *Issue, opts *UpdateQueryOptions) (*Issue, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%v", issue.Key)
|
||||
url, err := addOptions(apiEndpoint, opts)
|
||||
@ -831,7 +831,7 @@ func (s *IssueService) UpdateWithOptions(issue *Issue, opts *UpdateQueryOptions)
|
||||
|
||||
// UpdateWithContext updates an issue from a JSON representation. The issue is found by key.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue
|
||||
func (s *IssueService) UpdateWithContext(ctx context.Context, issue *Issue) (*Issue, *Response, error) {
|
||||
return s.UpdateWithOptions(issue, nil)
|
||||
}
|
||||
@ -867,7 +867,7 @@ func (s *IssueService) UpdateIssue(jiraID string, data map[string]interface{}) (
|
||||
|
||||
// AddCommentWithContext adds a new comment to issueID.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-addComment
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-addComment
|
||||
func (s *IssueService) AddCommentWithContext(ctx context.Context, issueID string, comment *Comment) (*Comment, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/comment", issueID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, comment)
|
||||
@ -892,7 +892,7 @@ func (s *IssueService) AddComment(issueID string, comment *Comment) (*Comment, *
|
||||
|
||||
// UpdateCommentWithContext updates the body of a comment, identified by comment.ID, on the issueID.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/comment-updateComment
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/comment-updateComment
|
||||
func (s *IssueService) UpdateCommentWithContext(ctx context.Context, issueID string, comment *Comment) (*Comment, *Response, error) {
|
||||
reqBody := struct {
|
||||
Body string `json:"body"`
|
||||
@ -921,7 +921,7 @@ func (s *IssueService) UpdateComment(issueID string, comment *Comment) (*Comment
|
||||
|
||||
// DeleteCommentWithContext Deletes a comment from an issueID.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-issue-issueIdOrKey-comment-id-delete
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-issue-issueIdOrKey-comment-id-delete
|
||||
func (s *IssueService) DeleteCommentWithContext(ctx context.Context, issueID, commentID string) error {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/comment/%s", issueID, commentID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "DELETE", apiEndpoint, nil)
|
||||
@ -1009,7 +1009,7 @@ func (s *IssueService) UpdateWorklogRecord(issueID, worklogID string, record *Wo
|
||||
|
||||
// AddLinkWithContext adds a link between two issues.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issueLink
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issueLink
|
||||
func (s *IssueService) AddLinkWithContext(ctx context.Context, issueLink *IssueLink) (*Response, error) {
|
||||
apiEndpoint := "rest/api/2/issueLink"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, issueLink)
|
||||
@ -1032,7 +1032,7 @@ func (s *IssueService) AddLink(issueLink *IssueLink) (*Response, error) {
|
||||
|
||||
// SearchWithContext will search for tickets according to the jql
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-query-issues
|
||||
// Jira API docs: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-query-issues
|
||||
func (s *IssueService) SearchWithContext(ctx context.Context, jql string, options *SearchOptions) ([]Issue, *Response, error) {
|
||||
u := url.URL{
|
||||
Path: "rest/api/2/search",
|
||||
@ -1043,7 +1043,6 @@ func (s *IssueService) SearchWithContext(ctx context.Context, jql string, option
|
||||
}
|
||||
|
||||
if options != nil {
|
||||
|
||||
if options.StartAt != 0 {
|
||||
uv.Add("startAt", strconv.Itoa(options.StartAt))
|
||||
}
|
||||
@ -1083,7 +1082,7 @@ func (s *IssueService) Search(jql string, options *SearchOptions) ([]Issue, *Res
|
||||
|
||||
// SearchPagesWithContext will get issues from all pages in a search
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-query-issues
|
||||
// Jira API docs: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-query-issues
|
||||
func (s *IssueService) SearchPagesWithContext(ctx context.Context, jql string, options *SearchOptions, f func(Issue) error) error {
|
||||
if options == nil {
|
||||
options = &SearchOptions{
|
||||
@ -1175,7 +1174,7 @@ func (s *IssueService) GetCustomFields(issueID string) (CustomFields, *Response,
|
||||
// GetTransitionsWithContext gets a list of the transitions possible for this issue by the current user,
|
||||
// along with fields that are required and their types.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getTransitions
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getTransitions
|
||||
func (s *IssueService) GetTransitionsWithContext(ctx context.Context, id string) ([]Transition, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/transitions?expand=transitions.fields", id)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -1199,7 +1198,7 @@ func (s *IssueService) GetTransitions(id string) ([]Transition, *Response, error
|
||||
// DoTransitionWithContext performs a transition on an issue.
|
||||
// When performing the transition you can update or set other issue fields.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition
|
||||
func (s *IssueService) DoTransitionWithContext(ctx context.Context, ticketID, transitionID string) (*Response, error) {
|
||||
payload := CreateTransitionPayload{
|
||||
Transition: TransitionPayload{
|
||||
@ -1217,7 +1216,7 @@ func (s *IssueService) DoTransition(ticketID, transitionID string) (*Response, e
|
||||
// DoTransitionWithPayloadWithContext performs a transition on an issue using any payload.
|
||||
// When performing the transition you can update or set other issue fields.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition
|
||||
func (s *IssueService) DoTransitionWithPayloadWithContext(ctx context.Context, ticketID, payload interface{}) (*Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/transitions", ticketID)
|
||||
|
||||
@ -1343,7 +1342,7 @@ func (s *IssueService) Delete(issueID string) (*Response, error) {
|
||||
|
||||
// GetWatchersWithContext wil return all the users watching/observing the given issue
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-getIssueWatchers
|
||||
// Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-getIssueWatchers
|
||||
func (s *IssueService) GetWatchersWithContext(ctx context.Context, issueID string) (*[]User, *Response, error) {
|
||||
watchesAPIEndpoint := fmt.Sprintf("rest/api/2/issue/%s/watchers", issueID)
|
||||
|
||||
@ -1386,7 +1385,7 @@ func (s *IssueService) GetWatchers(issueID string) (*[]User, *Response, error) {
|
||||
|
||||
// AddWatcherWithContext adds watcher to the given issue
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-addWatcher
|
||||
// Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-addWatcher
|
||||
func (s *IssueService) AddWatcherWithContext(ctx context.Context, issueID string, userName string) (*Response, error) {
|
||||
apiEndPoint := fmt.Sprintf("rest/api/2/issue/%s/watchers", issueID)
|
||||
|
||||
@ -1410,7 +1409,7 @@ func (s *IssueService) AddWatcher(issueID string, userName string) (*Response, e
|
||||
|
||||
// RemoveWatcherWithContext removes given user from given issue
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-removeWatcher
|
||||
// Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-removeWatcher
|
||||
func (s *IssueService) RemoveWatcherWithContext(ctx context.Context, issueID string, userName string) (*Response, error) {
|
||||
apiEndPoint := fmt.Sprintf("rest/api/2/issue/%s/watchers", issueID)
|
||||
|
||||
@ -1434,7 +1433,7 @@ func (s *IssueService) RemoveWatcher(issueID string, userName string) (*Response
|
||||
|
||||
// UpdateAssigneeWithContext updates the user assigned to work on the given issue
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/software/jira/docs/api/REST/7.10.2/#api/2/issue-assign
|
||||
// Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/7.10.2/#api/2/issue-assign
|
||||
func (s *IssueService) UpdateAssigneeWithContext(ctx context.Context, issueID string, assignee *User) (*Response, error) {
|
||||
apiEndPoint := fmt.Sprintf("rest/api/2/issue/%s/assignee", issueID)
|
||||
|
||||
@ -1468,7 +1467,7 @@ func (c ChangelogHistory) CreatedTime() (time.Time, error) {
|
||||
|
||||
// GetRemoteLinksWithContext gets remote issue links on the issue.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getRemoteIssueLinks
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getRemoteIssueLinks
|
||||
func (s *IssueService) GetRemoteLinksWithContext(ctx context.Context, id string) (*[]RemoteLink, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/remotelink", id)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -1491,7 +1490,7 @@ func (s *IssueService) GetRemoteLinks(id string) (*[]RemoteLink, *Response, erro
|
||||
|
||||
// AddRemoteLinkWithContext adds a remote link to issueID.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-remotelink-post
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-remotelink-post
|
||||
func (s *IssueService) AddRemoteLinkWithContext(ctx context.Context, issueID string, remotelink *RemoteLink) (*RemoteLink, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/remotelink", issueID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, remotelink)
|
||||
|
@ -7,16 +7,16 @@ import (
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// IssueLinkTypeService handles issue link types for the JIRA instance / API.
|
||||
// IssueLinkTypeService handles issue link types for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-group-Issue-link-types
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-group-Issue-link-types
|
||||
type IssueLinkTypeService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GetListWithContext gets all of the issue link types from JIRA.
|
||||
// GetListWithContext gets all of the issue link types from Jira.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-get
|
||||
func (s *IssueLinkTypeService) GetListWithContext(ctx context.Context) ([]IssueLinkType, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/issueLinkType"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -37,9 +37,9 @@ func (s *IssueLinkTypeService) GetList() ([]IssueLinkType, *Response, error) {
|
||||
return s.GetListWithContext(context.Background())
|
||||
}
|
||||
|
||||
// GetWithContext gets info of a specific issue link type from JIRA.
|
||||
// GetWithContext gets info of a specific issue link type from Jira.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-get
|
||||
func (s *IssueLinkTypeService) GetWithContext(ctx context.Context, ID string) (*IssueLinkType, *Response, error) {
|
||||
apiEndPoint := fmt.Sprintf("rest/api/2/issueLinkType/%s", ID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndPoint, nil)
|
||||
@ -60,9 +60,9 @@ func (s *IssueLinkTypeService) Get(ID string) (*IssueLinkType, *Response, error)
|
||||
return s.GetWithContext(context.Background(), ID)
|
||||
}
|
||||
|
||||
// CreateWithContext creates an issue link type in JIRA.
|
||||
// CreateWithContext creates an issue link type in Jira.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-post
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-post
|
||||
func (s *IssueLinkTypeService) CreateWithContext(ctx context.Context, linkType *IssueLinkType) (*IssueLinkType, *Response, error) {
|
||||
apiEndpoint := "/rest/api/2/issueLinkType"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, linkType)
|
||||
@ -97,7 +97,7 @@ func (s *IssueLinkTypeService) Create(linkType *IssueLinkType) (*IssueLinkType,
|
||||
|
||||
// UpdateWithContext updates an issue link type. The issue is found by key.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-put
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-put
|
||||
func (s *IssueLinkTypeService) UpdateWithContext(ctx context.Context, linkType *IssueLinkType) (*IssueLinkType, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issueLinkType/%s", linkType.ID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "PUT", apiEndpoint, linkType)
|
||||
@ -119,7 +119,7 @@ func (s *IssueLinkTypeService) Update(linkType *IssueLinkType) (*IssueLinkType,
|
||||
|
||||
// DeleteWithContext deletes an issue link type based on provided ID.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-delete
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-delete
|
||||
func (s *IssueLinkTypeService) DeleteWithContext(ctx context.Context, ID string) (*Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issueLinkType/%s", ID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "DELETE", apiEndpoint, nil)
|
||||
|
18
jira.go
18
jira.go
@ -26,7 +26,7 @@ type httpClient interface {
|
||||
Do(request *http.Request) (response *http.Response, err error)
|
||||
}
|
||||
|
||||
// A Client manages communication with the JIRA API.
|
||||
// A Client manages communication with the Jira API.
|
||||
type Client struct {
|
||||
// HTTP client used to communicate with the API.
|
||||
client httpClient
|
||||
@ -37,7 +37,7 @@ type Client struct {
|
||||
// Session storage if the user authenticates with a Session cookie
|
||||
session *Session
|
||||
|
||||
// Services used for talking to different parts of the JIRA API.
|
||||
// Services used for talking to different parts of the Jira API.
|
||||
Authentication *AuthenticationService
|
||||
Issue *IssueService
|
||||
Project *ProjectService
|
||||
@ -58,13 +58,13 @@ type Client struct {
|
||||
IssueLinkType *IssueLinkTypeService
|
||||
}
|
||||
|
||||
// NewClient returns a new JIRA API client.
|
||||
// NewClient returns a new Jira API client.
|
||||
// If a nil httpClient is provided, http.DefaultClient will be used.
|
||||
// To use API methods which require authentication you can follow the preferred solution and
|
||||
// provide an http.Client that will perform the authentication for you with OAuth and HTTP Basic (such as that provided by the golang.org/x/oauth2 library).
|
||||
// As an alternative you can use Session Cookie based authentication provided by this package as well.
|
||||
// See https://docs.atlassian.com/jira/REST/latest/#authentication
|
||||
// baseURL is the HTTP endpoint of your JIRA instance and should always be specified with a trailing slash.
|
||||
// baseURL is the HTTP endpoint of your Jira instance and should always be specified with a trailing slash.
|
||||
func NewClient(httpClient httpClient, baseURL string) (*Client, error) {
|
||||
if httpClient == nil {
|
||||
httpClient = http.DefaultClient
|
||||
@ -295,7 +295,7 @@ func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) {
|
||||
// CheckResponse checks the API response for errors, and returns them if present.
|
||||
// A response is considered an error if it has a status code outside the 200 range.
|
||||
// The caller is responsible to analyze the response body.
|
||||
// The body can contain JSON (if the error is intended) or xml (sometimes JIRA just failes).
|
||||
// The body can contain JSON (if the error is intended) or xml (sometimes Jira just failes).
|
||||
func CheckResponse(r *http.Response) error {
|
||||
if c := r.StatusCode; 200 <= c && c <= 299 {
|
||||
return nil
|
||||
@ -311,7 +311,7 @@ func (c *Client) GetBaseURL() url.URL {
|
||||
return *c.baseURL
|
||||
}
|
||||
|
||||
// Response represents JIRA API response. It wraps http.Response returned from
|
||||
// Response represents Jira API response. It wraps http.Response returned from
|
||||
// API and provides information about paging.
|
||||
type Response struct {
|
||||
*http.Response
|
||||
@ -382,9 +382,9 @@ func (t *BasicAuthTransport) transport() http.RoundTripper {
|
||||
// using Jira's cookie-based authentication.
|
||||
//
|
||||
// Note that it is generally preferable to use HTTP BASIC authentication with the REST API.
|
||||
// However, this resource may be used to mimic the behaviour of JIRA's log-in page (e.g. to display log-in errors to a user).
|
||||
// However, this resource may be used to mimic the behaviour of Jira's log-in page (e.g. to display log-in errors to a user).
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
type CookieAuthTransport struct {
|
||||
Username string
|
||||
Password string
|
||||
@ -479,7 +479,7 @@ func (t *CookieAuthTransport) transport() http.RoundTripper {
|
||||
//
|
||||
// NOTE: this form of auth should be used by add-ons installed from the Atlassian marketplace.
|
||||
//
|
||||
// JIRA docs: https://developer.atlassian.com/cloud/jira/platform/understanding-jwt
|
||||
// Jira docs: https://developer.atlassian.com/cloud/jira/platform/understanding-jwt
|
||||
// Examples in other languages:
|
||||
// https://bitbucket.org/atlassian/atlassian-jwt-ruby/src/d44a8e7a4649e4f23edaa784402655fda7c816ea/lib/atlassian/jwt.rb
|
||||
// https://bitbucket.org/atlassian/atlassian-jwt-py/src/master/atlassian_jwt/url_utils.py
|
||||
|
35
jira_test.go
35
jira_test.go
@ -14,14 +14,14 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
testJIRAInstanceURL = "https://issues.apache.org/jira/"
|
||||
testJiraInstanceURL = "https://issues.apache.org/jira/"
|
||||
)
|
||||
|
||||
var (
|
||||
// testMux is the HTTP request multiplexer used with the test server.
|
||||
testMux *http.ServeMux
|
||||
|
||||
// testClient is the JIRA client being tested.
|
||||
// testClient is the Jira client being tested.
|
||||
testClient *Client
|
||||
|
||||
// testServer is a test HTTP server used to provide mock API responses.
|
||||
@ -86,7 +86,8 @@ func TestNewClient_WrongUrl(t *testing.T) {
|
||||
func TestNewClient_WithHttpClient(t *testing.T) {
|
||||
httpClient := http.DefaultClient
|
||||
httpClient.Timeout = 10 * time.Minute
|
||||
c, err := NewClient(httpClient, testJIRAInstanceURL)
|
||||
|
||||
c, err := NewClient(httpClient, testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("Got an error: %s", err)
|
||||
}
|
||||
@ -100,7 +101,7 @@ func TestNewClient_WithHttpClient(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewClient_WithServices(t *testing.T) {
|
||||
c, err := NewClient(nil, testJIRAInstanceURL)
|
||||
c, err := NewClient(nil, testJiraInstanceURL)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Got an error: %s", err)
|
||||
@ -156,12 +157,12 @@ func TestCheckResponse(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClient_NewRequest(t *testing.T) {
|
||||
c, err := NewClient(nil, testJIRAInstanceURL)
|
||||
c, err := NewClient(nil, testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
|
||||
}
|
||||
|
||||
inURL, outURL := "rest/api/2/issue/", testJIRAInstanceURL+"rest/api/2/issue/"
|
||||
inURL, outURL := "rest/api/2/issue/", testJiraInstanceURL+"rest/api/2/issue/"
|
||||
inBody, outBody := &Issue{Key: "MESOS"}, `{"key":"MESOS"}`+"\n"
|
||||
req, _ := c.NewRequest("GET", inURL, inBody)
|
||||
|
||||
@ -178,12 +179,12 @@ func TestClient_NewRequest(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClient_NewRawRequest(t *testing.T) {
|
||||
c, err := NewClient(nil, testJIRAInstanceURL)
|
||||
c, err := NewClient(nil, testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
|
||||
}
|
||||
|
||||
inURL, outURL := "rest/api/2/issue/", testJIRAInstanceURL+"rest/api/2/issue/"
|
||||
inURL, outURL := "rest/api/2/issue/", testJiraInstanceURL+"rest/api/2/issue/"
|
||||
|
||||
outBody := `{"key":"MESOS"}` + "\n"
|
||||
inBody := outBody
|
||||
@ -211,7 +212,7 @@ func testURLParseError(t *testing.T, err error) {
|
||||
}
|
||||
|
||||
func TestClient_NewRequest_BadURL(t *testing.T) {
|
||||
c, err := NewClient(nil, testJIRAInstanceURL)
|
||||
c, err := NewClient(nil, testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
|
||||
}
|
||||
@ -220,7 +221,7 @@ func TestClient_NewRequest_BadURL(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClient_NewRequest_SessionCookies(t *testing.T) {
|
||||
c, err := NewClient(nil, testJIRAInstanceURL)
|
||||
c, err := NewClient(nil, testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
|
||||
}
|
||||
@ -249,7 +250,7 @@ func TestClient_NewRequest_SessionCookies(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClient_NewRequest_BasicAuth(t *testing.T) {
|
||||
c, err := NewClient(nil, testJIRAInstanceURL)
|
||||
c, err := NewClient(nil, testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
|
||||
}
|
||||
@ -275,7 +276,7 @@ func TestClient_NewRequest_BasicAuth(t *testing.T) {
|
||||
// since there is no difference between an HTTP request body that is an empty string versus one that is not set at all.
|
||||
// However in certain cases, intermediate systems may treat these differently resulting in subtle errors.
|
||||
func TestClient_NewRequest_EmptyBody(t *testing.T) {
|
||||
c, err := NewClient(nil, testJIRAInstanceURL)
|
||||
c, err := NewClient(nil, testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
|
||||
}
|
||||
@ -289,7 +290,7 @@ func TestClient_NewRequest_EmptyBody(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClient_NewMultiPartRequest(t *testing.T) {
|
||||
c, err := NewClient(nil, testJIRAInstanceURL)
|
||||
c, err := NewClient(nil, testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
|
||||
}
|
||||
@ -322,7 +323,7 @@ func TestClient_NewMultiPartRequest(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClient_NewMultiPartRequest_BasicAuth(t *testing.T) {
|
||||
c, err := NewClient(nil, testJIRAInstanceURL)
|
||||
c, err := NewClient(nil, testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
|
||||
}
|
||||
@ -411,7 +412,7 @@ func TestClient_Do_HTTPError(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test handling of an error caused by the internal http client's Do() function.
|
||||
// A redirect loop is pretty unlikely to occur within the JIRA API, but does allow us to exercise the right code path.
|
||||
// A redirect loop is pretty unlikely to occur within the Jira API, but does allow us to exercise the right code path.
|
||||
func TestClient_Do_RedirectLoop(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
@ -432,12 +433,12 @@ func TestClient_Do_RedirectLoop(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClient_GetBaseURL_WithURL(t *testing.T) {
|
||||
u, err := url.Parse(testJIRAInstanceURL)
|
||||
u, err := url.Parse(testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("URL parsing -> Got an error: %s", err)
|
||||
}
|
||||
|
||||
c, err := NewClient(nil, testJIRAInstanceURL)
|
||||
c, err := NewClient(nil, testJiraInstanceURL)
|
||||
if err != nil {
|
||||
t.Errorf("Client creation -> Got an error: %s", err)
|
||||
}
|
||||
|
@ -71,7 +71,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10004",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "QA",
|
||||
"id": "10004",
|
||||
@ -85,7 +85,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10005",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "Icebox",
|
||||
"id": "10005",
|
||||
@ -99,7 +99,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10006",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "To Be Specced",
|
||||
"id": "10006",
|
||||
@ -113,7 +113,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10100",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "Blocked",
|
||||
"id": "10100",
|
||||
@ -141,7 +141,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10205",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "Validation",
|
||||
"id": "10205",
|
||||
@ -155,7 +155,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10300",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "Graveyard",
|
||||
"id": "10300",
|
||||
@ -281,7 +281,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10510",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "cannot reproduce",
|
||||
"id": "10510",
|
||||
@ -295,7 +295,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10601",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "Done",
|
||||
"id": "10601",
|
||||
@ -309,7 +309,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10602",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "In Progress",
|
||||
"id": "10602",
|
||||
@ -323,7 +323,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10603",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "Backlog",
|
||||
"id": "10603",
|
||||
@ -337,7 +337,7 @@
|
||||
},
|
||||
{
|
||||
"self": "https://test.jira.org/rest/api/2/status/10700",
|
||||
"description": "This status is managed internally by JIRA Software",
|
||||
"description": "This status is managed internally by Jira Software",
|
||||
"iconUrl": "https://test.jira.org/",
|
||||
"name": "Specs Complete",
|
||||
"id": "10700",
|
||||
|
@ -78,9 +78,9 @@
|
||||
{
|
||||
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/8",
|
||||
"id": "8",
|
||||
"description": "A request for a new JIRA project to be set up",
|
||||
"description": "A request for a new Jira project to be set up",
|
||||
"iconUrl": "https://issues.apache.org/jira/images/icons/jiraman18.gif",
|
||||
"name": "New JIRA Project",
|
||||
"name": "New Jira Project",
|
||||
"subtask": false
|
||||
},
|
||||
{
|
||||
@ -102,7 +102,7 @@
|
||||
{
|
||||
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/11",
|
||||
"id": "11",
|
||||
"description": "A formal question. Initially added for the Legal JIRA.",
|
||||
"description": "A formal question. Initially added for the Legal Jira.",
|
||||
"iconUrl": "https://issues.apache.org/jira/images/icons/issuetypes/genericissue.png",
|
||||
"name": "Question",
|
||||
"subtask": false
|
||||
@ -134,7 +134,7 @@
|
||||
{
|
||||
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/15",
|
||||
"id": "15",
|
||||
"description": "Created by JIRA Agile - do not edit or delete. Issue type for a big user story that needs to be broken down.",
|
||||
"description": "Created by Jira Agile - do not edit or delete. Issue type for a big user story that needs to be broken down.",
|
||||
"iconUrl": "https://issues.apache.org/jira/images/icons/issuetypes/epic.png",
|
||||
"name": "Epic",
|
||||
"subtask": false
|
||||
@ -142,7 +142,7 @@
|
||||
{
|
||||
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/16",
|
||||
"id": "16",
|
||||
"description": "Created by JIRA Agile - do not edit or delete. Issue type for a user story.",
|
||||
"description": "Created by Jira Agile - do not edit or delete. Issue type for a user story.",
|
||||
"iconUrl": "https://issues.apache.org/jira/images/icons/issuetypes/story.png",
|
||||
"name": "Story",
|
||||
"subtask": false
|
||||
@ -278,7 +278,7 @@
|
||||
{
|
||||
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/10300",
|
||||
"id": "10300",
|
||||
"description": "For general IT problems and questions. Created by JIRA Service Desk.",
|
||||
"description": "For general IT problems and questions. Created by Jira Service Desk.",
|
||||
"iconUrl": "https://issues.apache.org/jira/servicedesk/issue-type-icons?icon=it-help",
|
||||
"name": "IT Help",
|
||||
"subtask": false
|
||||
@ -286,7 +286,7 @@
|
||||
{
|
||||
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/10301",
|
||||
"id": "10301",
|
||||
"description": "For new system accounts or passwords. Created by JIRA Service Desk.",
|
||||
"description": "For new system accounts or passwords. Created by Jira Service Desk.",
|
||||
"iconUrl": "https://issues.apache.org/jira/servicedesk/issue-type-icons?icon=access",
|
||||
"name": "Access",
|
||||
"subtask": false
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// PermissionSchemeService handles permissionschemes for the JIRA instance / API.
|
||||
// PermissionSchemeService handles permissionschemes for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Permissionscheme
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Permissionscheme
|
||||
type PermissionSchemeService struct {
|
||||
client *Client
|
||||
}
|
||||
@ -30,7 +30,7 @@ type Holder struct {
|
||||
|
||||
// GetListWithContext returns a list of all permission schemes
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-permissionscheme-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-permissionscheme-get
|
||||
func (s *PermissionSchemeService) GetListWithContext(ctx context.Context) (*PermissionSchemes, *Response, error) {
|
||||
apiEndpoint := "/rest/api/3/permissionscheme"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -55,7 +55,7 @@ func (s *PermissionSchemeService) GetList() (*PermissionSchemes, *Response, erro
|
||||
|
||||
// GetWithContext returns a full representation of the permission scheme for the schemeID
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-permissionscheme-schemeId-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-permissionscheme-schemeId-get
|
||||
func (s *PermissionSchemeService) GetWithContext(ctx context.Context, schemeID int) (*PermissionScheme, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/3/permissionscheme/%d", schemeID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
|
10
priority.go
10
priority.go
@ -2,14 +2,14 @@ package jira
|
||||
|
||||
import "context"
|
||||
|
||||
// PriorityService handles priorities for the JIRA instance / API.
|
||||
// PriorityService handles priorities for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Priority
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Priority
|
||||
type PriorityService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Priority represents a priority of a JIRA issue.
|
||||
// Priority represents a priority of a Jira issue.
|
||||
// Typical types are "Normal", "Moderate", "Urgent", ...
|
||||
type Priority struct {
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
@ -20,9 +20,9 @@ type Priority struct {
|
||||
Description string `json:"description,omitempty" structs:"description,omitempty"`
|
||||
}
|
||||
|
||||
// GetListWithContext gets all priorities from JIRA
|
||||
// GetListWithContext gets all priorities from Jira
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-priority-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-priority-get
|
||||
func (s *PriorityService) GetListWithContext(ctx context.Context) ([]Priority, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/priority"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
|
22
project.go
22
project.go
@ -7,9 +7,9 @@ import (
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
// ProjectService handles projects for the JIRA instance / API.
|
||||
// ProjectService handles projects for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project
|
||||
type ProjectService struct {
|
||||
client *Client
|
||||
}
|
||||
@ -35,7 +35,7 @@ type ProjectCategory struct {
|
||||
Description string `json:"description" structs:"description,omitempty"`
|
||||
}
|
||||
|
||||
// Project represents a JIRA Project.
|
||||
// Project represents a Jira Project.
|
||||
type Project struct {
|
||||
Expand string `json:"expand,omitempty" structs:"expand,omitempty"`
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
@ -81,9 +81,9 @@ type PermissionScheme struct {
|
||||
Permissions []Permission `json:"permissions" structs:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// GetListWithContext gets all projects form JIRA
|
||||
// GetListWithContext gets all projects form Jira
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
|
||||
func (s *ProjectService) GetListWithContext(ctx context.Context) (*ProjectList, *Response, error) {
|
||||
return s.ListWithOptionsWithContext(ctx, &GetQueryOptions{})
|
||||
}
|
||||
@ -93,10 +93,10 @@ func (s *ProjectService) GetList() (*ProjectList, *Response, error) {
|
||||
return s.GetListWithContext(context.Background())
|
||||
}
|
||||
|
||||
// ListWithOptionsWithContext gets all projects form JIRA with optional query params, like &GetQueryOptions{Expand: "issueTypes"} to get
|
||||
// ListWithOptionsWithContext gets all projects form Jira with optional query params, like &GetQueryOptions{Expand: "issueTypes"} to get
|
||||
// a list of all projects and their supported issuetypes
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
|
||||
func (s *ProjectService) ListWithOptionsWithContext(ctx context.Context, options *GetQueryOptions) (*ProjectList, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/project"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -128,10 +128,10 @@ func (s *ProjectService) ListWithOptions(options *GetQueryOptions) (*ProjectList
|
||||
}
|
||||
|
||||
// GetWithContext returns a full representation of the project for the given issue key.
|
||||
// JIRA will attempt to identify the project by the projectIdOrKey path parameter.
|
||||
// Jira will attempt to identify the project by the projectIdOrKey path parameter.
|
||||
// This can be an project id, or an project key.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
|
||||
func (s *ProjectService) GetWithContext(ctx context.Context, projectID string) (*Project, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/project/%s", projectID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -155,10 +155,10 @@ func (s *ProjectService) Get(projectID string) (*Project, *Response, error) {
|
||||
}
|
||||
|
||||
// GetPermissionSchemeWithContext returns a full representation of the permission scheme for the project
|
||||
// JIRA will attempt to identify the project by the projectIdOrKey path parameter.
|
||||
// Jira will attempt to identify the project by the projectIdOrKey path parameter.
|
||||
// This can be an project id, or an project key.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
|
||||
func (s *ProjectService) GetPermissionSchemeWithContext(ctx context.Context, projectID string) (*PermissionScheme, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/project/%s/permissionscheme", projectID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
|
@ -2,14 +2,14 @@ package jira
|
||||
|
||||
import "context"
|
||||
|
||||
// ResolutionService handles resolutions for the JIRA instance / API.
|
||||
// ResolutionService handles resolutions for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Resolution
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Resolution
|
||||
type ResolutionService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Resolution represents a resolution of a JIRA issue.
|
||||
// Resolution represents a resolution of a Jira issue.
|
||||
// Typical types are "Fixed", "Suspended", "Won't Fix", ...
|
||||
type Resolution struct {
|
||||
Self string `json:"self" structs:"self"`
|
||||
@ -18,9 +18,9 @@ type Resolution struct {
|
||||
Name string `json:"name" structs:"name"`
|
||||
}
|
||||
|
||||
// GetListWithContext gets all resolutions from JIRA
|
||||
// GetListWithContext gets all resolutions from Jira
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-resolution-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-resolution-get
|
||||
func (s *ResolutionService) GetListWithContext(ctx context.Context) ([]Resolution, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/resolution"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
|
12
role.go
12
role.go
@ -5,14 +5,14 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// RoleService handles roles for the JIRA instance / API.
|
||||
// RoleService handles roles for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Role
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Role
|
||||
type RoleService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Role represents a JIRA product role
|
||||
// Role represents a Jira product role
|
||||
type Role struct {
|
||||
Self string `json:"self" structs:"self"`
|
||||
Name string `json:"name" structs:"name"`
|
||||
@ -21,7 +21,7 @@ type Role struct {
|
||||
Actors []*Actor `json:"actors" structs:"actors"`
|
||||
}
|
||||
|
||||
// Actor represents a JIRA actor
|
||||
// Actor represents a Jira actor
|
||||
type Actor struct {
|
||||
ID int `json:"id" structs:"id"`
|
||||
DisplayName string `json:"displayName" structs:"displayName"`
|
||||
@ -38,7 +38,7 @@ type ActorUser struct {
|
||||
|
||||
// GetListWithContext returns a list of all available project roles
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-role-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-role-get
|
||||
func (s *RoleService) GetListWithContext(ctx context.Context) (*[]Role, *Response, error) {
|
||||
apiEndpoint := "rest/api/3/role"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -61,7 +61,7 @@ func (s *RoleService) GetList() (*[]Role, *Response, error) {
|
||||
|
||||
// GetWithContext retreives a single Role from Jira
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-role-id-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-role-id-get
|
||||
func (s *RoleService) GetWithContext(ctx context.Context, roleID int) (*Role, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/3/role/%d", roleID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
|
12
sprint.go
12
sprint.go
@ -7,7 +7,7 @@ import (
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
// SprintService handles sprints in JIRA Agile API.
|
||||
// SprintService handles sprints in Jira Agile API.
|
||||
// See https://docs.atlassian.com/jira-software/REST/cloud/
|
||||
type SprintService struct {
|
||||
client *Client
|
||||
@ -27,7 +27,7 @@ type IssuesInSprintResult struct {
|
||||
// Issues can only be moved to open or active sprints.
|
||||
// The maximum number of issues that can be moved in one operation is 50.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-moveIssuesToSprint
|
||||
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-moveIssuesToSprint
|
||||
func (s *SprintService) MoveIssuesToSprintWithContext(ctx context.Context, sprintID int, issueIDs []string) (*Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/sprint/%d/issue", sprintID)
|
||||
|
||||
@ -55,7 +55,7 @@ func (s *SprintService) MoveIssuesToSprint(sprintID int, issueIDs []string) (*Re
|
||||
// This only includes issues that the user has permission to view.
|
||||
// By default, the returned issues are ordered by rank.
|
||||
//
|
||||
// JIRA API Docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-getIssuesForSprint
|
||||
// Jira API Docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-getIssuesForSprint
|
||||
func (s *SprintService) GetIssuesForSprintWithContext(ctx context.Context, sprintID int) ([]Issue, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/sprint/%d/issue", sprintID)
|
||||
|
||||
@ -80,13 +80,13 @@ func (s *SprintService) GetIssuesForSprint(sprintID int) ([]Issue, *Response, er
|
||||
}
|
||||
|
||||
// GetIssueWithContext returns a full representation of the issue for the given issue key.
|
||||
// JIRA will attempt to identify the issue by the issueIdOrKey path parameter.
|
||||
// Jira will attempt to identify the issue by the issueIdOrKey path parameter.
|
||||
// This can be an issue id, or an issue key.
|
||||
// If the issue cannot be found via an exact match, JIRA will also look for the issue in a case-insensitive way, or by looking to see if the issue was moved.
|
||||
// If the issue cannot be found via an exact match, Jira will also look for the issue in a case-insensitive way, or by looking to see if the issue was moved.
|
||||
//
|
||||
// The given options will be appended to the query string
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/7.3.1/#agile/1.0/issue-getIssue
|
||||
// Jira API docs: https://docs.atlassian.com/jira-software/REST/7.3.1/#agile/1.0/issue-getIssue
|
||||
//
|
||||
// TODO: create agile service for holding all agile apis' implementation
|
||||
func (s *SprintService) GetIssueWithContext(ctx context.Context, issueID string, options *GetQueryOptions) (*Issue, *Response, error) {
|
||||
|
10
status.go
10
status.go
@ -2,16 +2,16 @@ package jira
|
||||
|
||||
import "context"
|
||||
|
||||
// StatusService handles staties for the JIRA instance / API.
|
||||
// StatusService handles staties for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-group-Workflow-statuses
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-group-Workflow-statuses
|
||||
type StatusService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Status represents the current status of a JIRA issue.
|
||||
// Status represents the current status of a Jira issue.
|
||||
// Typical status are "Open", "In Progress", "Closed", ...
|
||||
// Status can be user defined in every JIRA instance.
|
||||
// Status can be user defined in every Jira instance.
|
||||
type Status struct {
|
||||
Self string `json:"self" structs:"self"`
|
||||
Description string `json:"description" structs:"description"`
|
||||
@ -23,7 +23,7 @@ type Status struct {
|
||||
|
||||
// GetAllStatusesWithContext returns a list of all statuses associated with workflows.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-status-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-status-get
|
||||
func (s *StatusService) GetAllStatusesWithContext(ctx context.Context) ([]Status, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/status"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
|
@ -2,15 +2,15 @@ package jira
|
||||
|
||||
import "context"
|
||||
|
||||
// StatusCategoryService handles status categories for the JIRA instance / API.
|
||||
// StatusCategoryService handles status categories for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Statuscategory
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Statuscategory
|
||||
type StatusCategoryService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// StatusCategory represents the category a status belongs to.
|
||||
// Those categories can be user defined in every JIRA instance.
|
||||
// Those categories can be user defined in every Jira instance.
|
||||
type StatusCategory struct {
|
||||
Self string `json:"self" structs:"self"`
|
||||
ID int `json:"id" structs:"id"`
|
||||
@ -19,7 +19,7 @@ type StatusCategory struct {
|
||||
ColorName string `json:"colorName" structs:"colorName"`
|
||||
}
|
||||
|
||||
// These constants are the keys of the default JIRA status categories
|
||||
// These constants are the keys of the default Jira status categories
|
||||
const (
|
||||
StatusCategoryComplete = "done"
|
||||
StatusCategoryInProgress = "indeterminate"
|
||||
@ -27,9 +27,9 @@ const (
|
||||
StatusCategoryUndefined = "undefined"
|
||||
)
|
||||
|
||||
// GetListWithContext gets all status categories from JIRA
|
||||
// GetListWithContext gets all status categories from Jira
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-statuscategory-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-statuscategory-get
|
||||
func (s *StatusCategoryService) GetListWithContext(ctx context.Context) ([]StatusCategory, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/statuscategory"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
|
30
user.go
30
user.go
@ -7,14 +7,14 @@ import (
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// UserService handles users for the JIRA instance / API.
|
||||
// UserService handles users for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user
|
||||
type UserService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// User represents a JIRA user.
|
||||
// User represents a Jira user.
|
||||
type User struct {
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
AccountID string `json:"accountId,omitempty" structs:"accountId,omitempty"`
|
||||
@ -48,9 +48,9 @@ type userSearch []userSearchParam
|
||||
|
||||
type userSearchF func(userSearch) userSearch
|
||||
|
||||
// GetWithContext gets user info from JIRA
|
||||
// GetWithContext gets user info from Jira
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUser
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUser
|
||||
//
|
||||
// /!\ Deprecation notice: https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/
|
||||
// By 29 April 2019, we will remove personal data from the API that is used to identify users,
|
||||
@ -75,9 +75,9 @@ func (s *UserService) Get(username string) (*User, *Response, error) {
|
||||
return s.GetWithContext(context.Background(), username)
|
||||
}
|
||||
|
||||
// GetByAccountIDWithContext gets user info from JIRA
|
||||
// GetByAccountIDWithContext gets user info from Jira
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUser
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUser
|
||||
func (s *UserService) GetByAccountIDWithContext(ctx context.Context, accountID string) (*User, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/user?accountId=%s", accountID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -98,9 +98,9 @@ func (s *UserService) GetByAccountID(accountID string) (*User, *Response, error)
|
||||
return s.GetByAccountIDWithContext(context.Background(), accountID)
|
||||
}
|
||||
|
||||
// CreateWithContext creates an user in JIRA.
|
||||
// CreateWithContext creates an user in Jira.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-createUser
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-createUser
|
||||
func (s *UserService) CreateWithContext(ctx context.Context, user *User) (*User, *Response, error) {
|
||||
apiEndpoint := "/rest/api/2/user"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, user)
|
||||
@ -133,10 +133,10 @@ func (s *UserService) Create(user *User) (*User, *Response, error) {
|
||||
return s.CreateWithContext(context.Background(), user)
|
||||
}
|
||||
|
||||
// DeleteWithContext deletes an user from JIRA.
|
||||
// DeleteWithContext deletes an user from Jira.
|
||||
// Returns http.StatusNoContent on success.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-user-delete
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-user-delete
|
||||
func (s *UserService) DeleteWithContext(ctx context.Context, username string) (*Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/user?username=%s", username)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "DELETE", apiEndpoint, nil)
|
||||
@ -158,7 +158,7 @@ func (s *UserService) Delete(username string) (*Response, error) {
|
||||
|
||||
// GetGroupsWithContext returns the groups which the user belongs to
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUserGroups
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUserGroups
|
||||
func (s *UserService) GetGroupsWithContext(ctx context.Context, username string) (*[]UserGroup, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/user/groups?username=%s", username)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -181,7 +181,7 @@ func (s *UserService) GetGroups(username string) (*[]UserGroup, *Response, error
|
||||
|
||||
// GetSelfWithContext information about the current logged-in user
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-myself-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-myself-get
|
||||
func (s *UserService) GetSelfWithContext(ctx context.Context) (*User, *Response, error) {
|
||||
const apiEndpoint = "rest/api/2/myself"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -233,10 +233,10 @@ func WithInactive(inactive bool) userSearchF {
|
||||
}
|
||||
}
|
||||
|
||||
// FindWithContext searches for user info from JIRA:
|
||||
// FindWithContext searches for user info from Jira:
|
||||
// It can find users by email, username or name
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-findUsers
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-findUsers
|
||||
func (s *UserService) FindWithContext(ctx context.Context, property string, tweaks ...userSearchF) ([]User, *Response, error) {
|
||||
search := []userSearchParam{
|
||||
{
|
||||
|
14
version.go
14
version.go
@ -7,9 +7,9 @@ import (
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// VersionService handles Versions for the JIRA instance / API.
|
||||
// VersionService handles Versions for the Jira instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/version
|
||||
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/version
|
||||
type VersionService struct {
|
||||
client *Client
|
||||
}
|
||||
@ -28,9 +28,9 @@ type Version struct {
|
||||
StartDate string `json:"startDate,omitempty" structs:"startDate,omitempty"`
|
||||
}
|
||||
|
||||
// GetWithContext gets version info from JIRA
|
||||
// GetWithContext gets version info from Jira
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-id-get
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-id-get
|
||||
func (s *VersionService) GetWithContext(ctx context.Context, versionID int) (*Version, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/version/%v", versionID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
|
||||
@ -51,9 +51,9 @@ func (s *VersionService) Get(versionID int) (*Version, *Response, error) {
|
||||
return s.GetWithContext(context.Background(), versionID)
|
||||
}
|
||||
|
||||
// CreateWithContext creates a version in JIRA.
|
||||
// CreateWithContext creates a version in Jira.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-post
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-post
|
||||
func (s *VersionService) CreateWithContext(ctx context.Context, version *Version) (*Version, *Response, error) {
|
||||
apiEndpoint := "/rest/api/2/version"
|
||||
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, version)
|
||||
@ -88,7 +88,7 @@ func (s *VersionService) Create(version *Version) (*Version, *Response, error) {
|
||||
|
||||
// UpdateWithContext updates a version from a JSON representation.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-id-put
|
||||
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-id-put
|
||||
func (s *VersionService) UpdateWithContext(ctx context.Context, version *Version) (*Version, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/version/%v", version.ID)
|
||||
req, err := s.client.NewRequestWithContext(ctx, "PUT", apiEndpoint, version)
|
||||
|
Loading…
x
Reference in New Issue
Block a user