Skip to content

Commit c65a982

Browse files
committed
Merge branch 'master' into github-actions-testing
* master: feat(IssueService): allow empty JQL (#268) style: Fix staticcheck (static analysis) errors for this library (#283) feat(project): Add workflow to greet new contributors (#288) feat(project): Add cronjob to check for stale issues (#287) feat(issues): Add GetEditMeta on issue
2 parents 4f03fa8 + 4b91cf2 commit c65a982

23 files changed

+288
-113
lines changed

.github/workflows/greetings.yml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: Greetings
2+
on: [pull_request, issues]
3+
4+
jobs:
5+
greeting:
6+
runs-on: ubuntu-latest
7+
steps:
8+
- uses: actions/first-interaction@v1
9+
with:
10+
repo-token: ${{ secrets.GITHUB_TOKEN }}
11+
issue-message: 'Hi! Thank you for taking the time to create your first issue! Really cool to see you here for the first time. Please give us a bit of time to review it.'
12+
pr-message: 'Great! Thank you for taking the time to create your first pull request. It is always a pleasure to see people like you who spent time contributing. Please give us a bit of time to review it!'

.github/workflows/stale.yml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: "Close stale issues"
2+
on:
3+
schedule:
4+
- cron: "0 4 * * *"
5+
6+
jobs:
7+
stale:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/[email protected]
11+
with:
12+
repo-token: ${{ secrets.GITHUB_TOKEN }}
13+
stale-issue-message: >
14+
This issue has been automatically marked as stale because it has not had
15+
recent activity in the last 60 days. It will be closed in 7 days if no further activity occurs.
16+
Thank you for your contributions.
17+
days-before-stale: 60
18+
days-before-close: 7
19+
stale-issue-label: stale

authentication.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ func (s *AuthenticationService) AcquireSessionCookie(username, password string)
7979
}
8080

8181
if err != nil {
82-
return false, fmt.Errorf("Auth at JIRA instance failed (HTTP(S) request). %s", err)
82+
return false, fmt.Errorf("auth at Jira instance failed (HTTP(S) request). %s", err)
8383
}
8484
if resp != nil && resp.StatusCode != 200 {
85-
return false, fmt.Errorf("Auth at JIRA instance failed (HTTP(S) request). Status code: %d", resp.StatusCode)
85+
return false, fmt.Errorf("auth at Jira instance failed (HTTP(S) request). Status code: %d", resp.StatusCode)
8686
}
8787

