mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-26 06:16:56 +09:00
This PR introduces project workflows, allowing users to configure event-based automations directly from the UI. Users can define filters and actions for each workflow event, and duplicate existing events when needed. ### Concepts Every workflow is composed of `event`, `filters`, and `actions`. - **Event** - An Event defines when a workflow should be triggered. It represents specific activities such as an issue being added to the project, a pull request being merged, or a project column being changed. - **Filter** - A Filter refines when an event should take effect. It allows users to specify conditions like issue type, labels, or project columns to ensure actions only run in targeted scenarios. - **Action** - An Action defines what happens when the event and filters match. It performs operations such as adding labels, moving issues between columns, or changing the issue or pull request state. ### Available Events Currently, the following eight events are supported: - On issues/pull requests closed - On issues/pull requests reopened - On issues/pull requests was added to the project, including when created in it - On issues/pull requests was removed from the project - On issues/pull requests' column was changed - On code changes requested - On code review approved - On pull request merged Each event type supports its own set of filters and actions. ### Available Filters There are four types of filters that can be configured for an event: - **Apply to** - Specify the target type: `issues only`, `pull requests only`, or `issues and pull requests`. - **Labels** - Trigger the event only if the issue or pull request contains one or more specified labels. - **Move from column** - Filter events based on the original project column. - **Move to column** - Filter events based on the destination project column. ### Available Actions There are four types of actions that can be executed when an event is triggered: - **Add labels** - Automatically add one or more labels to the issue or pull request. - **Remove labels** - Remove one or more specified labels. - **Move to column** - Move the issue or pull request to a designated project column. - **Issue state** - Close or reopen the issue. Pull requests can only be closed. ### Enable/Disable an event workflow Each event workflow can be individually enabled or disabled. When disabled, the workflow will be ignored even if the event occurs. This feature is useful when you want to temporarily stop certain automated actions without deleting the workflow configuration. Workflows of closed projects don't run either. ### Clone an event workflow When you need multiple workflows for the same event, you can clone an existing event to create a new one with different filters and actions. This allows you to customize how the same event behaves under different conditions, making workflows more flexible and powerful. ### Permissions Permissions are checked when workflows are managed, not when they run: - Viewing a project's workflows needs read access to the project - Managing them needs write access to the project plus write access to both issues and pull requests of a repository project's repository, being an owner of an organization project's organization or a site administrator, or being the user of a user project. Tokens limited to public repositories can't manage owner-level projects' workflows - A workflow runs when its event happens to an item of an open project that can hold the item's repository, unless that repository is archived, no matter who caused the event, and applies its actions without further permission checks. Pull requests are never reopened - Changes show as made by "Project workflow" on behalf of the user who triggered the event and don't trigger other workflows - Only users who can read an item can put it on a board or move its card The management rule is also documented on `CanManageWorkflows` in `services/projects/workflow.go`. Fixes: #14359 Fixes: #26704 Fixes: #27990 Replaces: #28745 Documentation PR: https://gitea.com/gitea/docs/pulls/308 Co-authored-by: bircni <bircni@icloud.com> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Giteabot <teabot@gitea.io>
558 lines
18 KiB
Go
558 lines
18 KiB
Go
// Copyright 2018 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package notify
|
|
|
|
import (
|
|
"context"
|
|
|
|
actions_model "gitea.dev/models/actions"
|
|
git_model "gitea.dev/models/git"
|
|
issues_model "gitea.dev/models/issues"
|
|
packages_model "gitea.dev/models/packages"
|
|
project_model "gitea.dev/models/project"
|
|
repo_model "gitea.dev/models/repo"
|
|
user_model "gitea.dev/models/user"
|
|
"gitea.dev/modules/git"
|
|
"gitea.dev/modules/log"
|
|
"gitea.dev/modules/repository"
|
|
)
|
|
|
|
var notifiers []Notifier
|
|
|
|
func recoverPanic() {
|
|
if err := recover(); err != nil {
|
|
log.Error("PANIC while notifying: %v\n%s", err, log.Stack(2))
|
|
}
|
|
}
|
|
|
|
// RegisterNotifier providers method to receive notify messages
|
|
func RegisterNotifier(notifier Notifier) {
|
|
go notifier.Run()
|
|
notifiers = append(notifiers, notifier)
|
|
}
|
|
|
|
// NewWikiPage notifies creating new wiki pages to notifiers
|
|
func NewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.NewWikiPage(ctx, doer, repo, page, comment)
|
|
}
|
|
}
|
|
|
|
// EditWikiPage notifies editing or renaming wiki pages to notifiers
|
|
func EditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.EditWikiPage(ctx, doer, repo, page, comment)
|
|
}
|
|
}
|
|
|
|
// DeleteWikiPage notifies deleting wiki pages to notifiers
|
|
func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.DeleteWikiPage(ctx, doer, repo, page)
|
|
}
|
|
}
|
|
|
|
func shouldSendCommentChangeNotification(ctx context.Context, comment *issues_model.Comment) bool {
|
|
if err := comment.LoadReview(ctx); err != nil {
|
|
log.Error("LoadReview: %v", err)
|
|
return false
|
|
} else if comment.Review != nil && comment.Review.Type == issues_model.ReviewTypePending {
|
|
// Pending review comments updating should not triggered
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// CreateIssueComment notifies issue comment related message to notifiers
|
|
func CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
|
|
issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
|
|
) {
|
|
defer recoverPanic()
|
|
|
|
if !shouldSendCommentChangeNotification(ctx, comment) {
|
|
return
|
|
}
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.CreateIssueComment(ctx, doer, repo, issue, comment, mentions)
|
|
}
|
|
}
|
|
|
|
// NewIssue notifies new issue to notifiers
|
|
func NewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.NewIssue(ctx, issue, mentions)
|
|
}
|
|
}
|
|
|
|
// IssueChangeStatus notifies close or reopen issue to notifiers
|
|
func IssueChangeStatus(ctx context.Context, doer *user_model.User, commitID string, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.IssueChangeStatus(ctx, doer, commitID, issue, actionComment, closeOrReopen)
|
|
}
|
|
}
|
|
|
|
// DeleteIssue notify when some issue deleted
|
|
func DeleteIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.DeleteIssue(ctx, doer, issue)
|
|
}
|
|
}
|
|
|
|
// MergePullRequest notifies merge pull request to notifiers
|
|
func MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.MergePullRequest(ctx, doer, pr)
|
|
}
|
|
}
|
|
|
|
// AutoMergePullRequest notifies merge pull request to notifiers
|
|
func AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.AutoMergePullRequest(ctx, doer, pr)
|
|
}
|
|
}
|
|
|
|
// NewPullRequest notifies new pull request to notifiers
|
|
func NewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User) {
|
|
defer recoverPanic()
|
|
|
|
if err := pr.LoadIssue(ctx); err != nil {
|
|
log.Error("LoadIssue failed: %v", err)
|
|
return
|
|
}
|
|
if err := pr.Issue.LoadPoster(ctx); err != nil {
|
|
return
|
|
}
|
|
for _, notifier := range notifiers {
|
|
notifier.NewPullRequest(ctx, pr, mentions)
|
|
}
|
|
}
|
|
|
|
// PullRequestSynchronized notifies Synchronized pull request
|
|
func PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, before, after string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.PullRequestSynchronized(ctx, doer, pr, before, after)
|
|
}
|
|
}
|
|
|
|
// PullRequestReview notifies new pull request review
|
|
func PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
|
|
defer recoverPanic()
|
|
|
|
if err := review.LoadReviewer(ctx); err != nil {
|
|
log.Error("LoadReviewer failed: %v", err)
|
|
return
|
|
}
|
|
for _, notifier := range notifiers {
|
|
notifier.PullRequestReview(ctx, pr, review, comment, mentions)
|
|
}
|
|
}
|
|
|
|
// PullRequestCodeComment notifies new pull request code comment
|
|
func PullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) {
|
|
defer recoverPanic()
|
|
|
|
if err := comment.LoadPoster(ctx); err != nil {
|
|
log.Error("LoadPoster: %v", err)
|
|
return
|
|
}
|
|
for _, notifier := range notifiers {
|
|
notifier.PullRequestCodeComment(ctx, pr, comment, mentions)
|
|
}
|
|
}
|
|
|
|
// PullRequestChangeTargetBranch notifies when a pull request's target branch was changed
|
|
func PullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.PullRequestChangeTargetBranch(ctx, doer, pr, oldBranch)
|
|
}
|
|
}
|
|
|
|
// PullRequestPushCommits notifies when push commits to pull request's head branch
|
|
func PullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.PullRequestPushCommits(ctx, doer, pr, comment)
|
|
}
|
|
}
|
|
|
|
// PullReviewDismiss notifies when a review was dismissed by repo admin
|
|
func PullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.PullReviewDismiss(ctx, doer, review, comment)
|
|
}
|
|
}
|
|
|
|
// UpdateComment notifies update comment to notifiers
|
|
func UpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) {
|
|
defer recoverPanic()
|
|
|
|
if !shouldSendCommentChangeNotification(ctx, c) {
|
|
return
|
|
}
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.UpdateComment(ctx, doer, c, oldContent)
|
|
}
|
|
}
|
|
|
|
// DeleteComment notifies delete comment to notifiers
|
|
func DeleteComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment) {
|
|
defer recoverPanic()
|
|
|
|
if !shouldSendCommentChangeNotification(ctx, c) {
|
|
return
|
|
}
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.DeleteComment(ctx, doer, c)
|
|
}
|
|
}
|
|
|
|
// NewRelease notifies new release to notifiers
|
|
func NewRelease(ctx context.Context, rel *repo_model.Release) {
|
|
defer recoverPanic()
|
|
|
|
if err := rel.LoadAttributes(ctx); err != nil {
|
|
log.Error("LoadPublisher: %v", err)
|
|
return
|
|
}
|
|
for _, notifier := range notifiers {
|
|
notifier.NewRelease(ctx, rel)
|
|
}
|
|
}
|
|
|
|
// UpdateRelease notifies update release to notifiers
|
|
func UpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.UpdateRelease(ctx, doer, rel)
|
|
}
|
|
}
|
|
|
|
// DeleteRelease notifies delete release to notifiers
|
|
func DeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.DeleteRelease(ctx, doer, rel)
|
|
}
|
|
}
|
|
|
|
// IssueChangeMilestone notifies change milestone to notifiers
|
|
func IssueChangeMilestone(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.IssueChangeMilestone(ctx, doer, issue, oldMilestoneID)
|
|
}
|
|
}
|
|
|
|
// IssueChangeContent notifies change content to notifiers
|
|
func IssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldContent string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.IssueChangeContent(ctx, doer, issue, oldContent)
|
|
}
|
|
}
|
|
|
|
// IssueChangeAssignee notifies change content to notifiers
|
|
func IssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.IssueChangeAssignee(ctx, doer, issue, assignee, removed, comment)
|
|
}
|
|
}
|
|
|
|
// PullRequestReviewRequest notifies Request Review change
|
|
func PullRequestReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.PullRequestReviewRequest(ctx, doer, issue, reviewer, isRequest, comment)
|
|
}
|
|
}
|
|
|
|
// IssueClearLabels notifies clear labels to notifiers
|
|
func IssueClearLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.IssueClearLabels(ctx, doer, issue)
|
|
}
|
|
}
|
|
|
|
// IssueChangeTitle notifies change title to notifiers
|
|
func IssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.IssueChangeTitle(ctx, doer, issue, oldTitle)
|
|
}
|
|
}
|
|
|
|
// IssueChangeRef notifies change reference to notifiers
|
|
func IssueChangeRef(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldRef string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.IssueChangeRef(ctx, doer, issue, oldRef)
|
|
}
|
|
}
|
|
|
|
// IssueChangeLabels notifies change labels to notifiers
|
|
func IssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue,
|
|
addedLabels, removedLabels []*issues_model.Label,
|
|
) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.IssueChangeLabels(ctx, doer, issue, addedLabels, removedLabels)
|
|
}
|
|
}
|
|
|
|
func IssueChangeProjects(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, addedProjectIDs, removedProjectIDs []int64) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.IssueChangeProjects(ctx, doer, issue, addedProjectIDs, removedProjectIDs)
|
|
}
|
|
}
|
|
|
|
func IssueChangeProjectColumn(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldColumnID int64, newColumn *project_model.Column) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.IssueChangeProjectColumn(ctx, doer, issue, oldColumnID, newColumn)
|
|
}
|
|
}
|
|
|
|
// CreateRepository notifies create repository to notifiers
|
|
func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.CreateRepository(ctx, doer, u, repo)
|
|
}
|
|
}
|
|
|
|
// AdoptRepository notifies the adoption of a repository to notifiers
|
|
func AdoptRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.AdoptRepository(ctx, doer, u, repo)
|
|
}
|
|
}
|
|
|
|
// MigrateRepository notifies create repository to notifiers
|
|
func MigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.MigrateRepository(ctx, doer, u, repo)
|
|
}
|
|
}
|
|
|
|
// TransferRepository notifies create repository to notifiers
|
|
func TransferRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.TransferRepository(ctx, doer, repo, oldOwnerName)
|
|
}
|
|
}
|
|
|
|
// DeleteRepository notifies delete repository to notifiers
|
|
func DeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.DeleteRepository(ctx, doer, repo)
|
|
}
|
|
}
|
|
|
|
// ForkRepository notifies fork repository to notifiers
|
|
func ForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.ForkRepository(ctx, doer, oldRepo, repo)
|
|
}
|
|
}
|
|
|
|
// RenameRepository notifies repository renamed
|
|
func RenameRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldName string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.RenameRepository(ctx, doer, repo, oldName)
|
|
}
|
|
}
|
|
|
|
// PushCommits notifies commits pushed to notifiers
|
|
func PushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.PushCommits(ctx, pusher, repo, opts, commits)
|
|
}
|
|
}
|
|
|
|
// CreateRef notifies branch or tag creation to notifiers
|
|
func CreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.CreateRef(ctx, pusher, repo, refFullName, refID)
|
|
}
|
|
}
|
|
|
|
// DeleteRef notifies branch or tag deletion to notifiers
|
|
func DeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.DeleteRef(ctx, pusher, repo, refFullName)
|
|
}
|
|
}
|
|
|
|
// SyncPushCommits notifies commits pushed to notifiers
|
|
func SyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.SyncPushCommits(ctx, pusher, repo, opts, commits)
|
|
}
|
|
}
|
|
|
|
// SyncCreateRef notifies branch or tag creation to notifiers
|
|
func SyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.SyncCreateRef(ctx, pusher, repo, refFullName, refID)
|
|
}
|
|
}
|
|
|
|
// SyncDeleteRef notifies branch or tag deletion to notifiers
|
|
func SyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.SyncDeleteRef(ctx, pusher, repo, refFullName)
|
|
}
|
|
}
|
|
|
|
// RepoPendingTransfer notifies creation of pending transfer to notifiers
|
|
func RepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.RepoPendingTransfer(ctx, doer, newOwner, repo)
|
|
}
|
|
}
|
|
|
|
// PackageCreate notifies creation of a package to notifiers
|
|
func PackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.PackageCreate(ctx, doer, pd)
|
|
}
|
|
}
|
|
|
|
// PackageDelete notifies deletion of a package to notifiers
|
|
func PackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.PackageDelete(ctx, doer, pd)
|
|
}
|
|
}
|
|
|
|
// ChangeDefaultBranch notifies change default branch to notifiers
|
|
func ChangeDefaultBranch(ctx context.Context, repo *repo_model.Repository) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.ChangeDefaultBranch(ctx, repo)
|
|
}
|
|
}
|
|
|
|
func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, commit *repository.PushCommit, sender *user_model.User, status *git_model.CommitStatus) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.CreateCommitStatus(ctx, repo, commit, sender, status)
|
|
}
|
|
}
|
|
|
|
// WorkflowRunStatusUpdate dispatches a workflow run status change to every registered notifier.
|
|
// Prefer the helpers in services/actions/notify.go over calling this directly;
|
|
// unless you are sure the caller has already resolved the correct sender and paired notifications.
|
|
func WorkflowRunStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, run *actions_model.ActionRun) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.WorkflowRunStatusUpdate(ctx, repo, sender, run)
|
|
}
|
|
}
|
|
|
|
// WorkflowJobStatusUpdate dispatches a workflow job status change to every registered notifier.
|
|
// Prefer the helpers in services/actions/notify.go over calling this directly;
|
|
// unless you are sure the caller has already resolved the correct sender and paired notifications.
|
|
func WorkflowJobStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, job *actions_model.ActionRunJob, task *actions_model.ActionTask) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.WorkflowJobStatusUpdate(ctx, repo, sender, job, task)
|
|
}
|
|
}
|
|
|
|
// Callers must invoke this after any DB write affecting the user's unread count.
|
|
func NotificationCountChange(ctx context.Context, userID int64) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.NotificationCountChange(ctx, userID)
|
|
}
|
|
}
|
|
|
|
// Callers must invoke this after any stopwatch start/stop/cancel so the user's connected tabs refresh.
|
|
func StopwatchChanged(ctx context.Context, user *user_model.User) {
|
|
defer recoverPanic()
|
|
|
|
for _, notifier := range notifiers {
|
|
notifier.StopwatchChanged(ctx, user)
|
|
}
|
|
}
|