-
Notifications
You must be signed in to change notification settings - Fork 4
/
reference.go
89 lines (78 loc) · 2.51 KB
/
reference.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package patch2pr
import (
"context"
"fmt"
"strings"
"github.com/google/go-github/v63/github"
)
// Reference is a named reference in a repository.
type Reference struct {
client *github.Client
owner string
repo string
ref string
}
// NewReference creates a new Reference for ref in repo.
func NewReference(client *github.Client, repo Repository, ref string) *Reference {
if !strings.HasPrefix(ref, "refs/") {
ref = fmt.Sprintf("refs/%s", ref)
}
return &Reference{
client: client,
owner: repo.Owner,
repo: repo.Name,
ref: ref,
}
}
// Set creates or updates the reference to point to sha. If force is true and
// the reference exists, Set updates it even if the update is not a
// fast-forward.
func (r *Reference) Set(ctx context.Context, sha string, force bool) error {
// Test for existence because update and create return 422 responses if the
// the ref is missing or exists, respectively. The same code is also used
// for other errors like passing a bad SHA, so our only other option is to
// parse the string message, which is fragile.
var exists bool
if _, _, err := r.client.Git.GetRef(ctx, r.owner, r.repo, r.ref); err != nil {
if rerr, ok := err.(*github.ErrorResponse); !ok || rerr.Response.StatusCode != 404 {
return fmt.Errorf("get ref failed: %w", err)
}
} else {
exists = true
}
if exists {
if _, _, err := r.client.Git.UpdateRef(ctx, r.owner, r.repo, &github.Reference{
Ref: github.String(r.ref),
Object: &github.GitObject{
SHA: github.String(sha),
},
}, force); err != nil {
return fmt.Errorf("update ref failed: %w", err)
}
} else {
if _, _, err := r.client.Git.CreateRef(ctx, r.owner, r.repo, &github.Reference{
Ref: github.String(r.ref),
Object: &github.GitObject{
SHA: github.String(sha),
},
}); err != nil {
return fmt.Errorf("create ref failed: %w", err)
}
}
return nil
}
// PullRequest create a new pull request for the reference. The reference must
// be a branch (start with "refs/heads/".) The pull request takes values from
// spec, except for Head, which is set to the reference.
func (r *Reference) PullRequest(ctx context.Context, spec *github.NewPullRequest) (*github.PullRequest, error) {
if !strings.HasPrefix(r.ref, "refs/heads/") {
return nil, fmt.Errorf("reference %s is not a branch", r.ref)
}
specCopy := *spec
specCopy.Head = github.String(strings.TrimPrefix(r.ref, "refs/heads/"))
pr, _, err := r.client.PullRequests.Create(ctx, r.owner, r.repo, &specCopy)
if err != nil {
return nil, err
}
return pr, nil
}