code.gitea.io/gitea@v1.22.3/modules/actions/task_state.go (about)

     1  // Copyright 2022 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package actions
     5  
     6  import (
     7  	actions_model "code.gitea.io/gitea/models/actions"
     8  )
     9  
    10  const (
    11  	preStepName  = "Set up job"
    12  	postStepName = "Complete job"
    13  )
    14  
    15  // FullSteps returns steps with "Set up job" and "Complete job"
    16  func FullSteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep {
    17  	if len(task.Steps) == 0 {
    18  		return fullStepsOfEmptySteps(task)
    19  	}
    20  
    21  	// firstStep is the first step that has run or running, not include preStep.
    22  	// For example,
    23  	// 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): firstStep is step1.
    24  	// 2. preStep(Success) -> step1(Skipped) -> step2(Success) -> postStep(Success): firstStep is step2.
    25  	// 3. preStep(Success) -> step1(Running) -> step2(Waiting) -> postStep(Waiting): firstStep is step1.
    26  	// 4. preStep(Success) -> step1(Skipped) -> step2(Skipped) -> postStep(Skipped): firstStep is nil.
    27  	// 5. preStep(Success) -> step1(Cancelled) -> step2(Cancelled) -> postStep(Cancelled): firstStep is nil.
    28  	var firstStep *actions_model.ActionTaskStep
    29  	// lastHasRunStep is the last step that has run.
    30  	// For example,
    31  	// 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): lastHasRunStep is step1.
    32  	// 2. preStep(Success) -> step1(Success) -> step2(Success) -> step3(Success) -> postStep(Success): lastHasRunStep is step3.
    33  	// 3. preStep(Success) -> step1(Success) -> step2(Failure) -> step3 -> postStep(Waiting): lastHasRunStep is step2.
    34  	// So its Stopped is the Started of postStep when there are no more steps to run.
    35  	var lastHasRunStep *actions_model.ActionTaskStep
    36  
    37  	var logIndex int64
    38  	for _, step := range task.Steps {
    39  		if firstStep == nil && (step.Status.HasRun() || step.Status.IsRunning()) {
    40  			firstStep = step
    41  		}
    42  		if step.Status.HasRun() {
    43  			lastHasRunStep = step
    44  		}
    45  		logIndex += step.LogLength
    46  	}
    47  
    48  	preStep := &actions_model.ActionTaskStep{
    49  		Name:      preStepName,
    50  		LogLength: task.LogLength,
    51  		Started:   task.Started,
    52  		Status:    actions_model.StatusRunning,
    53  	}
    54  
    55  	// No step has run or is running, so preStep is equal to the task
    56  	if firstStep == nil {
    57  		preStep.Stopped = task.Stopped
    58  		preStep.Status = task.Status
    59  	} else {
    60  		preStep.LogLength = firstStep.LogIndex
    61  		preStep.Stopped = firstStep.Started
    62  		preStep.Status = actions_model.StatusSuccess
    63  	}
    64  	logIndex += preStep.LogLength
    65  
    66  	if lastHasRunStep == nil {
    67  		lastHasRunStep = preStep
    68  	}
    69  
    70  	postStep := &actions_model.ActionTaskStep{
    71  		Name:   postStepName,
    72  		Status: actions_model.StatusWaiting,
    73  	}
    74  	// If the lastHasRunStep is the last step, or it has failed, postStep has started.
    75  	if lastHasRunStep.Status.IsFailure() || lastHasRunStep == task.Steps[len(task.Steps)-1] {
    76  		postStep.LogIndex = logIndex
    77  		postStep.LogLength = task.LogLength - postStep.LogIndex
    78  		postStep.Started = lastHasRunStep.Stopped
    79  		postStep.Status = actions_model.StatusRunning
    80  	}
    81  	if task.Status.IsDone() {
    82  		postStep.Status = task.Status
    83  		postStep.Stopped = task.Stopped
    84  	}
    85  	ret := make([]*actions_model.ActionTaskStep, 0, len(task.Steps)+2)
    86  	ret = append(ret, preStep)
    87  	ret = append(ret, task.Steps...)
    88  	ret = append(ret, postStep)
    89  
    90  	return ret
    91  }
    92  
    93  func fullStepsOfEmptySteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep {
    94  	preStep := &actions_model.ActionTaskStep{
    95  		Name:      preStepName,
    96  		LogLength: task.LogLength,
    97  		Started:   task.Started,
    98  		Stopped:   task.Stopped,
    99  		Status:    actions_model.StatusRunning,
   100  	}
   101  
   102  	postStep := &actions_model.ActionTaskStep{
   103  		Name:     postStepName,
   104  		LogIndex: task.LogLength,
   105  		Started:  task.Stopped,
   106  		Stopped:  task.Stopped,
   107  		Status:   actions_model.StatusWaiting,
   108  	}
   109  
   110  	if task.Status.IsDone() {
   111  		preStep.Status = task.Status
   112  		if preStep.Status.IsSuccess() {
   113  			postStep.Status = actions_model.StatusSuccess
   114  		} else {
   115  			postStep.Status = actions_model.StatusCancelled
   116  		}
   117  	}
   118  
   119  	return []*actions_model.ActionTaskStep{
   120  		preStep,
   121  		postStep,
   122  	}
   123  }