Skip to content

Commit

Permalink
Avoid panic caused by broken payload when creating commit status (#23216
Browse files Browse the repository at this point in the history
)

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 #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>
  • Loading branch information
wolfogre and delvh authored Mar 4, 2023
1 parent ca84a61 commit 47b912c
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 14 deletions.
2 changes: 1 addition & 1 deletion routers/api/actions/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (s *Service) UpdateTask(
}

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

Expand Down
22 changes: 15 additions & 7 deletions routers/web/repo/actions/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/actions"
context_module "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
Expand Down Expand Up @@ -214,15 +215,18 @@ func Rerun(ctx *context_module.Context) {
job.Stopped = 0

if err := db.WithTx(ctx, func(ctx context.Context) error {
if _, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped"); err != nil {
return err
}
return actions_service.CreateCommitStatus(ctx, job)
_, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped")
return err
}); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}

if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
log.Error("Update commit status for job %v failed: %v", job.ID, err)
// go on
}

ctx.JSON(http.StatusOK, struct{}{})
}

Expand Down Expand Up @@ -255,16 +259,20 @@ func Cancel(ctx *context_module.Context) {
if err := actions_model.StopTask(ctx, job.TaskID, actions_model.StatusCancelled); err != nil {
return err
}
if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
return err
}
}
return nil
}); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}

for _, job := range jobs {
if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
log.Error("Update commit status for job %v failed: %v", job.ID, err)
// go on
}
}

ctx.JSON(http.StatusOK, struct{}{})
}

Expand Down
22 changes: 17 additions & 5 deletions services/actions/clear_tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
return fmt.Errorf("find tasks: %w", err)
}

jobs := make([]*actions_model.ActionRunJob, 0, len(tasks))
for _, task := range tasks {
if err := db.WithTx(ctx, func(ctx context.Context) error {
if err := actions_model.StopTask(ctx, task.ID, actions_model.StatusFailure); err != nil {
Expand All @@ -51,7 +52,8 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
if err := task.LoadJob(ctx); err != nil {
return err
}
return CreateCommitStatus(ctx, task.Job)
jobs = append(jobs, task.Job)
return nil
}); err != nil {
log.Warn("Cannot stop task %v: %v", task.ID, err)
// go on
Expand All @@ -61,6 +63,14 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
remove()
}
}

for _, job := range jobs {
if err := CreateCommitStatus(ctx, job); err != nil {
log.Error("Update commit status for job %v failed: %v", job.ID, err)
// go on
}
}

return nil
}

Expand All @@ -80,14 +90,16 @@ func CancelAbandonedJobs(ctx context.Context) error {
job.Status = actions_model.StatusCancelled
job.Stopped = now
if err := db.WithTx(ctx, func(ctx context.Context) error {
if _, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped"); err != nil {
return err
}
return CreateCommitStatus(ctx, job)
_, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped")
return err
}); err != nil {
log.Warn("cancel abandoned job %v: %v", job.ID, err)
// go on
}
if err := CreateCommitStatus(ctx, job); err != nil {
log.Error("Update commit status for job %v failed: %v", job.ID, err)
// go on
}
}

return nil
Expand Down
10 changes: 10 additions & 0 deletions services/actions/commit_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
return fmt.Errorf("GetPushEventPayload: %w", err)
}

// Since the payload comes from json data, we should check if it's broken, or it will cause panic
switch {
case payload.Repo == nil:
return fmt.Errorf("repo is missing in event payload")
case payload.Pusher == nil:
return fmt.Errorf("pusher is missing in event payload")
case payload.HeadCommit == nil:
return fmt.Errorf("head commit is missing in event payload")
}

creator, err := user_model.GetUserByID(ctx, payload.Pusher.ID)
if err != nil {
return fmt.Errorf("GetUserByID: %w", err)
Expand Down
3 changes: 2 additions & 1 deletion services/actions/notifier_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ func notify(ctx context.Context, input *notifyInput) error {
} else {
for _, job := range jobs {
if err := CreateCommitStatus(ctx, job); err != nil {
log.Error("CreateCommitStatus: %v", err)
log.Error("Update commit status for job %v failed: %v", job.ID, err)
// go on
}
}
}
Expand Down

0 comments on commit 47b912c

Please sign in to comment.