Skip to content

Commit e1c1b26

Browse files
cliedemanchristophwitzko
authored andcommitted
feat: Implemented Gitlab repository
1 parent 73f28bc commit e1c1b26

File tree

11 files changed

+509
-77
lines changed

11 files changed

+509
-77
lines changed

cmd/semantic-release/main.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"context"
54
"errors"
65
"fmt"
76
"io/ioutil"
@@ -57,7 +56,18 @@ func cliHandler(c *cli.Context) error {
5756
ci := condition.NewCI()
5857
logger.Printf("detected CI: %s\n", ci.Name())
5958

60-
repo, err := semrel.NewGithubRepository(context.TODO(), conf.GheHost, conf.Slug, conf.Token)
59+
var (
60+
repo semrel.Repository
61+
err error
62+
)
63+
64+
switch ci.Name() {
65+
case "Gitlab":
66+
repo, err = semrel.NewGitlabRepository(c.Context, conf.Gitlab.BaseURL, conf.Slug, conf.Token, ci.GetCurrentBranch(), conf.Gitlab.ProjectID)
67+
default:
68+
repo, err = semrel.NewGithubRepository(c.Context, conf.GheHost, conf.Slug, conf.Token)
69+
}
70+
6171
exitIfError(err)
6272

6373
logger.Println("getting default branch...")

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ require (
77
github.com/google/go-github/v30 v30.1.0
88
github.com/shuheiktgw/go-travis v0.2.4
99
github.com/urfave/cli/v2 v2.2.0
10+
github.com/xanzy/go-gitlab v0.31.0
1011
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
1112
)

go.sum

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q
44
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
55
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
66
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
7+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
79
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
810
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
911
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -12,6 +14,11 @@ github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQF
1214
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
1315
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
1416
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
17+
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
18+
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
19+
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
20+
github.com/hashicorp/go-retryablehttp v0.6.4 h1:BbgctKO892xEyOXnGiaAwIoSq1QZ/SS4AhjoAh9DnfY=
21+
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
1522
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1623
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1724
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
@@ -20,21 +27,32 @@ github.com/shuheiktgw/go-travis v0.2.4 h1:IAnh/Dyv7ql87qtJWUcvR5MM8e5iCDGoENl9Vz
2027
github.com/shuheiktgw/go-travis v0.2.4/go.mod h1:RtODX49bvgHTvfzFvGEPFtU0dKVk0D3PyvUQR/63hT0=
2128
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
2229
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
30+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
31+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
32+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
2333
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
2434
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
35+
github.com/xanzy/go-gitlab v0.31.0 h1:+nHztQuCXGSMluKe5Q9IRaPdz6tO8O0gMkQ0vqGpiBk=
36+
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
2537
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
2638
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
2739
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
40+
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
2841
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
2942
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
3043
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
3144
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
45+
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
3246
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
3347
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
48+
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
3449
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
3550
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
3651
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
52+
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
53+
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
3754
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
55+
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
3856
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
3957
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
4058
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

pkg/config/config.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import (
88
)
99

1010
type (
11+
// Gitlab Specific Config
12+
GitlabConfig struct {
13+
BaseURL string
14+
ProjectID string
15+
}
16+
1117
// Config is a complete set of app configuration
1218
Config struct {
1319
Token string
@@ -19,6 +25,7 @@ type (
1925
Vf bool
2026
Update string
2127
GheHost string
28+
Gitlab GitlabConfig
2229
Prerelease bool
2330
TravisCom bool
2431
BetaRelease BetaRelease
@@ -45,6 +52,10 @@ func NewConfig(c *cli.Context) *Config {
4552
Prerelease: c.Bool("prerelease"),
4653
TravisCom: c.Bool("travis-com"),
4754
Match: c.String("match"),
55+
Gitlab: GitlabConfig{
56+
BaseURL: c.String("gitlab-base-url"),
57+
ProjectID: c.String("gitlab-project-id"),
58+
},
4859
}
4960

5061
f, err := os.OpenFile(".semrelrc", os.O_RDONLY, 0)

pkg/config/flags.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import (
88
var CliFlags = []cli.Flag{
99
&cli.StringFlag{
1010
Name: "token",
11-
Usage: "github token",
12-
EnvVars: []string{"GITHUB_TOKEN", "GH_TOKEN"},
11+
Usage: "github or gitlab token",
12+
EnvVars: []string{"GITHUB_TOKEN", "GH_TOKEN", "GITLAB_TOKEN"},
1313
Required: true,
1414
},
1515
&cli.StringFlag{
1616
Name: "slug",
1717
Usage: "slug of the repository",
18-
EnvVars: []string{"GITHUB_REPOSITORY", "TRAVIS_REPO_SLUG"},
18+
EnvVars: []string{"GITHUB_REPOSITORY", "TRAVIS_REPO_SLUG", "CI_PROJECT_PATH_SLUG"},
1919
Required: true,
2020
},
2121
&cli.StringFlag{
@@ -59,4 +59,14 @@ var CliFlags = []cli.Flag{
5959
Name: "match",
6060
Usage: "Only consider tags matching the given glob(7) pattern, excluding the \"refs/tags/\" prefix.",
6161
},
62+
&cli.StringFlag{
63+
Name: "gitlab-base-url",
64+
Usage: "Gitlab self hosted api path",
65+
EnvVars: []string{"CI_SERVER_URL"},
66+
},
67+
&cli.StringFlag{
68+
Name: "gitlab-project-id",
69+
Usage: "Gitlab project unique id",
70+
EnvVars: []string{"CI_PROJECT_ID"},
71+
},
6272
}

pkg/semrel/github.go

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"errors"
66
"fmt"
77
"regexp"
8-
"sort"
98
"strings"
109

1110
"github.com/Masterminds/semver"
@@ -94,48 +93,8 @@ func (repo *GithubRepository) GetLatestRelease(vrange string, re *regexp.Regexp)
9493
}
9594
opts.Page = resp.NextPage
9695
}
97-
sort.Sort(allReleases)
9896

99-
var lastRelease *Release
100-
for _, r := range allReleases {
101-
if r.Version.Prerelease() == "" {
102-
lastRelease = r
103-
break
104-
}
105-
}
106-
107-
if vrange == "" {
108-
if lastRelease != nil {
109-
return lastRelease, nil
110-
}
111-
return &Release{"", &semver.Version{}}, nil
112-
}
113-
114-
constraint, err := semver.NewConstraint(vrange)
115-
if err != nil {
116-
return nil, err
117-
}
118-
for _, r := range allReleases {
119-
if constraint.Check(r.Version) {
120-
return r, nil
121-
}
122-
}
123-
124-
nver, err := semver.NewVersion(vrange)
125-
if err != nil {
126-
return nil, err
127-
}
128-
129-
splitPre := strings.SplitN(vrange, "-", 2)
130-
if len(splitPre) == 1 {
131-
return &Release{lastRelease.SHA, nver}, nil
132-
}
133-
134-
npver, err := nver.SetPrerelease(splitPre[1])
135-
if err != nil {
136-
return nil, err
137-
}
138-
return &Release{lastRelease.SHA, &npver}, nil
97+
return allReleases.GetLatestRelease(vrange)
13998
}
14099

141100
func (repo *GithubRepository) CreateRelease(changelog string, newVersion *semver.Version, prerelease bool, branch, sha string) error {

pkg/semrel/github_test.go

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ func TestNewGithubRepository(t *testing.T) {
2929
}
3030
}
3131

32-
func createCommit(sha, message string) *github.RepositoryCommit {
32+
func createGithubCommit(sha, message string) *github.RepositoryCommit {
3333
return &github.RepositoryCommit{SHA: &sha, Commit: &github.Commit{Message: &message}}
3434
}
3535

36-
func createRef(ref, sha string) *github.Reference {
36+
func createGithubRef(ref, sha string) *github.Reference {
3737
return &github.Reference{Ref: &ref, Object: &github.GitObject{SHA: &sha}}
3838
}
3939

@@ -42,19 +42,19 @@ var (
4242
GITHUB_DEFAULTBRANCH = "master"
4343
GITHUB_REPO = github.Repository{DefaultBranch: &GITHUB_DEFAULTBRANCH, Private: &GITHUB_REPO_PRIVATE}
4444
GITHUB_COMMITS = []*github.RepositoryCommit{
45-
createCommit("abcd", "feat(app): new feature"),
46-
createCommit("dcba", "Fix: bug"),
47-
createCommit("cdba", "Initial commit"),
48-
createCommit("efcd", "chore: break\nBREAKING CHANGE: breaks everything"),
45+
createGithubCommit("abcd", "feat(app): new feature"),
46+
createGithubCommit("dcba", "Fix: bug"),
47+
createGithubCommit("cdba", "Initial commit"),
48+
createGithubCommit("efcd", "chore: break\nBREAKING CHANGE: breaks everything"),
4949
}
5050
GITHUB_TAGS = []*github.Reference{
51-
createRef("refs/tags/test-tag", "deadbeef"),
52-
createRef("refs/tags/v1.0.0", "deadbeef"),
53-
createRef("refs/tags/v2.0.0", "deadbeef"),
54-
createRef("refs/tags/v2.1.0-beta", "deadbeef"),
55-
createRef("refs/tags/v3.0.0-beta.2", "deadbeef"),
56-
createRef("refs/tags/v3.0.0-beta.1", "deadbeef"),
57-
createRef("refs/tags/2020.04.19", "deadbeef"),
51+
createGithubRef("refs/tags/test-tag", "deadbeef"),
52+
createGithubRef("refs/tags/v1.0.0", "deadbeef"),
53+
createGithubRef("refs/tags/v2.0.0", "deadbeef"),
54+
createGithubRef("refs/tags/v2.1.0-beta", "deadbeef"),
55+
createGithubRef("refs/tags/v3.0.0-beta.2", "deadbeef"),
56+
createGithubRef("refs/tags/v3.0.0-beta.1", "deadbeef"),
57+
createGithubRef("refs/tags/2020.04.19", "deadbeef"),
5858
}
5959
)
6060

@@ -100,7 +100,7 @@ func githubHandler(w http.ResponseWriter, r *http.Request) {
100100
http.Error(w, "invalid route", http.StatusNotImplemented)
101101
}
102102

103-
func getNewTestRepo(t *testing.T) (*GithubRepository, *httptest.Server) {
103+
func getNewGithubTestRepo(t *testing.T) (*GithubRepository, *httptest.Server) {
104104
repo, err := NewGithubRepository(context.TODO(), "", "owner/test-repo", "token")
105105
if err != nil {
106106
t.Fatal(err)
@@ -112,7 +112,7 @@ func getNewTestRepo(t *testing.T) (*GithubRepository, *httptest.Server) {
112112
}
113113

114114
func TestGithubGetInfo(t *testing.T) {
115-
repo, ts := getNewTestRepo(t)
115+
repo, ts := getNewGithubTestRepo(t)
116116
defer ts.Close()
117117
defaultBranch, isPrivate, err := repo.GetInfo()
118118
if err != nil {
@@ -123,20 +123,8 @@ func TestGithubGetInfo(t *testing.T) {
123123
}
124124
}
125125

126-
func compareCommit(c *Commit, t, s string, change Change) bool {
127-
if c.Type != t || c.Scope != s {
128-
return false
129-
}
130-
if c.Change.Major != change.Major ||
131-
c.Change.Minor != change.Minor ||
132-
c.Change.Patch != change.Patch {
133-
return false
134-
}
135-
return true
136-
}
137-
138126
func TestGithubGetCommits(t *testing.T) {
139-
repo, ts := getNewTestRepo(t)
127+
repo, ts := getNewGithubTestRepo(t)
140128
defer ts.Close()
141129
commits, err := repo.GetCommits("")
142130
if err != nil {
@@ -155,7 +143,7 @@ func TestGithubGetCommits(t *testing.T) {
155143
}
156144

157145
func TestGithubGetLatestRelease(t *testing.T) {
158-
repo, ts := getNewTestRepo(t)
146+
repo, ts := getNewGithubTestRepo(t)
159147
defer ts.Close()
160148
release, err := repo.GetLatestRelease("", nil)
161149
if err != nil {
@@ -200,7 +188,7 @@ func TestGithubGetLatestRelease(t *testing.T) {
200188
}
201189

202190
func TestGithubCreateRelease(t *testing.T) {
203-
repo, ts := getNewTestRepo(t)
191+
repo, ts := getNewGithubTestRepo(t)
204192
defer ts.Close()
205193
newVersion, _ := semver.NewVersion("2.0.0")
206194
err := repo.CreateRelease("", newVersion, false, "", "deadbeef")

0 commit comments

Comments
 (0)