Skip to content

Commit 17da653

Browse files
committed
add support for builds api
1 parent 0971d29 commit 17da653

File tree

13 files changed

+554
-14
lines changed

13 files changed

+554
-14
lines changed

README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ go-gitlab-client is a simple client written in golang to consume gitlab API.
99
##features
1010

1111
*
12-
###Projects [gitlab api doc](http://api.gitlab.org/projects.html)
12+
### Projects [gitlab api doc](http://doc.gitlab.com/ce/api/projects.html)
1313
* list projects
1414
* get single project
1515
* remove project
1616

1717
*
18-
###Repositories [gitlab api doc](http://api.gitlab.org/repositories.html)
18+
### Repositories [gitlab api doc](http://doc.gitlab.com/ce/api/repositories.html)
1919
* list repository branches
2020
* get single repository branch
2121
* list project repository tags
@@ -24,17 +24,24 @@ go-gitlab-client is a simple client written in golang to consume gitlab API.
2424
* add/get/edit/rm project hook
2525

2626
*
27-
###Users [gitlab api doc](http://api.gitlab.org/users.html)
27+
### Users [gitlab api doc](http://api.gitlab.org/users.html)
2828
* get single user
2929
* manage user keys
3030

3131
*
32-
###Deploy Keys [gitlab api doc](http://api.gitlab.org/deploy_keys.html)
32+
### Deploy Keys [gitlab api doc](http://doc.gitlab.com/ce/api/deploy_keys.html)
3333
* list project deploy keys
3434
* add/get/rm project deploy key
3535

36-
37-
36+
*
37+
### Builds [gitlab api doc](http://doc.gitlab.com/ce/api/builds.html)
38+
* List project builds
39+
* Get a single build
40+
* List commit builds
41+
* Get build artifacts
42+
* Cancel a build
43+
* Retry a build
44+
* Erase a build
3845

3946
##Installation
4047

