mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 20:01:02 +00:00
Create separate Go file for build status updates
This commit is contained in:
parent
7fd68a706e
commit
fd361ddf2a
6 changed files with 201 additions and 34 deletions
|
@ -249,9 +249,10 @@ func ZombieKill(c *gin.Context) {
|
||||||
Config.Services.Queue.Error(context.Background(), fmt.Sprint(proc.ID), queue.ErrCancel)
|
Config.Services.Queue.Error(context.Background(), fmt.Sprint(proc.ID), queue.ErrCancel)
|
||||||
}
|
}
|
||||||
|
|
||||||
build.Status = model.StatusKilled
|
if _, err := UpdateToStatusKilled(store.FromContext(c), *build); err != nil {
|
||||||
build.Finished = time.Now().Unix()
|
c.AbortWithError(500, err)
|
||||||
store.FromContext(c).UpdateBuild(build)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.String(204, "")
|
c.String(204, "")
|
||||||
}
|
}
|
||||||
|
@ -275,9 +276,6 @@ func PostApproval(c *gin.Context) {
|
||||||
c.String(500, "cannot decline a build with status %s", build.Status)
|
c.String(500, "cannot decline a build with status %s", build.Status)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
build.Status = model.StatusPending
|
|
||||||
build.Reviewed = time.Now().Unix()
|
|
||||||
build.Reviewer = user.Login
|
|
||||||
|
|
||||||
// fetch the build file from the database
|
// fetch the build file from the database
|
||||||
configs, err := Config.Storage.Config.ConfigsForBuild(build.ID)
|
configs, err := Config.Storage.Config.ConfigsForBuild(build.ID)
|
||||||
|
@ -289,12 +287,12 @@ func PostApproval(c *gin.Context) {
|
||||||
|
|
||||||
netrc, err := remote_.Netrc(user, repo)
|
netrc, err := remote_.Netrc(user, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(500, "Failed to generate netrc file. %s", err)
|
c.String(500, "failed to generate netrc file. %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if uerr := store.UpdateBuild(c, build); err != nil {
|
if build, err = UpdateToStatusPending(store.FromContext(c), *build, user.Login); err != nil {
|
||||||
c.String(500, "error updating build. %s", uerr)
|
c.String(500, "error updating build. %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,11 +335,9 @@ func PostApproval(c *gin.Context) {
|
||||||
}
|
}
|
||||||
buildItems, err := b.Build()
|
buildItems, err := b.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
build.Status = model.StatusError
|
if _, err = UpdateToStatusError(store.FromContext(c), *build, err); err != nil {
|
||||||
build.Started = time.Now().Unix()
|
logrus.Errorf("Error setting error status of build for %s#%d. %s", repo.FullName, build.Number, err)
|
||||||
build.Finished = build.Started
|
}
|
||||||
build.Error = err.Error()
|
|
||||||
store.UpdateBuild(c, build)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
build = setBuildStepsOnBuild(b.Curr, buildItems)
|
build = setBuildStepsOnBuild(b.Curr, buildItems)
|
||||||
|
@ -388,12 +384,8 @@ func PostDecline(c *gin.Context) {
|
||||||
c.String(500, "cannot decline a build with status %s", build.Status)
|
c.String(500, "cannot decline a build with status %s", build.Status)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
build.Status = model.StatusDeclined
|
|
||||||
build.Reviewed = time.Now().Unix()
|
|
||||||
build.Reviewer = user.Login
|
|
||||||
|
|
||||||
err = store.UpdateBuild(c, build)
|
if _, err = UpdateToStatusDeclined(store.FromContext(c), *build, user.Login); err != nil {
|
||||||
if err != nil {
|
|
||||||
c.String(500, "error updating build. %s", err)
|
c.String(500, "error updating build. %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
120
server/buildStatus_test.go
Normal file
120
server/buildStatus_test.go
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
// Copyright 2019 mhmxs.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/laszlocph/woodpecker/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
const TIMEOUT = 3 * time.Second
|
||||||
|
|
||||||
|
type mockUpdateBuildStore struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockUpdateBuildStore) UpdateBuild(build *model.Build) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateToStatusRunning(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
build, _ := UpdateToStatusRunning(&mockUpdateBuildStore{}, model.Build{}, int64(1))
|
||||||
|
|
||||||
|
if model.StatusRunning != build.Status {
|
||||||
|
t.Errorf("Build status not equals '%s' != '%s'", model.StatusRunning, build.Status)
|
||||||
|
} else if int64(1) != build.Started {
|
||||||
|
t.Errorf("Build started not equals 1 != %d", build.Started)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateToStatusPending(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
|
||||||
|
build, _ := UpdateToStatusPending(&mockUpdateBuildStore{}, model.Build{}, "Reviewer")
|
||||||
|
|
||||||
|
if model.StatusPending != build.Status {
|
||||||
|
t.Errorf("Build status not equals '%s' != '%s'", model.StatusPending, build.Status)
|
||||||
|
} else if "Reviewer" != build.Reviewer {
|
||||||
|
t.Errorf("Reviewer not equals 'Reviewer' != '%s'", build.Reviewer)
|
||||||
|
} else if now > build.Reviewed {
|
||||||
|
t.Errorf("Reviewed not updated %d !< %d", now, build.Reviewed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateToStatusDeclined(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
|
||||||
|
build, _ := UpdateToStatusDeclined(&mockUpdateBuildStore{}, model.Build{}, "Reviewer")
|
||||||
|
|
||||||
|
if model.StatusDeclined != build.Status {
|
||||||
|
t.Errorf("Build status not equals '%s' != '%s'", model.StatusDeclined, build.Status)
|
||||||
|
} else if "Reviewer" != build.Reviewer {
|
||||||
|
t.Errorf("Reviewer not equals 'Reviewer' != '%s'", build.Reviewer)
|
||||||
|
} else if now > build.Reviewed {
|
||||||
|
t.Errorf("Reviewed not updated %d !< %d", now, build.Reviewed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateToStatusToDone(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
build, _ := UpdateStatusToDone(&mockUpdateBuildStore{}, model.Build{}, "status", int64(1))
|
||||||
|
|
||||||
|
if "status" != build.Status {
|
||||||
|
t.Errorf("Build status not equals 'status' != '%s'", build.Status)
|
||||||
|
} else if int64(1) != build.Finished {
|
||||||
|
t.Errorf("Build finished not equals 1 != %d", build.Finished)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateToStatusError(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
|
||||||
|
build, _ := UpdateToStatusError(&mockUpdateBuildStore{}, model.Build{}, errors.New("error"))
|
||||||
|
|
||||||
|
if "error" != build.Error {
|
||||||
|
t.Errorf("Build error not equals 'error' != '%s'", build.Error)
|
||||||
|
} else if model.StatusError != build.Status {
|
||||||
|
t.Errorf("Build status not equals '%s' != '%s'", model.StatusError, build.Status)
|
||||||
|
} else if now > build.Started {
|
||||||
|
t.Errorf("Started not updated %d !< %d", now, build.Started)
|
||||||
|
} else if build.Started != build.Finished {
|
||||||
|
t.Errorf("Build started and finished not equals %d != %d", build.Started, build.Finished)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateToStatusKilled(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
|
||||||
|
build, _ := UpdateToStatusKilled(&mockUpdateBuildStore{}, model.Build{})
|
||||||
|
|
||||||
|
if model.StatusKilled != build.Status {
|
||||||
|
t.Errorf("Build status not equals '%s' != '%s'", model.StatusKilled, build.Status)
|
||||||
|
} else if now > build.Finished {
|
||||||
|
t.Errorf("Finished not updated %d !< %d", now, build.Finished)
|
||||||
|
}
|
||||||
|
}
|
65
server/builsStatus.go
Normal file
65
server/builsStatus.go
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright 2019 mhmxs.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/laszlocph/woodpecker/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateBuildStore interface {
|
||||||
|
UpdateBuild(*model.Build) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateToStatusRunning(store UpdateBuildStore, build model.Build, started int64) (*model.Build, error) {
|
||||||
|
build.Status = model.StatusRunning
|
||||||
|
build.Started = started
|
||||||
|
return &build, store.UpdateBuild(&build)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateToStatusPending(store UpdateBuildStore, build model.Build, reviewer string) (*model.Build, error) {
|
||||||
|
build.Reviewer = reviewer
|
||||||
|
build.Status = model.StatusPending
|
||||||
|
build.Reviewed = time.Now().Unix()
|
||||||
|
return &build, store.UpdateBuild(&build)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateToStatusDeclined(store UpdateBuildStore, build model.Build, reviewer string) (*model.Build, error) {
|
||||||
|
build.Reviewer = reviewer
|
||||||
|
build.Status = model.StatusDeclined
|
||||||
|
build.Reviewed = time.Now().Unix()
|
||||||
|
return &build, store.UpdateBuild(&build)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateStatusToDone(store UpdateBuildStore, build model.Build, status string, stopped int64) (*model.Build, error) {
|
||||||
|
build.Status = status
|
||||||
|
build.Finished = stopped
|
||||||
|
return &build, store.UpdateBuild(&build)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateToStatusError(store UpdateBuildStore, build model.Build, err error) (*model.Build, error) {
|
||||||
|
build.Error = err.Error()
|
||||||
|
build.Status = model.StatusError
|
||||||
|
build.Started = time.Now().Unix()
|
||||||
|
build.Finished = build.Started
|
||||||
|
return &build, store.UpdateBuild(&build)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateToStatusKilled(store UpdateBuildStore, build model.Build) (*model.Build, error) {
|
||||||
|
build.Status = model.StatusKilled
|
||||||
|
build.Finished = time.Now().Unix()
|
||||||
|
return &build, store.UpdateBuild(&build)
|
||||||
|
}
|
|
@ -259,11 +259,9 @@ func PostHook(c *gin.Context) {
|
||||||
}
|
}
|
||||||
buildItems, err := b.Build()
|
buildItems, err := b.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
build.Status = model.StatusError
|
if _, err = UpdateToStatusError(store.FromContext(c), *build, err); err != nil {
|
||||||
build.Started = time.Now().Unix()
|
logrus.Errorf("Error setting error status of build for %s#%d. %s", repo.FullName, build.Number, err)
|
||||||
build.Finished = build.Started
|
}
|
||||||
build.Error = err.Error()
|
|
||||||
store.UpdateBuild(c, build)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
build = setBuildStepsOnBuild(b.Curr, buildItems)
|
build = setBuildStepsOnBuild(b.Curr, buildItems)
|
||||||
|
|
|
@ -326,9 +326,7 @@ func (s *RPC) Init(c context.Context, id string, state rpc.State) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if build.Status == model.StatusPending {
|
if build.Status == model.StatusPending {
|
||||||
build.Status = model.StatusRunning
|
if build, err = UpdateToStatusRunning(s.store, *build, state.Started); err != nil {
|
||||||
build.Started = state.Started
|
|
||||||
if err := s.store.UpdateBuild(build); err != nil {
|
|
||||||
log.Printf("error: init: cannot update build_id %d state: %s", build.ID, err)
|
log.Printf("error: init: cannot update build_id %d state: %s", build.ID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,9 +392,7 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
|
||||||
s.completeChildrenIfParentCompleted(procs, proc)
|
s.completeChildrenIfParentCompleted(procs, proc)
|
||||||
|
|
||||||
if !isThereRunningStage(procs) {
|
if !isThereRunningStage(procs) {
|
||||||
build.Status = buildStatus(procs)
|
if build, err = UpdateStatusToDone(s.store, *build, buildStatus(procs), proc.Stopped); err != nil {
|
||||||
build.Finished = proc.Stopped
|
|
||||||
if err := s.store.UpdateBuild(build); err != nil {
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,3 @@ func GetBuildQueue(c context.Context) ([]*model.Feed, error) {
|
||||||
func CreateBuild(c context.Context, build *model.Build, procs ...*model.Proc) error {
|
func CreateBuild(c context.Context, build *model.Build, procs ...*model.Proc) error {
|
||||||
return FromContext(c).CreateBuild(build, procs...)
|
return FromContext(c).CreateBuild(build, procs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateBuild(c context.Context, build *model.Build) error {
|
|
||||||
return FromContext(c).UpdateBuild(build)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue