mirror of
https://github.com/harness/drone.git
synced 2025-05-04 16:52:22 +08:00
159 lines
3.8 KiB
Go
159 lines
3.8 KiB
Go
// Copyright 2022 Harness Inc. All rights reserved.
|
|
// Use of this source code is governed by the Polyform Free Trial License
|
|
// that can be found in the LICENSE.md file for this repository.
|
|
|
|
package manager
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/harness/gitness/internal/pipeline/events"
|
|
"github.com/harness/gitness/internal/pipeline/scheduler"
|
|
"github.com/harness/gitness/internal/store"
|
|
"github.com/harness/gitness/livelog"
|
|
gitness_store "github.com/harness/gitness/store"
|
|
"github.com/harness/gitness/types"
|
|
"github.com/harness/gitness/types/enum"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type teardown struct {
|
|
Executions store.ExecutionStore
|
|
Events events.EventsStreamer
|
|
Logs livelog.LogStream
|
|
Scheduler scheduler.Scheduler
|
|
Repos store.RepoStore
|
|
Steps store.StepStore
|
|
Stages store.StageStore
|
|
}
|
|
|
|
func (t *teardown) do(ctx context.Context, stage *types.Stage) error {
|
|
log := log.With().
|
|
Int64("stage.id", stage.ID).
|
|
Logger()
|
|
log.Debug().Msg("manager: stage is complete. teardown")
|
|
|
|
execution, err := t.Executions.Find(noContext, stage.ExecutionID)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("manager: cannot find the execution")
|
|
return err
|
|
}
|
|
|
|
log = log.With().
|
|
Int64("execution.number", execution.Number).
|
|
Int64("execution.id", execution.ID).
|
|
Int64("repo.id", execution.RepoID).
|
|
Str("stage.status", stage.Status).
|
|
Logger()
|
|
|
|
repo, err := t.Repos.Find(noContext, execution.RepoID)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("manager: cannot find the repository")
|
|
return err
|
|
}
|
|
|
|
for _, step := range stage.Steps {
|
|
if len(step.Error) > 500 {
|
|
step.Error = step.Error[:500]
|
|
}
|
|
err := t.Steps.Update(noContext, step)
|
|
if err != nil {
|
|
log = log.With().
|
|
Str("step.name", step.Name).
|
|
Int64("step.id", step.ID).
|
|
Err(err).
|
|
Logger()
|
|
|
|
log.Error().Msg("manager: cannot persist the step")
|
|
return err
|
|
}
|
|
}
|
|
|
|
if len(stage.Error) > 500 {
|
|
stage.Error = stage.Error[:500]
|
|
}
|
|
|
|
err = t.Stages.Update(noContext, stage)
|
|
if err != nil {
|
|
log.Error().Err(err).
|
|
Msg("manager: cannot update the stage")
|
|
return err
|
|
}
|
|
|
|
for _, step := range stage.Steps {
|
|
t.Logs.Delete(noContext, step.ID)
|
|
}
|
|
|
|
stages, err := t.Stages.ListWithSteps(noContext, execution.ID)
|
|
if err != nil {
|
|
log.Warn().Err(err).
|
|
Msg("manager: cannot get stages")
|
|
return err
|
|
}
|
|
|
|
if isexecutionComplete(stages) == false {
|
|
log.Warn().Err(err).
|
|
Msg("manager: execution pending completion of additional stages")
|
|
return nil
|
|
}
|
|
|
|
log.Info().Msg("manager: execution is finished, teardown")
|
|
|
|
execution.Status = enum.CIStatusSuccess
|
|
execution.Finished = time.Now().UnixMilli()
|
|
for _, sibling := range stages {
|
|
if sibling.Status == enum.CIStatusKilled {
|
|
execution.Status = enum.CIStatusKilled
|
|
break
|
|
}
|
|
if sibling.Status == enum.CIStatusFailure {
|
|
execution.Status = enum.CIStatusFailure
|
|
break
|
|
}
|
|
if sibling.Status == enum.CIStatusError {
|
|
execution.Status = enum.CIStatusError
|
|
break
|
|
}
|
|
}
|
|
if execution.Started == 0 {
|
|
execution.Started = execution.Finished
|
|
}
|
|
|
|
err = t.Executions.Update(noContext, execution)
|
|
if err == gitness_store.ErrVersionConflict {
|
|
log.Warn().Err(err).
|
|
Msg("manager: execution updated by another goroutine")
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
log.Warn().Err(err).
|
|
Msg("manager: cannot update the execution")
|
|
return err
|
|
}
|
|
|
|
execution.Stages = stages
|
|
err = t.Events.Publish(noContext, repo.ParentID, executionEvent(enum.ExecutionCompleted, execution))
|
|
if err != nil {
|
|
log.Warn().Err(err).
|
|
Msg("manager: could not publish execution completed event")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func isexecutionComplete(stages []*types.Stage) bool {
|
|
for _, stage := range stages {
|
|
switch stage.Status {
|
|
case enum.CIStatusPending,
|
|
enum.CIStatusRunning,
|
|
enum.CIStatusWaitingOnDeps,
|
|
enum.CIStatusDeclined,
|
|
enum.CIStatusBlocked:
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|