Skip to content

Commit 9a5e69a

Browse files
committed
use graphql for repo milestones on issue list
Since we can obtain the necessary ID for the query on node ID from the GraphQL API, it makes sense to remove the REST version.
1 parent 75e8cb8 commit 9a5e69a

File tree

3 files changed

+28
-40
lines changed

3 files changed

+28
-40
lines changed

api/queries_issue.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package api
22

33
import (
44
"context"
5+
"encoding/base64"
56
"fmt"
6-
"strconv"
7+
"strings"
78
"time"
89

910
"github.com/cli/cli/internal/ghrepo"
@@ -249,13 +250,19 @@ func IssueList(client *Client, repo ghrepo.Interface, state string, labels []str
249250
}
250251

251252
if milestoneString != "" {
252-
milestones, err := RepoMilestonesREST(client, repo)
253+
milestones, err := RepoMilestones(client, repo)
253254
if err != nil {
254255
return nil, err
255256
}
257+
256258
for i := range milestones {
257-
if milestones[i].Title == milestoneString {
258-
variables["milestone"] = strconv.Itoa(milestones[i].ID)
259+
if strings.EqualFold(milestones[i].Title, milestoneString) {
260+
// The query for milestones requires the use of the milestone's database ID (see #1441)
261+
id, err := milestoneNodeIdToDatabaseId(milestones[i].ID)
262+
if err != nil {
263+
return nil, err
264+
}
265+
variables["milestone"] = id
259266
break
260267
}
261268
}
@@ -430,3 +437,20 @@ func IssueReopen(client *Client, repo ghrepo.Interface, issue Issue) error {
430437

431438
return err
432439
}
440+
441+
// milestoneNodeIdToDatabaseId extracts the REST Database ID from the GraphQL Node ID
442+
func milestoneNodeIdToDatabaseId(id string) (string, error) {
443+
// The node id is base64 obfuscated
444+
decoded, err := base64.StdEncoding.DecodeString(id)
445+
if err != nil {
446+
return "", err
447+
}
448+
449+
// The decoded node ID has a pattern like '09:Milestone12345'
450+
splitted := strings.Split(string(decoded), "Milestone")
451+
if len(splitted) != 2 {
452+
return "", fmt.Errorf("couldn't get database id from node id")
453+
}
454+
455+
return splitted[1], nil
456+
}

api/queries_repo.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"errors"
88
"fmt"
99
"sort"
10-
"strconv"
1110
"strings"
1211
"time"
1312

@@ -802,30 +801,3 @@ func RepoMilestones(client *Client, repo ghrepo.Interface) ([]RepoMilestone, err
802801

803802
return milestones, nil
804803
}
805-
806-
type RepoMilestoneREST struct {
807-
ID int
808-
Title string
809-
}
810-
811-
func RepoMilestonesREST(client *Client, repo ghrepo.Interface) ([]RepoMilestoneREST, error) {
812-
var allMilestones []RepoMilestoneREST
813-
814-
path := fmt.Sprintf("repos/%s/%s/milestones", repo.RepoOwner(), repo.RepoName())
815-
816-
for page := 1; ; page++ {
817-
var milestonesFromPage []RepoMilestoneREST
818-
819-
err := client.REST("GET", path+"?page="+strconv.Itoa(page), nil, &milestonesFromPage)
820-
if err != nil {
821-
return nil, err
822-
}
823-
824-
if len(milestonesFromPage) == 0 {
825-
break
826-
}
827-
allMilestones = append(allMilestones, milestonesFromPage...)
828-
}
829-
830-
return allMilestones, nil
831-
}

api/queries_repo_test.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,6 @@ func Test_RepoMetadata(t *testing.T) {
5454
"pageInfo": { "hasNextPage": false }
5555
} } } }
5656
`))
57-
http.Register(
58-
httpmock.REST("GET", "repos/OWNER/REPO/milestones"),
59-
httpmock.StringResponse(`
60-
[
61-
{ "title": "GA", "id": 1 },
62-
{ "title": "Big One.oh", "id": 2 }
63-
]
64-
`))
6557
http.Register(
6658
httpmock.GraphQL(`query RepositoryProjectList\b`),
6759
httpmock.StringResponse(`

0 commit comments

Comments
 (0)