Skip to content

Commit 0e826ea

Browse files
wolfogredelvh
authored andcommitted
Avoid panic caused by broken payload when creating commit status (go-gitea#23216)
When creating commit status for Actons jobs, a payload with nil `HeadCommit` will cause panic. Reported at: https://gitea.com/gitea/act_runner/issues/28#issuecomment-732166 Although the `HeadCommit` probably can not be nil after go-gitea#23215, `CreateCommitStatus` should protect itself, to avoid being broken in the future. In addition, it's enough to print error log instead of returning err when `CreateCommitStatus` failed. --------- Co-authored-by: delvh <dev.lh@web.de>
1 parent 7810192 commit 0e826ea

File tree

5 files changed

+45
-14
lines changed

5 files changed

+45
-14
lines changed

routers/api/actions/runner/runner.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ func (s *Service) UpdateTask(
150150
}
151151

152152
if err := actions_service.CreateCommitStatus(ctx, task.Job); err != nil {
153-
log.Error("Update commit status failed: %v", err)
153+
log.Error("Update commit status for job %v failed: %v", task.Job.ID, err)
154154
// go on
155155
}
156156

routers/web/repo/actions/view.go

+15-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"code.gitea.io/gitea/models/unit"
1616
"code.gitea.io/gitea/modules/actions"
1717
context_module "code.gitea.io/gitea/modules/context"
18+
"code.gitea.io/gitea/modules/log"
1819
"code.gitea.io/gitea/modules/timeutil"
1920
"code.gitea.io/gitea/modules/util"
2021
"code.gitea.io/gitea/modules/web"
@@ -207,15 +208,18 @@ func Rerun(ctx *context_module.Context) {
207208
job.Stopped = 0
208209

209210
if err := db.WithTx(ctx, func(ctx context.Context) error {
210-
if _, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped"); err != nil {
211-
return err
212-
}
213-
return actions_service.CreateCommitStatus(ctx, job)
211+
_, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped")
212+
return err
214213
}); err != nil {
215214
ctx.Error(http.StatusInternalServerError, err.Error())
216215
return
217216
}
218217

218+
if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
219+
log.Error("Update commit status for job %v failed: %v", job.ID, err)
220+
// go on
221+
}
222+
219223
ctx.JSON(http.StatusOK, struct{}{})
220224
}
221225

@@ -248,16 +252,20 @@ func Cancel(ctx *context_module.Context) {
248252
if err := actions_model.StopTask(ctx, job.TaskID, actions_model.StatusCancelled); err != nil {
249253
return err
250254
}
251-
if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
252-
return err
253-
}
254255
}
255256
return nil
256257
}); err != nil {
257258
ctx.Error(http.StatusInternalServerError, err.Error())
258259
return
259260
}
260261

262+
for _, job := range jobs {
263+
if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
264+
log.Error("Update commit status for job %v failed: %v", job.ID, err)
265+
// go on
266+
}
267+
}
268+
261269
ctx.JSON(http.StatusOK, struct{}{})
262270
}
263271

services/actions/clear_tasks.go

+17-5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
4343
return fmt.Errorf("find tasks: %w", err)
4444
}
4545

46+
jobs := make([]*actions_model.ActionRunJob, 0, len(tasks))
4647
for _, task := range tasks {
4748
if err := db.WithTx(ctx, func(ctx context.Context) error {
4849
if err := actions_model.StopTask(ctx, task.ID, actions_model.StatusFailure); err != nil {
@@ -51,7 +52,8 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
5152
if err := task.LoadJob(ctx); err != nil {
5253
return err
5354
}
54-
return CreateCommitStatus(ctx, task.Job)
55+
jobs = append(jobs, task.Job)
56+
return nil
5557
}); err != nil {
5658
log.Warn("Cannot stop task %v: %v", task.ID, err)
5759
// go on
@@ -61,6 +63,14 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
6163
remove()
6264
}
6365
}
66+
67+
for _, job := range jobs {
68+
if err := CreateCommitStatus(ctx, job); err != nil {
69+
log.Error("Update commit status for job %v failed: %v", job.ID, err)
70+
// go on
71+
}
72+
}
73+
6474
return nil
6575
}
6676

@@ -80,14 +90,16 @@ func CancelAbandonedJobs(ctx context.Context) error {
8090
job.Status = actions_model.StatusCancelled
8191
job.Stopped = now
8292
if err := db.WithTx(ctx, func(ctx context.Context) error {
83-
if _, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped"); err != nil {
84-
return err
85-
}
86-
return CreateCommitStatus(ctx, job)
93+
_, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped")
94+
return err
8795
}); err != nil {
8896
log.Warn("cancel abandoned job %v: %v", job.ID, err)
8997
// go on
9098
}
99+
if err := CreateCommitStatus(ctx, job); err != nil {
100+
log.Error("Update commit status for job %v failed: %v", job.ID, err)
101+
// go on
102+
}
91103
}
92104

93105
return nil

services/actions/commit_status.go

+10
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
3030
return fmt.Errorf("GetPushEventPayload: %w", err)
3131
}
3232

33+
// Since the payload comes from json data, we should check if it's broken, or it will cause panic
34+
switch {
35+
case payload.Repo == nil:
36+
return fmt.Errorf("repo is missing in event payload")
37+
case payload.Pusher == nil:
38+
return fmt.Errorf("pusher is missing in event payload")
39+
case payload.HeadCommit == nil:
40+
return fmt.Errorf("head commit is missing in event payload")
41+
}
42+
3343
creator, err := user_model.GetUserByID(ctx, payload.Pusher.ID)
3444
if err != nil {
3545
return fmt.Errorf("GetUserByID: %w", err)

services/actions/notifier_helper.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ func notify(ctx context.Context, input *notifyInput) error {
180180
} else {
181181
for _, job := range jobs {
182182
if err := CreateCommitStatus(ctx, job); err != nil {
183-
log.Error("CreateCommitStatus: %v", err)
183+
log.Error("Update commit status for job %v failed: %v", job.ID, err)
184+
// go on
184185
}
185186
}
186187
}

0 commit comments

Comments
 (0)