diff --git a/modules/structs/hook.go b/modules/structs/hook.go index aaa9fbc9d3..cd0eef851a 100644 --- a/modules/structs/hook.go +++ b/modules/structs/hook.go @@ -470,6 +470,22 @@ func (p *CommitStatusPayload) JSONPayload() ([]byte, error) { return json.MarshalIndent(p, "", " ") } +// WorkflowRunPayload represents a payload information of workflow run event. +type WorkflowRunPayload struct { + Action string `json:"action"` + Workflow *ActionWorkflow `json:"workflow"` + WorkflowRun *ActionWorkflowRun `json:"workflow_run"` + PullRequest *PullRequest `json:"pull_request,omitempty"` + Organization *Organization `json:"organization,omitempty"` + Repo *Repository `json:"repository"` + Sender *User `json:"sender"` +} + +// JSONPayload implements Payload +func (p *WorkflowRunPayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + // WorkflowJobPayload represents a payload information of workflow job event. type WorkflowJobPayload struct { Action string `json:"action"` diff --git a/modules/structs/repo_actions.go b/modules/structs/repo_actions.go index 22409b4aff..23bdb46d1b 100644 --- a/modules/structs/repo_actions.go +++ b/modules/structs/repo_actions.go @@ -87,8 +87,20 @@ type ActionArtifact struct { // ActionWorkflowRun represents a WorkflowRun type ActionWorkflowRun struct { ID int64 `json:"id"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + Event string `json:"event"` + RunAttempt int64 `json:"run_attempt"` + RunNumber int64 `json:"run_number"` RepositoryID int64 `json:"repository_id"` HeadSha string `json:"head_sha"` + HeadBranch string `json:"head_branch,omitempty"` + Status string `json:"status"` + Conclusion string `json:"conclusion,omitempty"` + // swagger:strfmt date-time + StartedAt time.Time `json:"started_at,omitempty"` + // swagger:strfmt date-time + CompletedAt time.Time `json:"completed_at,omitempty"` } // ActionArtifactsResponse returns ActionArtifacts diff --git a/modules/webhook/type.go b/modules/webhook/type.go index 72ffde26a1..bcf8903b2b 100644 --- a/modules/webhook/type.go +++ b/modules/webhook/type.go @@ -38,6 +38,7 @@ const ( HookEventPullRequestReview HookEventType = "pull_request_review" // Actions event only HookEventSchedule HookEventType = "schedule" + HookEventWorkflowRun HookEventType = "workflow_run" HookEventWorkflowJob HookEventType = "workflow_job" ) diff --git a/services/actions/clear_tasks.go b/services/actions/clear_tasks.go index 2aeb0e8c96..bfa10563bc 100644 --- a/services/actions/clear_tasks.go +++ b/services/actions/clear_tasks.go @@ -125,6 +125,9 @@ func CancelAbandonedJobs(ctx context.Context) error { if updated { _ = job.LoadAttributes(ctx) notify_service.WorkflowJobStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job, nil) + if job.Run != nil { + notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run) + } } } diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 1a23b4e0c5..1040607a56 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -6,6 +6,7 @@ package actions import ( "context" + actions_model "code.gitea.io/gitea/models/actions" issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" perm_model "code.gitea.io/gitea/models/perm" @@ -762,3 +763,13 @@ func (n *actionsNotifier) MigrateRepository(ctx context.Context, doer, u *user_m Sender: convert.ToUser(ctx, doer, nil), }).Notify(ctx) } + +func (n *actionsNotifier) WorkflowRunStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, run *actions_model.ActionRun) { + run.Status.IsBlocked() + newNotifyInput(repo, sender, webhook_module.HookEventWorkflowRun).WithPayload(&api.WorkflowRunPayload{ + Action: "queued", + Repo: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), + Organization: nil, + Sender: convert.ToUser(ctx, sender, nil), + }).Notify(ctx) +} diff --git a/services/notify/notifier.go b/services/notify/notifier.go index 40428454be..875a70e564 100644 --- a/services/notify/notifier.go +++ b/services/notify/notifier.go @@ -79,5 +79,7 @@ type Notifier interface { CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, commit *repository.PushCommit, sender *user_model.User, status *git_model.CommitStatus) + WorkflowRunStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, run *actions_model.ActionRun) + WorkflowJobStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, job *actions_model.ActionRunJob, task *actions_model.ActionTask) } diff --git a/services/notify/notify.go b/services/notify/notify.go index 9f8be4b577..0c6fdf9cef 100644 --- a/services/notify/notify.go +++ b/services/notify/notify.go @@ -376,6 +376,12 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, commit } } +func WorkflowRunStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, run *actions_model.ActionRun) { + for _, notifier := range notifiers { + notifier.WorkflowRunStatusUpdate(ctx, repo, sender, run) + } +} + func WorkflowJobStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, job *actions_model.ActionRunJob, task *actions_model.ActionTask) { for _, notifier := range notifiers { notifier.WorkflowJobStatusUpdate(ctx, repo, sender, job, task) diff --git a/services/notify/null.go b/services/notify/null.go index 9c794a2342..c3085d7c9e 100644 --- a/services/notify/null.go +++ b/services/notify/null.go @@ -214,5 +214,8 @@ func (*NullNotifier) ChangeDefaultBranch(ctx context.Context, repo *repo_model.R func (*NullNotifier) CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, commit *repository.PushCommit, sender *user_model.User, status *git_model.CommitStatus) { } +func (*NullNotifier) WorkflowRunStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, run *actions_model.ActionRun) { +} + func (*NullNotifier) WorkflowJobStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, job *actions_model.ActionRunJob, task *actions_model.ActionTask) { } diff --git a/services/webhook/notifier.go b/services/webhook/notifier.go index 7d779cd527..84842ea374 100644 --- a/services/webhook/notifier.go +++ b/services/webhook/notifier.go @@ -1030,6 +1030,45 @@ func (*webhookNotifier) WorkflowJobStatusUpdate(ctx context.Context, repo *repo_ } } +func (*webhookNotifier) WorkflowRunStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, run *actions_model.ActionRun) { + source := EventSource{ + Repository: repo, + Owner: repo.Owner, + } + + var org *api.Organization + if repo.Owner.IsOrganization() { + org = convert.ToOrganization(ctx, organization.OrgFromUser(repo.Owner)) + } + + status, conclusion := toActionStatus(run.Status) + + if err := PrepareWebhooks(ctx, source, webhook_module.HookEventWorkflowJob, &api.WorkflowRunPayload{ + Action: status, + Workflow: nil, + WorkflowRun: &api.ActionWorkflowRun{ + ID: run.ID, + RunNumber: run.Index, + HTMLURL: run.HTMLURL(), + // Missing api endpoint for this location, artifacts are available under a nested url + URL: fmt.Sprintf("%s/actions/runs/%d", repo.APIURL(), run.ID), + Event: run.TriggerEvent, + RunAttempt: 0, + HeadSha: run.CommitSHA, + HeadBranch: git.RefName(run.Ref).BranchName(), + Status: status, + Conclusion: conclusion, + StartedAt: run.Started.AsTime().UTC(), + CompletedAt: run.Stopped.AsTime().UTC(), + }, + Organization: org, + Repo: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeOwner}), + Sender: convert.ToUser(ctx, sender, nil), + }); err != nil { + log.Error("PrepareWebhooks: %v", err) + } +} + func toActionStatus(status actions_model.Status) (string, string) { var action string var conclusion string diff --git a/templates/repo/settings/webhook/settings.tmpl b/templates/repo/settings/webhook/settings.tmpl index 16ad263e42..5a69bd737c 100644 --- a/templates/repo/settings/webhook/settings.tmpl +++ b/templates/repo/settings/webhook/settings.tmpl @@ -264,6 +264,15 @@ +
+
+
+ + + {{ctx.Locale.Tr "repo.settings.event_workflow_run_desc"}} +
+
+