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