Skip to content

Commit

Permalink
Adapt to Tempo API v4 (#14)
Browse files Browse the repository at this point in the history
* not so trivial

* Change Tempo API version from 3 to 4

* CHANGELOG
  • Loading branch information
jzyinq authored Jan 20, 2025
1 parent b5fb42f commit 50a4ff6
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 30 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

## [0.11.0] - 2025-01-20
### Changed
- Tempo API version from 3 to 4 due to incoming shutdown of the old version

## [0.10.2] - 2025-01-08
### Fixed
- hardcoded `2024` while fetching holidays for given year
Expand Down Expand Up @@ -129,7 +133,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Added
- Initial release of gojira

[Unreleased]: https://github.com/jzyinq/gojira/compare/0.10.2...master
[Unreleased]: https://github.com/jzyinq/gojira/compare/0.11.0...master
[0.11.0]: https://github.com/jzyinq/gojira/compare/0.10.2...0.11.0
[0.10.2]: https://github.com/jzyinq/gojira/compare/0.10.1...0.10.2
[0.10.1]: https://github.com/jzyinq/gojira/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/jzyinq/gojira/compare/0.9.0...0.10.0
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ Just remember to urldecode it. Save it and you should ready to go!
## [Changelog](./CHANGELOG.md)

## Todo list
- [ ] Color legend for calendar
- [ ] Fetch holidays for other years than current
- [ ] Refactor ShowError focus return
- [ ] Open issue in modal if it's the only result?
- [ ] Prompt `are you sure want to exit` on escape key
Expand Down
7 changes: 4 additions & 3 deletions gojira/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"log"
"os"
"strconv"
"sync"
"time"

Expand Down Expand Up @@ -81,7 +82,7 @@ func NewWorklogIssues() error {
for i := range app.workLogs.logs {
waitGroup.Add(1)
go func(workLog *Worklog) {
issue, err := NewJiraClient().GetIssue(workLog.Issue.Key)
issue, err := NewJiraClient().GetIssue(strconv.Itoa(workLog.Issue.Id))
if err != nil {
errCh <- err // Send the error to the channel.
return
Expand Down Expand Up @@ -278,7 +279,7 @@ func (issue Issue) LogWork(logTime *time.Time, timeSpent string) error {
}
if Config.UpdateExistingWorklog {
for index, workLog := range todayWorklog {
if workLog.Issue.Key == issue.Key {
if strconv.Itoa(workLog.Issue.Id) == issue.Id {
timeSpentSum := FormatTimeSpent(TimeSpentToSeconds(timeSpent) + workLog.TimeSpentSeconds)
err := todayWorklog[index].Update(timeSpentSum)
if err != nil {
Expand All @@ -288,7 +289,7 @@ func (issue Issue) LogWork(logTime *time.Time, timeSpent string) error {
}
}
}
worklog, err := NewWorklog(issue.Key, logTime, timeSpent)
worklog, err := NewWorklog(issue.GetIdAsInt(), logTime, timeSpent)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion gojira/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func PrepareConfig() {
JiraLogin: GetEnv("GOJIRA_JIRA_LOGIN"),
JiraToken: GetEnv("GOJIRA_JIRA_TOKEN"),
JiraAccountId: GetEnv("GOJIRA_JIRA_ACCOUNT_ID"),
TempoUrl: "https://api.tempo.io/core/3",
TempoUrl: "https://api.tempo.io/4",
TempoToken: GetEnv("GOJIRA_TEMPO_TOKEN"),
UpdateExistingWorklog: true,
}
Expand Down
38 changes: 27 additions & 11 deletions gojira/jira.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
)
Expand Down Expand Up @@ -57,6 +58,7 @@ type JQLResponse struct {

type Issue struct {
Key string `json:"key"`
Id string `json:"id"`
Fields struct {
Summary string `json:"summary"`
Status struct {
Expand All @@ -65,6 +67,14 @@ type Issue struct {
} `json:"fields"`
}

func (issue Issue) GetIdAsInt() int {
value, err := strconv.ParseInt(issue.Id, 10, 64)
if err != nil {
return 0
}
return int(value)
}

type WorklogResponse struct {
Self string `json:"self"`
Author struct {
Expand Down Expand Up @@ -111,13 +121,19 @@ func (jc *JiraClient) GetLatestIssues() (JQLResponse, error) {
return jc.GetIssuesByJQL("assignee in (currentUser()) ORDER BY updated DESC, created DESC", 10)
}

func (jc *JiraClient) GetIssuesByKeys(issueKeys []string) (JQLResponse, error) {
issueKeysJQL := fmt.Sprintf("key in (%s) ORDER BY updated DESC, created DESC", strings.Join(issueKeys, ","))
func (jc *JiraClient) GetIssuesByKeys(issueKeys []int) (JQLResponse, error) {
// Convert []int to []string
issueKeysStr := make([]string, len(issueKeys))
for i, key := range issueKeys {
issueKeysStr[i] = fmt.Sprintf("%d", key)
}
issueKeysJQL := fmt.Sprintf("key in (%s) ORDER BY updated DESC, created DESC", strings.Join(issueKeysStr, ","))
return jc.GetIssuesByJQL(issueKeysJQL, len(issueKeys))
}

func (jc *JiraClient) GetIssue(issueKey string) (Issue, error) {
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%s?fields=summary,status", Config.JiraUrl, issueKey)
// issueKey could be JIRA-123 (key) or just 234235 (id)
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%s?fields=summary,status,id", Config.JiraUrl, issueKey)
response, err := SendHttpRequest("GET", requestUrl, nil, jc.getHttpHeaders(), 200)
if err != nil {
return Issue{}, err
Expand All @@ -130,15 +146,15 @@ func (jc *JiraClient) GetIssue(issueKey string) (Issue, error) {
return jiraIssue, nil
}

func (jc *JiraClient) CreateWorklog(issueKey string, logTime *time.Time, timeSpent string) (WorklogResponse, error) {
func (jc *JiraClient) CreateWorklog(issueId int, logTime *time.Time, timeSpent string) (WorklogResponse, error) {
payload := map[string]string{
"timeSpent": FormatTimeSpent(TimeSpentToSeconds(timeSpent)),
"adjustEstimate": "leave",
"started": logTime.Format("2006-01-02T15:04:05.000-0700"),
}
payloadJson, _ := json.Marshal(payload)
requestBody := bytes.NewBuffer(payloadJson)
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog?notifyUsers=false", Config.JiraUrl, issueKey)
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%d/worklog?notifyUsers=false", Config.JiraUrl, issueId)
response, err := SendHttpRequest("POST", requestUrl, requestBody, jc.getHttpHeaders(), 201)
if err != nil {
return WorklogResponse{}, err
Expand All @@ -152,21 +168,21 @@ func (jc *JiraClient) CreateWorklog(issueKey string, logTime *time.Time, timeSpe
return workLogRequest, nil
}

func (jc *JiraClient) UpdateWorklog(issueKey string, jiraWorklogId int, timeSpentInSeconds int) error {
func (jc *JiraClient) UpdateWorklog(issueId int, jiraWorklogId int, timeSpentInSeconds int) error {
payload := JiraWorklogUpdate{
TimeSpentSeconds: timeSpentInSeconds,
}
payloadJson, _ := json.Marshal(payload)
requestBody := bytes.NewBuffer(payloadJson)
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog/%d?notifyUsers=false",
Config.JiraUrl, issueKey, jiraWorklogId)
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%d/worklog/%d?notifyUsers=false",
Config.JiraUrl, issueId, jiraWorklogId)
_, err := SendHttpRequest("PUT", requestUrl, requestBody, jc.getHttpHeaders(), 200)
return err
}

func (jc *JiraClient) DeleteWorklog(issueKey string, jiraWorklogId int) error {
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog/%d?notifyUsers=false",
Config.JiraUrl, issueKey, jiraWorklogId)
func (jc *JiraClient) DeleteWorklog(issueId int, jiraWorklogId int) error {
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%d/worklog/%d?notifyUsers=false",
Config.JiraUrl, issueId, jiraWorklogId)
_, err := SendHttpRequest("DELETE", requestUrl, nil, jc.getHttpHeaders(), 204)
return err
}
5 changes: 3 additions & 2 deletions gojira/tempo.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"time"
)

Expand All @@ -26,7 +27,7 @@ type WorklogsResponse struct {
}

type WorklogUpdateRequest struct {
IssueKey string `json:"issueKey"`
Id string `json:"id"`
StartDate string `json:"startDate"`
StartTime string `json:"startTime"`
Description string `json:"description"`
Expand Down Expand Up @@ -58,7 +59,7 @@ func (tc *TempoClient) UpdateWorklog(worklog *Worklog, timeSpent string) error {
timeSpentInSeconds := TimeSpentToSeconds(timeSpent)

payload := WorklogUpdateRequest{
IssueKey: worklog.Issue.Key,
Id: strconv.Itoa(worklog.Issue.Id),
StartDate: worklog.StartDate,
StartTime: worklog.StartTime,
Description: worklog.Description,
Expand Down
24 changes: 12 additions & 12 deletions gojira/worklog.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"time"
)

func NewWorklog(issueKey string, logTime *time.Time, timeSpent string) (Worklog, error) {
workLogResponse, err := NewJiraClient().CreateWorklog(issueKey, logTime, timeSpent)
func NewWorklog(issueId int, logTime *time.Time, timeSpent string) (Worklog, error) {
workLogResponse, err := NewJiraClient().CreateWorklog(issueId, logTime, timeSpent)
if err != nil {
return Worklog{}, err
}
Expand All @@ -26,8 +26,8 @@ func NewWorklog(issueKey string, logTime *time.Time, timeSpent string) (Worklog,
StartTime: logTime.Format("15:04:05"),
TimeSpentSeconds: workLogResponse.Timespentseconds,
Issue: struct {
Key string `json:"key"`
}{Key: issueKey},
Id int `json:"id"`
}{Id: issueId},
}
return workLog, nil
}
Expand All @@ -36,7 +36,7 @@ type Worklog struct {
TempoWorklogid int `json:"tempoWorklogId"`
JiraWorklogID int `json:"jiraWorklogId"`
Issue struct {
Key string `json:"key"`
Id int `json:"id"`
} `json:"issue"`
TimeSpentSeconds int `json:"timeSpentSeconds"`
StartDate string `json:"startDate"`
Expand Down Expand Up @@ -85,7 +85,7 @@ func (wl *Worklogs) LogsOnDate(date *time.Time) ([]*Worklog, error) {

func findWorklogByIssueKey(worklogs []*Worklog, issueKey string) *Worklog {
for _, log := range worklogs {
if log.Issue.Key == issueKey {
if strconv.Itoa(log.Issue.Id) == issueKey {
return log
}
}
Expand All @@ -94,14 +94,14 @@ func findWorklogByIssueKey(worklogs []*Worklog, issueKey string) *Worklog {

func GetIssuesWithWorklogs(worklogs []*Worklog) ([]Issue, error) {
var err error
var worklogIssuesKeys []string
var worklogIssueIds []int
for _, worklog := range worklogs {
worklogIssuesKeys = append(worklogIssuesKeys, worklog.Issue.Key)
worklogIssueIds = append(worklogIssueIds, worklog.Issue.Id)
}
if len(worklogIssuesKeys) == 0 {
if len(worklogIssueIds) == 0 {
return []Issue{}, err
}
todaysIssues, err := NewJiraClient().GetIssuesByKeys(worklogIssuesKeys)
todaysIssues, err := NewJiraClient().GetIssuesByKeys(worklogIssueIds)
if err != nil {
return []Issue{}, err
}
Expand Down Expand Up @@ -187,7 +187,7 @@ func (wl *Worklog) Update(timeSpent string) error {
err = NewTempoClient().UpdateWorklog(wl, timeSpent)
} else {
// make update request to jira if tempoWorklogId is not set
err = NewJiraClient().UpdateWorklog(wl.Issue.Key, wl.JiraWorklogID, timeSpentInSeconds)
err = NewJiraClient().UpdateWorklog(wl.Issue.Id, wl.JiraWorklogID, timeSpentInSeconds)
}
if err != nil {
return err
Expand All @@ -203,7 +203,7 @@ func (wl *Worklogs) Delete(w *Worklog) error {
if w.TempoWorklogid != 0 {
err = NewTempoClient().DeleteWorklog(w.TempoWorklogid)
} else {
err = NewJiraClient().DeleteWorklog(w.Issue.Key, w.JiraWorklogID)
err = NewJiraClient().DeleteWorklog(w.Issue.Id, w.JiraWorklogID)
}
if err != nil {
logrus.Debug(w)
Expand Down

0 comments on commit 50a4ff6

Please sign in to comment.