mirror of
https://github.com/Threnklyn/jira.git
synced 2026-05-19 04:33:28 +02:00
7bfa241547
In #34 a fix was made to escape the issue type to support issue types with spaces in. This is an additional place where the issue type needs escaping, otherwise you get 400 Bad Request when trying to create an issue for an issuetype that has a space in.
588 lines
17 KiB
Go
588 lines
17 KiB
Go
package jira
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"mime/multipart"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/coryb/oreo"
|
|
|
|
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
|
|
)
|
|
|
|
type IssueQueryProvider interface {
|
|
ProvideIssueQueryString() string
|
|
}
|
|
|
|
type IssueOptions struct {
|
|
Fields []string `json:"fields,omitempty" yaml:"fields,omitempty"`
|
|
Expand []string `json:"expand,omitempty" yaml:"expand,omitempty"`
|
|
Properties []string `json:"properties,omitempty" yaml:"properties,omitempty"`
|
|
FieldsByKeys bool `json:"fieldsByKeys,omitempty" yaml:"fieldsByKeys,omitempty"`
|
|
UpdateHistory bool `json:"updateHistory,omitempty" yaml:"updateHistory,omitempty"`
|
|
}
|
|
|
|
func (o *IssueOptions) ProvideIssueQueryString() string {
|
|
params := []string{}
|
|
if len(o.Fields) > 0 {
|
|
params = append(params, "fields="+strings.Join(o.Fields, ","))
|
|
}
|
|
if len(o.Expand) > 0 {
|
|
params = append(params, "expand="+strings.Join(o.Expand, ","))
|
|
}
|
|
if len(o.Properties) > 0 {
|
|
params = append(params, "properties="+strings.Join(o.Properties, ","))
|
|
}
|
|
if o.FieldsByKeys {
|
|
params = append(params, "fieldsByKeys=true")
|
|
}
|
|
if o.UpdateHistory {
|
|
params = append(params, "updateHistory=true")
|
|
}
|
|
if len(params) > 0 {
|
|
return "?" + strings.Join(params, "&")
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getIssue
|
|
func (j *Jira) GetIssue(issue string, iqg IssueQueryProvider) (*jiradata.Issue, error) {
|
|
return GetIssue(j.UA, j.Endpoint, issue, iqg)
|
|
}
|
|
|
|
func GetIssue(ua HttpClient, endpoint string, issue string, iqg IssueQueryProvider) (*jiradata.Issue, error) {
|
|
query := ""
|
|
if iqg != nil {
|
|
query = iqg.ProvideIssueQueryString()
|
|
}
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s%s", endpoint, issue, query)
|
|
resp, err := ua.GetJSON(uri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
results := &jiradata.Issue{}
|
|
return results, readJSON(resp.Body, results)
|
|
}
|
|
return nil, responseError(resp)
|
|
}
|
|
|
|
func (j *Jira) GetIssueWorklog(issue string) (*jiradata.Worklogs, error) {
|
|
return GetIssueWorklog(j.UA, j.Endpoint, issue)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/worklog-getIssueWorklog
|
|
func GetIssueWorklog(ua HttpClient, endpoint string, issue string) (*jiradata.Worklogs, error) {
|
|
startAt := 0
|
|
total := 1
|
|
maxResults := 100
|
|
worklogs := jiradata.Worklogs{}
|
|
for startAt < total {
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog?startAt=%d&maxResults=%d", endpoint, issue, startAt, maxResults)
|
|
resp, err := ua.GetJSON(uri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
results := &jiradata.WorklogWithPagination{}
|
|
err := readJSON(resp.Body, results)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
startAt = startAt + maxResults
|
|
total = results.Total
|
|
for _, worklog := range results.Worklogs {
|
|
worklogs = append(worklogs, worklog)
|
|
}
|
|
} else {
|
|
return nil, responseError(resp)
|
|
}
|
|
}
|
|
return &worklogs, nil
|
|
}
|
|
|
|
type WorklogProvider interface {
|
|
ProvideWorklog() *jiradata.Worklog
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/worklog-addWorklog
|
|
func (j *Jira) AddIssueWorklog(issue string, wp WorklogProvider) (*jiradata.Worklog, error) {
|
|
return AddIssueWorklog(j.UA, j.Endpoint, issue, wp)
|
|
}
|
|
|
|
func AddIssueWorklog(ua HttpClient, endpoint string, issue string, wp WorklogProvider) (*jiradata.Worklog, error) {
|
|
req := wp.ProvideWorklog()
|
|
encoded, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog", endpoint, issue)
|
|
resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 201 {
|
|
results := &jiradata.Worklog{}
|
|
return results, readJSON(resp.Body, results)
|
|
}
|
|
return nil, responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getEditIssueMeta
|
|
func (j *Jira) GetIssueEditMeta(issue string) (*jiradata.EditMeta, error) {
|
|
return GetIssueEditMeta(j.UA, j.Endpoint, issue)
|
|
}
|
|
|
|
func GetIssueEditMeta(ua HttpClient, endpoint string, issue string) (*jiradata.EditMeta, error) {
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/editmeta", endpoint, issue)
|
|
resp, err := ua.GetJSON(uri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
results := &jiradata.EditMeta{}
|
|
return results, readJSON(resp.Body, results)
|
|
}
|
|
return nil, responseError(resp)
|
|
}
|
|
|
|
type IssueUpdateProvider interface {
|
|
ProvideIssueUpdate() *jiradata.IssueUpdate
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue
|
|
func (j *Jira) EditIssue(issue string, iup IssueUpdateProvider) error {
|
|
return EditIssue(j.UA, j.Endpoint, issue, iup)
|
|
}
|
|
|
|
func EditIssue(ua HttpClient, endpoint string, issue string, iup IssueUpdateProvider) error {
|
|
req := iup.ProvideIssueUpdate()
|
|
encoded, err := json.Marshal(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s", endpoint, issue)
|
|
resp, err := ua.Put(uri, "application/json", bytes.NewBuffer(encoded))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 204 {
|
|
return nil
|
|
}
|
|
return responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-createIssue
|
|
func (j *Jira) CreateIssue(iup IssueUpdateProvider) (*jiradata.IssueCreateResponse, error) {
|
|
return CreateIssue(j.UA, j.Endpoint, iup)
|
|
}
|
|
|
|
func CreateIssue(ua HttpClient, endpoint string, iup IssueUpdateProvider) (*jiradata.IssueCreateResponse, error) {
|
|
req := iup.ProvideIssueUpdate()
|
|
encoded, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue", endpoint)
|
|
resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 201 {
|
|
results := &jiradata.IssueCreateResponse{}
|
|
return results, readJSON(resp.Body, results)
|
|
}
|
|
return nil, responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getCreateIssueMeta
|
|
func (j *Jira) GetIssueCreateMetaProject(projectKey string) (*jiradata.CreateMetaProject, error) {
|
|
return GetIssueCreateMetaProject(j.UA, j.Endpoint, projectKey)
|
|
}
|
|
|
|
func GetIssueCreateMetaProject(ua HttpClient, endpoint string, projectKey string) (*jiradata.CreateMetaProject, error) {
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s&expand=projects.issuetypes.fields", endpoint, projectKey)
|
|
resp, err := ua.GetJSON(uri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
results := &jiradata.CreateMeta{}
|
|
err = readJSON(resp.Body, results)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, project := range results.Projects {
|
|
if project.Key == projectKey {
|
|
return project, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("Project %s not found", projectKey)
|
|
}
|
|
return nil, responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getCreateIssueMeta
|
|
func (j *Jira) GetIssueCreateMetaIssueType(projectKey, issueTypeName string) (*jiradata.IssueType, error) {
|
|
return GetIssueCreateMetaIssueType(j.UA, j.Endpoint, projectKey, issueTypeName)
|
|
}
|
|
|
|
func GetIssueCreateMetaIssueType(ua HttpClient, endpoint string, projectKey, issueTypeName string) (*jiradata.IssueType, error) {
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s&issuetypeNames=%s&expand=projects.issuetypes.fields", endpoint, projectKey, url.QueryEscape(issueTypeName))
|
|
resp, err := ua.GetJSON(uri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
results := &jiradata.CreateMeta{}
|
|
err = readJSON(resp.Body, results)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, project := range results.Projects {
|
|
if project.Key == projectKey {
|
|
for _, issueType := range project.IssueTypes {
|
|
if issueType.Name == issueTypeName {
|
|
return issueType, nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("Project %s and IssueType %s not found", projectKey, issueTypeName)
|
|
}
|
|
return nil, responseError(resp)
|
|
}
|
|
|
|
type LinkIssueProvider interface {
|
|
ProvideLinkIssueRequest() *jiradata.LinkIssueRequest
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issueLink-linkIssues
|
|
func (j *Jira) LinkIssues(lip LinkIssueProvider) error {
|
|
return LinkIssues(j.UA, j.Endpoint, lip)
|
|
}
|
|
|
|
func LinkIssues(ua HttpClient, endpoint string, lip LinkIssueProvider) error {
|
|
req := lip.ProvideLinkIssueRequest()
|
|
encoded, err := json.Marshal(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
uri := fmt.Sprintf("%s/rest/api/2/issueLink", endpoint)
|
|
resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 201 {
|
|
return nil
|
|
}
|
|
return responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getTransitions
|
|
func (j *Jira) GetIssueTransitions(issue string) (*jiradata.TransitionsMeta, error) {
|
|
return GetIssueTransitions(j.UA, j.Endpoint, issue)
|
|
}
|
|
|
|
func GetIssueTransitions(ua HttpClient, endpoint string, issue string) (*jiradata.TransitionsMeta, error) {
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/transitions?expand=transitions.fields", endpoint, issue)
|
|
resp, err := ua.GetJSON(uri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
results := &jiradata.TransitionsMeta{}
|
|
return results, readJSON(resp.Body, results)
|
|
}
|
|
return nil, responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-doTransition
|
|
func (j *Jira) TransitionIssue(issue string, iup IssueUpdateProvider) error {
|
|
return TransitionIssue(j.UA, j.Endpoint, issue, iup)
|
|
}
|
|
|
|
func TransitionIssue(ua HttpClient, endpoint string, issue string, iup IssueUpdateProvider) error {
|
|
req := iup.ProvideIssueUpdate()
|
|
encoded, err := json.Marshal(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/transitions", endpoint, issue)
|
|
resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 204 {
|
|
return nil
|
|
}
|
|
return responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issueLinkType-getIssueLinkTypes
|
|
func (j *Jira) GetIssueLinkTypes() (*jiradata.IssueLinkTypes, error) {
|
|
return GetIssueLinkTypes(j.UA, j.Endpoint)
|
|
}
|
|
|
|
func GetIssueLinkTypes(ua HttpClient, endpoint string) (*jiradata.IssueLinkTypes, error) {
|
|
uri := fmt.Sprintf("%s/rest/api/2/issueLinkType", endpoint)
|
|
resp, err := ua.GetJSON(uri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
results := struct {
|
|
IssueLinkTypes jiradata.IssueLinkTypes
|
|
}{
|
|
IssueLinkTypes: jiradata.IssueLinkTypes{},
|
|
}
|
|
return &results.IssueLinkTypes, readJSON(resp.Body, &results)
|
|
}
|
|
return nil, responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-addVote
|
|
func (j *Jira) IssueAddVote(issue string) error {
|
|
return IssueAddVote(j.UA, j.Endpoint, issue)
|
|
}
|
|
|
|
func IssueAddVote(ua HttpClient, endpoint string, issue string) error {
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/votes", endpoint, issue)
|
|
resp, err := ua.Post(uri, "application/json", strings.NewReader("{}"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 204 {
|
|
return nil
|
|
}
|
|
return responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-removeVote
|
|
func (j *Jira) IssueRemoveVote(issue string) error {
|
|
return IssueRemoveVote(j.UA, j.Endpoint, issue)
|
|
}
|
|
|
|
func IssueRemoveVote(ua HttpClient, endpoint string, issue string) error {
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/votes", endpoint, issue)
|
|
resp, err := ua.Delete(uri)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 204 {
|
|
return nil
|
|
}
|
|
return responseError(resp)
|
|
}
|
|
|
|
type RankRequestProvider interface {
|
|
ProvideRankRequest() *jiradata.RankRequest
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/issue-rankIssues
|
|
func (j *Jira) RankIssues(rrp RankRequestProvider) error {
|
|
return RankIssues(j.UA, j.Endpoint, rrp)
|
|
}
|
|
|
|
func RankIssues(ua HttpClient, endpoint string, rrp RankRequestProvider) error {
|
|
req := rrp.ProvideRankRequest()
|
|
encoded, err := json.Marshal(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
uri := fmt.Sprintf("%s/rest/agile/1.0/issue/rank", endpoint)
|
|
resp, err := ua.Put(uri, "application/json", bytes.NewBuffer(encoded))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 204 {
|
|
return nil
|
|
}
|
|
return responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-addWatcher
|
|
func (j *Jira) IssueAddWatcher(issue, user string) error {
|
|
return IssueAddWatcher(j.UA, j.Endpoint, issue, user)
|
|
}
|
|
|
|
func IssueAddWatcher(ua HttpClient, endpoint string, issue, user string) error {
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/watchers", endpoint, issue)
|
|
resp, err := ua.Post(uri, "application/json", strings.NewReader(fmt.Sprintf("%q", user)))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 204 {
|
|
return nil
|
|
}
|
|
return responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-addWatcher
|
|
func (j *Jira) IssueRemoveWatcher(issue, user string) error {
|
|
return IssueRemoveWatcher(j.UA, j.Endpoint, issue, user)
|
|
}
|
|
|
|
func IssueRemoveWatcher(ua HttpClient, endpoint string, issue, user string) error {
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/watchers?username=%s", endpoint, issue, user)
|
|
resp, err := ua.Delete(uri)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 204 {
|
|
return nil
|
|
}
|
|
return responseError(resp)
|
|
}
|
|
|
|
type CommentProvider interface {
|
|
ProvideComment() *jiradata.Comment
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/comment-addComment
|
|
func (j *Jira) IssueAddComment(issue string, cp CommentProvider) (*jiradata.Comment, error) {
|
|
return IssueAddComment(j.UA, j.Endpoint, issue, cp)
|
|
}
|
|
|
|
func IssueAddComment(ua HttpClient, endpoint string, issue string, cp CommentProvider) (*jiradata.Comment, error) {
|
|
req := cp.ProvideComment()
|
|
encoded, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/comment", endpoint, issue)
|
|
resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 201 {
|
|
results := jiradata.Comment{}
|
|
return &results, readJSON(resp.Body, &results)
|
|
}
|
|
return nil, responseError(resp)
|
|
}
|
|
|
|
type UserProvider interface {
|
|
ProvideUser() *jiradata.User
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-assign
|
|
func (j *Jira) IssueAssign(issue, name string) error {
|
|
return IssueAssign(j.UA, j.Endpoint, issue, name)
|
|
}
|
|
|
|
func IssueAssign(ua HttpClient, endpoint string, issue, name string) error {
|
|
// this is special, not using the jiradata.User structure
|
|
// because we need to be able to send `null` as the name param
|
|
// when we want to un-assign the issue
|
|
req := struct {
|
|
Name *string `json:"name"`
|
|
}{&name}
|
|
if name == "" {
|
|
req.Name = nil
|
|
}
|
|
|
|
encoded, err := json.Marshal(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
uri := fmt.Sprintf("%s/rest/api/2/issue/%s/assignee", endpoint, issue)
|
|
resp, err := ua.Put(uri, "application/json", bytes.NewBuffer(encoded))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 204 {
|
|
return nil
|
|
}
|
|
return responseError(resp)
|
|
}
|
|
|
|
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/attachments-addAttachment
|
|
func (j *Jira) IssueAttachFile(issue, filename string, contents io.Reader) (*jiradata.ListOfAttachment, error) {
|
|
return IssueAttachFile(j.UA, j.Endpoint, issue, filename, contents)
|
|
}
|
|
|
|
func IssueAttachFile(ua HttpClient, endpoint string, issue, filename string, contents io.Reader) (*jiradata.ListOfAttachment, error) {
|
|
var buf bytes.Buffer
|
|
w := multipart.NewWriter(&buf)
|
|
formFile, err := w.CreateFormFile("file", filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_, err = io.Copy(formFile, contents)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
uri, err := url.Parse(fmt.Sprintf("%s/rest/api/2/issue/%s/attachments", endpoint, issue))
|
|
req := oreo.RequestBuilder(uri).WithMethod("POST").WithHeader(
|
|
"X-Atlassian-Token", "no-check",
|
|
).WithHeader(
|
|
"Accept", "application/json",
|
|
).WithContentType(w.FormDataContentType()).WithBody(&buf).Build()
|
|
w.Close()
|
|
|
|
resp, err := ua.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
// FIXME move this to a test, and run go tests as part of our regression
|
|
if false {
|
|
// this is because schema is wrong, defaults to type `int`, so we manually change it
|
|
// to `string`. If the jiradata is regenerated we need to manually make the change
|
|
// again.
|
|
log.Debugf("Assert Attachment.ID is a string, rather than int: %v", &jiradata.Attachment{
|
|
ID: jiradata.IntOrString(0),
|
|
})
|
|
}
|
|
results := jiradata.ListOfAttachment{}
|
|
return &results, readJSON(resp.Body, &results)
|
|
}
|
|
return nil, responseError(resp)
|
|
}
|