diff --git a/controller/build.go b/controller/build.go index 0741fde2..bc457fc4 100644 --- a/controller/build.go +++ b/controller/build.go @@ -180,13 +180,19 @@ func PostBuild(c *gin.Context) { } // fetch the .drone.yml file from the database - raw, sec, err := remote_.Script(user, repo, build) + raw, err := remote_.File(user, repo, build, droneYml) if err != nil { - log.Errorf("failure to get .drone.yml for %s. %s", repo.FullName, err) + log.Errorf("failure to get build config for %s. %s", repo.FullName, err) c.AbortWithError(404, err) return } + // Fetch secrets file but don't exit on error as it's optional + sec, err := remote_.File(user, repo, build, droneSec) + if err != nil { + log.Debugf("cannot find build secrets for %s. %s", repo.FullName, err) + } + key, _ := store.GetKey(c, repo) netrc, err := remote_.Netrc(user, repo) if err != nil { diff --git a/controller/hook.go b/controller/hook.go index 58bc83fd..fecb3be4 100644 --- a/controller/hook.go +++ b/controller/hook.go @@ -21,6 +21,18 @@ import ( "github.com/drone/drone/yaml/matrix" ) +var ( + droneYml = os.Getenv("BUILD_CONFIG_FILE") + droneSec string +) + +func init() { + if droneYml == "" { + droneYml = ".drone.yml" + } + droneSec = fmt.Sprintf("%s.sec", strings.TrimSuffix(droneYml, filepath.Ext(droneYml))) +} + var skipRe = regexp.MustCompile(`\[(?i:ci *skip|skip *ci)\]`) func PostHook(c *gin.Context) { @@ -124,13 +136,18 @@ func PostHook(c *gin.Context) { } } - // fetch the .drone.yml file from the database - raw, sec, err := remote_.Script(user, repo, build) + // fetch the build file from the database + raw, err := remote_.File(user, repo, build, droneYml) if err != nil { - log.Errorf("failure to get .drone.yml for %s. %s", repo.FullName, err) + log.Errorf("failure to get build config for %s. %s", repo.FullName, err) c.AbortWithError(404, err) return } + sec, err := remote_.File(user, repo, build, droneSec) + if err != nil { + log.Debugf("cannot find build secrets for %s. %s", repo.FullName, err) + // NOTE we don't exit on failure. The sec file is optional + } axes, err := matrix.Parse(string(raw)) if err != nil { diff --git a/remote/bitbucket/bitbucket.go b/remote/bitbucket/bitbucket.go index 630c3eca..12d8a076 100644 --- a/remote/bitbucket/bitbucket.go +++ b/remote/bitbucket/bitbucket.go @@ -237,9 +237,8 @@ func (bb *Bitbucket) Perm(u *model.User, owner, name string) (*model.Perm, error return perms, nil } -// Script fetches the build script (.drone.yml) from the remote -// repository and returns in string format. -func (bb *Bitbucket) Script(u *model.User, r *model.Repo, b *model.Build) ([]byte, []byte, error) { +// File fetches a file from the remote repository and returns in string format. +func (bb *Bitbucket) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) { client := NewClientToken( bb.Client, bb.Secret, @@ -249,19 +248,12 @@ func (bb *Bitbucket) Script(u *model.User, r *model.Repo, b *model.Build) ([]byt }, ) - // fetches the .drone.yml for the specified revision. This file - // is required, and will error if not found - config, err := client.FindSource(r.Owner, r.Name, b.Commit, ".drone.yml") + config, err := client.FindSource(r.Owner, r.Name, b.Commit, f) if err != nil { - return nil, nil, err + return nil, err } - // fetches the .drone.sec for the specified revision. This file - // is completely optional, therefore we will not return a not - // found error - sec, _ := client.FindSource(r.Owner, r.Name, b.Commit, ".drone.sec") - - return []byte(config.Data), []byte(sec.Data), err + return []byte(config.Data), err } // Status sends the commit status to the remote system. @@ -280,10 +272,10 @@ func (bb *Bitbucket) Status(u *model.User, r *model.Repo, b *model.Build, link s desc := getDesc(b.Status) data := BuildStatus{ - State: status, - Key: "Drone", - Url: link, - Desc: desc, + State: status, + Key: "Drone", + Url: link, + Desc: desc, } err := client.CreateStatus(r.Owner, r.Name, b.Commit, &data) diff --git a/remote/github/github.go b/remote/github/github.go index 3e35ffeb..433bd2db 100644 --- a/remote/github/github.go +++ b/remote/github/github.go @@ -225,14 +225,11 @@ func (g *Github) Perm(u *model.User, owner, name string) (*model.Perm, error) { return m, nil } -// Script fetches the build script (.drone.yml) from the remote -// repository and returns in string format. -func (g *Github) Script(u *model.User, r *model.Repo, b *model.Build) ([]byte, []byte, error) { +// File fetches a file from the remote repository and returns in string format. +func (g *Github) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) { client := NewClient(g.API, u.Token, g.SkipVerify) - - cfg, err := GetFile(client, r.Owner, r.Name, ".drone.yml", b.Commit) - sec, _ := GetFile(client, r.Owner, r.Name, ".drone.sec", b.Commit) - return cfg, sec, err + cfg, err := GetFile(client, r.Owner, r.Name, f, b.Commit) + return cfg, err } // Status sends the commit status to the remote system. diff --git a/remote/gitlab/gitlab.go b/remote/gitlab/gitlab.go index e6aef04f..1be25292 100644 --- a/remote/gitlab/gitlab.go +++ b/remote/gitlab/gitlab.go @@ -23,16 +23,16 @@ const ( ) type Gitlab struct { - URL string - Client string - Secret string - AllowedOrgs []string - CloneMode string - Open bool - PrivateMode bool - SkipVerify bool - HideArchives bool - Search bool + URL string + Client string + Secret string + AllowedOrgs []string + CloneMode string + Open bool + PrivateMode bool + SkipVerify bool + HideArchives bool + Search bool } func Load(env envconfig.Env) *Gitlab { @@ -247,24 +247,19 @@ func (g *Gitlab) Perm(u *model.User, owner, name string) (*model.Perm, error) { return m, nil } -// GetScript fetches the build script (.drone.yml) from the remote -// repository and returns in string format. -func (g *Gitlab) Script(user *model.User, repo *model.Repo, build *model.Build) ([]byte, []byte, error) { +// File fetches a file from the remote repository and returns in string format. +func (g *Gitlab) File(user *model.User, repo *model.Repo, build *model.Build, f string) ([]byte, error) { var client = NewClient(g.URL, user.Token, g.SkipVerify) id, err := GetProjectId(g, client, repo.Owner, repo.Name) if err != nil { - return nil, nil, err + return nil, err } - out1, err := client.RepoRawFile(id, build.Commit, ".drone.yml") + out, err := client.RepoRawFile(id, build.Commit, f) if err != nil { - return nil, nil, err + return nil, err } - out2, err := client.RepoRawFile(id, build.Commit, ".drone.sec") - if err != nil { - return out1, nil, nil - } - return out1, out2, err + return out, err } // NOTE Currently gitlab doesn't support status for commits and events, diff --git a/remote/gogs/gogs.go b/remote/gogs/gogs.go index 96f85879..1a3535a5 100644 --- a/remote/gogs/gogs.go +++ b/remote/gogs/gogs.go @@ -1,7 +1,7 @@ package gogs import ( - "crypto/tls" + "crypto/tls" "fmt" "net" "net/http" @@ -59,7 +59,7 @@ func (g *Gogs) Login(res http.ResponseWriter, req *http.Request) (*model.User, b return nil, false, nil } - client := NewGogsClient(g.URL, "", g.SkipVerify) + client := NewGogsClient(g.URL, "", g.SkipVerify) // try to fetch drone token if it exists var accessToken string @@ -83,7 +83,7 @@ func (g *Gogs) Login(res http.ResponseWriter, req *http.Request) (*model.User, b accessToken = token.Sha1 } - client = NewGogsClient(g.URL, accessToken, g.SkipVerify) + client = NewGogsClient(g.URL, accessToken, g.SkipVerify) userInfo, err := client.GetUserInfo(username) if err != nil { return nil, false, err @@ -158,13 +158,11 @@ func (g *Gogs) Perm(u *model.User, owner, name string) (*model.Perm, error) { } -// Script fetches the build script (.drone.yml) from the remote -// repository and returns in string format. -func (g *Gogs) Script(u *model.User, r *model.Repo, b *model.Build) ([]byte, []byte, error) { +// File fetches a file from the remote repository and returns in string format. +func (g *Gogs) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) { client := NewGogsClient(g.URL, u.Token, g.SkipVerify) - cfg, err := client.GetFile(r.Owner, r.Name, b.Commit, ".drone.yml") - sec, _ := client.GetFile(r.Owner, r.Name, b.Commit, ".drone.sec") - return cfg, sec, err + cfg, err := client.GetFile(r.Owner, r.Name, b.Commit, f) + return cfg, err } // Status sends the commit status to the remote system. @@ -182,7 +180,7 @@ func (g *Gogs) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) { } host, _, err := net.SplitHostPort(url_.Host) if err == nil { - url_.Host=host + url_.Host = host } return &model.Netrc{ Login: u.Token, @@ -239,16 +237,16 @@ func (g *Gogs) Hook(r *http.Request) (*model.Repo, *model.Build, error) { // NewClient initializes and returns a API client. func NewGogsClient(url, token string, skipVerify bool) *gogs.Client { - sslClient := &http.Client{} - c := gogs.NewClient(url, token) + sslClient := &http.Client{} + c := gogs.NewClient(url, token) - if skipVerify { - sslClient.Transport = &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } - c.SetHTTPClient(sslClient) - } - return c + if skipVerify { + sslClient.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + c.SetHTTPClient(sslClient) + } + return c } func (g *Gogs) String() string { diff --git a/remote/mock/remote.go b/remote/mock/remote.go index 60aed3f3..28928b9f 100644 --- a/remote/mock/remote.go +++ b/remote/mock/remote.go @@ -119,35 +119,26 @@ func (_m *Remote) Perm(u *model.User, owner string, repo string) (*model.Perm, e return r0, r1 } -func (_m *Remote) Script(u *model.User, r *model.Repo, b *model.Build) ([]byte, []byte, error) { - ret := _m.Called(u, r, b) +func (_m *Remote) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) { + ret := _m.Called(u, r, b, f) var r0 []byte - if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, *model.Build) []byte); ok { - r0 = rf(u, r, b) + if rf, ok := ret.Get(0).(func(*model.User, *model.Repo, *model.Build, string) []byte); ok { + r0 = rf(u, r, b, f) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]byte) } } - var r1 []byte - if rf, ok := ret.Get(1).(func(*model.User, *model.Repo, *model.Build) []byte); ok { - r1 = rf(u, r, b) + var r1 error + if rf, ok := ret.Get(1).(func(*model.User, *model.Repo, *model.Build, string) error); ok { + r1 = rf(u, r, b, f) } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).([]byte) - } + r1 = ret.Error(1) } - var r2 error - if rf, ok := ret.Get(2).(func(*model.User, *model.Repo, *model.Build) error); ok { - r2 = rf(u, r, b) - } else { - r2 = ret.Error(2) - } - - return r0, r1, r2 + return r0, r1 } func (_m *Remote) Status(u *model.User, r *model.Repo, b *model.Build, link string) error { ret := _m.Called(u, r, b, link) diff --git a/remote/remote.go b/remote/remote.go index 8020bfb0..192154ea 100644 --- a/remote/remote.go +++ b/remote/remote.go @@ -55,9 +55,9 @@ type Remote interface { // the remote system for the specified user. Perm(u *model.User, owner, repo string) (*model.Perm, error) - // Script fetches the build script (.drone.yml) from the remote - // repository and returns in string format. - Script(u *model.User, r *model.Repo, b *model.Build) ([]byte, []byte, error) + // File fetches a file from the remote repository and returns in string + // format. + File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) // Status sends the commit status to the remote system. // An example would be the GitHub pull request status. @@ -115,10 +115,9 @@ func Perm(c context.Context, u *model.User, owner, repo string) (*model.Perm, er return FromContext(c).Perm(u, owner, repo) } -// Script fetches the build script (.drone.yml) from the remote -// repository and returns in string format. -func Script(c context.Context, u *model.User, r *model.Repo, b *model.Build) ([]byte, []byte, error) { - return FromContext(c).Script(u, r, b) +// File fetches a file from the remote repository and returns in string format. +func File(c context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) { + return FromContext(c).File(u, r, b, f) } // Status sends the commit status to the remote system.