code.gitea.io/gitea@v1.21.7/services/actions/notifier.go (about) 1 // Copyright 2022 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package actions 5 6 import ( 7 "context" 8 9 "code.gitea.io/gitea/models/db" 10 issues_model "code.gitea.io/gitea/models/issues" 11 packages_model "code.gitea.io/gitea/models/packages" 12 perm_model "code.gitea.io/gitea/models/perm" 13 access_model "code.gitea.io/gitea/models/perm/access" 14 repo_model "code.gitea.io/gitea/models/repo" 15 user_model "code.gitea.io/gitea/models/user" 16 "code.gitea.io/gitea/modules/git" 17 "code.gitea.io/gitea/modules/log" 18 "code.gitea.io/gitea/modules/repository" 19 "code.gitea.io/gitea/modules/setting" 20 api "code.gitea.io/gitea/modules/structs" 21 webhook_module "code.gitea.io/gitea/modules/webhook" 22 "code.gitea.io/gitea/services/convert" 23 notify_service "code.gitea.io/gitea/services/notify" 24 ) 25 26 type actionsNotifier struct { 27 notify_service.NullNotifier 28 } 29 30 var _ notify_service.Notifier = &actionsNotifier{} 31 32 // NewNotifier create a new actionsNotifier notifier 33 func NewNotifier() notify_service.Notifier { 34 return &actionsNotifier{} 35 } 36 37 // NewIssue notifies issue created event 38 func (n *actionsNotifier) NewIssue(ctx context.Context, issue *issues_model.Issue, _ []*user_model.User) { 39 ctx = withMethod(ctx, "NewIssue") 40 if err := issue.LoadRepo(ctx); err != nil { 41 log.Error("issue.LoadRepo: %v", err) 42 return 43 } 44 if err := issue.LoadPoster(ctx); err != nil { 45 log.Error("issue.LoadPoster: %v", err) 46 return 47 } 48 permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) 49 50 newNotifyInputFromIssue(issue, webhook_module.HookEventIssues).WithPayload(&api.IssuePayload{ 51 Action: api.HookIssueOpened, 52 Index: issue.Index, 53 Issue: convert.ToAPIIssue(ctx, issue), 54 Repository: convert.ToRepo(ctx, issue.Repo, permission), 55 Sender: convert.ToUser(ctx, issue.Poster, nil), 56 }).Notify(withMethod(ctx, "NewIssue")) 57 } 58 59 // IssueChangeContent notifies change content of issue 60 func (n *actionsNotifier) IssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldContent string) { 61 ctx = withMethod(ctx, "IssueChangeContent") 62 63 var err error 64 if err = issue.LoadRepo(ctx); err != nil { 65 log.Error("LoadRepo: %v", err) 66 return 67 } 68 69 permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) 70 if issue.IsPull { 71 if err = issue.LoadPullRequest(ctx); err != nil { 72 log.Error("loadPullRequest: %v", err) 73 return 74 } 75 newNotifyInputFromIssue(issue, webhook_module.HookEventPullRequest). 76 WithDoer(doer). 77 WithPayload(&api.PullRequestPayload{ 78 Action: api.HookIssueEdited, 79 Index: issue.Index, 80 PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), 81 Repository: convert.ToRepo(ctx, issue.Repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}), 82 Sender: convert.ToUser(ctx, doer, nil), 83 }). 84 WithPullRequest(issue.PullRequest). 85 Notify(ctx) 86 return 87 } 88 newNotifyInputFromIssue(issue, webhook_module.HookEventIssues). 89 WithDoer(doer). 90 WithPayload(&api.IssuePayload{ 91 Action: api.HookIssueEdited, 92 Index: issue.Index, 93 Issue: convert.ToAPIIssue(ctx, issue), 94 Repository: convert.ToRepo(ctx, issue.Repo, permission), 95 Sender: convert.ToUser(ctx, doer, nil), 96 }). 97 Notify(ctx) 98 } 99 100 // IssueChangeStatus notifies close or reopen issue to notifiers 101 func (n *actionsNotifier) IssueChangeStatus(ctx context.Context, doer *user_model.User, commitID string, issue *issues_model.Issue, _ *issues_model.Comment, isClosed bool) { 102 ctx = withMethod(ctx, "IssueChangeStatus") 103 permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) 104 if issue.IsPull { 105 if err := issue.LoadPullRequest(ctx); err != nil { 106 log.Error("LoadPullRequest: %v", err) 107 return 108 } 109 // Merge pull request calls issue.changeStatus so we need to handle separately. 110 apiPullRequest := &api.PullRequestPayload{ 111 Index: issue.Index, 112 PullRequest: convert.ToAPIPullRequest(db.DefaultContext, issue.PullRequest, nil), 113 Repository: convert.ToRepo(ctx, issue.Repo, permission), 114 Sender: convert.ToUser(ctx, doer, nil), 115 CommitID: commitID, 116 } 117 if isClosed { 118 apiPullRequest.Action = api.HookIssueClosed 119 } else { 120 apiPullRequest.Action = api.HookIssueReOpened 121 } 122 newNotifyInputFromIssue(issue, webhook_module.HookEventPullRequest). 123 WithDoer(doer). 124 WithPayload(apiPullRequest). 125 WithPullRequest(issue.PullRequest). 126 Notify(ctx) 127 return 128 } 129 apiIssue := &api.IssuePayload{ 130 Index: issue.Index, 131 Issue: convert.ToAPIIssue(ctx, issue), 132 Repository: convert.ToRepo(ctx, issue.Repo, permission), 133 Sender: convert.ToUser(ctx, doer, nil), 134 } 135 if isClosed { 136 apiIssue.Action = api.HookIssueClosed 137 } else { 138 apiIssue.Action = api.HookIssueReOpened 139 } 140 newNotifyInputFromIssue(issue, webhook_module.HookEventIssues). 141 WithDoer(doer). 142 WithPayload(apiIssue). 143 Notify(ctx) 144 } 145 146 // IssueChangeAssignee notifies assigned or unassigned to notifiers 147 func (n *actionsNotifier) IssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { 148 ctx = withMethod(ctx, "IssueChangeAssignee") 149 150 var action api.HookIssueAction 151 if removed { 152 action = api.HookIssueUnassigned 153 } else { 154 action = api.HookIssueAssigned 155 } 156 notifyIssueChange(ctx, doer, issue, webhook_module.HookEventPullRequestAssign, action) 157 } 158 159 // IssueChangeMilestone notifies assignee to notifiers 160 func (n *actionsNotifier) IssueChangeMilestone(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) { 161 ctx = withMethod(ctx, "IssueChangeMilestone") 162 163 var action api.HookIssueAction 164 if issue.MilestoneID > 0 { 165 action = api.HookIssueMilestoned 166 } else { 167 action = api.HookIssueDemilestoned 168 } 169 notifyIssueChange(ctx, doer, issue, webhook_module.HookEventPullRequestMilestone, action) 170 } 171 172 func (n *actionsNotifier) IssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, 173 _, _ []*issues_model.Label, 174 ) { 175 ctx = withMethod(ctx, "IssueChangeLabels") 176 notifyIssueChange(ctx, doer, issue, webhook_module.HookEventPullRequestLabel, api.HookIssueLabelUpdated) 177 } 178 179 func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, event webhook_module.HookEventType, action api.HookIssueAction) { 180 var err error 181 if err = issue.LoadRepo(ctx); err != nil { 182 log.Error("LoadRepo: %v", err) 183 return 184 } 185 186 if err = issue.LoadPoster(ctx); err != nil { 187 log.Error("LoadPoster: %v", err) 188 return 189 } 190 191 if issue.IsPull { 192 if err = issue.LoadPullRequest(ctx); err != nil { 193 log.Error("loadPullRequest: %v", err) 194 return 195 } 196 newNotifyInputFromIssue(issue, event). 197 WithDoer(doer). 198 WithPayload(&api.PullRequestPayload{ 199 Action: action, 200 Index: issue.Index, 201 PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), 202 Repository: convert.ToRepo(ctx, issue.Repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}), 203 Sender: convert.ToUser(ctx, doer, nil), 204 }). 205 WithPullRequest(issue.PullRequest). 206 Notify(ctx) 207 return 208 } 209 permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) 210 newNotifyInputFromIssue(issue, event). 211 WithDoer(doer). 212 WithPayload(&api.IssuePayload{ 213 Action: action, 214 Index: issue.Index, 215 Issue: convert.ToAPIIssue(ctx, issue), 216 Repository: convert.ToRepo(ctx, issue.Repo, permission), 217 Sender: convert.ToUser(ctx, doer, nil), 218 }). 219 Notify(ctx) 220 } 221 222 // CreateIssueComment notifies comment on an issue to notifiers 223 func (n *actionsNotifier) CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, 224 issue *issues_model.Issue, comment *issues_model.Comment, _ []*user_model.User, 225 ) { 226 ctx = withMethod(ctx, "CreateIssueComment") 227 228 if issue.IsPull { 229 notifyIssueCommentChange(ctx, doer, comment, "", webhook_module.HookEventPullRequestComment, api.HookIssueCommentCreated) 230 return 231 } 232 notifyIssueCommentChange(ctx, doer, comment, "", webhook_module.HookEventIssueComment, api.HookIssueCommentCreated) 233 } 234 235 func (n *actionsNotifier) UpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) { 236 ctx = withMethod(ctx, "UpdateComment") 237 238 if err := c.LoadIssue(ctx); err != nil { 239 log.Error("LoadIssue: %v", err) 240 return 241 } 242 243 if c.Issue.IsPull { 244 notifyIssueCommentChange(ctx, doer, c, oldContent, webhook_module.HookEventPullRequestComment, api.HookIssueCommentEdited) 245 return 246 } 247 notifyIssueCommentChange(ctx, doer, c, oldContent, webhook_module.HookEventIssueComment, api.HookIssueCommentEdited) 248 } 249 250 func (n *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) { 251 ctx = withMethod(ctx, "DeleteComment") 252 253 if err := comment.LoadIssue(ctx); err != nil { 254 log.Error("LoadIssue: %v", err) 255 return 256 } 257 258 if comment.Issue.IsPull { 259 notifyIssueCommentChange(ctx, doer, comment, "", webhook_module.HookEventPullRequestComment, api.HookIssueCommentDeleted) 260 return 261 } 262 notifyIssueCommentChange(ctx, doer, comment, "", webhook_module.HookEventIssueComment, api.HookIssueCommentDeleted) 263 } 264 265 func notifyIssueCommentChange(ctx context.Context, doer *user_model.User, comment *issues_model.Comment, oldContent string, event webhook_module.HookEventType, action api.HookIssueCommentAction) { 266 if err := comment.LoadIssue(ctx); err != nil { 267 log.Error("LoadIssue: %v", err) 268 return 269 } 270 if err := comment.Issue.LoadAttributes(ctx); err != nil { 271 log.Error("LoadAttributes: %v", err) 272 return 273 } 274 275 permission, _ := access_model.GetUserRepoPermission(ctx, comment.Issue.Repo, doer) 276 277 payload := &api.IssueCommentPayload{ 278 Action: action, 279 Issue: convert.ToAPIIssue(ctx, comment.Issue), 280 Comment: convert.ToAPIComment(ctx, comment.Issue.Repo, comment), 281 Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission), 282 Sender: convert.ToUser(ctx, doer, nil), 283 IsPull: comment.Issue.IsPull, 284 } 285 286 if action == api.HookIssueCommentEdited { 287 payload.Changes = &api.ChangesPayload{ 288 Body: &api.ChangesFromPayload{ 289 From: oldContent, 290 }, 291 } 292 } 293 294 if comment.Issue.IsPull { 295 if err := comment.Issue.LoadPullRequest(ctx); err != nil { 296 log.Error("LoadPullRequest: %v", err) 297 return 298 } 299 newNotifyInputFromIssue(comment.Issue, event). 300 WithDoer(doer). 301 WithPayload(payload). 302 WithPullRequest(comment.Issue.PullRequest). 303 Notify(ctx) 304 return 305 } 306 307 newNotifyInputFromIssue(comment.Issue, event). 308 WithDoer(doer). 309 WithPayload(payload). 310 Notify(ctx) 311 } 312 313 func (n *actionsNotifier) NewPullRequest(ctx context.Context, pull *issues_model.PullRequest, _ []*user_model.User) { 314 ctx = withMethod(ctx, "NewPullRequest") 315 316 if err := pull.LoadIssue(ctx); err != nil { 317 log.Error("pull.LoadIssue: %v", err) 318 return 319 } 320 if err := pull.Issue.LoadRepo(ctx); err != nil { 321 log.Error("pull.Issue.LoadRepo: %v", err) 322 return 323 } 324 if err := pull.Issue.LoadPoster(ctx); err != nil { 325 log.Error("pull.Issue.LoadPoster: %v", err) 326 return 327 } 328 329 permission, _ := access_model.GetUserRepoPermission(ctx, pull.Issue.Repo, pull.Issue.Poster) 330 331 newNotifyInputFromIssue(pull.Issue, webhook_module.HookEventPullRequest). 332 WithPayload(&api.PullRequestPayload{ 333 Action: api.HookIssueOpened, 334 Index: pull.Issue.Index, 335 PullRequest: convert.ToAPIPullRequest(ctx, pull, nil), 336 Repository: convert.ToRepo(ctx, pull.Issue.Repo, permission), 337 Sender: convert.ToUser(ctx, pull.Issue.Poster, nil), 338 }). 339 WithPullRequest(pull). 340 Notify(ctx) 341 } 342 343 func (n *actionsNotifier) CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) { 344 ctx = withMethod(ctx, "CreateRepository") 345 346 newNotifyInput(repo, doer, webhook_module.HookEventRepository).WithPayload(&api.RepositoryPayload{ 347 Action: api.HookRepoCreated, 348 Repository: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), 349 Organization: convert.ToUser(ctx, u, nil), 350 Sender: convert.ToUser(ctx, doer, nil), 351 }).Notify(ctx) 352 } 353 354 func (n *actionsNotifier) ForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository) { 355 ctx = withMethod(ctx, "ForkRepository") 356 357 oldPermission, _ := access_model.GetUserRepoPermission(ctx, oldRepo, doer) 358 permission, _ := access_model.GetUserRepoPermission(ctx, repo, doer) 359 360 // forked webhook 361 newNotifyInput(oldRepo, doer, webhook_module.HookEventFork).WithPayload(&api.ForkPayload{ 362 Forkee: convert.ToRepo(ctx, oldRepo, oldPermission), 363 Repo: convert.ToRepo(ctx, repo, permission), 364 Sender: convert.ToUser(ctx, doer, nil), 365 }).Notify(ctx) 366 367 u := repo.MustOwner(ctx) 368 369 // Add to hook queue for created repo after session commit. 370 if u.IsOrganization() { 371 newNotifyInput(repo, doer, webhook_module.HookEventRepository). 372 WithRef(oldRepo.DefaultBranch). 373 WithPayload(&api.RepositoryPayload{ 374 Action: api.HookRepoCreated, 375 Repository: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), 376 Organization: convert.ToUser(ctx, u, nil), 377 Sender: convert.ToUser(ctx, doer, nil), 378 }).Notify(ctx) 379 } 380 } 381 382 func (n *actionsNotifier) PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, _ *issues_model.Comment, _ []*user_model.User) { 383 ctx = withMethod(ctx, "PullRequestReview") 384 385 var reviewHookType webhook_module.HookEventType 386 387 switch review.Type { 388 case issues_model.ReviewTypeApprove: 389 reviewHookType = webhook_module.HookEventPullRequestReviewApproved 390 case issues_model.ReviewTypeComment: 391 reviewHookType = webhook_module.HookEventPullRequestReviewComment 392 case issues_model.ReviewTypeReject: 393 reviewHookType = webhook_module.HookEventPullRequestReviewRejected 394 default: 395 // unsupported review webhook type here 396 log.Error("Unsupported review webhook type") 397 return 398 } 399 400 if err := pr.LoadIssue(ctx); err != nil { 401 log.Error("pr.LoadIssue: %v", err) 402 return 403 } 404 405 permission, err := access_model.GetUserRepoPermission(ctx, review.Issue.Repo, review.Issue.Poster) 406 if err != nil { 407 log.Error("models.GetUserRepoPermission: %v", err) 408 return 409 } 410 411 newNotifyInput(review.Issue.Repo, review.Reviewer, reviewHookType). 412 WithRef(review.CommitID). 413 WithPayload(&api.PullRequestPayload{ 414 Action: api.HookIssueReviewed, 415 Index: review.Issue.Index, 416 PullRequest: convert.ToAPIPullRequest(db.DefaultContext, pr, nil), 417 Repository: convert.ToRepo(ctx, review.Issue.Repo, permission), 418 Sender: convert.ToUser(ctx, review.Reviewer, nil), 419 Review: &api.ReviewPayload{ 420 Type: string(reviewHookType), 421 Content: review.Content, 422 }, 423 }).Notify(ctx) 424 } 425 426 func (n *actionsNotifier) PullRequestReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { 427 if !issue.IsPull { 428 log.Warn("PullRequestReviewRequest: issue is not a pull request: %v", issue.ID) 429 return 430 } 431 432 ctx = withMethod(ctx, "PullRequestReviewRequest") 433 434 permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) 435 if err := issue.LoadPullRequest(ctx); err != nil { 436 log.Error("LoadPullRequest failed: %v", err) 437 return 438 } 439 var action api.HookIssueAction 440 if isRequest { 441 action = api.HookIssueReviewRequested 442 } else { 443 action = api.HookIssueReviewRequestRemoved 444 } 445 newNotifyInputFromIssue(issue, webhook_module.HookEventPullRequestReviewRequest). 446 WithDoer(doer). 447 WithPayload(&api.PullRequestPayload{ 448 Action: action, 449 Index: issue.Index, 450 PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), 451 RequestedReviewer: convert.ToUser(ctx, reviewer, nil), 452 Repository: convert.ToRepo(ctx, issue.Repo, permission), 453 Sender: convert.ToUser(ctx, doer, nil), 454 }). 455 WithPullRequest(issue.PullRequest). 456 Notify(ctx) 457 } 458 459 func (*actionsNotifier) MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) { 460 ctx = withMethod(ctx, "MergePullRequest") 461 462 // Reload pull request information. 463 if err := pr.LoadAttributes(ctx); err != nil { 464 log.Error("LoadAttributes: %v", err) 465 return 466 } 467 468 if err := pr.LoadIssue(ctx); err != nil { 469 log.Error("LoadAttributes: %v", err) 470 return 471 } 472 473 if err := pr.Issue.LoadRepo(db.DefaultContext); err != nil { 474 log.Error("pr.Issue.LoadRepo: %v", err) 475 return 476 } 477 478 permission, err := access_model.GetUserRepoPermission(ctx, pr.Issue.Repo, doer) 479 if err != nil { 480 log.Error("models.GetUserRepoPermission: %v", err) 481 return 482 } 483 484 // Merge pull request calls issue.changeStatus so we need to handle separately. 485 apiPullRequest := &api.PullRequestPayload{ 486 Index: pr.Issue.Index, 487 PullRequest: convert.ToAPIPullRequest(db.DefaultContext, pr, nil), 488 Repository: convert.ToRepo(ctx, pr.Issue.Repo, permission), 489 Sender: convert.ToUser(ctx, doer, nil), 490 Action: api.HookIssueClosed, 491 } 492 493 newNotifyInput(pr.Issue.Repo, doer, webhook_module.HookEventPullRequest). 494 WithRef(pr.MergedCommitID). 495 WithPayload(apiPullRequest). 496 WithPullRequest(pr). 497 Notify(ctx) 498 } 499 500 func (n *actionsNotifier) PushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { 501 ctx = withMethod(ctx, "PushCommits") 502 503 apiPusher := convert.ToUser(ctx, pusher, nil) 504 apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo.RepoPath(), repo.HTMLURL()) 505 if err != nil { 506 log.Error("commits.ToAPIPayloadCommits failed: %v", err) 507 return 508 } 509 510 newNotifyInput(repo, pusher, webhook_module.HookEventPush). 511 WithRef(opts.RefFullName.String()). 512 WithPayload(&api.PushPayload{ 513 Ref: opts.RefFullName.String(), 514 Before: opts.OldCommitID, 515 After: opts.NewCommitID, 516 CompareURL: setting.AppURL + commits.CompareURL, 517 Commits: apiCommits, 518 HeadCommit: apiHeadCommit, 519 Repo: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), 520 Pusher: apiPusher, 521 Sender: apiPusher, 522 }). 523 Notify(ctx) 524 } 525 526 func (n *actionsNotifier) CreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { 527 ctx = withMethod(ctx, "CreateRef") 528 529 apiPusher := convert.ToUser(ctx, pusher, nil) 530 apiRepo := convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}) 531 532 newNotifyInput(repo, pusher, webhook_module.HookEventCreate). 533 WithRef(refFullName.ShortName()). // FIXME: should we use a full ref name 534 WithPayload(&api.CreatePayload{ 535 Ref: refFullName.ShortName(), 536 Sha: refID, 537 RefType: refFullName.RefType(), 538 Repo: apiRepo, 539 Sender: apiPusher, 540 }). 541 Notify(ctx) 542 } 543 544 func (n *actionsNotifier) DeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { 545 ctx = withMethod(ctx, "DeleteRef") 546 547 apiPusher := convert.ToUser(ctx, pusher, nil) 548 apiRepo := convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}) 549 550 newNotifyInput(repo, pusher, webhook_module.HookEventDelete). 551 WithPayload(&api.DeletePayload{ 552 Ref: refFullName.ShortName(), 553 RefType: refFullName.RefType(), 554 PusherType: api.PusherTypeUser, 555 Repo: apiRepo, 556 Sender: apiPusher, 557 }). 558 Notify(ctx) 559 } 560 561 func (n *actionsNotifier) SyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { 562 ctx = withMethod(ctx, "SyncPushCommits") 563 564 apiPusher := convert.ToUser(ctx, pusher, nil) 565 apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(db.DefaultContext, repo.RepoPath(), repo.HTMLURL()) 566 if err != nil { 567 log.Error("commits.ToAPIPayloadCommits failed: %v", err) 568 return 569 } 570 571 newNotifyInput(repo, pusher, webhook_module.HookEventPush). 572 WithRef(opts.RefFullName.String()). 573 WithPayload(&api.PushPayload{ 574 Ref: opts.RefFullName.String(), 575 Before: opts.OldCommitID, 576 After: opts.NewCommitID, 577 CompareURL: setting.AppURL + commits.CompareURL, 578 Commits: apiCommits, 579 TotalCommits: commits.Len, 580 HeadCommit: apiHeadCommit, 581 Repo: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), 582 Pusher: apiPusher, 583 Sender: apiPusher, 584 }). 585 Notify(ctx) 586 } 587 588 func (n *actionsNotifier) SyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { 589 ctx = withMethod(ctx, "SyncCreateRef") 590 n.CreateRef(ctx, pusher, repo, refFullName, refID) 591 } 592 593 func (n *actionsNotifier) SyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { 594 ctx = withMethod(ctx, "SyncDeleteRef") 595 n.DeleteRef(ctx, pusher, repo, refFullName) 596 } 597 598 func (n *actionsNotifier) NewRelease(ctx context.Context, rel *repo_model.Release) { 599 ctx = withMethod(ctx, "NewRelease") 600 notifyRelease(ctx, rel.Publisher, rel, api.HookReleasePublished) 601 } 602 603 func (n *actionsNotifier) UpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) { 604 ctx = withMethod(ctx, "UpdateRelease") 605 notifyRelease(ctx, doer, rel, api.HookReleaseUpdated) 606 } 607 608 func (n *actionsNotifier) DeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) { 609 ctx = withMethod(ctx, "DeleteRelease") 610 notifyRelease(ctx, doer, rel, api.HookReleaseDeleted) 611 } 612 613 func (n *actionsNotifier) PackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) { 614 ctx = withMethod(ctx, "PackageCreate") 615 notifyPackage(ctx, doer, pd, api.HookPackageCreated) 616 } 617 618 func (n *actionsNotifier) PackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) { 619 ctx = withMethod(ctx, "PackageDelete") 620 notifyPackage(ctx, doer, pd, api.HookPackageDeleted) 621 } 622 623 func (n *actionsNotifier) AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) { 624 ctx = withMethod(ctx, "AutoMergePullRequest") 625 n.MergePullRequest(ctx, doer, pr) 626 } 627 628 func (n *actionsNotifier) PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) { 629 ctx = withMethod(ctx, "PullRequestSynchronized") 630 631 if err := pr.LoadIssue(ctx); err != nil { 632 log.Error("LoadAttributes: %v", err) 633 return 634 } 635 636 if err := pr.Issue.LoadRepo(db.DefaultContext); err != nil { 637 log.Error("pr.Issue.LoadRepo: %v", err) 638 return 639 } 640 641 newNotifyInput(pr.Issue.Repo, doer, webhook_module.HookEventPullRequestSync). 642 WithPayload(&api.PullRequestPayload{ 643 Action: api.HookIssueSynchronized, 644 Index: pr.Issue.Index, 645 PullRequest: convert.ToAPIPullRequest(ctx, pr, nil), 646 Repository: convert.ToRepo(ctx, pr.Issue.Repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}), 647 Sender: convert.ToUser(ctx, doer, nil), 648 }). 649 WithPullRequest(pr). 650 Notify(ctx) 651 } 652 653 func (n *actionsNotifier) PullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) { 654 ctx = withMethod(ctx, "PullRequestChangeTargetBranch") 655 656 if err := pr.LoadIssue(ctx); err != nil { 657 log.Error("LoadAttributes: %v", err) 658 return 659 } 660 661 if err := pr.Issue.LoadRepo(db.DefaultContext); err != nil { 662 log.Error("pr.Issue.LoadRepo: %v", err) 663 return 664 } 665 666 permission, _ := access_model.GetUserRepoPermission(ctx, pr.Issue.Repo, pr.Issue.Poster) 667 newNotifyInput(pr.Issue.Repo, doer, webhook_module.HookEventPullRequest). 668 WithPayload(&api.PullRequestPayload{ 669 Action: api.HookIssueEdited, 670 Index: pr.Issue.Index, 671 Changes: &api.ChangesPayload{ 672 Ref: &api.ChangesFromPayload{ 673 From: oldBranch, 674 }, 675 }, 676 PullRequest: convert.ToAPIPullRequest(ctx, pr, nil), 677 Repository: convert.ToRepo(ctx, pr.Issue.Repo, permission), 678 Sender: convert.ToUser(ctx, doer, nil), 679 }). 680 WithPullRequest(pr). 681 Notify(ctx) 682 } 683 684 func (n *actionsNotifier) NewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) { 685 ctx = withMethod(ctx, "NewWikiPage") 686 687 newNotifyInput(repo, doer, webhook_module.HookEventWiki).WithPayload(&api.WikiPayload{ 688 Action: api.HookWikiCreated, 689 Repository: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), 690 Sender: convert.ToUser(ctx, doer, nil), 691 Page: page, 692 Comment: comment, 693 }).Notify(ctx) 694 } 695 696 func (n *actionsNotifier) EditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) { 697 ctx = withMethod(ctx, "EditWikiPage") 698 699 newNotifyInput(repo, doer, webhook_module.HookEventWiki).WithPayload(&api.WikiPayload{ 700 Action: api.HookWikiEdited, 701 Repository: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), 702 Sender: convert.ToUser(ctx, doer, nil), 703 Page: page, 704 Comment: comment, 705 }).Notify(ctx) 706 } 707 708 func (n *actionsNotifier) DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page string) { 709 ctx = withMethod(ctx, "DeleteWikiPage") 710 711 newNotifyInput(repo, doer, webhook_module.HookEventWiki).WithPayload(&api.WikiPayload{ 712 Action: api.HookWikiDeleted, 713 Repository: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), 714 Sender: convert.ToUser(ctx, doer, nil), 715 Page: page, 716 }).Notify(ctx) 717 } 718 719 // MigrateRepository is used to detect workflows after a repository has been migrated 720 func (n *actionsNotifier) MigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) { 721 ctx = withMethod(ctx, "MigrateRepository") 722 723 newNotifyInput(repo, doer, webhook_module.HookEventRepository).WithPayload(&api.RepositoryPayload{ 724 Action: api.HookRepoCreated, 725 Repository: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), 726 Organization: convert.ToUser(ctx, u, nil), 727 Sender: convert.ToUser(ctx, doer, nil), 728 }).Notify(ctx) 729 }