From ba0805520ad1cadbf7ad165640636ed2b1df4471 Mon Sep 17 00:00:00 2001 From: Mayank Mohapatra <125661248+Mayank77maruti@users.noreply.github.com> Date: Sat, 15 Feb 2025 00:24:39 +0530 Subject: [PATCH 1/6] Notify action added Signed-off-by: Mayank Mohapatra <125661248+Mayank77maruti@users.noreply.github.com> --- services/actions/job_emitter.go | 8 +++++ services/mailer/notify.go | 61 +++++++++++++++++++++++++++++++++ services/notify/notifier.go | 5 ++- services/notify/notify.go | 8 +++++ services/notify/null.go | 5 +++ 5 files changed, 86 insertions(+), 1 deletion(-) diff --git a/services/actions/job_emitter.go b/services/actions/job_emitter.go index 1f859fcf70506..d0f4bfe31b6da 100644 --- a/services/actions/job_emitter.go +++ b/services/actions/job_emitter.go @@ -11,7 +11,9 @@ import ( actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/graceful" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/queue" + notify_service "code.gitea.io/gitea/services/notify" "github.com/nektos/act/pkg/jobparser" "xorm.io/builder" @@ -70,6 +72,12 @@ func checkJobsOfRun(ctx context.Context, runID int64) error { }); err != nil { return err } + run, _, err := db.GetByID[actions_model.ActionRun](ctx, runID) + if err != nil { + log.Error("GetByID failed: %v", err) + } else if run.Status == actions_model.StatusSuccess || run.Status == actions_model.StatusFailure { + notify_service.ActionRunFinished(ctx, run) + } CreateCommitStatus(ctx, jobs...) return nil } diff --git a/services/mailer/notify.go b/services/mailer/notify.go index e48b5d399d96c..9b6f0e6bd8f27 100644 --- a/services/mailer/notify.go +++ b/services/mailer/notify.go @@ -7,6 +7,7 @@ import ( "context" "fmt" + actions_model "code.gitea.io/gitea/models/actions" activities_model "code.gitea.io/gitea/models/activities" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -202,3 +203,63 @@ func (m *mailNotifier) RepoPendingTransfer(ctx context.Context, doer, newOwner * log.Error("SendRepoTransferNotifyMail: %v", err) } } + +func (m *mailNotifier) ActionRunFinished(ctx context.Context, run *actions_model.ActionRun) { + // Check status first to avoid unnecessary processing + if run.Status != actions_model.StatusSuccess && run.Status != actions_model.StatusFailure { + return + } + + // Load required attributes after status check + if err := run.LoadAttributes(ctx); err != nil { + log.Error("LoadAttributes: %v", err) + return + } + + subject := fmt.Sprintf("[%s] Workflow run %s: %s", + run.Repo.FullName(), + run.WorkflowName, + run.Status, + ) + + // Safely handle short commit SHA + commitSHA := run.CommitSHA + if len(commitSHA) > 7 { + commitSHA = commitSHA[:7] + } + + body := fmt.Sprintf(`Workflow "%s" run #%d has completed with status: %s + +Repository: %s +Branch: %s +Commit: %s +Triggered by: %s + +View the run details here: %s`, + run.WorkflowName, + run.Index, + run.Status, + run.Repo.FullName(), + run.RefName, + commitSHA, + run.TriggerUser.Name, + run.HTMLURL(), + ) + + // Send to repo owner if notifications enabled and email present + if run.Repo.Owner.Email != "" && + run.Repo.Owner.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { + if err := SendMail(ctx, []string{run.Repo.Owner.Email}, subject, body); err != nil { + log.Error("Failed to send email to repo owner %s: %v", run.Repo.Owner.Email, err) + } + } + + // Send to commit author if different from trigger user and notifications enabled + if run.TriggerUser.ID != run.CommitAuthor.ID && + run.CommitAuthor.Email != "" && + run.CommitAuthor.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { + if err := SendMail(ctx, []string{run.CommitAuthor.Email}, subject, body); err != nil { + log.Error("Failed to send email to commit author %s: %v", run.CommitAuthor.Email, err) + } + } +} diff --git a/services/notify/notifier.go b/services/notify/notifier.go index 29bbb5702b3bd..ee713ad3eb611 100644 --- a/services/notify/notifier.go +++ b/services/notify/notifier.go @@ -5,7 +5,8 @@ package notify import ( "context" - + + actions_model "code.gitea.io/gitea/models/actions" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" @@ -76,5 +77,7 @@ type Notifier interface { ChangeDefaultBranch(ctx context.Context, repo *repo_model.Repository) + ActionRunFinished(ctx context.Context, run *actions_model.ActionRun) + CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, commit *repository.PushCommit, sender *user_model.User, status *git_model.CommitStatus) } diff --git a/services/notify/notify.go b/services/notify/notify.go index c97d0fcbaf0af..e9ab638b742c7 100644 --- a/services/notify/notify.go +++ b/services/notify/notify.go @@ -6,6 +6,7 @@ package notify import ( "context" + actions_model "code.gitea.io/gitea/models/actions" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" @@ -374,3 +375,10 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, commit notifier.CreateCommitStatus(ctx, repo, commit, sender, status) } } + +// ActionRunFinished represents action run finished +func ActionRunFinished(ctx context.Context, run *actions_model.ActionRun) { + for _, notifier := range notifiers { + notifier.ActionRunFinished(ctx, run) + } +} diff --git a/services/notify/null.go b/services/notify/null.go index 7354efd70157c..5500ab0e42889 100644 --- a/services/notify/null.go +++ b/services/notify/null.go @@ -6,6 +6,7 @@ package notify import ( "context" + actions_model "code.gitea.io/gitea/models/actions" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" @@ -212,3 +213,7 @@ 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) { } + + +// ActionRunFinished represents action run finished +func (*NullNotifier) ActionRunFinished(ctx context.Context, run *actions_model.ActionRun) {} From 70f02e00ae68a3663d25187288f80b9d416a58db Mon Sep 17 00:00:00 2001 From: Mayank Mohapatra <125661248+Mayank77maruti@users.noreply.github.com> Date: Sat, 15 Feb 2025 00:43:17 +0530 Subject: [PATCH 2/6] Notify action added Signed-off-by: Mayank Mohapatra <125661248+Mayank77maruti@users.noreply.github.com> --- services/mailer/notify.go | 118 ++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 57 deletions(-) diff --git a/services/mailer/notify.go b/services/mailer/notify.go index 9b6f0e6bd8f27..0d050f5696f97 100644 --- a/services/mailer/notify.go +++ b/services/mailer/notify.go @@ -204,62 +204,66 @@ func (m *mailNotifier) RepoPendingTransfer(ctx context.Context, doer, newOwner * } } +// func (m *mailNotifier) ActionRunFinished(ctx context.Context, run *actions_model.ActionRun) { +// // Check status first to avoid unnecessary processing +// if run.Status != actions_model.StatusSuccess && run.Status != actions_model.StatusFailure { +// return +// } + +// // Load required attributes after status check +// if err := run.LoadAttributes(ctx); err != nil { +// log.Error("LoadAttributes: %v", err) +// return +// } + +// subject := fmt.Sprintf("[%s] Workflow run %s: %s", +// run.Repo.FullName(), +// run.WorkflowName, +// run.Status, +// ) + +// // Safely handle short commit SHA +// commitSHA := run.CommitSHA +// if len(commitSHA) > 7 { +// commitSHA = commitSHA[:7] +// } + +// body := fmt.Sprintf(`Workflow "%s" run #%d has completed with status: %s + +// Repository: %s +// Branch: %s +// Commit: %s +// Triggered by: %s + +// View the run details here: %s`, +// run.WorkflowName, +// run.Index, +// run.Status, +// run.Repo.FullName(), +// run.RefName, +// commitSHA, +// run.TriggerUser.Name, +// run.HTMLURL(), +// ) + +// // Send to repo owner if notifications enabled and email present +// if run.Repo.Owner.Email != "" && +// run.Repo.Owner.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { +// if err := SendMail(ctx, []string{run.Repo.Owner.Email}, subject, body); err != nil { +// log.Error("Failed to send email to repo owner %s: %v", run.Repo.Owner.Email, err) +// } +// } + +// // Send to commit author if different from trigger user and notifications enabled +// if run.TriggerUser.ID != run.CommitAuthor.ID && +// run.CommitAuthor.Email != "" && +// run.CommitAuthor.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { +// if err := SendMail(ctx, []string{run.CommitAuthor.Email}, subject, body); err != nil { +// log.Error("Failed to send email to commit author %s: %v", run.CommitAuthor.Email, err) +// } +// } +// } + func (m *mailNotifier) ActionRunFinished(ctx context.Context, run *actions_model.ActionRun) { - // Check status first to avoid unnecessary processing - if run.Status != actions_model.StatusSuccess && run.Status != actions_model.StatusFailure { - return - } - - // Load required attributes after status check - if err := run.LoadAttributes(ctx); err != nil { - log.Error("LoadAttributes: %v", err) - return - } - - subject := fmt.Sprintf("[%s] Workflow run %s: %s", - run.Repo.FullName(), - run.WorkflowName, - run.Status, - ) - - // Safely handle short commit SHA - commitSHA := run.CommitSHA - if len(commitSHA) > 7 { - commitSHA = commitSHA[:7] - } - - body := fmt.Sprintf(`Workflow "%s" run #%d has completed with status: %s - -Repository: %s -Branch: %s -Commit: %s -Triggered by: %s - -View the run details here: %s`, - run.WorkflowName, - run.Index, - run.Status, - run.Repo.FullName(), - run.RefName, - commitSHA, - run.TriggerUser.Name, - run.HTMLURL(), - ) - - // Send to repo owner if notifications enabled and email present - if run.Repo.Owner.Email != "" && - run.Repo.Owner.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { - if err := SendMail(ctx, []string{run.Repo.Owner.Email}, subject, body); err != nil { - log.Error("Failed to send email to repo owner %s: %v", run.Repo.Owner.Email, err) - } - } - - // Send to commit author if different from trigger user and notifications enabled - if run.TriggerUser.ID != run.CommitAuthor.ID && - run.CommitAuthor.Email != "" && - run.CommitAuthor.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { - if err := SendMail(ctx, []string{run.CommitAuthor.Email}, subject, body); err != nil { - log.Error("Failed to send email to commit author %s: %v", run.CommitAuthor.Email, err) - } - } + // TODO: send email to related users } From 95ee4c6a94ca4463b5acf8abb518d0075f4b93b6 Mon Sep 17 00:00:00 2001 From: Mayank Mohapatra <125661248+Mayank77maruti@users.noreply.github.com> Date: Sat, 15 Feb 2025 00:52:27 +0530 Subject: [PATCH 3/6] Notify action added Signed-off-by: Mayank Mohapatra <125661248+Mayank77maruti@users.noreply.github.com> --- services/mailer/notify.go | 118 ++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 61 deletions(-) diff --git a/services/mailer/notify.go b/services/mailer/notify.go index 0d050f5696f97..9b6f0e6bd8f27 100644 --- a/services/mailer/notify.go +++ b/services/mailer/notify.go @@ -204,66 +204,62 @@ func (m *mailNotifier) RepoPendingTransfer(ctx context.Context, doer, newOwner * } } -// func (m *mailNotifier) ActionRunFinished(ctx context.Context, run *actions_model.ActionRun) { -// // Check status first to avoid unnecessary processing -// if run.Status != actions_model.StatusSuccess && run.Status != actions_model.StatusFailure { -// return -// } - -// // Load required attributes after status check -// if err := run.LoadAttributes(ctx); err != nil { -// log.Error("LoadAttributes: %v", err) -// return -// } - -// subject := fmt.Sprintf("[%s] Workflow run %s: %s", -// run.Repo.FullName(), -// run.WorkflowName, -// run.Status, -// ) - -// // Safely handle short commit SHA -// commitSHA := run.CommitSHA -// if len(commitSHA) > 7 { -// commitSHA = commitSHA[:7] -// } - -// body := fmt.Sprintf(`Workflow "%s" run #%d has completed with status: %s - -// Repository: %s -// Branch: %s -// Commit: %s -// Triggered by: %s - -// View the run details here: %s`, -// run.WorkflowName, -// run.Index, -// run.Status, -// run.Repo.FullName(), -// run.RefName, -// commitSHA, -// run.TriggerUser.Name, -// run.HTMLURL(), -// ) - -// // Send to repo owner if notifications enabled and email present -// if run.Repo.Owner.Email != "" && -// run.Repo.Owner.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { -// if err := SendMail(ctx, []string{run.Repo.Owner.Email}, subject, body); err != nil { -// log.Error("Failed to send email to repo owner %s: %v", run.Repo.Owner.Email, err) -// } -// } - -// // Send to commit author if different from trigger user and notifications enabled -// if run.TriggerUser.ID != run.CommitAuthor.ID && -// run.CommitAuthor.Email != "" && -// run.CommitAuthor.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { -// if err := SendMail(ctx, []string{run.CommitAuthor.Email}, subject, body); err != nil { -// log.Error("Failed to send email to commit author %s: %v", run.CommitAuthor.Email, err) -// } -// } -// } - func (m *mailNotifier) ActionRunFinished(ctx context.Context, run *actions_model.ActionRun) { - // TODO: send email to related users + // Check status first to avoid unnecessary processing + if run.Status != actions_model.StatusSuccess && run.Status != actions_model.StatusFailure { + return + } + + // Load required attributes after status check + if err := run.LoadAttributes(ctx); err != nil { + log.Error("LoadAttributes: %v", err) + return + } + + subject := fmt.Sprintf("[%s] Workflow run %s: %s", + run.Repo.FullName(), + run.WorkflowName, + run.Status, + ) + + // Safely handle short commit SHA + commitSHA := run.CommitSHA + if len(commitSHA) > 7 { + commitSHA = commitSHA[:7] + } + + body := fmt.Sprintf(`Workflow "%s" run #%d has completed with status: %s + +Repository: %s +Branch: %s +Commit: %s +Triggered by: %s + +View the run details here: %s`, + run.WorkflowName, + run.Index, + run.Status, + run.Repo.FullName(), + run.RefName, + commitSHA, + run.TriggerUser.Name, + run.HTMLURL(), + ) + + // Send to repo owner if notifications enabled and email present + if run.Repo.Owner.Email != "" && + run.Repo.Owner.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { + if err := SendMail(ctx, []string{run.Repo.Owner.Email}, subject, body); err != nil { + log.Error("Failed to send email to repo owner %s: %v", run.Repo.Owner.Email, err) + } + } + + // Send to commit author if different from trigger user and notifications enabled + if run.TriggerUser.ID != run.CommitAuthor.ID && + run.CommitAuthor.Email != "" && + run.CommitAuthor.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { + if err := SendMail(ctx, []string{run.CommitAuthor.Email}, subject, body); err != nil { + log.Error("Failed to send email to commit author %s: %v", run.CommitAuthor.Email, err) + } + } } From 8963c10574c76b57c68abd0758f597d1f4a3eb72 Mon Sep 17 00:00:00 2001 From: Mayank Mohapatra <125661248+Mayank77maruti@users.noreply.github.com> Date: Sat, 15 Feb 2025 01:07:24 +0530 Subject: [PATCH 4/6] Notify action added Signed-off-by: Mayank Mohapatra <125661248+Mayank77maruti@users.noreply.github.com> --- services/mailer/notify.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/services/mailer/notify.go b/services/mailer/notify.go index 9b6f0e6bd8f27..058d75fb02539 100644 --- a/services/mailer/notify.go +++ b/services/mailer/notify.go @@ -216,9 +216,9 @@ func (m *mailNotifier) ActionRunFinished(ctx context.Context, run *actions_model return } - subject := fmt.Sprintf("[%s] Workflow run %s: %s", - run.Repo.FullName(), - run.WorkflowName, + subject := fmt.Sprintf("[%s] Workflow run %s: %s", + run.Repo.FullName(), + run.WorkflowID, run.Status, ) @@ -236,11 +236,11 @@ Commit: %s Triggered by: %s View the run details here: %s`, - run.WorkflowName, + run.WorkflowID, run.Index, run.Status, run.Repo.FullName(), - run.RefName, + run.PrettyRef(), commitSHA, run.TriggerUser.Name, run.HTMLURL(), @@ -249,17 +249,17 @@ View the run details here: %s`, // Send to repo owner if notifications enabled and email present if run.Repo.Owner.Email != "" && run.Repo.Owner.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { - if err := SendMail(ctx, []string{run.Repo.Owner.Email}, subject, body); err != nil { + if err := SendMailFrom(ctx, run.Repo.Owner.Email, subject, body); err != nil { log.Error("Failed to send email to repo owner %s: %v", run.Repo.Owner.Email, err) } } - // Send to commit author if different from trigger user and notifications enabled - if run.TriggerUser.ID != run.CommitAuthor.ID && - run.CommitAuthor.Email != "" && - run.CommitAuthor.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { - if err := SendMail(ctx, []string{run.CommitAuthor.Email}, subject, body); err != nil { - log.Error("Failed to send email to commit author %s: %v", run.CommitAuthor.Email, err) + // Send to trigger user if different from owner and notifications enabled + if run.TriggerUser.ID != run.Repo.Owner.ID && + run.TriggerUser.Email != "" && + run.TriggerUser.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { + if err := SendMailFrom(ctx, run.TriggerUser.Email, subject, body); err != nil { + log.Error("Failed to send email to trigger user %s: %v", run.TriggerUser.Email, err) } } } From 8184bfdde82b1d0e18a164553b28b7d13a6d200d Mon Sep 17 00:00:00 2001 From: Mayank Mohapatra <125661248+Mayank77maruti@users.noreply.github.com> Date: Mon, 24 Feb 2025 01:37:09 +0530 Subject: [PATCH 5/6] Update notify.go --- services/mailer/notify.go | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/services/mailer/notify.go b/services/mailer/notify.go index 058d75fb02539..ce561c8aa5a7c 100644 --- a/services/mailer/notify.go +++ b/services/mailer/notify.go @@ -198,19 +198,11 @@ func (m *mailNotifier) NewRelease(ctx context.Context, rel *repo_model.Release) MailNewRelease(ctx, rel) } -func (m *mailNotifier) RepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) { - if err := SendRepoTransferNotifyMail(ctx, doer, newOwner, repo); err != nil { - log.Error("SendRepoTransferNotifyMail: %v", err) - } -} - func (m *mailNotifier) ActionRunFinished(ctx context.Context, run *actions_model.ActionRun) { - // Check status first to avoid unnecessary processing if run.Status != actions_model.StatusSuccess && run.Status != actions_model.StatusFailure { return } - // Load required attributes after status check if err := run.LoadAttributes(ctx); err != nil { log.Error("LoadAttributes: %v", err) return @@ -222,19 +214,16 @@ func (m *mailNotifier) ActionRunFinished(ctx context.Context, run *actions_model run.Status, ) - // Safely handle short commit SHA commitSHA := run.CommitSHA if len(commitSHA) > 7 { commitSHA = commitSHA[:7] } body := fmt.Sprintf(`Workflow "%s" run #%d has completed with status: %s - Repository: %s Branch: %s Commit: %s Triggered by: %s - View the run details here: %s`, run.WorkflowID, run.Index, @@ -246,19 +235,27 @@ View the run details here: %s`, run.HTMLURL(), ) - // Send to repo owner if notifications enabled and email present + // Send to repo owner if run.Repo.Owner.Email != "" && run.Repo.Owner.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { - if err := SendMailFrom(ctx, run.Repo.Owner.Email, subject, body); err != nil { + if err := mailer.SendAsyncEmail(ctx, mailer.Mail{ + To: []string{run.Repo.Owner.Email}, + Subject: subject, + Body: body, + }); err != nil { log.Error("Failed to send email to repo owner %s: %v", run.Repo.Owner.Email, err) } } - // Send to trigger user if different from owner and notifications enabled + // Send to trigger user if run.TriggerUser.ID != run.Repo.Owner.ID && run.TriggerUser.Email != "" && run.TriggerUser.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { - if err := SendMailFrom(ctx, run.TriggerUser.Email, subject, body); err != nil { + if err := mailer.SendAsyncEmail(ctx, mailer.Mail{ + To: []string{run.TriggerUser.Email}, + Subject: subject, + Body: body, + }); err != nil { log.Error("Failed to send email to trigger user %s: %v", run.TriggerUser.Email, err) } } From 93427b4de2d211c42e68a19e43cadec95770222d Mon Sep 17 00:00:00 2001 From: Mayank Mohapatra <125661248+Mayank77maruti@users.noreply.github.com> Date: Mon, 24 Feb 2025 01:38:23 +0530 Subject: [PATCH 6/6] Update notify.go --- services/mailer/notify.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/mailer/notify.go b/services/mailer/notify.go index ce561c8aa5a7c..922d6163ae9ab 100644 --- a/services/mailer/notify.go +++ b/services/mailer/notify.go @@ -198,6 +198,10 @@ func (m *mailNotifier) NewRelease(ctx context.Context, rel *repo_model.Release) MailNewRelease(ctx, rel) } +func (m *mailNotifier) RepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) { + if err := SendRepoTransferNotifyMail(ctx, doer, newOwner, repo); err != nil { + log.Error("SendRepoTransferNotifyMail: %v", err) + } func (m *mailNotifier) ActionRunFinished(ctx context.Context, run *actions_model.ActionRun) { if run.Status != actions_model.StatusSuccess && run.Status != actions_model.StatusFailure { return