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>
This commit is contained in:
Pavel Borzenkov 2020-06-27 19:03:25 +03:00
parent c66eebc6fb
commit 3afec6f90a
2 changed files with 52 additions and 1 deletions

View file

@ -1015,7 +1015,16 @@ func BranchDeleteRemote(client *Client, repo ghrepo.Interface, branch string) er
NodeID string `json:"node_id"`
}
path := fmt.Sprintf("repos/%s/%s/git/refs/heads/%s", repo.RepoOwner(), repo.RepoName(), branch)
return client.REST("DELETE", path, nil, &response)
err := client.REST("DELETE", path, nil, &response)
if err != nil {
var httpErr HTTPError
// The ref might have already been deleted by GitHub
if !errors.As(err, &httpErr) || httpErr.Code != 422 {
return err
}
}
return nil
}
func min(a, b int) int {

42
api/queries_pr_test.go Normal file
View file

@ -0,0 +1,42 @@
package api
import (
"bytes"
"testing"
"github.com/cli/cli/internal/ghrepo"
"github.com/cli/cli/pkg/httpmock"
)
func TestBranchDeleteRemote(t *testing.T) {
var tests = []struct {
name string
code int
body string
expectError bool
}{
{name: "success", code: 204, body: "", expectError: false},
{name: "error", code: 500, body: `{"message": "oh no"}`, expectError: true},
{
name: "already_deleted",
code: 422,
body: `{"message": "Reference does not exist"}`,
expectError: false,
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
http := &httpmock.Registry{}
client := NewClient(ReplaceTripper(http))
http.StubResponse(tc.code, bytes.NewBufferString(tc.body))
repo, _ := ghrepo.FromFullName("OWNER/REPO")
err := BranchDeleteRemote(client, repo, "branch")
if isError := err != nil; isError != tc.expectError {
t.Fatalf("unexpected result: %v", err)
}
})
}
}