From 5d727b89954b36fb46caf642320a0542d89bf83f Mon Sep 17 00:00:00 2001 From: Miguel de la Cruz Date: Sun, 1 Mar 2020 12:30:49 +0100 Subject: [PATCH] Complete create-jira-ticket command --- cmd/standalone.go | 30 ++++++++++++++++----------- http/http.go | 26 ++++++++++++++++++++++++ jira/jira.go | 52 +++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 http/http.go diff --git a/cmd/standalone.go b/cmd/standalone.go index 4531cf0..91517e1 100644 --- a/cmd/standalone.go +++ b/cmd/standalone.go @@ -32,13 +32,17 @@ func CreateJiraTicketStandaloneCmd() *cobra.Command { RunE: createJiraTicketStandaloneCmdF, } - cmd.Flags().StringP("username", "u", "", "the jira username") + cmd.Flags().String("epic", "", "the jira epic id to associate the ticket with") + _ = cmd.MarkFlagRequired("epic") + cmd.Flags().String("team", "", "the team for the new ticket") + _ = cmd.MarkFlagRequired("epic") + cmd.Flags().String("username", "", "the jira username") _ = cmd.MarkFlagRequired("username") - cmd.Flags().StringP("token", "t", "", "the jira token") + cmd.Flags().String("token", "", "the jira token") _ = cmd.MarkFlagRequired("token") - cmd.Flags().StringP("summary", "s", "", "the summary of the ticket") + cmd.Flags().String("summary", "", "the summary of the ticket") _ = cmd.MarkFlagRequired("summary") - cmd.Flags().StringP("template", "m", "", "the template to render the description of the ticket") + cmd.Flags().String("template", "", "the template to render the description of the ticket") _ = cmd.MarkFlagRequired("template") cmd.Flags().StringSliceP("vars", "v", []string{}, "the variables to use in the template") @@ -58,12 +62,14 @@ func getVarMap(vars []string) (map[string]string, error) { } func createJiraTicketStandaloneCmdF(cmd *cobra.Command, _ []string) error { + epicId, _ := cmd.Flags().GetString("epic") + team, _ := cmd.Flags().GetString("team") username, _ := cmd.Flags().GetString("username") token, _ := cmd.Flags().GetString("token") summaryTmplStr, _ := cmd.Flags().GetString("summary") templatePath, _ := cmd.Flags().GetString("template") vars, _ := cmd.Flags().GetStringSlice("vars") - + varMap, err := getVarMap(vars) if err != nil { return fmt.Errorf("error processing vars: %w") @@ -79,25 +85,25 @@ func createJiraTicketStandaloneCmdF(cmd *cobra.Command, _ []string) error { ErrorAndExit(cmd, err) } summary := summaryBytes.String() - + descTmpl, err := template.ParseFiles(templatePath) if err != nil { ErrorAndExit(cmd, err) } - - var descriptionBytes bytes.Buffer + + var descriptionBytes bytes.Buffer if err := descTmpl.Execute(&descriptionBytes, varMap); err != nil { ErrorAndExit(cmd, err) } description := descriptionBytes.String() - + jiraClient := jira.NewClient(username, token) - - ticketKey, err := jiraClient.CreateTicket(summary, description) + + ticketKey, err := jiraClient.CreateTicket(epicId, team, summary, description) if err != nil { ErrorAndExit(cmd, err) } - + cmd.Printf("Ticket %s successfully created in JIRA", ticketKey) return nil } diff --git a/http/http.go b/http/http.go new file mode 100644 index 0000000..633fb2d --- /dev/null +++ b/http/http.go @@ -0,0 +1,26 @@ +package http + +import ( + "bytes" + "net/http" +) + +func Do(method, username, token, url string, body []byte) (*http.Response, error) { + req, err := http.NewRequest("POST", url, bytes.NewBuffer(body)) + if err != nil { + return nil, err + } + req.SetBasicAuth(username, token) + req.Header.Add("Content-Type", "application/json") + + client := http.Client{} + return client.Do(req) +} + +func DoGet(username, token, url string) (*http.Response, error) { + return Do("GET", username, token, url, []byte{}) +} + +func DoPost(username, token, url string, body []byte) (*http.Response, error) { + return Do("POST", username, token, url, body) +} diff --git a/jira/jira.go b/jira/jira.go index a8d0040..73c9360 100644 --- a/jira/jira.go +++ b/jira/jira.go @@ -1,22 +1,62 @@ package jira import ( - "fmt" + "encoding/json" + "io/ioutil" + + "git.ctrlz.es/mgdelacroix/campaigner/http" ) type JiraClient struct { Username string - Token string + Token string + Url string +} + +type JiraIssue struct { + Key string `json:"key"` } func NewClient(username, token string) *JiraClient { return &JiraClient{ Username: username, - Token: token, + Token: token, + Url: "https://mattermost.atlassian.net/rest/api/2", } } -func (c *JiraClient) CreateTicket(summary, description string) (string, error) { - fmt.Printf("Summary: %s\nDescription: %s\n", summary, description) - return "", nil +func (c *JiraClient) CreateTicket(epicId, team, summary, description string) (string, error) { + data := map[string]interface{}{ + "fields": map[string]interface{}{ + "project": map[string]interface{}{"key": "MM"}, + "summary": summary, + "description": description, + "issuetype": map[string]interface{}{"name": "Story"}, + "customfield_10007": epicId, + "customfield_11101": map[string]interface{}{"value": team}, + }, + } + + body, err := json.Marshal(data) + if err != nil { + return "", err + } + + res, err := http.DoPost(c.Username, c.Token, c.Url+"/issue/", body) + if err != nil { + return "", err + } + defer res.Body.Close() + + respBody, err := ioutil.ReadAll(res.Body) + if err != nil { + return "", err + } + + var issue JiraIssue + if err := json.Unmarshal(respBody, &issue); err != nil { + return "", err + } + + return issue.Key, nil }