builds.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package gogitlab
2+
3+
import (
4+
"encoding/json"
5+
"io"
6+
)
7+
8+
const (
9+
project_builds = "/projects/:id/builds" // List project builds
10+
project_build = "/projects/:id/builds/:build_id" // Get a single build
11+
project_commit_builds = "/projects/:id/repository/commits/:sha/builds" // List commit builds
12+
project_build_artifacts = "/projects/:id/builds/:build_id/artifacts" // Get build artifacts
13+
project_build_cancel = "/projects/:id/builds/:build_id/cancel" // Cancel a build
14+
project_build_retry = "/projects/:id/builds/:build_id/retry" // Retry a build
15+
project_build_erase = "/projects/:id/builds/:build_id/erase" // Erase a build
16+
)
17+
18+
type ArtifactsFile struct {
19+
Filename string `json:"filename"`
20+
Size int `json:"size"`
21+
}
22+
23+
type Build struct {
24+
Id int `json:"id"`
25+
ArtifactsFile ArtifactsFile `json:"artifacts_file"`
26+
Commit Commit `json:"commit"`
27+
CreatedAt string `json:"created_at"`
28+
DownloadURL string `json:"download_url"`
29+
FinishedAt string `json:"finished_at"`
30+
Name string `json:"name"`
31+
Ref string `json:"ref"`
32+
Stage string `json:"stage"`
33+
StartedAt string `json:"started_at"`
34+
Status string `json:"status"`
35+
Tag bool `json:"tag"`
36+
User User `json:"user"`
37+
}
38+
39+
func (g *Gitlab) ProjectBuilds(id string) ([]*Build, error) {
40+
url, opaque := g.ResourceUrlRaw(project_builds, map[string]string{
41+
":id": id,
42+
})
43+
44+
builds := make([]*Build, 0)
45+
46+
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
47+
if err != nil {
48+
return builds, err
49+
}
50+
51+
err = json.Unmarshal(contents, &builds)
52+
53+
return builds, err
54+
}
55+
56+
func (g *Gitlab) ProjectCommitBuilds(id, sha1 string) ([]*Build, error) {
57+
url, opaque := g.ResourceUrlRaw(project_commit_builds, map[string]string{
58+
":id": id,
59+
":sha": sha1,
60+
})
61+
62+
builds := make([]*Build, 0)
63+
64+
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
65+
if err != nil {
66+
return builds, err
67+
}
68+
69+
err = json.Unmarshal(contents, &builds)
70+
71+
return builds, err
72+
}
73+
74+
func (g *Gitlab) ProjectBuild(id, buildId string) (*Build, error) {
75+
url, opaque := g.ResourceUrlRaw(project_build, map[string]string{
76+
":id": id,
77+
":build_id": buildId,
78+
})
79+
80+
build := &Build{}
81+
82+
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
83+
if err != nil {
84+
return nil, err
85+
}
86+
87+
err = json.Unmarshal(contents, &build)
88+
89+
return build, err
90+
}
91+
92+
func (g *Gitlab) ProjectBuildArtifacts(id, buildId string) (io.ReadCloser, error) {
93+
url, _ := g.ResourceUrlRaw(project_build_artifacts, map[string]string{
94+
":id": id,
95+
":build_id": buildId,
96+
})
97+
98+
resp, err := g.execRequest("GET", url, nil)
99+
100+
if err != nil {
101+
return nil, err
102+
}
103+
104+
return resp.Body, nil
105+
}
106+
107+
func (g *Gitlab) ProjectCancelBuild(id, buildId string) (*Build, error) {
108+
url, opaque := g.ResourceUrlRaw(project_build_cancel, map[string]string{
109+
":id": id,
110+
":build_id": buildId,
111+
})
112+
113+
build := &Build{}
114+
115+
contents, err := g.buildAndExecRequestRaw("POST", url, opaque, nil)
116+
if err != nil {
117+
return nil, err
118+
}
119+
120+
err = json.Unmarshal(contents, &build)
121+
122+
return build, err
123+
}
124+
125+
func (g *Gitlab) ProjectRetryBuild(id, buildId string) (*Build, error) {
126+
url, opaque := g.ResourceUrlRaw(project_build_retry, map[string]string{
127+
":id": id,
128+
":build_id": buildId,
129+
})
130+
131+
build := &Build{}
132+
133+
contents, err := g.buildAndExecRequestRaw("POST", url, opaque, nil)
134+
if err != nil {
135+
return nil, err
136+
}
137+
138+
err = json.Unmarshal(contents, &build)
139+
140+
return build, err
141+
}
142+
143+
func (g *Gitlab) ProjectEraseBuild(id, buildId string) (*Build, error) {
144+
url, opaque := g.ResourceUrlRaw(project_build_erase, map[string]string{
145+
":id": id,
146+
":build_id": buildId,
147+
})
148+
149+
build := &Build{}
150+
151+
contents, err := g.buildAndExecRequestRaw("POST", url, opaque, nil)
152+
if err != nil {
153+
return nil, err
154+
}
155+
156+
err = json.Unmarshal(contents, &build)
157+
158+
return build, err
159+
}

builds_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package gogitlab
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"io/ioutil"
6+
"testing"
7+
)
8+
9+
func TestProjectBuilds(t *testing.T) {
10+
ts, gitlab := Stub("stubs/builds/list.json")
11+
defer ts.Close()
12+
13+
builds, err := gitlab.ProjectBuilds("3")
14+
15+
assert.Nil(t, err)
16+
assert.Equal(t, len(builds), 2)
17+
assert.Equal(t, builds[0].ArtifactsFile.Filename, "artifacts.zip")
18+
}
19+
20+
func TestProjectCommitBuilds(t *testing.T) {
21+
ts, gitlab := Stub("stubs/builds/commit_builds_list.json")
22+
defer ts.Close()
23+
24+
builds, err := gitlab.ProjectBuilds("3")
25+
26+
assert.Nil(t, err)
27+
assert.Equal(t, len(builds), 2)
28+
assert.Equal(t, builds[1].User.AvatarUrl, "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon")
29+
}
30+
31+
func TestProjectBuild(t *testing.T) {
32+
ts, gitlab := Stub("stubs/builds/build.json")
33+
defer ts.Close()
34+
35+
build, err := gitlab.ProjectBuild("3", "12")
36+
37+
assert.Nil(t, err)
38+
assert.Equal(t, build.Commit.Id, "0ff3ae198f8601a285adcf5c0fff204ee6fba5fd")
39+
}
40+
41+
func TestProjectCancelBuild(t *testing.T) {
42+
ts, gitlab := Stub("stubs/builds/cancel.json")
43+
defer ts.Close()
44+
45+
build, err := gitlab.ProjectBuild("3", "12")
46+
47+
assert.Nil(t, err)
48+
assert.Equal(t, build.Status, "canceled")
49+
}
50+
51+
func TestProjectRetryBuild(t *testing.T) {
52+
ts, gitlab := Stub("stubs/builds/retry.json")
53+
defer ts.Close()
54+
55+
build, err := gitlab.ProjectBuild("3", "12")
56+
57+
assert.Nil(t, err)
58+
assert.Equal(t, build.Status, "pending")
59+
}
60+
61+
func TestProjectEraseBuild(t *testing.T) {
62+
ts, gitlab := Stub("stubs/builds/erase.json")
63+
defer ts.Close()
64+
65+
build, err := gitlab.ProjectBuild("3", "12")
66+
67+
assert.Nil(t, err)
68+
assert.Equal(t, build.Status, "failed")
69+
}
70+
71+
func TestProjectArtifact(t *testing.T) {
72+
ts, gitlab := Stub("stubs/builds/content.txt")
73+
defer ts.Close()
74+
75+
r, err := gitlab.ProjectBuildArtifacts("3", "12")
76+
77+
assert.Nil(t, err)
78+
79+
defer r.Close()
80+
81+
contents, err := ioutil.ReadAll(r)
82+
83+
assert.Equal(t, string(contents), "a content")
84+
}

