Skip to content

Commit 07267ab

Browse files
authored
Add new RemoveMilestone method on IssuesService (#2195)
Fixes: #236.
1 parent a9c254e commit 07267ab

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

github/issues.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,29 @@ func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, num
299299
return i, resp, nil
300300
}
301301

302+
// Remove a milestone from an issue.
303+
//
304+
// This is a helper method to explicitly update an issue with a `null` milestone, thereby removing it.
305+
//
306+
// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/issues/#update-an-issue
307+
func (s *IssuesService) RemoveMilestone(ctx context.Context, owner, repo string, issueNumber int) (*Issue, *Response, error) {
308+
u := fmt.Sprintf("repos/%v/%v/issues/%v", owner, repo, issueNumber)
309+
req, err := s.client.NewRequest("PATCH", u, &struct {
310+
Milestone *Milestone `json:"milestone"`
311+
}{})
312+
if err != nil {
313+
return nil, nil, err
314+
}
315+
316+
i := new(Issue)
317+
resp, err := s.client.Do(ctx, req, i)
318+
if err != nil {
319+
return nil, resp, err
320+
}
321+
322+
return i, resp, nil
323+
}
324+
302325
// LockIssueOptions specifies the optional parameters to the
303326
// IssuesService.Lock method.
304327
type LockIssueOptions struct {

github/issues_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,40 @@ func TestIssuesService_Edit(t *testing.T) {
345345
})
346346
}
347347

348+
func TestIssuesService_RemoveMilestone(t *testing.T) {
349+
client, mux, _, teardown := setup()
350+
defer teardown()
351+
mux.HandleFunc("/repos/o/r/issues/1", func(w http.ResponseWriter, r *http.Request) {
352+
testMethod(t, r, "PATCH")
353+
fmt.Fprint(w, `{"number":1}`)
354+
})
355+
356+
ctx := context.Background()
357+
issue, _, err := client.Issues.RemoveMilestone(ctx, "o", "r", 1)
358+
if err != nil {
359+
t.Errorf("Issues.RemoveMilestone returned error: %v", err)
360+
}
361+
362+
want := &Issue{Number: Int(1)}
363+
if !cmp.Equal(issue, want) {
364+
t.Errorf("Issues.RemoveMilestone returned %+v, want %+v", issue, want)
365+
}
366+
367+
const methodName = "RemoveMilestone"
368+
testBadOptions(t, methodName, func() (err error) {
369+
_, _, err = client.Issues.RemoveMilestone(ctx, "\n", "\n", -1)
370+
return err
371+
})
372+
373+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
374+
got, resp, err := client.Issues.RemoveMilestone(ctx, "o", "r", 1)
375+
if got != nil {
376+
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
377+
}
378+
return resp, err
379+
})
380+
}
381+
348382
func TestIssuesService_Edit_invalidOwner(t *testing.T) {
349383
client, _, _, teardown := setup()
350384
defer teardown()

0 commit comments

Comments
 (0)