Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix createmeta issue on jira 9.x #502

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# TODO

* https://confluence.atlassian.com/jiracore/createmeta-rest-endpoint-to-be-removed-975040986.html
* Jira 9.0 moved the parameters on api/2/issue/createmeta into path values
Need to allow both versions to function
Need a configuration item to indicate which url/method to call
Need to write the new method to conform to the new api method format
Need new jiradata type because the api endpoint changed the output json schema
* slipstream to create jiradata types
slipscheme -stdout schema/IssueTypes.json > jiradata/IssueTypes.go

* Old API Doc: https://docs.atlassian.com/software/jira/docs/api/REST/7.2.7/#api/2/issue-getCreateIssueMeta
* New API Doc: https://docs.atlassian.com/software/jira/docs/api/REST/9.0.0/#issue-getCreateIssueMetaProjectIssueTypes
34 changes: 12 additions & 22 deletions issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,43 +247,38 @@ func CreateIssue(ua HttpClient, endpoint string, iup IssueUpdateProvider) (*jira
}

// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getCreateIssueMeta
func (j *Jira) GetIssueCreateMetaProject(projectKey string) (*jiradata.CreateMetaProject, error) {
func (j *Jira) GetIssueCreateMetaProject(projectKey string) (jiradata.Values, error) {
return GetIssueCreateMetaProject(j.UA, j.Endpoint, projectKey)
}

func GetIssueCreateMetaProject(ua HttpClient, endpoint string, projectKey string) (*jiradata.CreateMetaProject, error) {
func GetIssueCreateMetaProject(ua HttpClient, endpoint string, projectKey string) (jiradata.Values, error) {
uri := URLJoin(endpoint, "rest/api/2/issue/createmeta")
uri += fmt.Sprintf("?projectKeys=%s&expand=projects.issuetypes.fields", projectKey)
uri += fmt.Sprintf("/%s/issuetypes", projectKey)
resp, err := ua.GetJSON(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode == 200 {
results := &jiradata.CreateMeta{}
results := &jiradata.PageOfCreateMetaIssueType{}
err = json.NewDecoder(resp.Body).Decode(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 results.Values, nil
}
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) {
func (j *Jira) GetIssueCreateMetaIssueType(projectKey, issueTypeName string) (*jiradata.CreateMetaIssueType, error) {
return GetIssueCreateMetaIssueType(j.UA, j.Endpoint, projectKey, issueTypeName)
}

func GetIssueCreateMetaIssueType(ua HttpClient, endpoint string, projectKey, issueTypeName string) (*jiradata.IssueType, error) {
func GetIssueCreateMetaIssueType(ua HttpClient, endpoint string, projectKey, issueTypeName string) (*jiradata.CreateMetaIssueType, error) {
uri := URLJoin(endpoint, "rest/api/2/issue/createmeta")
uri += fmt.Sprintf("?projectKeys=%s&issuetypeNames=%s&expand=projects.issuetypes.fields", projectKey, url.QueryEscape(issueTypeName))
uri += fmt.Sprintf("/%s/issuetypes", projectKey)
resp, err := ua.GetJSON(uri)
if err != nil {
return nil, err
Expand All @@ -293,18 +288,13 @@ func GetIssueCreateMetaIssueType(ua HttpClient, endpoint string, projectKey, iss
if resp.StatusCode != 200 {
return nil, responseError(resp)
}
results := &jiradata.CreateMeta{}
results := &jiradata.PageOfCreateMetaIssueType{}
if err := json.NewDecoder(resp.Body).Decode(results); err != nil {
return nil, err
}
for _, project := range results.Projects {
if project.Key != projectKey {
continue
}
for _, issueType := range project.IssueTypes {
if issueType.Name == issueTypeName {
return issueType, nil
}
for _, issueType := range results.Values {
if issueType.Name == issueTypeName {
return issueType, nil
}
}
return nil, fmt.Errorf("project %s and IssueType %s not found", projectKey, issueTypeName)
Expand Down
29 changes: 14 additions & 15 deletions jiracmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ func CmdCreate(o *oreo.Client, globals *jiracli.GlobalOptions, opts *CreateOptio
}

type templateInput struct {
Meta *jiradata.IssueType `yaml:"meta" json:"meta"`
Overrides map[string]string `yaml:"overrides" json:"overrides"`
Meta *jiradata.CreateMetaIssueType `yaml:"meta" json:"meta"`
Overrides map[string]string `yaml:"overrides" json:"overrides"`
}

if err := defaultIssueType(o, globals.Endpoint.Value, &opts.Project, &opts.IssueType); err != nil {
Expand Down Expand Up @@ -157,26 +157,25 @@ func defaultIssueType(o *oreo.Client, endpoint string, project, issuetype *strin
if issuetype != nil && *issuetype != "" {
return nil
}
projectMeta, err := jira.GetIssueCreateMetaProject(o, endpoint, *project)
issueTypes, err := jira.GetIssueCreateMetaProject(o, endpoint, *project)
if err != nil {
return err
}

issueTypes := map[string]bool{}

for _, issuetype := range projectMeta.IssueTypes {
issueTypes[issuetype.Name] = true
}

// prefer "Bug" type
if _, ok := issueTypes["Bug"]; ok {
*issuetype = "Bug"
return nil
for _, issueType := range issueTypes {
if issueType.Name == "Bug" {
*issuetype = "Bug"
return nil
}
}

// next best default it "Task"
if _, ok := issueTypes["Task"]; ok {
*issuetype = "Task"
return nil
for _, issueType := range issueTypes {
if issueType.Name == "Task" {
*issuetype = "Task"
return nil
}
}

return fmt.Errorf("Unable to find default issueType of Bug or Task, please set --issuetype argument or set the `issuetype` config property")
Expand Down
6 changes: 3 additions & 3 deletions jiracmd/subtask.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ func CmdSubtask(o *oreo.Client, globals *jiracli.GlobalOptions, opts *SubtaskOpt
}

type templateInput struct {
Meta *jiradata.IssueType `yaml:"meta" json:"meta"`
Overrides map[string]string `yaml:"overrides" json:"overrides"`
Parent *jiradata.Issue `yaml:"parent" json:"parent"`
Meta *jiradata.CreateMetaIssueType `yaml:"meta" json:"meta"`
Overrides map[string]string `yaml:"overrides" json:"overrides"`
Parent *jiradata.Issue `yaml:"parent" json:"parent"`
}

parent, err := jira.GetIssue(o, globals.Endpoint.Value, opts.Issue, nil)
Expand Down
11 changes: 6 additions & 5 deletions jiradata/AllowedValues.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ package jiradata
/////////////////////////////////////////////////////////////////////////

// AllowedValues defined from schema:
// {
// "title": "allowedValues",
// "type": "array",
// "items": {}
// }
//
// {
// "title": "allowedValues",
// "type": "array",
// "items": {}
// }
type AllowedValues []interface{}
159 changes: 159 additions & 0 deletions jiradata/PageOfCreateMetaIssueType.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package jiradata

/////////////////////////////////////////////////////////////////////////
// This Code is Generated by SlipScheme Project:
// https://github.com/coryb/slipscheme
//
// Generated with command:
// slipscheme -dir jiradata schema/IssueTypes.json
/////////////////////////////////////////////////////////////////////////
// DO NOT EDIT //
/////////////////////////////////////////////////////////////////////////

// PageOfCreateMetaIssueType defined from schema:
//
// {
// "title": "Page of Create Meta Issue Type",
// "id": "https://docs.atlassian.com/jira/REST/schema/page-of-create-meta-issue-type#",
// "type": "object",
// "properties": {
// "last": {
// "title": "last",
// "type": "boolean"
// },
// "size": {
// "title": "size",
// "type": "integer"
// },
// "start": {
// "title": "start",
// "type": "integer"
// },
// "total": {
// "title": "total",
// "type": "integer"
// },
// "values": {
// "title": "values",
// "type": "array",
// "items": {
// "title": "Create Meta Issue Type",
// "type": "object",
// "properties": {
// "avatarId": {
// "title": "avatarId",
// "type": "integer"
// },
// "description": {
// "title": "description",
// "type": "string"
// },
// "expand": {
// "title": "expand",
// "type": "string"
// },
// "fields": {
// "title": "fields",
// "type": "object",
// "patternProperties": {
// ".+": {
// "title": "Field Meta",
// "type": "object",
// "properties": {
// "allowedValues": {
// "title": "allowedValues",
// "type": "array",
// "items": {}
// },
// "autoCompleteUrl": {
// "title": "autoCompleteUrl",
// "type": "string"
// },
// "defaultValue": {
// "title": "defaultValue"
// },
// "fieldId": {
// "title": "fieldId",
// "type": "string"
// },
// "hasDefaultValue": {
// "title": "hasDefaultValue",
// "type": "boolean"
// },
// "name": {
// "title": "name",
// "type": "string"
// },
// "operations": {
// "title": "operations",
// "type": "array",
// "items": {
// "type": "string"
// }
// },
// "required": {
// "title": "required",
// "type": "boolean"
// },
// "schema": {
// "title": "Json Type",
// "type": "object",
// "properties": {
// "custom": {
// "title": "custom",
// "type": "string"
// },
// "customId": {
// "title": "customId",
// "type": "integer"
// },
// "items": {
// "title": "items",
// "type": "string"
// },
// "system": {
// "title": "system",
// "type": "string"
// },
// "type": {
// "title": "type",
// "type": "string"
// }
// }
// }
// }
// }
// }
// },
// "iconUrl": {
// "title": "iconUrl",
// "type": "string"
// },
// "id": {
// "title": "id",
// "type": "string"
// },
// "name": {
// "title": "name",
// "type": "string"
// },
// "self": {
// "title": "self",
// "type": "string"
// },
// "subtask": {
// "title": "subtask",
// "type": "boolean"
// }
// }
// }
// }
// }
// }
type PageOfCreateMetaIssueType struct {
Last bool `json:"last,omitempty" yaml:"last,omitempty"`
Size int `json:"size,omitempty" yaml:"size,omitempty"`
Start int `json:"start,omitempty" yaml:"start,omitempty"`
Total int `json:"total,omitempty" yaml:"total,omitempty"`
Values Values `json:"values,omitempty" yaml:"values,omitempty"`
}
Loading