mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 20:01:02 +00:00
Status line for each pipeline on Github
This commit is contained in:
parent
a433591afa
commit
1d47ba8a32
16 changed files with 78 additions and 41 deletions
|
@ -214,7 +214,7 @@ func (c *config) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status creates a build status for the Bitbucket commit.
|
// Status creates a build status for the Bitbucket commit.
|
||||||
func (c *config) Status(u *model.User, r *model.Repo, b *model.Build, link string) error {
|
func (c *config) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||||
status := internal.BuildStatus{
|
status := internal.BuildStatus{
|
||||||
State: convertStatus(b.Status),
|
State: convertStatus(b.Status),
|
||||||
Desc: convertDesc(b.Status),
|
Desc: convertDesc(b.Status),
|
||||||
|
|
|
@ -283,7 +283,7 @@ func Test_bitbucket(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should update the status", func() {
|
g.It("Should update the status", func() {
|
||||||
err := c.Status(fakeUser, fakeRepo, fakeBuild, "http://127.0.0.1")
|
err := c.Status(fakeUser, fakeRepo, fakeBuild, "http://127.0.0.1", nil)
|
||||||
g.Assert(err == nil).IsTrue()
|
g.Assert(err == nil).IsTrue()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ func (c *Config) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status is not supported by the bitbucketserver driver.
|
// Status is not supported by the bitbucketserver driver.
|
||||||
func (c *Config) Status(u *model.User, r *model.Repo, b *model.Build, link string) error {
|
func (c *Config) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||||
status := internal.BuildStatus{
|
status := internal.BuildStatus{
|
||||||
State: convertStatus(b.Status),
|
State: convertStatus(b.Status),
|
||||||
Desc: convertDesc(b.Status),
|
Desc: convertDesc(b.Status),
|
||||||
|
|
|
@ -243,7 +243,7 @@ func (c *Coding) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status sends the commit status to the remote system.
|
// Status sends the commit status to the remote system.
|
||||||
func (c *Coding) Status(u *model.User, r *model.Repo, b *model.Build, link string) error {
|
func (c *Coding) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||||
// EMPTY: not implemented in Coding OAuth API
|
// EMPTY: not implemented in Coding OAuth API
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ func (c *client) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status is not supported by the Gogs driver.
|
// Status is not supported by the Gogs driver.
|
||||||
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string) error {
|
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,7 @@ func (c *client) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status is supported by the Gitea driver.
|
// Status is supported by the Gitea driver.
|
||||||
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string) error {
|
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||||
client := c.newClientToken(u.Token)
|
client := c.newClientToken(u.Token)
|
||||||
|
|
||||||
status := getStatus(b.Status)
|
status := getStatus(b.Status)
|
||||||
|
|
|
@ -18,10 +18,10 @@ import (
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/laszlocph/drone-oss-08/model"
|
|
||||||
"github.com/laszlocph/drone-oss-08/remote/gitea/fixtures"
|
|
||||||
"github.com/franela/goblin"
|
"github.com/franela/goblin"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/laszlocph/drone-oss-08/model"
|
||||||
|
"github.com/laszlocph/drone-oss-08/remote/gitea/fixtures"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_gitea(t *testing.T) {
|
func Test_gitea(t *testing.T) {
|
||||||
|
@ -149,7 +149,7 @@ func Test_gitea(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should return nil from send build status", func() {
|
g.It("Should return nil from send build status", func() {
|
||||||
err := c.Status(fakeUser, fakeRepo, fakeBuild, "http://gitea.io")
|
err := c.Status(fakeUser, fakeRepo, fakeBuild, "http://gitea.io", nil)
|
||||||
g.Assert(err == nil).IsTrue()
|
g.Assert(err == nil).IsTrue()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -430,17 +430,17 @@ func matchingHooks(hooks []github.Hook, rawurl string) *github.Hook {
|
||||||
|
|
||||||
// Status sends the commit status to the remote system.
|
// Status sends the commit status to the remote system.
|
||||||
// An example would be the GitHub pull request status.
|
// An example would be the GitHub pull request status.
|
||||||
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string) error {
|
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||||
client := c.newClientToken(u.Token)
|
client := c.newClientToken(u.Token)
|
||||||
switch b.Event {
|
switch b.Event {
|
||||||
case "deployment":
|
case "deployment":
|
||||||
return deploymentStatus(client, r, b, link)
|
return deploymentStatus(client, r, b, link)
|
||||||
default:
|
default:
|
||||||
return repoStatus(client, r, b, link, c.Context)
|
return repoStatus(client, r, b, link, c.Context, proc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func repoStatus(client *github.Client, r *model.Repo, b *model.Build, link, ctx string) error {
|
func repoStatus(client *github.Client, r *model.Repo, b *model.Build, link, ctx string, proc *model.Proc) error {
|
||||||
context := ctx
|
context := ctx
|
||||||
switch b.Event {
|
switch b.Event {
|
||||||
case model.EventPull:
|
case model.EventPull:
|
||||||
|
@ -451,10 +451,19 @@ func repoStatus(client *github.Client, r *model.Repo, b *model.Build, link, ctx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status := github.String(convertStatus(b.Status))
|
||||||
|
desc := github.String(convertDesc(b.Status))
|
||||||
|
|
||||||
|
if proc != nil {
|
||||||
|
context += "/" + proc.Name
|
||||||
|
status = github.String(convertStatus(proc.State))
|
||||||
|
desc = github.String(convertDesc(proc.State))
|
||||||
|
}
|
||||||
|
|
||||||
data := github.RepoStatus{
|
data := github.RepoStatus{
|
||||||
Context: github.String(context),
|
Context: github.String(context),
|
||||||
State: github.String(convertStatus(b.Status)),
|
State: status,
|
||||||
Description: github.String(convertDesc(b.Status)),
|
Description: desc,
|
||||||
TargetURL: github.String(link),
|
TargetURL: github.String(link),
|
||||||
}
|
}
|
||||||
_, _, err := client.Repositories.CreateStatus(r.Owner, r.Name, b.Commit, &data)
|
_, _, err := client.Repositories.CreateStatus(r.Owner, r.Name, b.Commit, &data)
|
||||||
|
|
|
@ -345,7 +345,7 @@ func (c *Gitlab) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]
|
||||||
// NOTE Currently gitlab doesn't support status for commits and events,
|
// NOTE Currently gitlab doesn't support status for commits and events,
|
||||||
// also if we want get MR status in gitlab we need implement a special plugin for gitlab,
|
// also if we want get MR status in gitlab we need implement a special plugin for gitlab,
|
||||||
// gitlab uses API to fetch build status on client side. But for now we skip this.
|
// gitlab uses API to fetch build status on client side. But for now we skip this.
|
||||||
func (g *Gitlab) Status(u *model.User, repo *model.Repo, b *model.Build, link string) error {
|
func (g *Gitlab) Status(u *model.User, repo *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||||
|
|
||||||
status := getStatus(b.Status)
|
status := getStatus(b.Status)
|
||||||
|
|
|
@ -345,7 +345,7 @@ func (c *Gitlab) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]
|
||||||
// NOTE Currently gitlab doesn't support status for commits and events,
|
// NOTE Currently gitlab doesn't support status for commits and events,
|
||||||
// also if we want get MR status in gitlab we need implement a special plugin for gitlab,
|
// also if we want get MR status in gitlab we need implement a special plugin for gitlab,
|
||||||
// gitlab uses API to fetch build status on client side. But for now we skip this.
|
// gitlab uses API to fetch build status on client side. But for now we skip this.
|
||||||
func (g *Gitlab) Status(u *model.User, repo *model.Repo, b *model.Build, link string) error {
|
func (g *Gitlab) Status(u *model.User, repo *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||||
|
|
||||||
status := getStatus(b.Status)
|
status := getStatus(b.Status)
|
||||||
|
|
|
@ -207,7 +207,7 @@ func (c *client) Dir(u *model.User, r *model.Repo, b *model.Build, f string) ([]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status is not supported by the Gogs driver.
|
// Status is not supported by the Gogs driver.
|
||||||
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string) error {
|
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ func Test_gogs(t *testing.T) {
|
||||||
|
|
||||||
g.It("Should return no-op for usupporeted features", func() {
|
g.It("Should return no-op for usupporeted features", func() {
|
||||||
_, err1 := c.Auth("octocat", "4vyW6b49Z")
|
_, err1 := c.Auth("octocat", "4vyW6b49Z")
|
||||||
err2 := c.Status(nil, nil, nil, "")
|
err2 := c.Status(nil, nil, nil, "", nil)
|
||||||
err3 := c.Deactivate(nil, nil, "")
|
err3 := c.Deactivate(nil, nil, "")
|
||||||
g.Assert(err1 != nil).IsTrue()
|
g.Assert(err1 != nil).IsTrue()
|
||||||
g.Assert(err2 == nil).IsTrue()
|
g.Assert(err2 == nil).IsTrue()
|
||||||
|
|
|
@ -55,7 +55,7 @@ type Remote interface {
|
||||||
|
|
||||||
// Status sends the commit status to the remote system.
|
// Status sends the commit status to the remote system.
|
||||||
// An example would be the GitHub pull request status.
|
// An example would be the GitHub pull request status.
|
||||||
Status(u *model.User, r *model.Repo, b *model.Build, link string) error
|
Status(u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error
|
||||||
|
|
||||||
// Netrc returns a .netrc file that can be used to clone
|
// Netrc returns a .netrc file that can be used to clone
|
||||||
// private repositories from a remote system.
|
// private repositories from a remote system.
|
||||||
|
@ -127,8 +127,8 @@ func Perm(c context.Context, u *model.User, owner, repo string) (*model.Perm, er
|
||||||
|
|
||||||
// Status sends the commit status to the remote system.
|
// Status sends the commit status to the remote system.
|
||||||
// An example would be the GitHub pull request status.
|
// An example would be the GitHub pull request status.
|
||||||
func Status(c context.Context, u *model.User, r *model.Repo, b *model.Build, link string) error {
|
func Status(c context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||||
return FromContext(c).Status(u, r, b, link)
|
return FromContext(c).Status(u, r, b, link, proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Netrc returns a .netrc file that can be used to clone
|
// Netrc returns a .netrc file that can be used to clone
|
||||||
|
|
|
@ -307,14 +307,6 @@ func PostApproval(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
|
||||||
uri := fmt.Sprintf("%s/%s/%d", httputil.GetURL(c.Request), repo.FullName, build.Number)
|
|
||||||
err = remote_.Status(user, repo, build, uri)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
var yamls []*remote.FileMeta
|
var yamls []*remote.FileMeta
|
||||||
for _, y := range configs {
|
for _, y := range configs {
|
||||||
yamls = append(yamls, &remote.FileMeta{Data: []byte(y.Data), Name: y.Name})
|
yamls = append(yamls, &remote.FileMeta{Data: []byte(y.Data), Name: y.Name})
|
||||||
|
@ -346,6 +338,20 @@ func PostApproval(c *gin.Context) {
|
||||||
logrus.Errorf("error persisting procs %s/%d: %s", repo.FullName, build.Number, err)
|
logrus.Errorf("error persisting procs %s/%d: %s", repo.FullName, build.Number, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
for _, item := range buildItems {
|
||||||
|
uri := fmt.Sprintf("%s/%s/%d", httputil.GetURL(c.Request), repo.FullName, build.Number)
|
||||||
|
if len(buildItems) > 1 {
|
||||||
|
err = remote_.Status(user, repo, build, uri, item.Proc)
|
||||||
|
} else {
|
||||||
|
err = remote_.Status(user, repo, build, uri, nil)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
publishToTopic(c, build, repo)
|
publishToTopic(c, build, repo)
|
||||||
queueBuild(build, repo, buildItems)
|
queueBuild(build, repo, buildItems)
|
||||||
}
|
}
|
||||||
|
@ -380,7 +386,7 @@ func PostDecline(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uri := fmt.Sprintf("%s/%s/%d", httputil.GetURL(c.Request), repo.FullName, build.Number)
|
uri := fmt.Sprintf("%s/%s/%d", httputil.GetURL(c.Request), repo.FullName, build.Number)
|
||||||
err = remote_.Status(user, repo, build, uri)
|
err = remote_.Status(user, repo, build, uri, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,14 +221,6 @@ func PostHook(c *gin.Context) {
|
||||||
// get the previous build so that we can send status change notifications
|
// get the previous build so that we can send status change notifications
|
||||||
last, _ := store.GetBuildLastBefore(c, repo, build.Branch, build.ID)
|
last, _ := store.GetBuildLastBefore(c, repo, build.Branch, build.ID)
|
||||||
|
|
||||||
defer func() {
|
|
||||||
uri := fmt.Sprintf("%s/%s/%d", httputil.GetURL(c.Request), repo.FullName, build.Number)
|
|
||||||
err = remote_.Status(user, repo, build, uri)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
b := procBuilder{
|
b := procBuilder{
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
Curr: build,
|
Curr: build,
|
||||||
|
@ -255,6 +247,20 @@ func PostHook(c *gin.Context) {
|
||||||
logrus.Errorf("error persisting procs %s/%d: %s", repo.FullName, build.Number, err)
|
logrus.Errorf("error persisting procs %s/%d: %s", repo.FullName, build.Number, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
for _, item := range buildItems {
|
||||||
|
uri := fmt.Sprintf("%s/%s/%d", httputil.GetURL(c.Request), repo.FullName, build.Number)
|
||||||
|
if len(buildItems) > 1 {
|
||||||
|
err = remote_.Status(user, repo, build, uri, item.Proc)
|
||||||
|
} else {
|
||||||
|
err = remote_.Status(user, repo, build, uri, nil)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
publishToTopic(c, build, repo)
|
publishToTopic(c, build, repo)
|
||||||
queueBuild(build, repo, buildItems)
|
queueBuild(build, repo, buildItems)
|
||||||
}
|
}
|
||||||
|
|
|
@ -401,7 +401,13 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
|
||||||
log.Printf("error: done: cannot update build_id %d final state: %s", build.ID, err)
|
log.Printf("error: done: cannot update build_id %d final state: %s", build.ID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.updateRemoteStatus(repo, build)
|
if !isMultiPipeline(procs) {
|
||||||
|
s.updateRemoteStatus(repo, build, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isMultiPipeline(procs) {
|
||||||
|
s.updateRemoteStatus(repo, build, proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.logger.Close(c, id); err != nil {
|
if err := s.logger.Close(c, id); err != nil {
|
||||||
|
@ -413,6 +419,16 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isMultiPipeline(procs []*model.Proc) bool {
|
||||||
|
countPPIDZero := 0
|
||||||
|
for _, proc := range procs {
|
||||||
|
if proc.PPID == 0 {
|
||||||
|
countPPIDZero++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return countPPIDZero > 1
|
||||||
|
}
|
||||||
|
|
||||||
// Log implements the rpc.Log function
|
// Log implements the rpc.Log function
|
||||||
func (s *RPC) Log(c context.Context, id string, line *rpc.Line) error {
|
func (s *RPC) Log(c context.Context, id string, line *rpc.Line) error {
|
||||||
entry := new(logging.Entry)
|
entry := new(logging.Entry)
|
||||||
|
@ -474,7 +490,7 @@ func buildStatus(procs []*model.Proc) string {
|
||||||
return status
|
return status
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *RPC) updateRemoteStatus(repo *model.Repo, build *model.Build) {
|
func (s *RPC) updateRemoteStatus(repo *model.Repo, build *model.Build, proc *model.Proc) {
|
||||||
user, err := s.store.GetUser(repo.UserID)
|
user, err := s.store.GetUser(repo.UserID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if refresher, ok := s.remote.(remote.Refresher); ok {
|
if refresher, ok := s.remote.(remote.Refresher); ok {
|
||||||
|
@ -484,7 +500,7 @@ func (s *RPC) updateRemoteStatus(repo *model.Repo, build *model.Build) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uri := fmt.Sprintf("%s/%s/%d", s.host, repo.FullName, build.Number)
|
uri := fmt.Sprintf("%s/%s/%d", s.host, repo.FullName, build.Number)
|
||||||
err = s.remote.Status(user, repo, build, uri)
|
err = s.remote.Status(user, repo, build, uri, proc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
logrus.Errorf("error setting commit status for %s/%d: %v", repo.FullName, build.Number, err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue