Skip to content

Commit 24941a1

Browse files
authored
Add more webhooks support and refactor webhook templates directory (#3929)
* add more webhook support * move hooks templates to standalone dir and add more webhooks ui * fix tests * update vendor checksum * add more webhook support * move hooks templates to standalone dir and add more webhooks ui * fix tests * update vendor checksum * update vendor Signed-off-by: Bo-Yi Wu <[email protected]> * load attributes when created release * update comparsion doc
1 parent 188fe6c commit 24941a1

33 files changed

+1010
-118
lines changed

docs/content/doc/features/comparison.en-us.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ _Symbols used in table:_
537537
</tr>
538538
<tr>
539539
<td>Webhook support</td>
540-
<td></td>
540+
<td></td>
541541
<td>✓</td>
542542
<td>✓</td>
543543
<td>✓</td>

models/action.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,16 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
618618
case ActionDeleteBranch: // Delete Branch
619619
isHookEventPush = true
620620

621+
if err = PrepareWebhooks(repo, HookEventDelete, &api.DeletePayload{
622+
Ref: refName,
623+
RefType: "branch",
624+
PusherType: api.PusherTypeUser,
625+
Repo: apiRepo,
626+
Sender: apiPusher,
627+
}); err != nil {
628+
return fmt.Errorf("PrepareWebhooks.(delete branch): %v", err)
629+
}
630+
621631
case ActionPushTag: // Create
622632
isHookEventPush = true
623633

@@ -640,6 +650,16 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
640650
}
641651
case ActionDeleteTag: // Delete Tag
642652
isHookEventPush = true
653+
654+
if err = PrepareWebhooks(repo, HookEventDelete, &api.DeletePayload{
655+
Ref: refName,
656+
RefType: "tag",
657+
PusherType: api.PusherTypeUser,
658+
Repo: apiRepo,
659+
Sender: apiPusher,
660+
}); err != nil {
661+
return fmt.Errorf("PrepareWebhooks.(delete tag): %v", err)
662+
}
643663
}
644664

