Go · 2192 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 // Package runstate owns shared workflow-run status derivation helpers.
4 package runstate
5
6 import (
7 "context"
8
9 actionsdb "github.com/tenseleyFlow/shithub/internal/actions/sqlc"
10 )
11
12 // RollupAfterCancel updates the parent workflow_run after one or more jobs in
13 // the run received a cancellation request. If all jobs are terminal, the run is
14 // completed with the derived conclusion; otherwise it is marked running.
15 func RollupAfterCancel(
16 ctx context.Context,
17 q *actionsdb.Queries,
18 db actionsdb.DBTX,
19 runID int64,
20 ) (bool, actionsdb.CheckConclusion, error) {
21 jobs, err := q.ListJobsForRun(ctx, db, runID)
22 if err != nil {
23 return false, "", err
24 }
25 runConclusion, complete := DeriveWorkflowRunConclusion(jobs)
26 if complete {
27 if _, err := q.CompleteWorkflowRun(ctx, db, actionsdb.CompleteWorkflowRunParams{
28 ID: runID,
29 Conclusion: runConclusion,
30 }); err != nil {
31 return false, "", err
32 }
33 return true, runConclusion, nil
34 }
35 if err := q.MarkWorkflowRunRunning(ctx, db, runID); err != nil {
36 return false, "", err
37 }
38 return false, "", nil
39 }
40
41 // DeriveWorkflowRunConclusion mirrors GitHub's "worst job wins" rollup for
42 // the conclusion set shithub currently supports.
43 func DeriveWorkflowRunConclusion(jobs []actionsdb.ListJobsForRunRow) (actionsdb.CheckConclusion, bool) {
44 if len(jobs) == 0 {
45 return actionsdb.CheckConclusionFailure, true
46 }
47 worst := actionsdb.CheckConclusionSuccess
48 for _, job := range jobs {
49 switch job.Status {
50 case actionsdb.WorkflowJobStatusCompleted, actionsdb.WorkflowJobStatusCancelled, actionsdb.WorkflowJobStatusSkipped:
51 default:
52 return "", false
53 }
54 if job.Status == actionsdb.WorkflowJobStatusCancelled {
55 worst = actionsdb.CheckConclusionCancelled
56 continue
57 }
58 if !job.Conclusion.Valid {
59 return actionsdb.CheckConclusionFailure, true
60 }
61 c := job.Conclusion.CheckConclusion
62 if c == actionsdb.CheckConclusionFailure ||
63 c == actionsdb.CheckConclusionTimedOut ||
64 c == actionsdb.CheckConclusionActionRequired {
65 return c, true
66 }
67 if c == actionsdb.CheckConclusionCancelled {
68 worst = actionsdb.CheckConclusionCancelled
69 }
70 }
71 return worst, true
72 }
73