@@ -7,16 +7,13 @@ package lifecycle |
| 7 | 7 | import ( |
| 8 | 8 | "context" |
| 9 | 9 | "errors" |
| 10 | | - "fmt" |
| 11 | 10 | "strings" |
| 12 | | - "time" |
| 13 | 11 | |
| 14 | 12 | "github.com/jackc/pgx/v5" |
| 15 | | - "github.com/jackc/pgx/v5/pgtype" |
| 16 | 13 | |
| 14 | + "github.com/tenseleyFlow/shithub/internal/actions/checksync" |
| 15 | + "github.com/tenseleyFlow/shithub/internal/actions/runstate" |
| 17 | 16 | actionsdb "github.com/tenseleyFlow/shithub/internal/actions/sqlc" |
| 18 | | - "github.com/tenseleyFlow/shithub/internal/checks" |
| 19 | | - checksdb "github.com/tenseleyFlow/shithub/internal/checks/sqlc" |
| 20 | 17 | "github.com/tenseleyFlow/shithub/internal/infra/metrics" |
| 21 | 18 | ) |
| 22 | 19 | |
@@ -72,7 +69,7 @@ func CancelRun(ctx context.Context, deps Deps, runID int64, reason string) (Canc |
| 72 | 69 | runConclusion actionsdb.CheckConclusion |
| 73 | 70 | ) |
| 74 | 71 | if len(changed) > 0 { |
| 75 | | - runCompleted, runConclusion, err = rollupRunAfterCancel(ctx, q, tx, runID) |
| 72 | + runCompleted, runConclusion, err = runstate.RollupAfterCancel(ctx, q, tx, runID) |
| 76 | 73 | if err != nil { |
| 77 | 74 | return CancelResult{}, err |
| 78 | 75 | } |
@@ -137,7 +134,7 @@ func CancelJob(ctx context.Context, deps Deps, jobID int64, reason string) (Canc |
| 137 | 134 | runConclusion actionsdb.CheckConclusion |
| 138 | 135 | ) |
| 139 | 136 | if len(changed) > 0 { |
| 140 | | - runCompleted, runConclusion, err = rollupRunAfterCancel(ctx, q, tx, runID) |
| 137 | + runCompleted, runConclusion, err = runstate.RollupAfterCancel(ctx, q, tx, runID) |
| 141 | 138 | if err != nil { |
| 142 | 139 | return CancelResult{}, err |
| 143 | 140 | } |
@@ -157,63 +154,6 @@ func CancelJob(ctx context.Context, deps Deps, jobID int64, reason string) (Canc |
| 157 | 154 | }, nil |
| 158 | 155 | } |
| 159 | 156 | |
| 160 | | -func rollupRunAfterCancel( |
| 161 | | - ctx context.Context, |
| 162 | | - q *actionsdb.Queries, |
| 163 | | - tx pgx.Tx, |
| 164 | | - runID int64, |
| 165 | | -) (bool, actionsdb.CheckConclusion, error) { |
| 166 | | - jobs, err := q.ListJobsForRun(ctx, tx, runID) |
| 167 | | - if err != nil { |
| 168 | | - return false, "", err |
| 169 | | - } |
| 170 | | - runConclusion, complete := deriveWorkflowRunConclusion(jobs) |
| 171 | | - if complete { |
| 172 | | - if _, err := q.CompleteWorkflowRun(ctx, tx, actionsdb.CompleteWorkflowRunParams{ |
| 173 | | - ID: runID, |
| 174 | | - Conclusion: runConclusion, |
| 175 | | - }); err != nil { |
| 176 | | - return false, "", err |
| 177 | | - } |
| 178 | | - return true, runConclusion, nil |
| 179 | | - } |
| 180 | | - if err := q.MarkWorkflowRunRunning(ctx, tx, runID); err != nil { |
| 181 | | - return false, "", err |
| 182 | | - } |
| 183 | | - return false, "", nil |
| 184 | | -} |
| 185 | | - |
| 186 | | -func deriveWorkflowRunConclusion(jobs []actionsdb.ListJobsForRunRow) (actionsdb.CheckConclusion, bool) { |
| 187 | | - if len(jobs) == 0 { |
| 188 | | - return actionsdb.CheckConclusionFailure, true |
| 189 | | - } |
| 190 | | - worst := actionsdb.CheckConclusionSuccess |
| 191 | | - for _, job := range jobs { |
| 192 | | - switch job.Status { |
| 193 | | - case actionsdb.WorkflowJobStatusCompleted, actionsdb.WorkflowJobStatusCancelled, actionsdb.WorkflowJobStatusSkipped: |
| 194 | | - default: |
| 195 | | - return "", false |
| 196 | | - } |
| 197 | | - if job.Status == actionsdb.WorkflowJobStatusCancelled { |
| 198 | | - worst = actionsdb.CheckConclusionCancelled |
| 199 | | - continue |
| 200 | | - } |
| 201 | | - if !job.Conclusion.Valid { |
| 202 | | - return actionsdb.CheckConclusionFailure, true |
| 203 | | - } |
| 204 | | - c := job.Conclusion.CheckConclusion |
| 205 | | - if c == actionsdb.CheckConclusionFailure || |
| 206 | | - c == actionsdb.CheckConclusionTimedOut || |
| 207 | | - c == actionsdb.CheckConclusionActionRequired { |
| 208 | | - return c, true |
| 209 | | - } |
| 210 | | - if c == actionsdb.CheckConclusionCancelled { |
| 211 | | - worst = actionsdb.CheckConclusionCancelled |
| 212 | | - } |
| 213 | | - } |
| 214 | | - return worst, true |
| 215 | | -} |
| 216 | | - |
| 217 | 157 | func recordCancelledJobs(jobs []actionsdb.WorkflowJob, reason string) { |
| 218 | 158 | if len(jobs) == 0 { |
| 219 | 159 | return |
@@ -235,74 +175,12 @@ func cancelReason(reason string) string { |
| 235 | 175 | } |
| 236 | 176 | |
| 237 | 177 | func syncChangedJobChecks(ctx context.Context, deps Deps, jobs []actionsdb.WorkflowJob) { |
| 238 | | - for _, job := range jobs { |
| 239 | | - if job.Status != actionsdb.WorkflowJobStatusRunning && |
| 240 | | - job.Status != actionsdb.WorkflowJobStatusCompleted && |
| 241 | | - job.Status != actionsdb.WorkflowJobStatusCancelled { |
| 242 | | - continue |
| 243 | | - } |
| 244 | | - if err := SyncCheckRunForJob(ctx, deps, job); err != nil && deps.Logger != nil { |
| 245 | | - deps.Logger.WarnContext(ctx, "actions lifecycle: sync check_run", "job_id", job.ID, "error", err) |
| 246 | | - } |
| 247 | | - } |
| 178 | + checksync.ChangedJobs(ctx, checksync.Deps{Pool: deps.Pool, Logger: deps.Logger}, jobs) |
| 248 | 179 | } |
| 249 | 180 | |
| 250 | 181 | // SyncCheckRunForJob mirrors an Actions workflow_job row into its check_run |
| 251 | 182 | // row. Missing check rows are non-fatal because check creation is already |
| 252 | 183 | // best-effort in the trigger path and can be reconciled independently. |
| 253 | 184 | func SyncCheckRunForJob(ctx context.Context, deps Deps, job actionsdb.WorkflowJob) error { |
| 254 | | - if deps.Pool == nil { |
| 255 | | - return errors.New("actions lifecycle: nil Pool") |
| 256 | | - } |
| 257 | | - run, err := actionsdb.New().GetWorkflowRunByID(ctx, deps.Pool, job.RunID) |
| 258 | | - if err != nil { |
| 259 | | - return err |
| 260 | | - } |
| 261 | | - name := strings.TrimSpace(job.JobName) |
| 262 | | - if name == "" { |
| 263 | | - name = job.JobKey |
| 264 | | - } |
| 265 | | - checkRun, err := checksdb.New().GetCheckRunByExternalID(ctx, deps.Pool, checksdb.GetCheckRunByExternalIDParams{ |
| 266 | | - RepoID: run.RepoID, |
| 267 | | - HeadSha: run.HeadSha, |
| 268 | | - Name: name, |
| 269 | | - ExternalID: pgtype.Text{String: fmt.Sprintf("workflow_run:%d:job:%s", job.RunID, job.JobKey), Valid: true}, |
| 270 | | - }) |
| 271 | | - if err != nil { |
| 272 | | - if errors.Is(err, pgx.ErrNoRows) { |
| 273 | | - return nil |
| 274 | | - } |
| 275 | | - return err |
| 276 | | - } |
| 277 | | - params := checks.UpdateParams{ |
| 278 | | - RunID: checkRun.ID, |
| 279 | | - HasStatus: true, |
| 280 | | - HasStartedAt: true, |
| 281 | | - StartedAt: timeFromPg(job.StartedAt), |
| 282 | | - } |
| 283 | | - switch job.Status { |
| 284 | | - case actionsdb.WorkflowJobStatusRunning: |
| 285 | | - params.Status = "in_progress" |
| 286 | | - case actionsdb.WorkflowJobStatusCompleted, actionsdb.WorkflowJobStatusCancelled: |
| 287 | | - params.Status = "completed" |
| 288 | | - params.HasConclusion = true |
| 289 | | - if job.Conclusion.Valid { |
| 290 | | - params.Conclusion = string(job.Conclusion.CheckConclusion) |
| 291 | | - } else if job.Status == actionsdb.WorkflowJobStatusCancelled { |
| 292 | | - params.Conclusion = string(actionsdb.CheckConclusionCancelled) |
| 293 | | - } |
| 294 | | - params.HasCompletedAt = true |
| 295 | | - params.CompletedAt = timeFromPg(job.CompletedAt) |
| 296 | | - default: |
| 297 | | - return nil |
| 298 | | - } |
| 299 | | - _, err = checks.Update(ctx, checks.Deps{Pool: deps.Pool, Logger: deps.Logger}, params) |
| 300 | | - return err |
| 301 | | -} |
| 302 | | - |
| 303 | | -func timeFromPg(ts pgtype.Timestamptz) time.Time { |
| 304 | | - if !ts.Valid { |
| 305 | | - return time.Time{} |
| 306 | | - } |
| 307 | | - return ts.Time |
| 185 | + return checksync.Job(ctx, checksync.Deps{Pool: deps.Pool, Logger: deps.Logger}, job) |
| 308 | 186 | } |