645665
if isHookEventPush {

models/issue_comment.go

Lines changed: 92 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@ const (
8383
type Comment struct {
8484
ID int64 `xorm:"pk autoincr"`
8585
Type CommentType
86-
PosterID int64 `xorm:"INDEX"`
87-
Poster *User `xorm:"-"`
88-
IssueID int64 `xorm:"INDEX"`
86+
PosterID int64 `xorm:"INDEX"`
87+
Poster *User `xorm:"-"`
88+
IssueID int64 `xorm:"INDEX"`
89+
Issue *Issue `xorm:"-"`
8990
LabelID int64
9091
Label *Label `xorm:"-"`
9192
OldMilestoneID int64
@@ -116,6 +117,15 @@ type Comment struct {
116117
ShowTag CommentTag `xorm:"-"`
117118
}
118119

120+
// LoadIssue loads issue from database
121+
func (c *Comment) LoadIssue() (err error) {
122+
if c.Issue != nil {
123+
return nil
124+
}
125+
c.Issue, err = GetIssueByID(c.IssueID)
126+
return
127+
}
128+
119129
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
120130
func (c *Comment) AfterLoad(session *xorm.Session) {
121131
var err error
@@ -146,40 +156,40 @@ func (c *Comment) AfterDelete() {
146156

147157
// HTMLURL formats a URL-string to the issue-comment
148158
func (c *Comment) HTMLURL() string {
149-
issue, err := GetIssueByID(c.IssueID)
159+
err := c.LoadIssue()
150160
if err != nil { // Silently dropping errors :unamused:
151-
log.Error(4, "GetIssueByID(%d): %v", c.IssueID, err)
161+
log.Error(4, "LoadIssue(%d): %v", c.IssueID, err)
152162
return ""
153163
}
154-
return fmt.Sprintf("%s#%s", issue.HTMLURL(), c.HashTag())
164+
return fmt.Sprintf("%s#%s", c.Issue.HTMLURL(), c.HashTag())
155165
}
156166

157167
// IssueURL formats a URL-string to the issue
158168
func (c *Comment) IssueURL() string {
159-
issue, err := GetIssueByID(c.IssueID)
169+
err := c.LoadIssue()
160170
if err != nil { // Silently dropping errors :unamused:
161-
log.Error(4, "GetIssueByID(%d): %v", c.IssueID, err)
171+
log.Error(4, "LoadIssue(%d): %v", c.IssueID, err)
162172
return ""
163173
}
164174

165-
if issue.IsPull {
175+
if c.Issue.IsPull {
166176
return ""
167177
}
168-
return issue.HTMLURL()
178+
return c.Issue.HTMLURL()
169179
}
170180

171181
// PRURL formats a URL-string to the pull-request
172182
func (c *Comment) PRURL() string {
173-
issue, err := GetIssueByID(c.IssueID)
183+
err := c.LoadIssue()
174184
if err != nil { // Silently dropping errors :unamused:
175-
log.Error(4, "GetIssueByID(%d): %v", c.IssueID, err)
185+
log.Error(4, "LoadIssue(%d): %v", c.IssueID, err)
176186
return ""
177187
}
178188

179-
if !issue.IsPull {
189+
if !c.Issue.IsPull {
180190
return ""
181191
}
182-
return issue.HTMLURL()
192+
return c.Issue.HTMLURL()
183193
}
184194

185195
// APIFormat converts a Comment to the api.Comment format
@@ -196,9 +206,14 @@ func (c *Comment) APIFormat() *api.Comment {
196206
}
197207
}
198208

209+
// CommentHashTag returns unique hash tag for comment id.
210+
func CommentHashTag(id int64) string {
211+
return fmt.Sprintf("issuecomment-%d", id)
212+
}
213+
199214
// HashTag returns unique hash tag for comment.
200215
func (c *Comment) HashTag() string {
201-
return "issuecomment-" + com.ToStr(c.ID)
216+
return CommentHashTag(c.ID)
202217
}
203218

204219
// EventTag returns unique event hash tag for comment.
@@ -576,14 +591,29 @@ func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) {
576591

577592
// CreateIssueComment creates a plain issue comment.
578593
func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content string, attachments []string) (*Comment, error) {
579-
return CreateComment(&CreateCommentOptions{
594+
comment, err := CreateComment(&CreateCommentOptions{
580595
Type: CommentTypeComment,
581596
Doer: doer,
582597
Repo: repo,
583598
Issue: issue,
584599
Content: content,
585600
Attachments: attachments,
586601
})
602+
if err != nil {
603+
return nil, fmt.Errorf("CreateComment: %v", err)
604+
}
605+
606+
mode, _ := AccessLevel(doer.ID, repo)
607+
if err = PrepareWebhooks(repo, HookEventIssueComment, &api.IssueCommentPayload{
608+
Action: api.HookIssueCommentCreated,
609+
Issue: issue.APIFormat(),
610+
Comment: comment.APIFormat(),
611+
Repository: repo.APIFormat(mode),
612+
Sender: doer.APIFormat(),
613+
}); err != nil {
614+
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
615+
}
616+
return comment, nil
587617
}
588618

589619
// CreateRefComment creates a commit reference comment to issue.
@@ -696,17 +726,41 @@ func GetCommentsByRepoIDSince(repoID, since int64) ([]*Comment, error) {
696726
}
697727

698728
// UpdateComment updates information of comment.
699-
func UpdateComment(c *Comment) error {
729+
func UpdateComment(doer *User, c *Comment, oldContent string) error {
700730
if _, err := x.ID(c.ID).AllCols().Update(c); err != nil {
701731
return err
702732
} else if c.Type == CommentTypeComment {
703733
UpdateIssueIndexer(c.IssueID)
704734
}
735+
736+
if err := c.LoadIssue(); err != nil {
737+
return err
738+
}
739+
if err := c.Issue.LoadAttributes(); err != nil {
740+
return err
741+
}
742+
743+
mode, _ := AccessLevel(doer.ID, c.Issue.Repo)
744+
if err := PrepareWebhooks(c.Issue.Repo, HookEventIssueComment, &api.IssueCommentPayload{
745+
Action: api.HookIssueCommentEdited,
746+
Issue: c.Issue.APIFormat(),
747+
Comment: c.APIFormat(),
748+
Changes: &api.ChangesPayload{
749+
Body: &api.ChangesFromPayload{
750+
From: oldContent,
751+
},
752+
},
753+
Repository: c.Issue.Repo.APIFormat(mode),
754+
Sender: doer.APIFormat(),
755+
}); err != nil {
756+
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", c.ID, err)
757+
}
758+
705759
return nil
706760
}
707761

708762
// DeleteComment deletes the comment
709-
func DeleteComment(comment *Comment) error {
763+
func DeleteComment(doer *User, comment *Comment) error {
710764
sess := x.NewSession()
711765
defer sess.Close()
712766
if err := sess.Begin(); err != nil {
@@ -733,5 +787,25 @@ func DeleteComment(comment *Comment) error {
733787
} else if comment.Type == CommentTypeComment {
734788
UpdateIssueIndexer(comment.IssueID)
735789
}
790+
791+
if err := comment.LoadIssue(); err != nil {
792+
return err
793+
}
794+
if err := comment.Issue.LoadAttributes(); err != nil {
795+
return err
796+
}
797+
798+
mode, _ := AccessLevel(doer.ID, comment.Issue.Repo)
799+
800+
if err := PrepareWebhooks(comment.Issue.Repo, HookEventIssueComment, &api.IssueCommentPayload{
801+
Action: api.HookIssueCommentDeleted,
802+
Issue: comment.Issue.APIFormat(),
803+
Comment: comment.APIFormat(),
804+
Repository: comment.Issue.Repo.APIFormat(mode),
805+
Sender: doer.APIFormat(),
806+
}); err != nil {
807+
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
808+
}
809+
736810
return nil
737811
}

models/issue_milestone.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
package models
66

77
import (
8+
"fmt"
9+
10+
"code.gitea.io/gitea/modules/log"
811
"code.gitea.io/gitea/modules/setting"
912
"code.gitea.io/gitea/modules/util"
1013
api "code.gitea.io/sdk/gitea"
@@ -358,7 +361,49 @@ func ChangeMilestoneAssign(issue *Issue, doer *User, oldMilestoneID int64) (err
358361
if err = changeMilestoneAssign(sess, doer, issue, oldMilestoneID); err != nil {
359362
return err
360363
}
361-
return sess.Commit()
364+
365+
if err = sess.Commit(); err != nil {
366+
return fmt.Errorf("Commit: %v", err)
367+
}
368+
369+
var hookAction api.HookIssueAction
370+
if issue.MilestoneID > 0 {
371+
hookAction = api.HookIssueMilestoned
372+
} else {
373+
hookAction = api.HookIssueDemilestoned
374+
}
375+
376+
if err = issue.LoadAttributes(); err != nil {
377+
return err
378+
}
379+
380+
mode, _ := AccessLevel(doer.ID, issue.Repo)
381+
if issue.IsPull {
382+
err = issue.PullRequest.LoadIssue()
383+
if err != nil {
384+
log.Error(2, "LoadIssue: %v", err)
385+
return
386+
}
387+
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
388+
Action: hookAction,
389+
Index: issue.Index,
390+
PullRequest: issue.PullRequest.APIFormat(),
391+
Repository: issue.Repo.APIFormat(mode),
392+
Sender: doer.APIFormat(),
393+
})
394+
} else {
395+
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
396+
Action: hookAction,
397+
Index: issue.Index,
398+
Issue: issue.APIFormat(),
399+
Repository: issue.Repo.APIFormat(mode),
400+
Sender: doer.APIFormat(),
401+
})
402+
}
403+
if err != nil {
404+
log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
405+
}
406+
return nil
362407
}
363408

364409
// DeleteMilestoneByRepoID deletes a milestone from a repository.

models/issue_milestone_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ func TestChangeMilestoneAssign(t *testing.T) {
232232
assert.NoError(t, PrepareTestDatabase())
233233
issue := AssertExistsAndLoadBean(t, &Issue{RepoID: 1}).(*Issue)
234234
doer := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
235+
assert.NotNil(t, issue)
236+
assert.NotNil(t, doer)
235237

236238
oldMilestoneID := issue.MilestoneID
237239
issue.MilestoneID = 2

models/release.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strings"
1111

1212
"code.gitea.io/git"
13+
"code.gitea.io/gitea/modules/log"
1314
"code.gitea.io/gitea/modules/process"
1415
"code.gitea.io/gitea/modules/setting"
1516
"code.gitea.io/gitea/modules/util"
@@ -190,8 +191,27 @@ func CreateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []stri
190191
}
191192

192193
err = addReleaseAttachments(rel.ID, attachmentUUIDs)
194+
if err != nil {
195+
return err
196+
}
193197

194-
return err
198+
if !rel.IsDraft {
199+
if err := rel.LoadAttributes(); err != nil {
200+
log.Error(2, "LoadAttributes: %v", err)
201+
} else {
202+
mode, _ := AccessLevel(rel.PublisherID, rel.Repo)
203+
if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
204+
Action: api.HookReleasePublished,
205+
Release: rel.APIFormat(),
206+
Repository: rel.Repo.APIFormat(mode),
207+
Sender: rel.Publisher.APIFormat(),
208+
}); err != nil {
209+
log.Error(2, "PrepareWebhooks: %v", err)
210+
}
211+
}
212+
}
213+
214+
return nil
195215
}
196216

197217
// GetRelease returns release by given ID.

models/repo.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2456,6 +2456,17 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
24562456
return nil, err
24572457
}
24582458

2459+
oldMode, _ := AccessLevel(doer.ID, oldRepo)
2460+
mode, _ := AccessLevel(doer.ID, repo)
2461+
2462+
if err = PrepareWebhooks(oldRepo, HookEventFork, &api.ForkPayload{
2463+
Forkee: repo.APIFormat(mode),
2464+
Repo: oldRepo.APIFormat(oldMode),
2465+
Sender: doer.APIFormat(),
2466+
}); err != nil {
2467+
log.Error(2, "PrepareWebhooks [repo_id: %d]: %v", oldRepo.ID, err)
2468+
}
2469+
24592470
if err = repo.UpdateSize(); err != nil {
24602471
log.Error(4, "Failed to update size for repository: %v", err)
24612472
}

0 commit comments

Comments
 (0)