/
repo.go
130 lines (117 loc) · 2.99 KB
/
repo.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package types
import (
"context"
"fmt"
"github.com/Masterminds/semver"
"github.com/shurcooL/githubv4"
"golang.org/x/oauth2"
"gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing"
"os"
"sort"
)
type Repo struct {
Repository *git.Repository
GraphQlClient *githubv4.Client
}
type Incrementation string
type IncrementingFunction func(version *semver.Version) semver.Version
const (
Major Incrementation = "major"
Minor Incrementation = "minor"
Patch Incrementation = "patch"
)
var incrementationMap = map[Incrementation] IncrementingFunction {
Major: func(version *semver.Version) semver.Version {
return version.IncMajor()
},
Minor: func(version *semver.Version) semver.Version {
return version.IncMinor()
},
Patch: func(version *semver.Version) semver.Version {
return version.IncPatch()
},
}
func (r *Repo) CreateReleaseBranch(inc Incrementation) error {
next, err := r.IncrementVersion(inc)
if err != nil {
return err
}
headRef, err := r.Repository.Head()
if err != nil {
return err
}
return r.pushReleaseBranch(next, headRef)
}
func (r Repo) FetchLatestTag() (*semver.Version, error) {
tags, err := r.Repository.Tags()
if err != nil {
return nil, err
}
var versions []*semver.Version
err = tags.ForEach(func(reference *plumbing.Reference) error {
if version, err := semver.NewVersion(reference.Name().Short()); err == nil {
versions = append(versions, version)
}
return nil
})
if err != nil {
return nil, err
}
if len(versions) == 0 {
return semver.NewVersion("0.0.0")
}
sort.Sort(semver.Collection(versions))
return versions[len(versions) - 1], nil
}
func (r Repo) IncrementVersion(inc Incrementation) (semver.Version, error) {
current, err := r.FetchLatestTag()
if err != nil {
return semver.Version{}, err
}
version := incrementationMap[inc](current)
return version, err
}
func (r *Repo) pushReleaseBranch(next semver.Version, ref *plumbing.Reference) error {
err := r.pushRef(
fmt.Sprintf("refs/heads/release/v%s", next.String()),
ref.Hash().String(),
)
if err != nil {
return err
}
return r.pushRef(
fmt.Sprintf("refs/tags/v%s", next.String()),
ref.Hash().String(),
)
}
func (r *Repo) pushRef(name string, hash string) error {
var m struct {
CreateRef struct {
Ref struct {
Name githubv4.String
}
} `graphql:"createRef(input:$input)"`
}
input := githubv4.CreateRefInput{
RepositoryID: githubv4.ID(os.Getenv("INPUT_REPO-ID")),
Name: githubv4.String(name),
Oid: githubv4.GitObjectID(hash),
}
return r.GraphQlClient.Mutate(context.Background(), &m, input, nil)
}
func InitializeRepo(dir string, errHandler func(msg interface{})) *Repo {
repo, err := git.PlainOpen(dir)
errHandler(err)
return &Repo{
Repository: repo,
GraphQlClient: createClient(),
}
}
func createClient() *githubv4.Client {
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
)
httpClient := oauth2.NewClient(context.Background(), src)
return githubv4.NewClient(httpClient)
}