X Tutup
Skip to content

Commit 3afec6f

Browse files
committed
api: gracefully handle already deleted remote refs
If a GitHub repo is configured to automatically delete branches after PR is merged, `gh pr merge` fails with error like: failed to delete remote branch: ... (422): 'Reference does not exist' Gracefully handle such case and don't report the error. Signed-off-by: Pavel Borzenkov <pavel.borzenkov@gmail.com>
1 parent c66eebc commit 3afec6f

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

api/queries_pr.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,16 @@ func BranchDeleteRemote(client *Client, repo ghrepo.Interface, branch string) er
10151015
NodeID string `json:"node_id"`
10161016
}
10171017
path := fmt.Sprintf("repos/%s/%s/git/refs/heads/%s", repo.RepoOwner(), repo.RepoName(), branch)
1018-
return client.REST("DELETE", path, nil, &response)
1018+
err := client.REST("DELETE", path, nil, &response)
1019+
if err != nil {
1020+
var httpErr HTTPError
1021+
// The ref might have already been deleted by GitHub
1022+
if !errors.As(err, &httpErr) || httpErr.Code != 422 {
1023+
return err
1024+
}
1025+
}
1026+
1027+
return nil
10191028
}
10201029

10211030
func min(a, b int) int {

api/queries_pr_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package api
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/cli/cli/internal/ghrepo"
8+
"github.com/cli/cli/pkg/httpmock"
9+
)
10+
11+
func TestBranchDeleteRemote(t *testing.T) {
12+
var tests = []struct {
13+
name string
14+
code int
15+
body string
16+
expectError bool
17+
}{
18+
{name: "success", code: 204, body: "", expectError: false},
19+
{name: "error", code: 500, body: `{"message": "oh no"}`, expectError: true},
20+
{
21+
name: "already_deleted",
22+
code: 422,
23+
body: `{"message": "Reference does not exist"}`,
24+
expectError: false,
25+
},
26+
}
27+
28+
for _, tc := range tests {
29+
tc := tc
30+
t.Run(tc.name, func(t *testing.T) {
31+
http := &httpmock.Registry{}
32+
client := NewClient(ReplaceTripper(http))
33+
34+
http.StubResponse(tc.code, bytes.NewBufferString(tc.body))
35+
repo, _ := ghrepo.FromFullName("OWNER/REPO")
36+
err := BranchDeleteRemote(client, repo, "branch")
37+
if isError := err != nil; isError != tc.expectError {
38+
t.Fatalf("unexpected result: %v", err)
39+
}
40+
})
41+
}
42+
}

0 commit comments

Comments
 (0)
X Tutup