8888
s.client.session = session
@@ -127,15 +127,15 @@ func (s *AuthenticationService) Logout() error {
127127
apiEndpoint := "rest/auth/1/session"
128128
req, err := s.client.NewRequest("DELETE", apiEndpoint, nil)
129129
if err != nil {
130-
return fmt.Errorf("Creating the request to log the user out failed : %s", err)
130+
return fmt.Errorf("creating the request to log the user out failed : %s", err)
131131
}
132132

133133
resp, err := s.client.Do(req, nil)
134134
if err != nil {
135-
return fmt.Errorf("Error sending the logout request: %s", err)
135+
return fmt.Errorf("error sending the logout request: %s", err)
136136
}
137137
if resp.StatusCode != 204 {
138-
return fmt.Errorf("The logout was unsuccessful with status %d", resp.StatusCode)
138+
return fmt.Errorf("the logout was unsuccessful with status %d", resp.StatusCode)
139139
}
140140

141141
// If logout successful, delete session
@@ -150,37 +150,37 @@ func (s *AuthenticationService) Logout() error {
150150
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
151151
func (s *AuthenticationService) GetCurrentUser() (*Session, error) {
152152
if s == nil {
153-
return nil, fmt.Errorf("AUthenticaiton Service is not instantiated")
153+
return nil, fmt.Errorf("authenticaiton Service is not instantiated")
154154
}
155155
if s.authType != authTypeSession || s.client.session == nil {
156-
return nil, fmt.Errorf("No user is authenticated yet")
156+
return nil, fmt.Errorf("no user is authenticated yet")
157157
}
158158

159159
apiEndpoint := "rest/auth/1/session"
160160
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
161161
if err != nil {
162-
return nil, fmt.Errorf("Could not create request for getting user info : %s", err)
162+
return nil, fmt.Errorf("could not create request for getting user info : %s", err)
163163
}
164164

165165
resp, err := s.client.Do(req, nil)
166166
if err != nil {
167-
return nil, fmt.Errorf("Error sending request to get user info : %s", err)
167+
return nil, fmt.Errorf("error sending request to get user info : %s", err)
168168
}
169169
if resp.StatusCode != 200 {
170-
return nil, fmt.Errorf("Getting user info failed with status : %d", resp.StatusCode)
170+
return nil, fmt.Errorf("getting user info failed with status : %d", resp.StatusCode)
171171
}
172172

173173
defer resp.Body.Close()
174174
ret := new(Session)
175175
data, err := ioutil.ReadAll(resp.Body)
176176
if err != nil {
177-
return nil, fmt.Errorf("Couldn't read body from the response : %s", err)
177+
return nil, fmt.Errorf("couldn't read body from the response : %s", err)
178178
}
179179

180180
err = json.Unmarshal(data, &ret)
181181

182182
if err != nil {
183-
return nil, fmt.Errorf("Could not unmarshall received user info : %s", err)
183+
return nil, fmt.Errorf("could not unmarshall received user info : %s", err)
184184
}
185185

186186
return ret, nil

authentication_test.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ func TestAuthenticationService_AcquireSessionCookie_Failure(t *testing.T) {
1919
if err != nil {
2020
t.Errorf("Error in read body: %s", err)
2121
}
22-
if bytes.Index(b, []byte(`"username":"foo"`)) < 0 {
22+
if !bytes.Contains(b, []byte(`"username":"foo"`)) {
2323
t.Error("No username found")
2424
}
25-
if bytes.Index(b, []byte(`"password":"bar"`)) < 0 {
25+
if !bytes.Contains(b, []byte(`"password":"bar"`)) {
2626
t.Error("No password found")
2727
}
2828

@@ -53,10 +53,10 @@ func TestAuthenticationService_AcquireSessionCookie_Success(t *testing.T) {
5353
if err != nil {
5454
t.Errorf("Error in read body: %s", err)
5555
}
56-
if bytes.Index(b, []byte(`"username":"foo"`)) < 0 {
56+
if !bytes.Contains(b, []byte(`"username":"foo"`)) {
5757
t.Error("No username found")
5858
}
59-
if bytes.Index(b, []byte(`"password":"bar"`)) < 0 {
59+
if !bytes.Contains(b, []byte(`"password":"bar"`)) {
6060
t.Error("No password found")
6161
}
6262

@@ -144,10 +144,10 @@ func TestAithenticationService_GetUserInfo_AccessForbidden_Fail(t *testing.T) {
144144
if err != nil {
145145
t.Errorf("Error in read body: %s", err)
146146
}
147-
if bytes.Index(b, []byte(`"username":"foo"`)) < 0 {
147+
if !bytes.Contains(b, []byte(`"username":"foo"`)) {
148148
t.Error("No username found")
149149
}
150-
if bytes.Index(b, []byte(`"password":"bar"`)) < 0 {
150+
if !bytes.Contains(b, []byte(`"password":"bar"`)) {
151151
t.Error("No password found")
152152
}
153153

@@ -182,10 +182,10 @@ func TestAuthenticationService_GetUserInfo_NonOkStatusCode_Fail(t *testing.T) {
182182
if err != nil {
183183
t.Errorf("Error in read body: %s", err)
184184
}
185-
if bytes.Index(b, []byte(`"username":"foo"`)) < 0 {
185+
if !bytes.Contains(b, []byte(`"username":"foo"`)) {
186186
t.Error("No username found")
187187
}
188-
if bytes.Index(b, []byte(`"password":"bar"`)) < 0 {
188+
if !bytes.Contains(b, []byte(`"password":"bar"`)) {
189189
t.Error("No password found")
190190
}
191191

@@ -238,10 +238,10 @@ func TestAuthenticationService_GetUserInfo_Success(t *testing.T) {
238238
if err != nil {
239239
t.Errorf("Error in read body: %s", err)
240240
}
241-
if bytes.Index(b, []byte(`"username":"foo"`)) < 0 {
241+
if !bytes.Contains(b, []byte(`"username":"foo"`)) {
242242
t.Error("No username found")
243243
}
244-
if bytes.Index(b, []byte(`"password":"bar"`)) < 0 {
244+
if !bytes.Contains(b, []byte(`"password":"bar"`)) {
245245
t.Error("No password found")
246246
}
247247

@@ -280,10 +280,10 @@ func TestAuthenticationService_Logout_Success(t *testing.T) {
280280
if err != nil {
281281
t.Errorf("Error in read body: %s", err)
282282
}
283-
if bytes.Index(b, []byte(`"username":"foo"`)) < 0 {
283+
if !bytes.Contains(b, []byte(`"username":"foo"`)) {
284284
t.Error("No username found")
285285
}
286-
if bytes.Index(b, []byte(`"password":"bar"`)) < 0 {
286+
if !bytes.Contains(b, []byte(`"password":"bar"`)) {
287287
t.Error("No password found")
288288
}
289289

board_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,13 @@ func TestBoardService_GetAllSprintsWithOptions(t *testing.T) {
204204
})
205205

206206
sprints, _, err := testClient.Board.GetAllSprintsWithOptions(123, &GetAllSprintsOptions{State: "active,future"})
207-
208207
if err != nil {
209208
t.Errorf("Got error: %v", err)
210209
}
211210

212211
if sprints == nil {
213212
t.Error("Expected sprint list. Got nil.")
213+
return
214214
}
215215

216216
if len(sprints.Values) != 1 {
@@ -235,13 +235,13 @@ func TestBoardService_GetBoardConfigoration(t *testing.T) {
235235
})
236236

237237
boardConfiguration, _, err := testClient.Board.GetBoardConfiguration(35)
238-
239238
if err != nil {
240239
t.Errorf("Got error: %v", err)
241240
}
242241

243242
if boardConfiguration == nil {
244243
t.Error("Expected boardConfiguration. Got nil.")
244+
return
245245
}
246246

247247
if len(boardConfiguration.ColumnConfig.Columns) != 6 {

error.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ func NewJiraError(resp *Response, httpError error) error {
3434
if strings.HasPrefix(contentType, "application/json") {
3535
err = json.Unmarshal(body, &jerr)
3636
if err != nil {
37-
httpError = errors.Wrap(errors.New("Could not parse JSON"), httpError.Error())
37+
httpError = errors.Wrap(errors.New("could not parse JSON"), httpError.Error())
3838
return errors.Wrap(err, httpError.Error())
3939
}
4040
} else {
4141
if httpError == nil {
42-
return fmt.Errorf("Got Response Status %s:%s", resp.Status, string(body))
42+
return fmt.Errorf("got response status %s:%s", resp.Status, string(body))
4343
}
4444
return errors.Wrap(httpError, fmt.Sprintf("%s: %s", resp.Status, string(body)))
4545
}

error_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ func TestError_BadJSON(t *testing.T) {
9696
err := NewJiraError(resp, errors.New("Original http error"))
9797
msg := err.Error()
9898

99-
if !strings.Contains(msg, "Could not parse JSON") {
100-
t.Errorf("Expected the 'Could not parse JSON' error message: Got\n%s\n", msg)
99+
if !strings.Contains(msg, "could not parse JSON") {
100+
t.Errorf("Expected the 'could not parse JSON' error message: Got\n%s\n", msg)
101101
}
102102
}
103103

filter_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func TestFilterService_Get(t *testing.T) {
4141
testMux.HandleFunc(testAPIEndpoint, func(writer http.ResponseWriter, request *http.Request) {
4242
testMethod(t, request, "GET")
4343
testRequestURL(t, request, testAPIEndpoint)
44-
fmt.Fprintf(writer, string(raw))
44+
fmt.Fprint(writer, string(raw))
4545
})
4646

4747
filter, _, err := testClient.Filter.Get(10000)

issue.go

+24-17
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"net/http"
1111
"net/url"
1212
"reflect"
13+
"strconv"
1314
"strings"
1415
"time"
1516

@@ -192,7 +193,7 @@ func (i *IssueFields) UnmarshalJSON(data []byte) error {
192193
options := strings.Split(tagDetail, ",")
193194

194195
if len(options) == 0 {
195-
return fmt.Errorf("No tags options found for %s", field.Name)
196+
return fmt.Errorf("no tags options found for %s", field.Name)
196197
}
197198
// the first one is the json tag
198199
key := options[0]
@@ -757,11 +758,11 @@ func (s *IssueService) Create(issue *Issue) (*Issue, *Response, error) {
757758
defer resp.Body.Close()
758759
data, err := ioutil.ReadAll(resp.Body)
759760
if err != nil {
760-
return nil, resp, fmt.Errorf("Could not read the returned data")
761+
return nil, resp, fmt.Errorf("could not read the returned data")
761762
}
762763
err = json.Unmarshal(data, responseIssue)
763764
if err != nil {
764-
return nil, resp, fmt.Errorf("Could not unmarshall the data into struct")
765+
return nil, resp, fmt.Errorf("could not unmarshall the data into struct")
765766
}
766767
return responseIssue, resp, nil
767768
}
@@ -939,7 +940,7 @@ func (s *IssueService) UpdateWorklogRecord(issueID, worklogID string, record *Wo
939940
//
940941
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issueLink
941942
func (s *IssueService) AddLink(issueLink *IssueLink) (*Response, error) {
942-
apiEndpoint := fmt.Sprintf("rest/api/2/issueLink")
943+
apiEndpoint := "rest/api/2/issueLink"
943944
req, err := s.client.NewRequest("POST", apiEndpoint, issueLink)
944945
if err != nil {
945946
return nil, err
@@ -957,29 +958,35 @@ func (s *IssueService) AddLink(issueLink *IssueLink) (*Response, error) {
957958
//
958959
// JIRA API docs: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-query-issues
959960
func (s *IssueService) Search(jql string, options *SearchOptions) ([]Issue, *Response, error) {
960-
var u string
961-
if options == nil {
962-
u = fmt.Sprintf("rest/api/2/search?jql=%s", url.QueryEscape(jql))
963-
} else {
964-
u = "rest/api/2/search?jql=" + url.QueryEscape(jql)
961+
u := url.URL{
962+
Path: "rest/api/2/search",
963+
}
964+
uv := url.Values{}
965+
if jql != "" {
966+
uv.Add("jql", url.QueryEscape(jql))
967+
}
968+
969+
if options != nil {
965970
if options.StartAt != 0 {
966-
u += fmt.Sprintf("&startAt=%d", options.StartAt)
971+
uv.Add("startAt", strconv.Itoa(options.StartAt))
967972
}
968973
if options.MaxResults != 0 {
969-
u += fmt.Sprintf("&amp;maxResults=%d", options.MaxResults)
974+
uv.Add("maxResults", strconv.Itoa(options.MaxResults))
970975
}
971976
if options.Expand != "" {
972-
u += fmt.Sprintf("&expand=%s", options.Expand)
977+
uv.Add("expand", options.Expand)
973978
}
974979
if strings.Join(options.Fields, ",") != "" {
975-
u += fmt.Sprintf("&fields=%s", strings.Join(options.Fields, ","))
980+
uv.Add("fields", strings.Join(options.Fields, ","))
976981
}
977982
if options.ValidateQuery != "" {
978-
u += fmt.Sprintf("&validateQuery=%s", options.ValidateQuery)
983+
uv.Add("validateQuery", options.ValidateQuery)
979984
}
980985
}
981986

982-
req, err := s.client.NewRequest("GET", u, nil)
987+
u.RawQuery = uv.Encode()
988+
989+
req, err := s.client.NewRequest("GET", u.String(), nil)
983990
if err != nil {
984991
return []Issue{}, nil, err
985992
}
@@ -1195,7 +1202,7 @@ func InitIssueWithMetaAndFields(metaProject *MetaProject, metaIssuetype *MetaIss
11951202
Value: value,
11961203
}
11971204
default:
1198-
return nil, fmt.Errorf("Unknown issue type encountered: %s for %s", valueType, key)
1205+
return nil, fmt.Errorf("unknown issue type encountered: %s for %s", valueType, key)
11991206
}
12001207
}
12011208

@@ -1240,8 +1247,8 @@ func (s *IssueService) GetWatchers(issueID string) (*[]User, *Response, error) {
12401247
}
12411248

12421249
result := []User{}
1243-
user := new(User)
12441250
for _, watcher := range watches.Watchers {
1251+
var user *User
12451252
if watcher.AccountID != "" {
12461253
user, resp, err = s.client.User.GetByAccountID(watcher.AccountID)
12471254
if err != nil {

0 commit comments

Comments
 (0)