mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	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 <appleboy.tw@gmail.com> * load attributes when created release * update comparsion doc
This commit is contained in:
		@@ -537,7 +537,7 @@ _Symbols used in table:_
 | 
				
			|||||||
    </tr>
 | 
					    </tr>
 | 
				
			||||||
    <tr>
 | 
					    <tr>
 | 
				
			||||||
      <td>Webhook support</td>
 | 
					      <td>Webhook support</td>
 | 
				
			||||||
      <td>⁄</td>
 | 
					      <td>✓</td>
 | 
				
			||||||
      <td>✓</td>
 | 
					      <td>✓</td>
 | 
				
			||||||
      <td>✓</td>
 | 
					      <td>✓</td>
 | 
				
			||||||
      <td>✓</td>
 | 
					      <td>✓</td>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -618,6 +618,16 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
 | 
				
			|||||||
	case ActionDeleteBranch: // Delete Branch
 | 
						case ActionDeleteBranch: // Delete Branch
 | 
				
			||||||
		isHookEventPush = true
 | 
							isHookEventPush = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err = PrepareWebhooks(repo, HookEventDelete, &api.DeletePayload{
 | 
				
			||||||
 | 
								Ref:        refName,
 | 
				
			||||||
 | 
								RefType:    "branch",
 | 
				
			||||||
 | 
								PusherType: api.PusherTypeUser,
 | 
				
			||||||
 | 
								Repo:       apiRepo,
 | 
				
			||||||
 | 
								Sender:     apiPusher,
 | 
				
			||||||
 | 
							}); err != nil {
 | 
				
			||||||
 | 
								return fmt.Errorf("PrepareWebhooks.(delete branch): %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case ActionPushTag: // Create
 | 
						case ActionPushTag: // Create
 | 
				
			||||||
		isHookEventPush = true
 | 
							isHookEventPush = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -640,6 +650,16 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	case ActionDeleteTag: // Delete Tag
 | 
						case ActionDeleteTag: // Delete Tag
 | 
				
			||||||
		isHookEventPush = true
 | 
							isHookEventPush = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err = PrepareWebhooks(repo, HookEventDelete, &api.DeletePayload{
 | 
				
			||||||
 | 
								Ref:        refName,
 | 
				
			||||||
 | 
								RefType:    "tag",
 | 
				
			||||||
 | 
								PusherType: api.PusherTypeUser,
 | 
				
			||||||
 | 
								Repo:       apiRepo,
 | 
				
			||||||
 | 
								Sender:     apiPusher,
 | 
				
			||||||
 | 
							}); err != nil {
 | 
				
			||||||
 | 
								return fmt.Errorf("PrepareWebhooks.(delete tag): %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if isHookEventPush {
 | 
						if isHookEventPush {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,9 +83,10 @@ const (
 | 
				
			|||||||
type Comment struct {
 | 
					type Comment struct {
 | 
				
			||||||
	ID              int64 `xorm:"pk autoincr"`
 | 
						ID              int64 `xorm:"pk autoincr"`
 | 
				
			||||||
	Type            CommentType
 | 
						Type            CommentType
 | 
				
			||||||
	PosterID        int64 `xorm:"INDEX"`
 | 
						PosterID        int64  `xorm:"INDEX"`
 | 
				
			||||||
	Poster          *User `xorm:"-"`
 | 
						Poster          *User  `xorm:"-"`
 | 
				
			||||||
	IssueID         int64 `xorm:"INDEX"`
 | 
						IssueID         int64  `xorm:"INDEX"`
 | 
				
			||||||
 | 
						Issue           *Issue `xorm:"-"`
 | 
				
			||||||
	LabelID         int64
 | 
						LabelID         int64
 | 
				
			||||||
	Label           *Label `xorm:"-"`
 | 
						Label           *Label `xorm:"-"`
 | 
				
			||||||
	OldMilestoneID  int64
 | 
						OldMilestoneID  int64
 | 
				
			||||||
@@ -116,6 +117,15 @@ type Comment struct {
 | 
				
			|||||||
	ShowTag CommentTag `xorm:"-"`
 | 
						ShowTag CommentTag `xorm:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LoadIssue loads issue from database
 | 
				
			||||||
 | 
					func (c *Comment) LoadIssue() (err error) {
 | 
				
			||||||
 | 
						if c.Issue != nil {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						c.Issue, err = GetIssueByID(c.IssueID)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
					// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
				
			||||||
func (c *Comment) AfterLoad(session *xorm.Session) {
 | 
					func (c *Comment) AfterLoad(session *xorm.Session) {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
@@ -146,40 +156,40 @@ func (c *Comment) AfterDelete() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// HTMLURL formats a URL-string to the issue-comment
 | 
					// HTMLURL formats a URL-string to the issue-comment
 | 
				
			||||||
func (c *Comment) HTMLURL() string {
 | 
					func (c *Comment) HTMLURL() string {
 | 
				
			||||||
	issue, err := GetIssueByID(c.IssueID)
 | 
						err := c.LoadIssue()
 | 
				
			||||||
	if err != nil { // Silently dropping errors :unamused:
 | 
						if err != nil { // Silently dropping errors :unamused:
 | 
				
			||||||
		log.Error(4, "GetIssueByID(%d): %v", c.IssueID, err)
 | 
							log.Error(4, "LoadIssue(%d): %v", c.IssueID, err)
 | 
				
			||||||
		return ""
 | 
							return ""
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return fmt.Sprintf("%s#%s", issue.HTMLURL(), c.HashTag())
 | 
						return fmt.Sprintf("%s#%s", c.Issue.HTMLURL(), c.HashTag())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IssueURL formats a URL-string to the issue
 | 
					// IssueURL formats a URL-string to the issue
 | 
				
			||||||
func (c *Comment) IssueURL() string {
 | 
					func (c *Comment) IssueURL() string {
 | 
				
			||||||
	issue, err := GetIssueByID(c.IssueID)
 | 
						err := c.LoadIssue()
 | 
				
			||||||
	if err != nil { // Silently dropping errors :unamused:
 | 
						if err != nil { // Silently dropping errors :unamused:
 | 
				
			||||||
		log.Error(4, "GetIssueByID(%d): %v", c.IssueID, err)
 | 
							log.Error(4, "LoadIssue(%d): %v", c.IssueID, err)
 | 
				
			||||||
		return ""
 | 
							return ""
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if issue.IsPull {
 | 
						if c.Issue.IsPull {
 | 
				
			||||||
		return ""
 | 
							return ""
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return issue.HTMLURL()
 | 
						return c.Issue.HTMLURL()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PRURL formats a URL-string to the pull-request
 | 
					// PRURL formats a URL-string to the pull-request
 | 
				
			||||||
func (c *Comment) PRURL() string {
 | 
					func (c *Comment) PRURL() string {
 | 
				
			||||||
	issue, err := GetIssueByID(c.IssueID)
 | 
						err := c.LoadIssue()
 | 
				
			||||||
	if err != nil { // Silently dropping errors :unamused:
 | 
						if err != nil { // Silently dropping errors :unamused:
 | 
				
			||||||
		log.Error(4, "GetIssueByID(%d): %v", c.IssueID, err)
 | 
							log.Error(4, "LoadIssue(%d): %v", c.IssueID, err)
 | 
				
			||||||
		return ""
 | 
							return ""
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !issue.IsPull {
 | 
						if !c.Issue.IsPull {
 | 
				
			||||||
		return ""
 | 
							return ""
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return issue.HTMLURL()
 | 
						return c.Issue.HTMLURL()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// APIFormat converts a Comment to the api.Comment format
 | 
					// APIFormat converts a Comment to the api.Comment format
 | 
				
			||||||
@@ -196,9 +206,14 @@ func (c *Comment) APIFormat() *api.Comment {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CommentHashTag returns unique hash tag for comment id.
 | 
				
			||||||
 | 
					func CommentHashTag(id int64) string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("issuecomment-%d", id)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HashTag returns unique hash tag for comment.
 | 
					// HashTag returns unique hash tag for comment.
 | 
				
			||||||
func (c *Comment) HashTag() string {
 | 
					func (c *Comment) HashTag() string {
 | 
				
			||||||
	return "issuecomment-" + com.ToStr(c.ID)
 | 
						return CommentHashTag(c.ID)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EventTag returns unique event hash tag for comment.
 | 
					// EventTag returns unique event hash tag for comment.
 | 
				
			||||||
@@ -576,7 +591,7 @@ func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// CreateIssueComment creates a plain issue comment.
 | 
					// CreateIssueComment creates a plain issue comment.
 | 
				
			||||||
func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content string, attachments []string) (*Comment, error) {
 | 
					func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content string, attachments []string) (*Comment, error) {
 | 
				
			||||||
	return CreateComment(&CreateCommentOptions{
 | 
						comment, err := CreateComment(&CreateCommentOptions{
 | 
				
			||||||
		Type:        CommentTypeComment,
 | 
							Type:        CommentTypeComment,
 | 
				
			||||||
		Doer:        doer,
 | 
							Doer:        doer,
 | 
				
			||||||
		Repo:        repo,
 | 
							Repo:        repo,
 | 
				
			||||||
@@ -584,6 +599,21 @@ func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content stri
 | 
				
			|||||||
		Content:     content,
 | 
							Content:     content,
 | 
				
			||||||
		Attachments: attachments,
 | 
							Attachments: attachments,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("CreateComment: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mode, _ := AccessLevel(doer.ID, repo)
 | 
				
			||||||
 | 
						if err = PrepareWebhooks(repo, HookEventIssueComment, &api.IssueCommentPayload{
 | 
				
			||||||
 | 
							Action:     api.HookIssueCommentCreated,
 | 
				
			||||||
 | 
							Issue:      issue.APIFormat(),
 | 
				
			||||||
 | 
							Comment:    comment.APIFormat(),
 | 
				
			||||||
 | 
							Repository: repo.APIFormat(mode),
 | 
				
			||||||
 | 
							Sender:     doer.APIFormat(),
 | 
				
			||||||
 | 
						}); err != nil {
 | 
				
			||||||
 | 
							log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return comment, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateRefComment creates a commit reference comment to issue.
 | 
					// CreateRefComment creates a commit reference comment to issue.
 | 
				
			||||||
@@ -696,17 +726,41 @@ func GetCommentsByRepoIDSince(repoID, since int64) ([]*Comment, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateComment updates information of comment.
 | 
					// UpdateComment updates information of comment.
 | 
				
			||||||
func UpdateComment(c *Comment) error {
 | 
					func UpdateComment(doer *User, c *Comment, oldContent string) error {
 | 
				
			||||||
	if _, err := x.ID(c.ID).AllCols().Update(c); err != nil {
 | 
						if _, err := x.ID(c.ID).AllCols().Update(c); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	} else if c.Type == CommentTypeComment {
 | 
						} else if c.Type == CommentTypeComment {
 | 
				
			||||||
		UpdateIssueIndexer(c.IssueID)
 | 
							UpdateIssueIndexer(c.IssueID)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := c.LoadIssue(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := c.Issue.LoadAttributes(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mode, _ := AccessLevel(doer.ID, c.Issue.Repo)
 | 
				
			||||||
 | 
						if err := PrepareWebhooks(c.Issue.Repo, HookEventIssueComment, &api.IssueCommentPayload{
 | 
				
			||||||
 | 
							Action:  api.HookIssueCommentEdited,
 | 
				
			||||||
 | 
							Issue:   c.Issue.APIFormat(),
 | 
				
			||||||
 | 
							Comment: c.APIFormat(),
 | 
				
			||||||
 | 
							Changes: &api.ChangesPayload{
 | 
				
			||||||
 | 
								Body: &api.ChangesFromPayload{
 | 
				
			||||||
 | 
									From: oldContent,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							Repository: c.Issue.Repo.APIFormat(mode),
 | 
				
			||||||
 | 
							Sender:     doer.APIFormat(),
 | 
				
			||||||
 | 
						}); err != nil {
 | 
				
			||||||
 | 
							log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", c.ID, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DeleteComment deletes the comment
 | 
					// DeleteComment deletes the comment
 | 
				
			||||||
func DeleteComment(comment *Comment) error {
 | 
					func DeleteComment(doer *User, comment *Comment) error {
 | 
				
			||||||
	sess := x.NewSession()
 | 
						sess := x.NewSession()
 | 
				
			||||||
	defer sess.Close()
 | 
						defer sess.Close()
 | 
				
			||||||
	if err := sess.Begin(); err != nil {
 | 
						if err := sess.Begin(); err != nil {
 | 
				
			||||||
@@ -733,5 +787,25 @@ func DeleteComment(comment *Comment) error {
 | 
				
			|||||||
	} else if comment.Type == CommentTypeComment {
 | 
						} else if comment.Type == CommentTypeComment {
 | 
				
			||||||
		UpdateIssueIndexer(comment.IssueID)
 | 
							UpdateIssueIndexer(comment.IssueID)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := comment.LoadIssue(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := comment.Issue.LoadAttributes(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mode, _ := AccessLevel(doer.ID, comment.Issue.Repo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := PrepareWebhooks(comment.Issue.Repo, HookEventIssueComment, &api.IssueCommentPayload{
 | 
				
			||||||
 | 
							Action:     api.HookIssueCommentDeleted,
 | 
				
			||||||
 | 
							Issue:      comment.Issue.APIFormat(),
 | 
				
			||||||
 | 
							Comment:    comment.APIFormat(),
 | 
				
			||||||
 | 
							Repository: comment.Issue.Repo.APIFormat(mode),
 | 
				
			||||||
 | 
							Sender:     doer.APIFormat(),
 | 
				
			||||||
 | 
						}); err != nil {
 | 
				
			||||||
 | 
							log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,9 @@
 | 
				
			|||||||
package models
 | 
					package models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
	api "code.gitea.io/sdk/gitea"
 | 
						api "code.gitea.io/sdk/gitea"
 | 
				
			||||||
@@ -358,7 +361,49 @@ func ChangeMilestoneAssign(issue *Issue, doer *User, oldMilestoneID int64) (err
 | 
				
			|||||||
	if err = changeMilestoneAssign(sess, doer, issue, oldMilestoneID); err != nil {
 | 
						if err = changeMilestoneAssign(sess, doer, issue, oldMilestoneID); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return sess.Commit()
 | 
					
 | 
				
			||||||
 | 
						if err = sess.Commit(); err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("Commit: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var hookAction api.HookIssueAction
 | 
				
			||||||
 | 
						if issue.MilestoneID > 0 {
 | 
				
			||||||
 | 
							hookAction = api.HookIssueMilestoned
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							hookAction = api.HookIssueDemilestoned
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err = issue.LoadAttributes(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mode, _ := AccessLevel(doer.ID, issue.Repo)
 | 
				
			||||||
 | 
						if issue.IsPull {
 | 
				
			||||||
 | 
							err = issue.PullRequest.LoadIssue()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Error(2, "LoadIssue: %v", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
 | 
				
			||||||
 | 
								Action:      hookAction,
 | 
				
			||||||
 | 
								Index:       issue.Index,
 | 
				
			||||||
 | 
								PullRequest: issue.PullRequest.APIFormat(),
 | 
				
			||||||
 | 
								Repository:  issue.Repo.APIFormat(mode),
 | 
				
			||||||
 | 
								Sender:      doer.APIFormat(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
 | 
				
			||||||
 | 
								Action:     hookAction,
 | 
				
			||||||
 | 
								Index:      issue.Index,
 | 
				
			||||||
 | 
								Issue:      issue.APIFormat(),
 | 
				
			||||||
 | 
								Repository: issue.Repo.APIFormat(mode),
 | 
				
			||||||
 | 
								Sender:     doer.APIFormat(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DeleteMilestoneByRepoID deletes a milestone from a repository.
 | 
					// DeleteMilestoneByRepoID deletes a milestone from a repository.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -232,6 +232,8 @@ func TestChangeMilestoneAssign(t *testing.T) {
 | 
				
			|||||||
	assert.NoError(t, PrepareTestDatabase())
 | 
						assert.NoError(t, PrepareTestDatabase())
 | 
				
			||||||
	issue := AssertExistsAndLoadBean(t, &Issue{RepoID: 1}).(*Issue)
 | 
						issue := AssertExistsAndLoadBean(t, &Issue{RepoID: 1}).(*Issue)
 | 
				
			||||||
	doer := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
 | 
						doer := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
 | 
				
			||||||
 | 
						assert.NotNil(t, issue)
 | 
				
			||||||
 | 
						assert.NotNil(t, doer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	oldMilestoneID := issue.MilestoneID
 | 
						oldMilestoneID := issue.MilestoneID
 | 
				
			||||||
	issue.MilestoneID = 2
 | 
						issue.MilestoneID = 2
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/git"
 | 
						"code.gitea.io/git"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/process"
 | 
						"code.gitea.io/gitea/modules/process"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
@@ -190,8 +191,27 @@ func CreateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []stri
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = addReleaseAttachments(rel.ID, attachmentUUIDs)
 | 
						err = addReleaseAttachments(rel.ID, attachmentUUIDs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err
 | 
						if !rel.IsDraft {
 | 
				
			||||||
 | 
							if err := rel.LoadAttributes(); err != nil {
 | 
				
			||||||
 | 
								log.Error(2, "LoadAttributes: %v", err)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								mode, _ := AccessLevel(rel.PublisherID, rel.Repo)
 | 
				
			||||||
 | 
								if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
 | 
				
			||||||
 | 
									Action:     api.HookReleasePublished,
 | 
				
			||||||
 | 
									Release:    rel.APIFormat(),
 | 
				
			||||||
 | 
									Repository: rel.Repo.APIFormat(mode),
 | 
				
			||||||
 | 
									Sender:     rel.Publisher.APIFormat(),
 | 
				
			||||||
 | 
								}); err != nil {
 | 
				
			||||||
 | 
									log.Error(2, "PrepareWebhooks: %v", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetRelease returns release by given ID.
 | 
					// GetRelease returns release by given ID.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2456,6 +2456,17 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						oldMode, _ := AccessLevel(doer.ID, oldRepo)
 | 
				
			||||||
 | 
						mode, _ := AccessLevel(doer.ID, repo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err = PrepareWebhooks(oldRepo, HookEventFork, &api.ForkPayload{
 | 
				
			||||||
 | 
							Forkee: repo.APIFormat(mode),
 | 
				
			||||||
 | 
							Repo:   oldRepo.APIFormat(oldMode),
 | 
				
			||||||
 | 
							Sender: doer.APIFormat(),
 | 
				
			||||||
 | 
						}); err != nil {
 | 
				
			||||||
 | 
							log.Error(2, "PrepareWebhooks [repo_id: %d]: %v", oldRepo.ID, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = repo.UpdateSize(); err != nil {
 | 
						if err = repo.UpdateSize(); err != nil {
 | 
				
			||||||
		log.Error(4, "Failed to update size for repository: %v", err)
 | 
							log.Error(4, "Failed to update size for repository: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,10 +66,15 @@ func IsValidHookContentType(name string) bool {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// HookEvents is a set of web hook events
 | 
					// HookEvents is a set of web hook events
 | 
				
			||||||
type HookEvents struct {
 | 
					type HookEvents struct {
 | 
				
			||||||
	Create      bool `json:"create"`
 | 
						Create       bool `json:"create"`
 | 
				
			||||||
	Push        bool `json:"push"`
 | 
						Delete       bool `json:"delete"`
 | 
				
			||||||
	PullRequest bool `json:"pull_request"`
 | 
						Fork         bool `json:"fork"`
 | 
				
			||||||
	Repository  bool `json:"repository"`
 | 
						Issues       bool `json:"issues"`
 | 
				
			||||||
 | 
						IssueComment bool `json:"issue_comment"`
 | 
				
			||||||
 | 
						Push         bool `json:"push"`
 | 
				
			||||||
 | 
						PullRequest  bool `json:"pull_request"`
 | 
				
			||||||
 | 
						Repository   bool `json:"repository"`
 | 
				
			||||||
 | 
						Release      bool `json:"release"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HookEvent represents events that will delivery hook.
 | 
					// HookEvent represents events that will delivery hook.
 | 
				
			||||||
@@ -155,6 +160,30 @@ func (w *Webhook) HasCreateEvent() bool {
 | 
				
			|||||||
		(w.ChooseEvents && w.HookEvents.Create)
 | 
							(w.ChooseEvents && w.HookEvents.Create)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HasDeleteEvent returns true if hook enabled delete event.
 | 
				
			||||||
 | 
					func (w *Webhook) HasDeleteEvent() bool {
 | 
				
			||||||
 | 
						return w.SendEverything ||
 | 
				
			||||||
 | 
							(w.ChooseEvents && w.HookEvents.Delete)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HasForkEvent returns true if hook enabled fork event.
 | 
				
			||||||
 | 
					func (w *Webhook) HasForkEvent() bool {
 | 
				
			||||||
 | 
						return w.SendEverything ||
 | 
				
			||||||
 | 
							(w.ChooseEvents && w.HookEvents.Fork)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HasIssuesEvent returns true if hook enabled issues event.
 | 
				
			||||||
 | 
					func (w *Webhook) HasIssuesEvent() bool {
 | 
				
			||||||
 | 
						return w.SendEverything ||
 | 
				
			||||||
 | 
							(w.ChooseEvents && w.HookEvents.Issues)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HasIssueCommentEvent returns true if hook enabled issue_comment event.
 | 
				
			||||||
 | 
					func (w *Webhook) HasIssueCommentEvent() bool {
 | 
				
			||||||
 | 
						return w.SendEverything ||
 | 
				
			||||||
 | 
							(w.ChooseEvents && w.HookEvents.IssueComment)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HasPushEvent returns true if hook enabled push event.
 | 
					// HasPushEvent returns true if hook enabled push event.
 | 
				
			||||||
func (w *Webhook) HasPushEvent() bool {
 | 
					func (w *Webhook) HasPushEvent() bool {
 | 
				
			||||||
	return w.PushOnly || w.SendEverything ||
 | 
						return w.PushOnly || w.SendEverything ||
 | 
				
			||||||
@@ -167,23 +196,46 @@ func (w *Webhook) HasPullRequestEvent() bool {
 | 
				
			|||||||
		(w.ChooseEvents && w.HookEvents.PullRequest)
 | 
							(w.ChooseEvents && w.HookEvents.PullRequest)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HasReleaseEvent returns if hook enabled release event.
 | 
				
			||||||
 | 
					func (w *Webhook) HasReleaseEvent() bool {
 | 
				
			||||||
 | 
						return w.SendEverything ||
 | 
				
			||||||
 | 
							(w.ChooseEvents && w.HookEvents.Release)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HasRepositoryEvent returns if hook enabled repository event.
 | 
					// HasRepositoryEvent returns if hook enabled repository event.
 | 
				
			||||||
func (w *Webhook) HasRepositoryEvent() bool {
 | 
					func (w *Webhook) HasRepositoryEvent() bool {
 | 
				
			||||||
	return w.SendEverything ||
 | 
						return w.SendEverything ||
 | 
				
			||||||
		(w.ChooseEvents && w.HookEvents.Repository)
 | 
							(w.ChooseEvents && w.HookEvents.Repository)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (w *Webhook) eventCheckers() []struct {
 | 
				
			||||||
 | 
						has func() bool
 | 
				
			||||||
 | 
						typ HookEventType
 | 
				
			||||||
 | 
					} {
 | 
				
			||||||
 | 
						return []struct {
 | 
				
			||||||
 | 
							has func() bool
 | 
				
			||||||
 | 
							typ HookEventType
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{w.HasCreateEvent, HookEventCreate},
 | 
				
			||||||
 | 
							{w.HasDeleteEvent, HookEventDelete},
 | 
				
			||||||
 | 
							{w.HasForkEvent, HookEventFork},
 | 
				
			||||||
 | 
							{w.HasPushEvent, HookEventPush},
 | 
				
			||||||
 | 
							{w.HasIssuesEvent, HookEventIssues},
 | 
				
			||||||
 | 
							{w.HasIssueCommentEvent, HookEventIssueComment},
 | 
				
			||||||
 | 
							{w.HasPullRequestEvent, HookEventPullRequest},
 | 
				
			||||||
 | 
							{w.HasRepositoryEvent, HookEventRepository},
 | 
				
			||||||
 | 
							{w.HasReleaseEvent, HookEventRelease},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EventsArray returns an array of hook events
 | 
					// EventsArray returns an array of hook events
 | 
				
			||||||
func (w *Webhook) EventsArray() []string {
 | 
					func (w *Webhook) EventsArray() []string {
 | 
				
			||||||
	events := make([]string, 0, 3)
 | 
						events := make([]string, 0, 7)
 | 
				
			||||||
	if w.HasCreateEvent() {
 | 
					
 | 
				
			||||||
		events = append(events, "create")
 | 
						for _, c := range w.eventCheckers() {
 | 
				
			||||||
	}
 | 
							if c.has() {
 | 
				
			||||||
	if w.HasPushEvent() {
 | 
								events = append(events, string(c.typ))
 | 
				
			||||||
		events = append(events, "push")
 | 
							}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if w.HasPullRequestEvent() {
 | 
					 | 
				
			||||||
		events = append(events, "pull_request")
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return events
 | 
						return events
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -373,10 +425,15 @@ type HookEventType string
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Types of hook events
 | 
					// Types of hook events
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	HookEventCreate      HookEventType = "create"
 | 
						HookEventCreate       HookEventType = "create"
 | 
				
			||||||
	HookEventPush        HookEventType = "push"
 | 
						HookEventDelete       HookEventType = "delete"
 | 
				
			||||||
	HookEventPullRequest HookEventType = "pull_request"
 | 
						HookEventFork         HookEventType = "fork"
 | 
				
			||||||
	HookEventRepository  HookEventType = "repository"
 | 
						HookEventPush         HookEventType = "push"
 | 
				
			||||||
 | 
						HookEventIssues       HookEventType = "issues"
 | 
				
			||||||
 | 
						HookEventIssueComment HookEventType = "issue_comment"
 | 
				
			||||||
 | 
						HookEventPullRequest  HookEventType = "pull_request"
 | 
				
			||||||
 | 
						HookEventRepository   HookEventType = "repository"
 | 
				
			||||||
 | 
						HookEventRelease      HookEventType = "release"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HookRequest represents hook task request information.
 | 
					// HookRequest represents hook task request information.
 | 
				
			||||||
@@ -488,22 +545,11 @@ func PrepareWebhook(w *Webhook, repo *Repository, event HookEventType, p api.Pay
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func prepareWebhook(e Engine, w *Webhook, repo *Repository, event HookEventType, p api.Payloader) error {
 | 
					func prepareWebhook(e Engine, w *Webhook, repo *Repository, event HookEventType, p api.Payloader) error {
 | 
				
			||||||
	switch event {
 | 
						for _, e := range w.eventCheckers() {
 | 
				
			||||||
	case HookEventCreate:
 | 
							if event == e.typ {
 | 
				
			||||||
		if !w.HasCreateEvent() {
 | 
								if !e.has() {
 | 
				
			||||||
			return nil
 | 
									return nil
 | 
				
			||||||
		}
 | 
								}
 | 
				
			||||||
	case HookEventPush:
 | 
					 | 
				
			||||||
		if !w.HasPushEvent() {
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	case HookEventPullRequest:
 | 
					 | 
				
			||||||
		if !w.HasPullRequestEvent() {
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	case HookEventRepository:
 | 
					 | 
				
			||||||
		if !w.HasRepositoryEvent() {
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,6 +49,38 @@ func getDingtalkCreatePayload(p *api.CreatePayload) (*DingtalkPayload, error) {
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDingtalkDeletePayload(p *api.DeletePayload) (*DingtalkPayload, error) {
 | 
				
			||||||
 | 
						// created tag/branch
 | 
				
			||||||
 | 
						refName := git.RefEndName(p.Ref)
 | 
				
			||||||
 | 
						title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &DingtalkPayload{
 | 
				
			||||||
 | 
							MsgType: "actionCard",
 | 
				
			||||||
 | 
							ActionCard: dingtalk.ActionCard{
 | 
				
			||||||
 | 
								Text:        title,
 | 
				
			||||||
 | 
								Title:       title,
 | 
				
			||||||
 | 
								HideAvatar:  "0",
 | 
				
			||||||
 | 
								SingleTitle: fmt.Sprintf("view branch %s", refName),
 | 
				
			||||||
 | 
								SingleURL:   p.Repo.HTMLURL + "/src/" + refName,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDingtalkForkPayload(p *api.ForkPayload) (*DingtalkPayload, error) {
 | 
				
			||||||
 | 
						title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &DingtalkPayload{
 | 
				
			||||||
 | 
							MsgType: "actionCard",
 | 
				
			||||||
 | 
							ActionCard: dingtalk.ActionCard{
 | 
				
			||||||
 | 
								Text:        title,
 | 
				
			||||||
 | 
								Title:       title,
 | 
				
			||||||
 | 
								HideAvatar:  "0",
 | 
				
			||||||
 | 
								SingleTitle: fmt.Sprintf("view forked repo %s", p.Repo.FullName),
 | 
				
			||||||
 | 
								SingleURL:   p.Repo.HTMLURL,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getDingtalkPushPayload(p *api.PushPayload) (*DingtalkPayload, error) {
 | 
					func getDingtalkPushPayload(p *api.PushPayload) (*DingtalkPayload, error) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		branchName = git.RefEndName(p.Ref)
 | 
							branchName = git.RefEndName(p.Ref)
 | 
				
			||||||
@@ -98,6 +130,80 @@ func getDingtalkPushPayload(p *api.PushPayload) (*DingtalkPayload, error) {
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDingtalkIssuesPayload(p *api.IssuePayload) (*DingtalkPayload, error) {
 | 
				
			||||||
 | 
						var text, title string
 | 
				
			||||||
 | 
						switch p.Action {
 | 
				
			||||||
 | 
						case api.HookIssueOpened:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue opened: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
						case api.HookIssueClosed:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue closed: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
						case api.HookIssueReOpened:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue re-opened: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
						case api.HookIssueEdited:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue edited: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
						case api.HookIssueAssigned:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue assigned to %s: #%d %s", p.Repository.FullName,
 | 
				
			||||||
 | 
								p.Issue.Assignee.UserName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
						case api.HookIssueUnassigned:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue unassigned: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
						case api.HookIssueLabelUpdated:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Pull request labels updated: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
						case api.HookIssueLabelCleared:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Pull request labels cleared: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
						case api.HookIssueSynchronized:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &DingtalkPayload{
 | 
				
			||||||
 | 
							MsgType: "actionCard",
 | 
				
			||||||
 | 
							ActionCard: dingtalk.ActionCard{
 | 
				
			||||||
 | 
								Text:        text,
 | 
				
			||||||
 | 
								Title:       title,
 | 
				
			||||||
 | 
								HideAvatar:  "0",
 | 
				
			||||||
 | 
								SingleTitle: "view pull request",
 | 
				
			||||||
 | 
								SingleURL:   p.Issue.URL,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDingtalkIssueCommentPayload(p *api.IssueCommentPayload) (*DingtalkPayload, error) {
 | 
				
			||||||
 | 
						title := fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title)
 | 
				
			||||||
 | 
						url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID))
 | 
				
			||||||
 | 
						var content string
 | 
				
			||||||
 | 
						switch p.Action {
 | 
				
			||||||
 | 
						case api.HookIssueCommentCreated:
 | 
				
			||||||
 | 
							title = "New comment: " + title
 | 
				
			||||||
 | 
							content = p.Comment.Body
 | 
				
			||||||
 | 
						case api.HookIssueCommentEdited:
 | 
				
			||||||
 | 
							title = "Comment edited: " + title
 | 
				
			||||||
 | 
							content = p.Comment.Body
 | 
				
			||||||
 | 
						case api.HookIssueCommentDeleted:
 | 
				
			||||||
 | 
							title = "Comment deleted: " + title
 | 
				
			||||||
 | 
							url = fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index)
 | 
				
			||||||
 | 
							content = p.Comment.Body
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &DingtalkPayload{
 | 
				
			||||||
 | 
							MsgType: "actionCard",
 | 
				
			||||||
 | 
							ActionCard: dingtalk.ActionCard{
 | 
				
			||||||
 | 
								Text:        content,
 | 
				
			||||||
 | 
								Title:       title,
 | 
				
			||||||
 | 
								HideAvatar:  "0",
 | 
				
			||||||
 | 
								SingleTitle: "view pull request",
 | 
				
			||||||
 | 
								SingleURL:   url,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getDingtalkPullRequestPayload(p *api.PullRequestPayload) (*DingtalkPayload, error) {
 | 
					func getDingtalkPullRequestPayload(p *api.PullRequestPayload) (*DingtalkPayload, error) {
 | 
				
			||||||
	var text, title string
 | 
						var text, title string
 | 
				
			||||||
	switch p.Action {
 | 
						switch p.Action {
 | 
				
			||||||
@@ -182,6 +288,27 @@ func getDingtalkRepositoryPayload(p *api.RepositoryPayload) (*DingtalkPayload, e
 | 
				
			|||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDingtalkReleasePayload(p *api.ReleasePayload) (*DingtalkPayload, error) {
 | 
				
			||||||
 | 
						var title, url string
 | 
				
			||||||
 | 
						switch p.Action {
 | 
				
			||||||
 | 
						case api.HookReleasePublished:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Release created", p.Release.TagName)
 | 
				
			||||||
 | 
							url = p.Release.URL
 | 
				
			||||||
 | 
							return &DingtalkPayload{
 | 
				
			||||||
 | 
								MsgType: "actionCard",
 | 
				
			||||||
 | 
								ActionCard: dingtalk.ActionCard{
 | 
				
			||||||
 | 
									Text:        title,
 | 
				
			||||||
 | 
									Title:       title,
 | 
				
			||||||
 | 
									HideAvatar:  "0",
 | 
				
			||||||
 | 
									SingleTitle: "view repository",
 | 
				
			||||||
 | 
									SingleURL:   url,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDingtalkPayload converts a ding talk webhook into a DingtalkPayload
 | 
					// GetDingtalkPayload converts a ding talk webhook into a DingtalkPayload
 | 
				
			||||||
func GetDingtalkPayload(p api.Payloader, event HookEventType, meta string) (*DingtalkPayload, error) {
 | 
					func GetDingtalkPayload(p api.Payloader, event HookEventType, meta string) (*DingtalkPayload, error) {
 | 
				
			||||||
	s := new(DingtalkPayload)
 | 
						s := new(DingtalkPayload)
 | 
				
			||||||
@@ -189,12 +316,22 @@ func GetDingtalkPayload(p api.Payloader, event HookEventType, meta string) (*Din
 | 
				
			|||||||
	switch event {
 | 
						switch event {
 | 
				
			||||||
	case HookEventCreate:
 | 
						case HookEventCreate:
 | 
				
			||||||
		return getDingtalkCreatePayload(p.(*api.CreatePayload))
 | 
							return getDingtalkCreatePayload(p.(*api.CreatePayload))
 | 
				
			||||||
 | 
						case HookEventDelete:
 | 
				
			||||||
 | 
							return getDingtalkDeletePayload(p.(*api.DeletePayload))
 | 
				
			||||||
 | 
						case HookEventFork:
 | 
				
			||||||
 | 
							return getDingtalkForkPayload(p.(*api.ForkPayload))
 | 
				
			||||||
 | 
						case HookEventIssues:
 | 
				
			||||||
 | 
							return getDingtalkIssuesPayload(p.(*api.IssuePayload))
 | 
				
			||||||
 | 
						case HookEventIssueComment:
 | 
				
			||||||
 | 
							return getDingtalkIssueCommentPayload(p.(*api.IssueCommentPayload))
 | 
				
			||||||
	case HookEventPush:
 | 
						case HookEventPush:
 | 
				
			||||||
		return getDingtalkPushPayload(p.(*api.PushPayload))
 | 
							return getDingtalkPushPayload(p.(*api.PushPayload))
 | 
				
			||||||
	case HookEventPullRequest:
 | 
						case HookEventPullRequest:
 | 
				
			||||||
		return getDingtalkPullRequestPayload(p.(*api.PullRequestPayload))
 | 
							return getDingtalkPullRequestPayload(p.(*api.PullRequestPayload))
 | 
				
			||||||
	case HookEventRepository:
 | 
						case HookEventRepository:
 | 
				
			||||||
		return getDingtalkRepositoryPayload(p.(*api.RepositoryPayload))
 | 
							return getDingtalkRepositoryPayload(p.(*api.RepositoryPayload))
 | 
				
			||||||
 | 
						case HookEventRelease:
 | 
				
			||||||
 | 
							return getDingtalkReleasePayload(p.(*api.ReleasePayload))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return s, nil
 | 
						return s, nil
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -115,6 +115,51 @@ func getDiscordCreatePayload(p *api.CreatePayload, meta *DiscordMeta) (*DiscordP
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDiscordDeletePayload(p *api.DeletePayload, meta *DiscordMeta) (*DiscordPayload, error) {
 | 
				
			||||||
 | 
						// deleted tag/branch
 | 
				
			||||||
 | 
						refName := git.RefEndName(p.Ref)
 | 
				
			||||||
 | 
						title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &DiscordPayload{
 | 
				
			||||||
 | 
							Username:  meta.Username,
 | 
				
			||||||
 | 
							AvatarURL: meta.IconURL,
 | 
				
			||||||
 | 
							Embeds: []DiscordEmbed{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Title: title,
 | 
				
			||||||
 | 
									URL:   p.Repo.HTMLURL + "/src/" + refName,
 | 
				
			||||||
 | 
									Color: warnColor,
 | 
				
			||||||
 | 
									Author: DiscordEmbedAuthor{
 | 
				
			||||||
 | 
										Name:    p.Sender.UserName,
 | 
				
			||||||
 | 
										URL:     setting.AppURL + p.Sender.UserName,
 | 
				
			||||||
 | 
										IconURL: p.Sender.AvatarURL,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDiscordForkPayload(p *api.ForkPayload, meta *DiscordMeta) (*DiscordPayload, error) {
 | 
				
			||||||
 | 
						// fork
 | 
				
			||||||
 | 
						title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &DiscordPayload{
 | 
				
			||||||
 | 
							Username:  meta.Username,
 | 
				
			||||||
 | 
							AvatarURL: meta.IconURL,
 | 
				
			||||||
 | 
							Embeds: []DiscordEmbed{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Title: title,
 | 
				
			||||||
 | 
									URL:   p.Repo.HTMLURL,
 | 
				
			||||||
 | 
									Color: successColor,
 | 
				
			||||||
 | 
									Author: DiscordEmbedAuthor{
 | 
				
			||||||
 | 
										Name:    p.Sender.UserName,
 | 
				
			||||||
 | 
										URL:     setting.AppURL + p.Sender.UserName,
 | 
				
			||||||
 | 
										IconURL: p.Sender.AvatarURL,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getDiscordPushPayload(p *api.PushPayload, meta *DiscordMeta) (*DiscordPayload, error) {
 | 
					func getDiscordPushPayload(p *api.PushPayload, meta *DiscordMeta) (*DiscordPayload, error) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		branchName = git.RefEndName(p.Ref)
 | 
							branchName = git.RefEndName(p.Ref)
 | 
				
			||||||
@@ -165,6 +210,108 @@ func getDiscordPushPayload(p *api.PushPayload, meta *DiscordMeta) (*DiscordPaylo
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDiscordIssuesPayload(p *api.IssuePayload, meta *DiscordMeta) (*DiscordPayload, error) {
 | 
				
			||||||
 | 
						var text, title string
 | 
				
			||||||
 | 
						var color int
 | 
				
			||||||
 | 
						switch p.Action {
 | 
				
			||||||
 | 
						case api.HookIssueOpened:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue opened: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
							color = warnColor
 | 
				
			||||||
 | 
						case api.HookIssueClosed:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue closed: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							color = failedColor
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
						case api.HookIssueReOpened:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue re-opened: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
							color = warnColor
 | 
				
			||||||
 | 
						case api.HookIssueEdited:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue edited: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
							color = warnColor
 | 
				
			||||||
 | 
						case api.HookIssueAssigned:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue assigned to %s: #%d %s", p.Repository.FullName,
 | 
				
			||||||
 | 
								p.Issue.Assignee.UserName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
							color = successColor
 | 
				
			||||||
 | 
						case api.HookIssueUnassigned:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue unassigned: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
							color = warnColor
 | 
				
			||||||
 | 
						case api.HookIssueLabelUpdated:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue labels updated: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
							color = warnColor
 | 
				
			||||||
 | 
						case api.HookIssueLabelCleared:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue labels cleared: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
							color = warnColor
 | 
				
			||||||
 | 
						case api.HookIssueSynchronized:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
 | 
				
			||||||
 | 
							text = p.Issue.Body
 | 
				
			||||||
 | 
							color = warnColor
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &DiscordPayload{
 | 
				
			||||||
 | 
							Username:  meta.Username,
 | 
				
			||||||
 | 
							AvatarURL: meta.IconURL,
 | 
				
			||||||
 | 
							Embeds: []DiscordEmbed{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Title:       title,
 | 
				
			||||||
 | 
									Description: text,
 | 
				
			||||||
 | 
									URL:         p.Issue.URL,
 | 
				
			||||||
 | 
									Color:       color,
 | 
				
			||||||
 | 
									Author: DiscordEmbedAuthor{
 | 
				
			||||||
 | 
										Name:    p.Sender.UserName,
 | 
				
			||||||
 | 
										URL:     setting.AppURL + p.Sender.UserName,
 | 
				
			||||||
 | 
										IconURL: p.Sender.AvatarURL,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDiscordIssueCommentPayload(p *api.IssueCommentPayload, discord *DiscordMeta) (*DiscordPayload, error) {
 | 
				
			||||||
 | 
						title := fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title)
 | 
				
			||||||
 | 
						url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID))
 | 
				
			||||||
 | 
						content := ""
 | 
				
			||||||
 | 
						var color int
 | 
				
			||||||
 | 
						switch p.Action {
 | 
				
			||||||
 | 
						case api.HookIssueCommentCreated:
 | 
				
			||||||
 | 
							title = "New comment: " + title
 | 
				
			||||||
 | 
							content = p.Comment.Body
 | 
				
			||||||
 | 
							color = successColor
 | 
				
			||||||
 | 
						case api.HookIssueCommentEdited:
 | 
				
			||||||
 | 
							title = "Comment edited: " + title
 | 
				
			||||||
 | 
							content = p.Comment.Body
 | 
				
			||||||
 | 
							color = warnColor
 | 
				
			||||||
 | 
						case api.HookIssueCommentDeleted:
 | 
				
			||||||
 | 
							title = "Comment deleted: " + title
 | 
				
			||||||
 | 
							url = fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index)
 | 
				
			||||||
 | 
							content = p.Comment.Body
 | 
				
			||||||
 | 
							color = warnColor
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &DiscordPayload{
 | 
				
			||||||
 | 
							Username:  discord.Username,
 | 
				
			||||||
 | 
							AvatarURL: discord.IconURL,
 | 
				
			||||||
 | 
							Embeds: []DiscordEmbed{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Title:       title,
 | 
				
			||||||
 | 
									Description: content,
 | 
				
			||||||
 | 
									URL:         url,
 | 
				
			||||||
 | 
									Color:       color,
 | 
				
			||||||
 | 
									Author: DiscordEmbedAuthor{
 | 
				
			||||||
 | 
										Name:    p.Sender.UserName,
 | 
				
			||||||
 | 
										URL:     setting.AppURL + p.Sender.UserName,
 | 
				
			||||||
 | 
										IconURL: p.Sender.AvatarURL,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getDiscordPullRequestPayload(p *api.PullRequestPayload, meta *DiscordMeta) (*DiscordPayload, error) {
 | 
					func getDiscordPullRequestPayload(p *api.PullRequestPayload, meta *DiscordMeta) (*DiscordPayload, error) {
 | 
				
			||||||
	var text, title string
 | 
						var text, title string
 | 
				
			||||||
	var color int
 | 
						var color int
 | 
				
			||||||
@@ -267,6 +414,35 @@ func getDiscordRepositoryPayload(p *api.RepositoryPayload, meta *DiscordMeta) (*
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDiscordReleasePayload(p *api.ReleasePayload, meta *DiscordMeta) (*DiscordPayload, error) {
 | 
				
			||||||
 | 
						var title, url string
 | 
				
			||||||
 | 
						var color int
 | 
				
			||||||
 | 
						switch p.Action {
 | 
				
			||||||
 | 
						case api.HookReleasePublished:
 | 
				
			||||||
 | 
							title = fmt.Sprintf("[%s] Release created", p.Release.TagName)
 | 
				
			||||||
 | 
							url = p.Release.URL
 | 
				
			||||||
 | 
							color = successColor
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &DiscordPayload{
 | 
				
			||||||
 | 
							Username:  meta.Username,
 | 
				
			||||||
 | 
							AvatarURL: meta.IconURL,
 | 
				
			||||||
 | 
							Embeds: []DiscordEmbed{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Title:       title,
 | 
				
			||||||
 | 
									Description: fmt.Sprintf("%s", p.Release.Note),
 | 
				
			||||||
 | 
									URL:         url,
 | 
				
			||||||
 | 
									Color:       color,
 | 
				
			||||||
 | 
									Author: DiscordEmbedAuthor{
 | 
				
			||||||
 | 
										Name:    p.Sender.UserName,
 | 
				
			||||||
 | 
										URL:     setting.AppURL + p.Sender.UserName,
 | 
				
			||||||
 | 
										IconURL: p.Sender.AvatarURL,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDiscordPayload converts a discord webhook into a DiscordPayload
 | 
					// GetDiscordPayload converts a discord webhook into a DiscordPayload
 | 
				
			||||||
func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*DiscordPayload, error) {
 | 
					func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*DiscordPayload, error) {
 | 
				
			||||||
	s := new(DiscordPayload)
 | 
						s := new(DiscordPayload)
 | 
				
			||||||
@@ -279,12 +455,22 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*Disc
 | 
				
			|||||||
	switch event {
 | 
						switch event {
 | 
				
			||||||
	case HookEventCreate:
 | 
						case HookEventCreate:
 | 
				
			||||||
		return getDiscordCreatePayload(p.(*api.CreatePayload), discord)
 | 
							return getDiscordCreatePayload(p.(*api.CreatePayload), discord)
 | 
				
			||||||
 | 
						case HookEventDelete:
 | 
				
			||||||
 | 
							return getDiscordDeletePayload(p.(*api.DeletePayload), discord)
 | 
				
			||||||
 | 
						case HookEventFork:
 | 
				
			||||||
 | 
							return getDiscordForkPayload(p.(*api.ForkPayload), discord)
 | 
				
			||||||
 | 
						case HookEventIssues:
 | 
				
			||||||
 | 
							return getDiscordIssuesPayload(p.(*api.IssuePayload), discord)
 | 
				
			||||||
 | 
						case HookEventIssueComment:
 | 
				
			||||||
 | 
							return getDiscordIssueCommentPayload(p.(*api.IssueCommentPayload), discord)
 | 
				
			||||||
	case HookEventPush:
 | 
						case HookEventPush:
 | 
				
			||||||
		return getDiscordPushPayload(p.(*api.PushPayload), discord)
 | 
							return getDiscordPushPayload(p.(*api.PushPayload), discord)
 | 
				
			||||||
	case HookEventPullRequest:
 | 
						case HookEventPullRequest:
 | 
				
			||||||
		return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), discord)
 | 
							return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), discord)
 | 
				
			||||||
	case HookEventRepository:
 | 
						case HookEventRepository:
 | 
				
			||||||
		return getDiscordRepositoryPayload(p.(*api.RepositoryPayload), discord)
 | 
							return getDiscordRepositoryPayload(p.(*api.RepositoryPayload), discord)
 | 
				
			||||||
 | 
						case HookEventRelease:
 | 
				
			||||||
 | 
							return getDiscordReleasePayload(p.(*api.ReleasePayload), discord)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return s, nil
 | 
						return s, nil
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -106,6 +106,122 @@ func getSlackCreatePayload(p *api.CreatePayload, slack *SlackMeta) (*SlackPayloa
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getSlackDeletePayload composes Slack payload for delete a branch or tag.
 | 
				
			||||||
 | 
					func getSlackDeletePayload(p *api.DeletePayload, slack *SlackMeta) (*SlackPayload, error) {
 | 
				
			||||||
 | 
						refName := git.RefEndName(p.Ref)
 | 
				
			||||||
 | 
						repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
 | 
				
			||||||
 | 
						text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName)
 | 
				
			||||||
 | 
						return &SlackPayload{
 | 
				
			||||||
 | 
							Channel:  slack.Channel,
 | 
				
			||||||
 | 
							Text:     text,
 | 
				
			||||||
 | 
							Username: slack.Username,
 | 
				
			||||||
 | 
							IconURL:  slack.IconURL,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getSlackForkPayload composes Slack payload for forked by a repository.
 | 
				
			||||||
 | 
					func getSlackForkPayload(p *api.ForkPayload, slack *SlackMeta) (*SlackPayload, error) {
 | 
				
			||||||
 | 
						baseLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
 | 
				
			||||||
 | 
						forkLink := SlackLinkFormatter(p.Forkee.HTMLURL, p.Forkee.FullName)
 | 
				
			||||||
 | 
						text := fmt.Sprintf("%s is forked to %s", baseLink, forkLink)
 | 
				
			||||||
 | 
						return &SlackPayload{
 | 
				
			||||||
 | 
							Channel:  slack.Channel,
 | 
				
			||||||
 | 
							Text:     text,
 | 
				
			||||||
 | 
							Username: slack.Username,
 | 
				
			||||||
 | 
							IconURL:  slack.IconURL,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getSlackIssuesPayload(p *api.IssuePayload, slack *SlackMeta) (*SlackPayload, error) {
 | 
				
			||||||
 | 
						senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
 | 
				
			||||||
 | 
						titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index),
 | 
				
			||||||
 | 
							fmt.Sprintf("#%d %s", p.Index, p.Issue.Title))
 | 
				
			||||||
 | 
						var text, title, attachmentText string
 | 
				
			||||||
 | 
						switch p.Action {
 | 
				
			||||||
 | 
						case api.HookIssueOpened:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Issue submitted by %s", p.Repository.FullName, senderLink)
 | 
				
			||||||
 | 
							title = titleLink
 | 
				
			||||||
 | 
							attachmentText = SlackTextFormatter(p.Issue.Body)
 | 
				
			||||||
 | 
						case api.HookIssueClosed:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Issue closed: %s by %s", p.Repository.FullName, titleLink, senderLink)
 | 
				
			||||||
 | 
						case api.HookIssueReOpened:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Issue re-opened: %s by %s", p.Repository.FullName, titleLink, senderLink)
 | 
				
			||||||
 | 
						case api.HookIssueEdited:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Issue edited: %s by %s", p.Repository.FullName, titleLink, senderLink)
 | 
				
			||||||
 | 
							attachmentText = SlackTextFormatter(p.Issue.Body)
 | 
				
			||||||
 | 
						case api.HookIssueAssigned:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Issue assigned to %s: %s by %s", p.Repository.FullName,
 | 
				
			||||||
 | 
								SlackLinkFormatter(setting.AppURL+p.Issue.Assignee.UserName, p.Issue.Assignee.UserName),
 | 
				
			||||||
 | 
								titleLink, senderLink)
 | 
				
			||||||
 | 
						case api.HookIssueUnassigned:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Issue unassigned: %s by %s", p.Repository.FullName, titleLink, senderLink)
 | 
				
			||||||
 | 
						case api.HookIssueLabelUpdated:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Issue labels updated: %s by %s", p.Repository.FullName, titleLink, senderLink)
 | 
				
			||||||
 | 
						case api.HookIssueLabelCleared:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Issue labels cleared: %s by %s", p.Repository.FullName, titleLink, senderLink)
 | 
				
			||||||
 | 
						case api.HookIssueSynchronized:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Issue synchronized: %s by %s", p.Repository.FullName, titleLink, senderLink)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &SlackPayload{
 | 
				
			||||||
 | 
							Channel:  slack.Channel,
 | 
				
			||||||
 | 
							Text:     text,
 | 
				
			||||||
 | 
							Username: slack.Username,
 | 
				
			||||||
 | 
							IconURL:  slack.IconURL,
 | 
				
			||||||
 | 
							Attachments: []SlackAttachment{{
 | 
				
			||||||
 | 
								Color: slack.Color,
 | 
				
			||||||
 | 
								Title: title,
 | 
				
			||||||
 | 
								Text:  attachmentText,
 | 
				
			||||||
 | 
							}},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (*SlackPayload, error) {
 | 
				
			||||||
 | 
						senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
 | 
				
			||||||
 | 
						titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)),
 | 
				
			||||||
 | 
							fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
 | 
				
			||||||
 | 
						var text, title, attachmentText string
 | 
				
			||||||
 | 
						switch p.Action {
 | 
				
			||||||
 | 
						case api.HookIssueCommentCreated:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] New comment created by %s", p.Repository.FullName, senderLink)
 | 
				
			||||||
 | 
							title = titleLink
 | 
				
			||||||
 | 
							attachmentText = SlackTextFormatter(p.Comment.Body)
 | 
				
			||||||
 | 
						case api.HookIssueCommentEdited:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Comment edited by %s", p.Repository.FullName, senderLink)
 | 
				
			||||||
 | 
							title = titleLink
 | 
				
			||||||
 | 
							attachmentText = SlackTextFormatter(p.Comment.Body)
 | 
				
			||||||
 | 
						case api.HookIssueCommentDeleted:
 | 
				
			||||||
 | 
							text = fmt.Sprintf("[%s] Comment deleted by %s", p.Repository.FullName, senderLink)
 | 
				
			||||||
 | 
							title = SlackLinkFormatter(fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index),
 | 
				
			||||||
 | 
								fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
 | 
				
			||||||
 | 
							attachmentText = SlackTextFormatter(p.Comment.Body)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &SlackPayload{
 | 
				
			||||||
 | 
							Channel:  slack.Channel,
 | 
				
			||||||
 | 
							Text:     text,
 | 
				
			||||||
 | 
							Username: slack.Username,
 | 
				
			||||||
 | 
							IconURL:  slack.IconURL,
 | 
				
			||||||
 | 
							Attachments: []SlackAttachment{{
 | 
				
			||||||
 | 
								Color: slack.Color,
 | 
				
			||||||
 | 
								Title: title,
 | 
				
			||||||
 | 
								Text:  attachmentText,
 | 
				
			||||||
 | 
							}},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getSlackReleasePayload(p *api.ReleasePayload, slack *SlackMeta) (*SlackPayload, error) {
 | 
				
			||||||
 | 
						repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.Name)
 | 
				
			||||||
 | 
						refLink := SlackLinkFormatter(p.Repository.HTMLURL+"/src/"+p.Release.TagName, p.Release.TagName)
 | 
				
			||||||
 | 
						text := fmt.Sprintf("[%s] new release %s published by %s", repoLink, refLink, p.Sender.UserName)
 | 
				
			||||||
 | 
						return &SlackPayload{
 | 
				
			||||||
 | 
							Channel:  slack.Channel,
 | 
				
			||||||
 | 
							Text:     text,
 | 
				
			||||||
 | 
							Username: slack.Username,
 | 
				
			||||||
 | 
							IconURL:  slack.IconURL,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) (*SlackPayload, error) {
 | 
					func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) (*SlackPayload, error) {
 | 
				
			||||||
	// n new commits
 | 
						// n new commits
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
@@ -238,12 +354,22 @@ func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (*SlackP
 | 
				
			|||||||
	switch event {
 | 
						switch event {
 | 
				
			||||||
	case HookEventCreate:
 | 
						case HookEventCreate:
 | 
				
			||||||
		return getSlackCreatePayload(p.(*api.CreatePayload), slack)
 | 
							return getSlackCreatePayload(p.(*api.CreatePayload), slack)
 | 
				
			||||||
 | 
						case HookEventDelete:
 | 
				
			||||||
 | 
							return getSlackDeletePayload(p.(*api.DeletePayload), slack)
 | 
				
			||||||
 | 
						case HookEventFork:
 | 
				
			||||||
 | 
							return getSlackForkPayload(p.(*api.ForkPayload), slack)
 | 
				
			||||||
 | 
						case HookEventIssues:
 | 
				
			||||||
 | 
							return getSlackIssuesPayload(p.(*api.IssuePayload), slack)
 | 
				
			||||||
 | 
						case HookEventIssueComment:
 | 
				
			||||||
 | 
							return getSlackIssueCommentPayload(p.(*api.IssueCommentPayload), slack)
 | 
				
			||||||
	case HookEventPush:
 | 
						case HookEventPush:
 | 
				
			||||||
		return getSlackPushPayload(p.(*api.PushPayload), slack)
 | 
							return getSlackPushPayload(p.(*api.PushPayload), slack)
 | 
				
			||||||
	case HookEventPullRequest:
 | 
						case HookEventPullRequest:
 | 
				
			||||||
		return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack)
 | 
							return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack)
 | 
				
			||||||
	case HookEventRepository:
 | 
						case HookEventRepository:
 | 
				
			||||||
		return getSlackRepositoryPayload(p.(*api.RepositoryPayload), slack)
 | 
							return getSlackRepositoryPayload(p.(*api.RepositoryPayload), slack)
 | 
				
			||||||
 | 
						case HookEventRelease:
 | 
				
			||||||
 | 
							return getSlackReleasePayload(p.(*api.ReleasePayload), slack)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return s, nil
 | 
						return s, nil
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,7 +73,7 @@ func TestWebhook_UpdateEvent(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestWebhook_EventsArray(t *testing.T) {
 | 
					func TestWebhook_EventsArray(t *testing.T) {
 | 
				
			||||||
	assert.Equal(t, []string{"create", "push", "pull_request"},
 | 
						assert.Equal(t, []string{"create", "delete", "fork", "push", "issues", "issue_comment", "pull_request", "repository", "release"},
 | 
				
			||||||
		(&Webhook{
 | 
							(&Webhook{
 | 
				
			||||||
			HookEvent: &HookEvent{SendEverything: true},
 | 
								HookEvent: &HookEvent{SendEverything: true},
 | 
				
			||||||
		}).EventsArray(),
 | 
							}).EventsArray(),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -155,12 +155,17 @@ func (f *ProtectBranchForm) Validate(ctx *macaron.Context, errs binding.Errors)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// WebhookForm form for changing web hook
 | 
					// WebhookForm form for changing web hook
 | 
				
			||||||
type WebhookForm struct {
 | 
					type WebhookForm struct {
 | 
				
			||||||
	Events      string
 | 
						Events       string
 | 
				
			||||||
	Create      bool
 | 
						Create       bool
 | 
				
			||||||
	Push        bool
 | 
						Delete       bool
 | 
				
			||||||
	PullRequest bool
 | 
						Fork         bool
 | 
				
			||||||
	Repository  bool
 | 
						Issues       bool
 | 
				
			||||||
	Active      bool
 | 
						IssueComment bool
 | 
				
			||||||
 | 
						Release      bool
 | 
				
			||||||
 | 
						Push         bool
 | 
				
			||||||
 | 
						PullRequest  bool
 | 
				
			||||||
 | 
						Repository   bool
 | 
				
			||||||
 | 
						Active       bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PushOnly if the hook will be triggered when push
 | 
					// PushOnly if the hook will be triggered when push
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1000,6 +1000,16 @@ settings.event_send_everything = All Events
 | 
				
			|||||||
settings.event_choose = Custom Events…
 | 
					settings.event_choose = Custom Events…
 | 
				
			||||||
settings.event_create = Create
 | 
					settings.event_create = Create
 | 
				
			||||||
settings.event_create_desc = Branch or tag created.
 | 
					settings.event_create_desc = Branch or tag created.
 | 
				
			||||||
 | 
					settings.event_delete = Delete
 | 
				
			||||||
 | 
					settings.event_delete_desc = Branch or tag deleted
 | 
				
			||||||
 | 
					settings.event_fork = Fork
 | 
				
			||||||
 | 
					settings.event_fork_desc = Repository forked
 | 
				
			||||||
 | 
					settings.event_issues = Issues
 | 
				
			||||||
 | 
					settings.event_issues_desc = Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
 | 
				
			||||||
 | 
					settings.event_issue_comment = Issue Comment
 | 
				
			||||||
 | 
					settings.event_issue_comment_desc = Issue comment created, edited, or deleted.
 | 
				
			||||||
 | 
					settings.event_release = Release
 | 
				
			||||||
 | 
					settings.event_release_desc = Release published in a repository.
 | 
				
			||||||
settings.event_pull_request = Pull Request
 | 
					settings.event_pull_request = Pull Request
 | 
				
			||||||
settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared or synchronized.
 | 
					settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared or synchronized.
 | 
				
			||||||
settings.event_push = Push
 | 
					settings.event_push = Push
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -261,8 +261,9 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						oldContent := comment.Content
 | 
				
			||||||
	comment.Content = form.Body
 | 
						comment.Content = form.Body
 | 
				
			||||||
	if err := models.UpdateComment(comment); err != nil {
 | 
						if err := models.UpdateComment(ctx.User, comment, oldContent); err != nil {
 | 
				
			||||||
		ctx.Error(500, "UpdateComment", err)
 | 
							ctx.Error(500, "UpdateComment", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -348,7 +349,7 @@ func deleteIssueComment(ctx *context.APIContext) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = models.DeleteComment(comment); err != nil {
 | 
						if err = models.DeleteComment(ctx.User, comment); err != nil {
 | 
				
			||||||
		ctx.Error(500, "DeleteCommentByID", err)
 | 
							ctx.Error(500, "DeleteCommentByID", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,12 +7,13 @@ package utils
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	api "code.gitea.io/sdk/gitea"
 | 
						api "code.gitea.io/sdk/gitea"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/context"
 | 
						"code.gitea.io/gitea/modules/context"
 | 
				
			||||||
	"code.gitea.io/gitea/routers/api/v1/convert"
 | 
						"code.gitea.io/gitea/routers/api/v1/convert"
 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"github.com/Unknwon/com"
 | 
						"github.com/Unknwon/com"
 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetOrgHook get an organization's webhook. If there is an error, write to
 | 
					// GetOrgHook get an organization's webhook. If there is an error, write to
 | 
				
			||||||
@@ -98,9 +99,15 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID
 | 
				
			|||||||
		HookEvent: &models.HookEvent{
 | 
							HookEvent: &models.HookEvent{
 | 
				
			||||||
			ChooseEvents: true,
 | 
								ChooseEvents: true,
 | 
				
			||||||
			HookEvents: models.HookEvents{
 | 
								HookEvents: models.HookEvents{
 | 
				
			||||||
				Create:      com.IsSliceContainsStr(form.Events, string(models.HookEventCreate)),
 | 
									Create:       com.IsSliceContainsStr(form.Events, string(models.HookEventCreate)),
 | 
				
			||||||
				Push:        com.IsSliceContainsStr(form.Events, string(models.HookEventPush)),
 | 
									Delete:       com.IsSliceContainsStr(form.Events, string(models.HookEventDelete)),
 | 
				
			||||||
				PullRequest: com.IsSliceContainsStr(form.Events, string(models.HookEventPullRequest)),
 | 
									Fork:         com.IsSliceContainsStr(form.Events, string(models.HookEventFork)),
 | 
				
			||||||
 | 
									Issues:       com.IsSliceContainsStr(form.Events, string(models.HookEventIssues)),
 | 
				
			||||||
 | 
									IssueComment: com.IsSliceContainsStr(form.Events, string(models.HookEventIssueComment)),
 | 
				
			||||||
 | 
									Push:         com.IsSliceContainsStr(form.Events, string(models.HookEventPush)),
 | 
				
			||||||
 | 
									PullRequest:  com.IsSliceContainsStr(form.Events, string(models.HookEventPullRequest)),
 | 
				
			||||||
 | 
									Repository:   com.IsSliceContainsStr(form.Events, string(models.HookEventRepository)),
 | 
				
			||||||
 | 
									Release:      com.IsSliceContainsStr(form.Events, string(models.HookEventRelease)),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		IsActive:     form.Active,
 | 
							IsActive:     form.Active,
 | 
				
			||||||
@@ -211,6 +218,16 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *models.Webho
 | 
				
			|||||||
	w.Create = com.IsSliceContainsStr(form.Events, string(models.HookEventCreate))
 | 
						w.Create = com.IsSliceContainsStr(form.Events, string(models.HookEventCreate))
 | 
				
			||||||
	w.Push = com.IsSliceContainsStr(form.Events, string(models.HookEventPush))
 | 
						w.Push = com.IsSliceContainsStr(form.Events, string(models.HookEventPush))
 | 
				
			||||||
	w.PullRequest = com.IsSliceContainsStr(form.Events, string(models.HookEventPullRequest))
 | 
						w.PullRequest = com.IsSliceContainsStr(form.Events, string(models.HookEventPullRequest))
 | 
				
			||||||
 | 
						w.Create = com.IsSliceContainsStr(form.Events, string(models.HookEventCreate))
 | 
				
			||||||
 | 
						w.Delete = com.IsSliceContainsStr(form.Events, string(models.HookEventDelete))
 | 
				
			||||||
 | 
						w.Fork = com.IsSliceContainsStr(form.Events, string(models.HookEventFork))
 | 
				
			||||||
 | 
						w.Issues = com.IsSliceContainsStr(form.Events, string(models.HookEventIssues))
 | 
				
			||||||
 | 
						w.IssueComment = com.IsSliceContainsStr(form.Events, string(models.HookEventIssueComment))
 | 
				
			||||||
 | 
						w.Push = com.IsSliceContainsStr(form.Events, string(models.HookEventPush))
 | 
				
			||||||
 | 
						w.PullRequest = com.IsSliceContainsStr(form.Events, string(models.HookEventPullRequest))
 | 
				
			||||||
 | 
						w.Repository = com.IsSliceContainsStr(form.Events, string(models.HookEventRepository))
 | 
				
			||||||
 | 
						w.Release = com.IsSliceContainsStr(form.Events, string(models.HookEventRelease))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := w.UpdateEvent(); err != nil {
 | 
						if err := w.UpdateEvent(); err != nil {
 | 
				
			||||||
		ctx.Error(500, "UpdateEvent", err)
 | 
							ctx.Error(500, "UpdateEvent", err)
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1086,6 +1086,7 @@ func UpdateCommentContent(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						oldContent := comment.Content
 | 
				
			||||||
	comment.Content = ctx.Query("content")
 | 
						comment.Content = ctx.Query("content")
 | 
				
			||||||
	if len(comment.Content) == 0 {
 | 
						if len(comment.Content) == 0 {
 | 
				
			||||||
		ctx.JSON(200, map[string]interface{}{
 | 
							ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
@@ -1093,7 +1094,7 @@ func UpdateCommentContent(ctx *context.Context) {
 | 
				
			|||||||
		})
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err = models.UpdateComment(comment); err != nil {
 | 
						if err = models.UpdateComment(ctx.User, comment, oldContent); err != nil {
 | 
				
			||||||
		ctx.ServerError("UpdateComment", err)
 | 
							ctx.ServerError("UpdateComment", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1119,7 +1120,7 @@ func DeleteComment(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = models.DeleteComment(comment); err != nil {
 | 
						if err = models.DeleteComment(ctx.User, comment); err != nil {
 | 
				
			||||||
		ctx.ServerError("DeleteCommentByID", err)
 | 
							ctx.ServerError("DeleteCommentByID", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,9 +23,9 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	tplHooks      base.TplName = "repo/settings/hooks"
 | 
						tplHooks      base.TplName = "repo/settings/webhook/base"
 | 
				
			||||||
	tplHookNew    base.TplName = "repo/settings/hook_new"
 | 
						tplHookNew    base.TplName = "repo/settings/webhook/new"
 | 
				
			||||||
	tplOrgHookNew base.TplName = "org/settings/hook_new"
 | 
						tplOrgHookNew base.TplName = "org/settings/webhook/new"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Webhooks render web hooks list page
 | 
					// Webhooks render web hooks list page
 | 
				
			||||||
@@ -118,10 +118,15 @@ func ParseHookEvent(form auth.WebhookForm) *models.HookEvent {
 | 
				
			|||||||
		SendEverything: form.SendEverything(),
 | 
							SendEverything: form.SendEverything(),
 | 
				
			||||||
		ChooseEvents:   form.ChooseEvents(),
 | 
							ChooseEvents:   form.ChooseEvents(),
 | 
				
			||||||
		HookEvents: models.HookEvents{
 | 
							HookEvents: models.HookEvents{
 | 
				
			||||||
			Create:      form.Create,
 | 
								Create:       form.Create,
 | 
				
			||||||
			Push:        form.Push,
 | 
								Delete:       form.Delete,
 | 
				
			||||||
			PullRequest: form.PullRequest,
 | 
								Fork:         form.Fork,
 | 
				
			||||||
			Repository:  form.Repository,
 | 
								Issues:       form.Issues,
 | 
				
			||||||
 | 
								IssueComment: form.IssueComment,
 | 
				
			||||||
 | 
								Release:      form.Release,
 | 
				
			||||||
 | 
								Push:         form.Push,
 | 
				
			||||||
 | 
								PullRequest:  form.PullRequest,
 | 
				
			||||||
 | 
								Repository:   form.Repository,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
	{{template "repo/header" .}}
 | 
						{{template "repo/header" .}}
 | 
				
			||||||
	{{template "repo/settings/navbar" .}}
 | 
						{{template "repo/settings/navbar" .}}
 | 
				
			||||||
	<div class="ui container">
 | 
						<div class="ui container">
 | 
				
			||||||
		{{template "repo/settings/hook_list" .}}
 | 
							{{template "repo/settings/webhook/list" .}}
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
{{template "base/footer" .}}
 | 
					{{template "base/footer" .}}
 | 
				
			||||||
@@ -6,6 +6,6 @@
 | 
				
			|||||||
			<label for="payload_url">{{.i18n.Tr "repo.settings.payload_url"}}</label>
 | 
								<label for="payload_url">{{.i18n.Tr "repo.settings.payload_url"}}</label>
 | 
				
			||||||
			<input id="payload_url" name="payload_url" type="url" value="{{.Webhook.URL}}" autofocus required>
 | 
								<input id="payload_url" name="payload_url" type="url" value="{{.Webhook.URL}}" autofocus required>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		{{template "repo/settings/hook_settings" .}}
 | 
							{{template "repo/settings/webhook/settings" .}}
 | 
				
			||||||
	</form>
 | 
						</form>
 | 
				
			||||||
{{end}}
 | 
					{{end}}
 | 
				
			||||||
@@ -14,6 +14,6 @@
 | 
				
			|||||||
			<label for="icon_url">{{.i18n.Tr "repo.settings.discord_icon_url"}}</label>
 | 
								<label for="icon_url">{{.i18n.Tr "repo.settings.discord_icon_url"}}</label>
 | 
				
			||||||
			<input id="icon_url" name="icon_url" value="{{.DiscordHook.IconURL}}" placeholder="e.g. https://example.com/img/favicon.png">
 | 
								<input id="icon_url" name="icon_url" value="{{.DiscordHook.IconURL}}" placeholder="e.g. https://example.com/img/favicon.png">
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		{{template "repo/settings/hook_settings" .}}
 | 
							{{template "repo/settings/webhook/settings" .}}
 | 
				
			||||||
	</form>
 | 
						</form>
 | 
				
			||||||
{{end}}
 | 
					{{end}}
 | 
				
			||||||
@@ -23,6 +23,6 @@
 | 
				
			|||||||
			<label for="secret">{{.i18n.Tr "repo.settings.secret"}}</label>
 | 
								<label for="secret">{{.i18n.Tr "repo.settings.secret"}}</label>
 | 
				
			||||||
			<input id="secret" name="secret" type="password" value="{{.Webhook.Secret}}" autocomplete="off">
 | 
								<input id="secret" name="secret" type="password" value="{{.Webhook.Secret}}" autocomplete="off">
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		{{template "repo/settings/hook_settings" .}}
 | 
							{{template "repo/settings/webhook/settings" .}}
 | 
				
			||||||
	</form>
 | 
						</form>
 | 
				
			||||||
{{end}}
 | 
					{{end}}
 | 
				
			||||||
@@ -23,6 +23,6 @@
 | 
				
			|||||||
			<label for="secret">{{.i18n.Tr "repo.settings.secret"}}</label>
 | 
								<label for="secret">{{.i18n.Tr "repo.settings.secret"}}</label>
 | 
				
			||||||
			<input id="secret" name="secret" type="password" value="{{.Webhook.Secret}}" autocomplete="off">
 | 
								<input id="secret" name="secret" type="password" value="{{.Webhook.Secret}}" autocomplete="off">
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		{{template "repo/settings/hook_settings" .}}
 | 
							{{template "repo/settings/webhook/settings" .}}
 | 
				
			||||||
	</form>
 | 
						</form>
 | 
				
			||||||
{{end}}
 | 
					{{end}}
 | 
				
			||||||
@@ -48,4 +48,4 @@
 | 
				
			|||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{template "repo/settings/hook_delete_modal" .}}
 | 
					{{template "repo/settings/webhook/delete_modal" .}}
 | 
				
			||||||
@@ -21,14 +21,14 @@
 | 
				
			|||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</h4>
 | 
							</h4>
 | 
				
			||||||
		<div class="ui attached segment">
 | 
							<div class="ui attached segment">
 | 
				
			||||||
			{{template "repo/settings/hook_gitea" .}}
 | 
								{{template "repo/settings/webhook/gitea" .}}
 | 
				
			||||||
			{{template "repo/settings/hook_gogs" .}}
 | 
								{{template "repo/settings/webhook/gogs" .}}
 | 
				
			||||||
			{{template "repo/settings/hook_slack" .}}
 | 
								{{template "repo/settings/webhook/slack" .}}
 | 
				
			||||||
			{{template "repo/settings/hook_discord" .}}
 | 
								{{template "repo/settings/webhook/discord" .}}
 | 
				
			||||||
			{{template "repo/settings/hook_dingtalk" .}}
 | 
								{{template "repo/settings/webhook/dingtalk" .}}
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		{{template "repo/settings/hook_history" .}}
 | 
							{{template "repo/settings/webhook/history" .}}
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
{{template "base/footer" .}}
 | 
					{{template "base/footer" .}}
 | 
				
			||||||
@@ -32,6 +32,26 @@
 | 
				
			|||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 | 
							<!-- Delete -->
 | 
				
			||||||
 | 
							<div class="seven wide column">
 | 
				
			||||||
 | 
								<div class="field">
 | 
				
			||||||
 | 
									<div class="ui checkbox">
 | 
				
			||||||
 | 
										<input class="hidden" name="delete" type="checkbox" tabindex="0" {{if .Webhook.Delete}}checked{{end}}>
 | 
				
			||||||
 | 
										<label>{{.i18n.Tr "repo.settings.event_delete"}}</label>
 | 
				
			||||||
 | 
										<span class="help">{{.i18n.Tr "repo.settings.event_delete_desc"}}</span>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
							<!-- Fork -->
 | 
				
			||||||
 | 
							<div class="seven wide column">
 | 
				
			||||||
 | 
								<div class="field">
 | 
				
			||||||
 | 
									<div class="ui checkbox">
 | 
				
			||||||
 | 
										<input class="hidden" name="fork" type="checkbox" tabindex="0" {{if .Webhook.Fork}}checked{{end}}>
 | 
				
			||||||
 | 
										<label>{{.i18n.Tr "repo.settings.event_fork"}}</label>
 | 
				
			||||||
 | 
										<span class="help">{{.i18n.Tr "repo.settings.event_fork_desc"}}</span>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
		<!-- Push -->
 | 
							<!-- Push -->
 | 
				
			||||||
		<div class="seven wide column">
 | 
							<div class="seven wide column">
 | 
				
			||||||
			<div class="field">
 | 
								<div class="field">
 | 
				
			||||||
@@ -42,6 +62,26 @@
 | 
				
			|||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 | 
							<!-- Issues -->
 | 
				
			||||||
 | 
							<div class="seven wide column">
 | 
				
			||||||
 | 
								<div class="field">
 | 
				
			||||||
 | 
									<div class="ui checkbox">
 | 
				
			||||||
 | 
										<input class="hidden" name="issues" type="checkbox" tabindex="0" {{if .Webhook.Issues}}checked{{end}}>
 | 
				
			||||||
 | 
										<label>{{.i18n.Tr "repo.settings.event_issues"}}</label>
 | 
				
			||||||
 | 
										<span class="help">{{.i18n.Tr "repo.settings.event_issues_desc"}}</span>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
							<!-- Issue Comment -->
 | 
				
			||||||
 | 
							<div class="seven wide column">
 | 
				
			||||||
 | 
								<div class="field">
 | 
				
			||||||
 | 
									<div class="ui checkbox">
 | 
				
			||||||
 | 
										<input class="hidden" name="issue_comment" type="checkbox" tabindex="0" {{if .Webhook.IssueComment}}checked{{end}}>
 | 
				
			||||||
 | 
										<label>{{.i18n.Tr "repo.settings.event_issue_comment"}}</label>
 | 
				
			||||||
 | 
										<span class="help">{{.i18n.Tr "repo.settings.event_issue_comment_desc"}}</span>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
		<!-- Pull Request -->
 | 
							<!-- Pull Request -->
 | 
				
			||||||
		<div class="seven wide column">
 | 
							<div class="seven wide column">
 | 
				
			||||||
			<div class="field">
 | 
								<div class="field">
 | 
				
			||||||
@@ -62,6 +102,16 @@
 | 
				
			|||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 | 
							<!-- Release -->
 | 
				
			||||||
 | 
							<div class="seven wide column">
 | 
				
			||||||
 | 
								<div class="field">
 | 
				
			||||||
 | 
									<div class="ui checkbox">
 | 
				
			||||||
 | 
										<input class="hidden" name="release" type="checkbox" tabindex="0" {{if .Webhook.Release}}checked{{end}}>
 | 
				
			||||||
 | 
										<label>{{.i18n.Tr "repo.settings.event_release"}}</label>
 | 
				
			||||||
 | 
										<span class="help">{{.i18n.Tr "repo.settings.event_release_desc"}}</span>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -83,4 +133,4 @@
 | 
				
			|||||||
	{{end}}
 | 
						{{end}}
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{template "repo/settings/hook_delete_modal" .}}
 | 
					{{template "repo/settings/webhook/delete_modal" .}}
 | 
				
			||||||
@@ -23,6 +23,6 @@
 | 
				
			|||||||
			<label for="color">{{.i18n.Tr "repo.settings.slack_color"}}</label>
 | 
								<label for="color">{{.i18n.Tr "repo.settings.slack_color"}}</label>
 | 
				
			||||||
			<input id="color" name="color" value="{{.SlackHook.Color}}" placeholder="e.g. #dd4b39, good, warning, danger">
 | 
								<input id="color" name="color" value="{{.SlackHook.Color}}" placeholder="e.g. #dd4b39, good, warning, danger">
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		{{template "repo/settings/hook_settings" .}}
 | 
							{{template "repo/settings/webhook/settings" .}}
 | 
				
			||||||
	</form>
 | 
						</form>
 | 
				
			||||||
{{end}}
 | 
					{{end}}
 | 
				
			||||||
							
								
								
									
										122
									
								
								vendor/code.gitea.io/sdk/gitea/hook.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										122
									
								
								vendor/code.gitea.io/sdk/gitea/hook.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -172,9 +172,14 @@ type PayloadCommitVerification struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	_ Payloader = &CreatePayload{}
 | 
						_ Payloader = &CreatePayload{}
 | 
				
			||||||
 | 
						_ Payloader = &DeletePayload{}
 | 
				
			||||||
 | 
						_ Payloader = &ForkPayload{}
 | 
				
			||||||
	_ Payloader = &PushPayload{}
 | 
						_ Payloader = &PushPayload{}
 | 
				
			||||||
	_ Payloader = &IssuePayload{}
 | 
						_ Payloader = &IssuePayload{}
 | 
				
			||||||
 | 
						_ Payloader = &IssueCommentPayload{}
 | 
				
			||||||
	_ Payloader = &PullRequestPayload{}
 | 
						_ Payloader = &PullRequestPayload{}
 | 
				
			||||||
 | 
						_ Payloader = &RepositoryPayload{}
 | 
				
			||||||
 | 
						_ Payloader = &ReleasePayload{}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// _________                        __
 | 
					// _________                        __
 | 
				
			||||||
@@ -224,6 +229,123 @@ func ParseCreateHook(raw []byte) (*CreatePayload, error) {
 | 
				
			|||||||
	return hook, nil
 | 
						return hook, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ________         .__          __
 | 
				
			||||||
 | 
					// \______ \   ____ |  |   _____/  |_  ____
 | 
				
			||||||
 | 
					//  |    |  \_/ __ \|  | _/ __ \   __\/ __ \
 | 
				
			||||||
 | 
					//  |    `   \  ___/|  |_\  ___/|  | \  ___/
 | 
				
			||||||
 | 
					// /_______  /\___  >____/\___  >__|  \___  >
 | 
				
			||||||
 | 
					//         \/     \/          \/          \/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PusherType define the type to push
 | 
				
			||||||
 | 
					type PusherType string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// describe all the PusherTypes
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						PusherTypeUser PusherType = "user"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeletePayload represents delete payload
 | 
				
			||||||
 | 
					type DeletePayload struct {
 | 
				
			||||||
 | 
						Ref        string      `json:"ref"`
 | 
				
			||||||
 | 
						RefType    string      `json:"ref_type"`
 | 
				
			||||||
 | 
						PusherType PusherType  `json:"pusher_type"`
 | 
				
			||||||
 | 
						Repo       *Repository `json:"repository"`
 | 
				
			||||||
 | 
						Sender     *User       `json:"sender"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetSecret implements Payload
 | 
				
			||||||
 | 
					func (p *DeletePayload) SetSecret(secret string) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JSONPayload implements Payload
 | 
				
			||||||
 | 
					func (p *DeletePayload) JSONPayload() ([]byte, error) {
 | 
				
			||||||
 | 
						return json.MarshalIndent(p, "", "  ")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ___________           __
 | 
				
			||||||
 | 
					// \_   _____/__________|  | __
 | 
				
			||||||
 | 
					//  |    __)/  _ \_  __ \  |/ /
 | 
				
			||||||
 | 
					//  |     \(  <_> )  | \/    <
 | 
				
			||||||
 | 
					//  \___  / \____/|__|  |__|_ \
 | 
				
			||||||
 | 
					//      \/                   \/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ForkPayload represents fork payload
 | 
				
			||||||
 | 
					type ForkPayload struct {
 | 
				
			||||||
 | 
						Forkee *Repository `json:"forkee"`
 | 
				
			||||||
 | 
						Repo   *Repository `json:"repository"`
 | 
				
			||||||
 | 
						Sender *User       `json:"sender"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetSecret implements Payload
 | 
				
			||||||
 | 
					func (p *ForkPayload) SetSecret(secret string) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JSONPayload implements Payload
 | 
				
			||||||
 | 
					func (p *ForkPayload) JSONPayload() ([]byte, error) {
 | 
				
			||||||
 | 
						return json.MarshalIndent(p, "", "  ")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HookIssueCommentAction defines hook issue comment action
 | 
				
			||||||
 | 
					type HookIssueCommentAction string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// all issue comment actions
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						HookIssueCommentCreated HookIssueCommentAction = "created"
 | 
				
			||||||
 | 
						HookIssueCommentEdited  HookIssueCommentAction = "edited"
 | 
				
			||||||
 | 
						HookIssueCommentDeleted HookIssueCommentAction = "deleted"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IssueCommentPayload represents a payload information of issue comment event.
 | 
				
			||||||
 | 
					type IssueCommentPayload struct {
 | 
				
			||||||
 | 
						Action     HookIssueCommentAction `json:"action"`
 | 
				
			||||||
 | 
						Issue      *Issue                 `json:"issue"`
 | 
				
			||||||
 | 
						Comment    *Comment               `json:"comment"`
 | 
				
			||||||
 | 
						Changes    *ChangesPayload        `json:"changes,omitempty"`
 | 
				
			||||||
 | 
						Repository *Repository            `json:"repository"`
 | 
				
			||||||
 | 
						Sender     *User                  `json:"sender"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetSecret implements Payload
 | 
				
			||||||
 | 
					func (p *IssueCommentPayload) SetSecret(secret string) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JSONPayload implements Payload
 | 
				
			||||||
 | 
					func (p *IssueCommentPayload) JSONPayload() ([]byte, error) {
 | 
				
			||||||
 | 
						return json.MarshalIndent(p, "", "  ")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// __________       .__
 | 
				
			||||||
 | 
					// \______   \ ____ |  |   ____ _____    ______ ____
 | 
				
			||||||
 | 
					//  |       _// __ \|  | _/ __ \\__  \  /  ___// __ \
 | 
				
			||||||
 | 
					//  |    |   \  ___/|  |_\  ___/ / __ \_\___ \\  ___/
 | 
				
			||||||
 | 
					//  |____|_  /\___  >____/\___  >____  /____  >\___  >
 | 
				
			||||||
 | 
					//         \/     \/          \/     \/     \/     \/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HookReleaseAction defines hook release action type
 | 
				
			||||||
 | 
					type HookReleaseAction string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// all release actions
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						HookReleasePublished HookReleaseAction = "published"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ReleasePayload represents a payload information of release event.
 | 
				
			||||||
 | 
					type ReleasePayload struct {
 | 
				
			||||||
 | 
						Action     HookReleaseAction `json:"action"`
 | 
				
			||||||
 | 
						Release    *Release          `json:"release"`
 | 
				
			||||||
 | 
						Repository *Repository       `json:"repository"`
 | 
				
			||||||
 | 
						Sender     *User             `json:"sender"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetSecret implements Payload
 | 
				
			||||||
 | 
					func (p *ReleasePayload) SetSecret(secret string) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JSONPayload implements Payload
 | 
				
			||||||
 | 
					func (p *ReleasePayload) JSONPayload() ([]byte, error) {
 | 
				
			||||||
 | 
						return json.MarshalIndent(p, "", "  ")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// __________             .__
 | 
					// __________             .__
 | 
				
			||||||
// \______   \__ __  _____|  |__
 | 
					// \______   \__ __  _____|  |__
 | 
				
			||||||
//  |     ___/  |  \/  ___/  |  \
 | 
					//  |     ___/  |  \/  ___/  |  \
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								vendor/code.gitea.io/sdk/gitea/issue.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								vendor/code.gitea.io/sdk/gitea/issue.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -118,14 +118,14 @@ func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// EditIssueOption options for editing an issue
 | 
					// EditIssueOption options for editing an issue
 | 
				
			||||||
type EditIssueOption struct {
 | 
					type EditIssueOption struct {
 | 
				
			||||||
	Title     string     `json:"title"`
 | 
						Title     string   `json:"title"`
 | 
				
			||||||
	Body      *string    `json:"body"`
 | 
						Body      *string  `json:"body"`
 | 
				
			||||||
	Assignee  *string    `json:"assignee"`
 | 
						Assignee  *string  `json:"assignee"`
 | 
				
			||||||
	Assignees []string   `json:"assignees"`
 | 
						Assignees []string `json:"assignees"`
 | 
				
			||||||
	Milestone *int64     `json:"milestone"`
 | 
						Milestone *int64   `json:"milestone"`
 | 
				
			||||||
	State     *string    `json:"state"`
 | 
						State     *string  `json:"state"`
 | 
				
			||||||
	// swagger:strfmt date-time
 | 
						// swagger:strfmt date-time
 | 
				
			||||||
	Deadline  *time.Time `json:"due_date"`
 | 
						Deadline *time.Time `json:"due_date"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EditIssue modify an existing issue for a given repository
 | 
					// EditIssue modify an existing issue for a given repository
 | 
				
			||||||
@@ -138,3 +138,17 @@ func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption)
 | 
				
			|||||||
	return issue, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index),
 | 
						return issue, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index),
 | 
				
			||||||
		jsonHeader, bytes.NewReader(body), issue)
 | 
							jsonHeader, bytes.NewReader(body), issue)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// EditDeadlineOption options for creating a deadline
 | 
				
			||||||
 | 
					type EditDeadlineOption struct {
 | 
				
			||||||
 | 
						// required:true
 | 
				
			||||||
 | 
						// swagger:strfmt date-time
 | 
				
			||||||
 | 
						Deadline *time.Time `json:"due_date"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IssueDeadline represents an issue deadline
 | 
				
			||||||
 | 
					// swagger:model
 | 
				
			||||||
 | 
					type IssueDeadline struct {
 | 
				
			||||||
 | 
						// swagger:strfmt date-time
 | 
				
			||||||
 | 
						Deadline *time.Time `json:"due_date"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								vendor/code.gitea.io/sdk/gitea/pull.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/code.gitea.io/sdk/gitea/pull.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -85,16 +85,16 @@ func (c *Client) GetPullRequest(owner, repo string, index int64) (*PullRequest,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// CreatePullRequestOption options when creating a pull request
 | 
					// CreatePullRequestOption options when creating a pull request
 | 
				
			||||||
type CreatePullRequestOption struct {
 | 
					type CreatePullRequestOption struct {
 | 
				
			||||||
	Head      string     `json:"head" binding:"Required"`
 | 
						Head      string   `json:"head" binding:"Required"`
 | 
				
			||||||
	Base      string     `json:"base" binding:"Required"`
 | 
						Base      string   `json:"base" binding:"Required"`
 | 
				
			||||||
	Title     string     `json:"title" binding:"Required"`
 | 
						Title     string   `json:"title" binding:"Required"`
 | 
				
			||||||
	Body      string     `json:"body"`
 | 
						Body      string   `json:"body"`
 | 
				
			||||||
	Assignee  string     `json:"assignee"`
 | 
						Assignee  string   `json:"assignee"`
 | 
				
			||||||
	Assignees []string   `json:"assignees"`
 | 
						Assignees []string `json:"assignees"`
 | 
				
			||||||
	Milestone int64      `json:"milestone"`
 | 
						Milestone int64    `json:"milestone"`
 | 
				
			||||||
	Labels    []int64    `json:"labels"`
 | 
						Labels    []int64  `json:"labels"`
 | 
				
			||||||
	// swagger:strfmt date-time
 | 
						// swagger:strfmt date-time
 | 
				
			||||||
	Deadline  *time.Time `json:"due_date"`
 | 
						Deadline *time.Time `json:"due_date"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreatePullRequest create pull request with options
 | 
					// CreatePullRequest create pull request with options
 | 
				
			||||||
@@ -110,15 +110,15 @@ func (c *Client) CreatePullRequest(owner, repo string, opt CreatePullRequestOpti
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// EditPullRequestOption options when modify pull request
 | 
					// EditPullRequestOption options when modify pull request
 | 
				
			||||||
type EditPullRequestOption struct {
 | 
					type EditPullRequestOption struct {
 | 
				
			||||||
	Title     string     `json:"title"`
 | 
						Title     string   `json:"title"`
 | 
				
			||||||
	Body      string     `json:"body"`
 | 
						Body      string   `json:"body"`
 | 
				
			||||||
	Assignee  string     `json:"assignee"`
 | 
						Assignee  string   `json:"assignee"`
 | 
				
			||||||
	Assignees []string   `json:"assignees"`
 | 
						Assignees []string `json:"assignees"`
 | 
				
			||||||
	Milestone int64      `json:"milestone"`
 | 
						Milestone int64    `json:"milestone"`
 | 
				
			||||||
	Labels    []int64    `json:"labels"`
 | 
						Labels    []int64  `json:"labels"`
 | 
				
			||||||
	State     *string    `json:"state"`
 | 
						State     *string  `json:"state"`
 | 
				
			||||||
	// swagger:strfmt date-time
 | 
						// swagger:strfmt date-time
 | 
				
			||||||
	Deadline  *time.Time `json:"due_date"`
 | 
						Deadline *time.Time `json:"due_date"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EditPullRequest modify pull request with PR id and options
 | 
					// EditPullRequest modify pull request with PR id and options
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								vendor/vendor.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/vendor.json
									
									
									
									
										vendored
									
									
								
							@@ -9,10 +9,10 @@
 | 
				
			|||||||
			"revisionTime": "2018-04-21T01:08:19Z"
 | 
								"revisionTime": "2018-04-21T01:08:19Z"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"checksumSHA1": "WMD6+Qh2+5hd9uiq910pF/Ihylw=",
 | 
								"checksumSHA1": "LnxY/6xD4h9dCCJ5nxKEfZZs1Vk=",
 | 
				
			||||||
			"path": "code.gitea.io/sdk/gitea",
 | 
								"path": "code.gitea.io/sdk/gitea",
 | 
				
			||||||
			"revision": "1c8d12f79a51605ed91587aa6b86cf38fc0f987f",
 | 
								"revision": "7fa627fa5d67d18c39d6dd3c6c4db836916bf234",
 | 
				
			||||||
			"revisionTime": "2018-05-01T11:15:19Z"
 | 
								"revisionTime": "2018-05-10T12:54:05Z"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"checksumSHA1": "bOODD4Gbw3GfcuQPU2dI40crxxk=",
 | 
								"checksumSHA1": "bOODD4Gbw3GfcuQPU2dI40crxxk=",
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user