gitlab.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ func (g *Gitlab) ResourceUrl(url string, params map[string]string) string {
6868
return url
6969
}
7070

71-
func (g *Gitlab) buildAndExecRequest(method, url string, body []byte) ([]byte, error) {
72-
71+
func (g *Gitlab) execRequest(method, url string, body []byte) (*http.Response, error) {
7372
var req *http.Request
7473
var err error
7574

@@ -79,6 +78,7 @@ func (g *Gitlab) buildAndExecRequest(method, url string, body []byte) ([]byte, e
7978
} else {
8079
req, err = http.NewRequest(method, url, nil)
8180
}
81+
8282
if err != nil {
8383
panic("Error while building gitlab request")
8484
}
@@ -87,16 +87,28 @@ func (g *Gitlab) buildAndExecRequest(method, url string, body []byte) ([]byte, e
8787
if err != nil {
8888
return nil, fmt.Errorf("Client.Do error: %q", err)
8989
}
90+
91+
if resp.StatusCode >= http.StatusBadRequest {
92+
err = fmt.Errorf("*Gitlab.buildAndExecRequest failed: <%d> %s", resp.StatusCode, req.URL)
93+
}
94+
95+
return resp, err
96+
}
97+
98+
func (g *Gitlab) buildAndExecRequest(method, url string, body []byte) ([]byte, error) {
99+
resp, err := g.execRequest(method, url, body)
100+
101+
if err != nil {
102+
return nil, err
103+
}
104+
90105
defer resp.Body.Close()
106+
91107
contents, err := ioutil.ReadAll(resp.Body)
92108
if err != nil {
93109
fmt.Printf("%s", err)
94110
}
95111

96-
if resp.StatusCode >= 400 {
97-
err = fmt.Errorf("*Gitlab.buildAndExecRequest failed: <%d> %s", resp.StatusCode, req.URL)
98-
}
99-
100112
return contents, err
101113
}
102114

@@ -115,6 +127,7 @@ func (g *Gitlab) ResourceUrlRaw(u string, params map[string]string) (string, str
115127
return u, ""
116128
}
117129
opaque := "//" + p.Host + g.ApiPath + path
130+
118131
return u, opaque
119132
}
120133

helper_test.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,23 @@ import (
77
)
88

99
func Stub(filename string) (*httptest.Server, *Gitlab) {
10-
stub, _ := ioutil.ReadFile(filename)
10+
11+
var err error
12+
13+
stub := []byte("")
14+
15+
if len(filename) > 0 {
16+
stub, err = ioutil.ReadFile(filename)
17+
18+
if err != nil {
19+
panic(err)
20+
}
21+
}
22+
1123
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1224
w.Write([]byte(stub))
1325
}))
1426
gitlab := NewGitlab(ts.URL, "", "")
27+
1528
return ts, gitlab
1629
}

0 commit comments

Comments
 (0)