Fix some webhooks bugs (#3981)

* fix some webhooks bugs

* update vendor

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>

* fix test

* fix clearlabels

* fix pullrequest webhook bug fix #3492

* update release webhook description

* remove unused code

* fix push webhook in pull request

* small changes
This commit is contained in:
Lunny Xiao 2018-05-21 10:28:29 +08:00 committed by GitHub
parent dc0ef38950
commit 6bdc556b7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 277 additions and 45 deletions

View file

@ -370,11 +370,19 @@ func (issue *Issue) HasLabel(labelID int64) bool {
func (issue *Issue) sendLabelUpdatedWebhook(doer *User) { func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
var err error var err error
if issue.IsPull {
if err = issue.loadRepo(x); err != nil { if err = issue.loadRepo(x); err != nil {
log.Error(4, "loadRepo: %v", err) log.Error(4, "loadRepo: %v", err)
return return
} }
if err = issue.loadPoster(x); err != nil {
log.Error(4, "loadPoster: %v", err)
return
}
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull {
if err = issue.loadPullRequest(x); err != nil { if err = issue.loadPullRequest(x); err != nil {
log.Error(4, "loadPullRequest: %v", err) log.Error(4, "loadPullRequest: %v", err)
return return
@ -390,6 +398,14 @@ func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
Repository: issue.Repo.APIFormat(AccessModeNone), Repository: issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}) })
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueLabelUpdated,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} }
if err != nil { if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err) log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
@ -505,6 +521,11 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
return fmt.Errorf("Commit: %v", err) return fmt.Errorf("Commit: %v", err)
} }
if err = issue.loadPoster(x); err != nil {
return fmt.Errorf("loadPoster: %v", err)
}
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
err = issue.PullRequest.LoadIssue() err = issue.PullRequest.LoadIssue()
if err != nil { if err != nil {
@ -515,7 +536,15 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
Action: api.HookIssueLabelCleared, Action: api.HookIssueLabelCleared,
Index: issue.Index, Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(), PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone), Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueLabelCleared,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}) })
} }
@ -675,13 +704,14 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
return fmt.Errorf("Commit: %v", err) return fmt.Errorf("Commit: %v", err)
} }
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
// Merge pull request calls issue.changeStatus so we need to handle separately. // Merge pull request calls issue.changeStatus so we need to handle separately.
issue.PullRequest.Issue = issue issue.PullRequest.Issue = issue
apiPullRequest := &api.PullRequestPayload{ apiPullRequest := &api.PullRequestPayload{
Index: issue.Index, Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(), PullRequest: issue.PullRequest.APIFormat(),
Repository: repo.APIFormat(AccessModeNone), Repository: repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
} }
if isClosed { if isClosed {
@ -690,6 +720,19 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
apiPullRequest.Action = api.HookIssueReOpened apiPullRequest.Action = api.HookIssueReOpened
} }
err = PrepareWebhooks(repo, HookEventPullRequest, apiPullRequest) err = PrepareWebhooks(repo, HookEventPullRequest, apiPullRequest)
} else {
apiIssue := &api.IssuePayload{
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: repo.APIFormat(mode),
Sender: doer.APIFormat(),
}
if isClosed {
apiIssue.Action = api.HookIssueClosed
} else {
apiIssue.Action = api.HookIssueReOpened
}
err = PrepareWebhooks(repo, HookEventIssues, apiIssue)
} }
if err != nil { if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err) log.Error(4, "PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err)
@ -723,6 +766,7 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
return err return err
} }
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
issue.PullRequest.Issue = issue issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{ err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
@ -734,10 +778,24 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
}, },
}, },
PullRequest: issue.PullRequest.APIFormat(), PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone), Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}) })
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueEdited,
Index: issue.Index,
Changes: &api.ChangesPayload{
Title: &api.ChangesFromPayload{
From: oldTitle,
},
},
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: issue.Poster.APIFormat(),
})
} }
if err != nil { if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err) log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
} else { } else {
@ -774,6 +832,7 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
return fmt.Errorf("UpdateIssueCols: %v", err) return fmt.Errorf("UpdateIssueCols: %v", err)
} }
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
issue.PullRequest.Issue = issue issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{ err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
@ -785,7 +844,20 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
}, },
}, },
PullRequest: issue.PullRequest.APIFormat(), PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone), Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueEdited,
Index: issue.Index,
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
From: oldContent,
},
},
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}) })
} }
@ -980,6 +1052,19 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []in
log.Error(4, "MailParticipants: %v", err) log.Error(4, "MailParticipants: %v", err)
} }
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if err = PrepareWebhooks(repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueOpened,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: repo.APIFormat(mode),
Sender: issue.Poster.APIFormat(),
}); err != nil {
log.Error(4, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(issue.RepoID)
}
return nil return nil
} }

View file

@ -159,12 +159,16 @@ func (issue *Issue) changeAssignee(sess *xorm.Session, doer *User, assigneeID in
return fmt.Errorf("createAssigneeComment: %v", err) return fmt.Errorf("createAssigneeComment: %v", err)
} }
mode, _ := accessLevel(sess, doer.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
issue.PullRequest = &PullRequest{Issue: issue} if err = issue.loadPullRequest(sess); err != nil {
return fmt.Errorf("loadPullRequest: %v", err)
}
issue.PullRequest.Issue = issue
apiPullRequest := &api.PullRequestPayload{ apiPullRequest := &api.PullRequestPayload{
Index: issue.Index, Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(), PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone), Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
} }
if removed { if removed {
@ -172,7 +176,23 @@ func (issue *Issue) changeAssignee(sess *xorm.Session, doer *User, assigneeID in
} else { } else {
apiPullRequest.Action = api.HookIssueAssigned apiPullRequest.Action = api.HookIssueAssigned
} }
if err := PrepareWebhooks(issue.Repo, HookEventPullRequest, apiPullRequest); err != nil { if err := prepareWebhooks(sess, issue.Repo, HookEventPullRequest, apiPullRequest); err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err)
return nil
}
} else {
apiIssue := &api.IssuePayload{
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
}
if removed {
apiIssue.Action = api.HookIssueUnassigned
} else {
apiIssue.Action = api.HookIssueAssigned
}
if err := prepareWebhooks(sess, issue.Repo, HookEventIssues, apiIssue); err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err) log.Error(4, "PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err)
return nil return nil
} }

View file

@ -612,6 +612,8 @@ func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content stri
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}); err != nil { }); err != nil {
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err) log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
} else {
go HookQueue.Add(repo.ID)
} }
return comment, nil return comment, nil
} }
@ -754,6 +756,8 @@ func UpdateComment(doer *User, c *Comment, oldContent string) error {
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}); err != nil { }); err != nil {
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", c.ID, err) log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", c.ID, err)
} else {
go HookQueue.Add(c.Issue.Repo.ID)
} }
return nil return nil
@ -805,6 +809,8 @@ func DeleteComment(doer *User, comment *Comment) error {
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}); err != nil { }); err != nil {
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err) log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
} else {
go HookQueue.Add(comment.Issue.Repo.ID)
} }
return nil return nil

View file

@ -402,6 +402,8 @@ func ChangeMilestoneAssign(issue *Issue, doer *User, oldMilestoneID int64) (err
} }
if err != nil { if err != nil {
log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err) log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
} else {
go HookQueue.Add(issue.RepoID)
} }
return nil return nil
} }

View file

@ -54,28 +54,30 @@ func newIssueUsers(e Engine, repo *Repository, issue *Issue) error {
func updateIssueAssignee(e *xorm.Session, issue *Issue, assigneeID int64) (removed bool, err error) { func updateIssueAssignee(e *xorm.Session, issue *Issue, assigneeID int64) (removed bool, err error) {
// Check if the user exists // Check if the user exists
_, err = GetUserByID(assigneeID) assignee, err := GetUserByID(assigneeID)
if err != nil { if err != nil {
return false, err return false, err
} }
// Check if the submitted user is already assigne, if yes delete him otherwise add him // Check if the submitted user is already assigne, if yes delete him otherwise add him
var toBeDeleted bool var i int
for _, assignee := range issue.Assignees { for i = 0; i < len(issue.Assignees); i++ {
if assignee.ID == assigneeID { if issue.Assignees[i].ID == assigneeID {
toBeDeleted = true
break break
} }
} }
assigneeIn := IssueAssignees{AssigneeID: assigneeID, IssueID: issue.ID} assigneeIn := IssueAssignees{AssigneeID: assigneeID, IssueID: issue.ID}
toBeDeleted := i < len(issue.Assignees)
if toBeDeleted { if toBeDeleted {
issue.Assignees = append(issue.Assignees[:i], issue.Assignees[i:]...)
_, err = e.Delete(assigneeIn) _, err = e.Delete(assigneeIn)
if err != nil { if err != nil {
return toBeDeleted, err return toBeDeleted, err
} }
} else { } else {
issue.Assignees = append(issue.Assignees, assignee)
_, err = e.Insert(assigneeIn) _, err = e.Insert(assigneeIn)
if err != nil { if err != nil {
return toBeDeleted, err return toBeDeleted, err

View file

@ -457,15 +457,18 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
log.Error(4, "LoadAttributes: %v", err) log.Error(4, "LoadAttributes: %v", err)
return nil return nil
} }
mode, _ := AccessLevel(doer.ID, pr.Issue.Repo)
if err = PrepareWebhooks(pr.Issue.Repo, HookEventPullRequest, &api.PullRequestPayload{ if err = PrepareWebhooks(pr.Issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueClosed, Action: api.HookIssueClosed,
Index: pr.Index, Index: pr.Index,
PullRequest: pr.APIFormat(), PullRequest: pr.APIFormat(),
Repository: pr.Issue.Repo.APIFormat(AccessModeNone), Repository: pr.Issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}); err != nil { }); err != nil {
log.Error(4, "PrepareWebhooks: %v", err) log.Error(4, "PrepareWebhooks: %v", err)
return nil } else {
go HookQueue.Add(pr.Issue.Repo.ID)
} }
l, err := baseGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase) l, err := baseGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase)
@ -492,12 +495,14 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
After: mergeCommit.ID.String(), After: mergeCommit.ID.String(),
CompareURL: setting.AppURL + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID), CompareURL: setting.AppURL + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID),
Commits: ListToPushCommits(l).ToAPIPayloadCommits(pr.BaseRepo.HTMLURL()), Commits: ListToPushCommits(l).ToAPIPayloadCommits(pr.BaseRepo.HTMLURL()),
Repo: pr.BaseRepo.APIFormat(AccessModeNone), Repo: pr.BaseRepo.APIFormat(mode),
Pusher: pr.HeadRepo.MustOwner().APIFormat(), Pusher: pr.HeadRepo.MustOwner().APIFormat(),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
} }
if err = PrepareWebhooks(pr.BaseRepo, HookEventPush, p); err != nil { if err = PrepareWebhooks(pr.BaseRepo, HookEventPush, p); err != nil {
return fmt.Errorf("PrepareWebhooks: %v", err) log.Error(4, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(pr.BaseRepo.ID)
} }
return nil return nil
} }
@ -782,16 +787,18 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
pr.Issue = pull pr.Issue = pull
pull.PullRequest = pr pull.PullRequest = pr
mode, _ := AccessLevel(pull.Poster.ID, repo)
if err = PrepareWebhooks(repo, HookEventPullRequest, &api.PullRequestPayload{ if err = PrepareWebhooks(repo, HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueOpened, Action: api.HookIssueOpened,
Index: pull.Index, Index: pull.Index,
PullRequest: pr.APIFormat(), PullRequest: pr.APIFormat(),
Repository: repo.APIFormat(AccessModeNone), Repository: repo.APIFormat(mode),
Sender: pull.Poster.APIFormat(), Sender: pull.Poster.APIFormat(),
}); err != nil { }); err != nil {
log.Error(4, "PrepareWebhooks: %v", err) log.Error(4, "PrepareWebhooks: %v", err)
} } else {
go HookQueue.Add(repo.ID) go HookQueue.Add(repo.ID)
}
return nil return nil
} }

View file

@ -207,6 +207,8 @@ func CreateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []stri
Sender: rel.Publisher.APIFormat(), Sender: rel.Publisher.APIFormat(),
}); err != nil { }); err != nil {
log.Error(2, "PrepareWebhooks: %v", err) log.Error(2, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
} }
} }
} }
@ -371,7 +373,7 @@ func SortReleases(rels []*Release) {
} }
// UpdateRelease updates information of a release. // UpdateRelease updates information of a release.
func UpdateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []string) (err error) { func UpdateRelease(doer *User, gitRepo *git.Repository, rel *Release, attachmentUUIDs []string) (err error) {
if err = createTag(gitRepo, rel); err != nil { if err = createTag(gitRepo, rel); err != nil {
return err return err
} }
@ -382,8 +384,25 @@ func UpdateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []stri
return err return err
} }
err = rel.loadAttributes(x)
if err != nil {
return err
}
err = addReleaseAttachments(rel.ID, attachmentUUIDs) err = addReleaseAttachments(rel.ID, attachmentUUIDs)
mode, _ := accessLevel(x, doer.ID, rel.Repo)
if err1 := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleaseUpdated,
Release: rel.APIFormat(),
Repository: rel.Repo.APIFormat(mode),
Sender: rel.Publisher.APIFormat(),
}); err1 != nil {
log.Error(2, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
}
return err return err
} }
@ -429,6 +448,18 @@ func DeleteReleaseByID(id int64, u *User, delTag bool) error {
} }
} }
mode, _ := accessLevel(x, u.ID, rel.Repo)
if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleaseDeleted,
Release: rel.APIFormat(),
Repository: rel.Repo.APIFormat(mode),
Sender: rel.Publisher.APIFormat(),
}); err != nil {
log.Error(2, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
}
return nil return nil
} }

View file

@ -2460,11 +2460,13 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
mode, _ := AccessLevel(doer.ID, repo) mode, _ := AccessLevel(doer.ID, repo)
if err = PrepareWebhooks(oldRepo, HookEventFork, &api.ForkPayload{ if err = PrepareWebhooks(oldRepo, HookEventFork, &api.ForkPayload{
Forkee: repo.APIFormat(mode), Forkee: oldRepo.APIFormat(oldMode),
Repo: oldRepo.APIFormat(oldMode), Repo: repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}); err != nil { }); err != nil {
log.Error(2, "PrepareWebhooks [repo_id: %d]: %v", oldRepo.ID, err) log.Error(2, "PrepareWebhooks [repo_id: %d]: %v", oldRepo.ID, err)
} else {
go HookQueue.Add(oldRepo.ID)
} }
if err = repo.UpdateSize(); err != nil { if err = repo.UpdateSize(); err != nil {

View file

@ -43,7 +43,7 @@ func getDingtalkCreatePayload(p *api.CreatePayload) (*DingtalkPayload, error) {
Text: title, Text: title,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: fmt.Sprintf("view branch %s", refName), SingleTitle: fmt.Sprintf("view ref %s", refName),
SingleURL: p.Repo.HTMLURL + "/src/" + refName, SingleURL: p.Repo.HTMLURL + "/src/" + refName,
}, },
}, nil }, nil
@ -60,7 +60,7 @@ func getDingtalkDeletePayload(p *api.DeletePayload) (*DingtalkPayload, error) {
Text: title, Text: title,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: fmt.Sprintf("view branch %s", refName), SingleTitle: fmt.Sprintf("view ref %s", refName),
SingleURL: p.Repo.HTMLURL + "/src/" + refName, SingleURL: p.Repo.HTMLURL + "/src/" + refName,
}, },
}, nil }, nil
@ -153,23 +153,30 @@ func getDingtalkIssuesPayload(p *api.IssuePayload) (*DingtalkPayload, error) {
title = fmt.Sprintf("[%s] Issue unassigned: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) title = fmt.Sprintf("[%s] Issue unassigned: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body text = p.Issue.Body
case api.HookIssueLabelUpdated: case api.HookIssueLabelUpdated:
title = fmt.Sprintf("[%s] Pull request labels updated: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) title = fmt.Sprintf("[%s] Issue labels updated: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body text = p.Issue.Body
case api.HookIssueLabelCleared: case api.HookIssueLabelCleared:
title = fmt.Sprintf("[%s] Pull request labels cleared: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) title = fmt.Sprintf("[%s] Issue labels cleared: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body text = p.Issue.Body
case api.HookIssueSynchronized: case api.HookIssueSynchronized:
title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Issue milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Issue clear milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body text = p.Issue.Body
} }
return &DingtalkPayload{ return &DingtalkPayload{
MsgType: "actionCard", MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{ ActionCard: dingtalk.ActionCard{
Text: text, Text: title + "\r\n\r\n" + text,
//Markdown: "# " + title + "\n" + text,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: "view pull request", SingleTitle: "view issue",
SingleURL: p.Issue.URL, SingleURL: p.Issue.URL,
}, },
}, nil }, nil
@ -195,10 +202,10 @@ func getDingtalkIssueCommentPayload(p *api.IssueCommentPayload) (*DingtalkPayloa
return &DingtalkPayload{ return &DingtalkPayload{
MsgType: "actionCard", MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{ ActionCard: dingtalk.ActionCard{
Text: content, Text: title + "\r\n\r\n" + content,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: "view pull request", SingleTitle: "view issue comment",
SingleURL: url, SingleURL: url,
}, },
}, nil }, nil
@ -243,12 +250,19 @@ func getDingtalkPullRequestPayload(p *api.PullRequestPayload) (*DingtalkPayload,
case api.HookIssueSynchronized: case api.HookIssueSynchronized:
title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body text = p.PullRequest.Body
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Pull request milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Pull request clear milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
} }
return &DingtalkPayload{ return &DingtalkPayload{
MsgType: "actionCard", MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{ ActionCard: dingtalk.ActionCard{
Text: text, Text: title + "\r\n\r\n" + text,
//Markdown: "# " + title + "\n" + text,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: "view pull request", SingleTitle: "view pull request",
@ -300,7 +314,34 @@ func getDingtalkReleasePayload(p *api.ReleasePayload) (*DingtalkPayload, error)
Text: title, Text: title,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: "view repository", SingleTitle: "view release",
SingleURL: url,
},
}, nil
case api.HookReleaseUpdated:
title = fmt.Sprintf("[%s] Release updated", p.Release.TagName)
url = p.Release.URL
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: "view release",
SingleURL: url,
},
}, nil
case api.HookReleaseDeleted:
title = fmt.Sprintf("[%s] Release deleted", p.Release.TagName)
url = p.Release.URL
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: "view release",
SingleURL: url, SingleURL: url,
}, },
}, nil }, nil

View file

@ -251,6 +251,14 @@ func getDiscordIssuesPayload(p *api.IssuePayload, meta *DiscordMeta) (*DiscordPa
title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body text = p.Issue.Body
color = warnColor color = warnColor
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Issue milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
color = warnColor
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Issue clear milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
color = warnColor
} }
return &DiscordPayload{ return &DiscordPayload{
@ -362,6 +370,14 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, meta *DiscordMeta)
title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body text = p.PullRequest.Body
color = warnColor color = warnColor
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Pull request milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
color = warnColor
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Pull request clear milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
color = warnColor
} }
return &DiscordPayload{ return &DiscordPayload{
@ -422,6 +438,14 @@ func getDiscordReleasePayload(p *api.ReleasePayload, meta *DiscordMeta) (*Discor
title = fmt.Sprintf("[%s] Release created", p.Release.TagName) title = fmt.Sprintf("[%s] Release created", p.Release.TagName)
url = p.Release.URL url = p.Release.URL
color = successColor color = successColor
case api.HookReleaseUpdated:
title = fmt.Sprintf("[%s] Release updated", p.Release.TagName)
url = p.Release.URL
color = successColor
case api.HookReleaseDeleted:
title = fmt.Sprintf("[%s] Release deleted", p.Release.TagName)
url = p.Release.URL
color = successColor
} }
return &DiscordPayload{ return &DiscordPayload{

View file

@ -213,7 +213,17 @@ func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (
func getSlackReleasePayload(p *api.ReleasePayload, slack *SlackMeta) (*SlackPayload, error) { func getSlackReleasePayload(p *api.ReleasePayload, slack *SlackMeta) (*SlackPayload, error) {
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.Name) repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.Name)
refLink := SlackLinkFormatter(p.Repository.HTMLURL+"/src/"+p.Release.TagName, p.Release.TagName) 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) var text string
switch p.Action {
case api.HookReleasePublished:
text = fmt.Sprintf("[%s] new release %s published by %s", repoLink, refLink, p.Sender.UserName)
case api.HookReleaseUpdated:
text = fmt.Sprintf("[%s] new release %s updated by %s", repoLink, refLink, p.Sender.UserName)
case api.HookReleaseDeleted:
text = fmt.Sprintf("[%s] new release %s deleted by %s", repoLink, refLink, p.Sender.UserName)
}
return &SlackPayload{ return &SlackPayload{
Channel: slack.Channel, Channel: slack.Channel,
Text: text, Text: text,

View file

@ -1031,7 +1031,7 @@ settings.event_issues_desc = Issue opened, closed, reopened, edited, assigned, u
settings.event_issue_comment = Issue Comment settings.event_issue_comment = Issue Comment
settings.event_issue_comment_desc = Issue comment created, edited, or deleted. settings.event_issue_comment_desc = Issue comment created, edited, or deleted.
settings.event_release = Release settings.event_release = Release
settings.event_release_desc = Release published in a repository. settings.event_release_desc = Release published, updated or deleted 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

View file

@ -171,7 +171,7 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
rel.Repo = ctx.Repo.Repository rel.Repo = ctx.Repo.Repository
rel.Publisher = ctx.User rel.Publisher = ctx.User
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, nil); err != nil { if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
ctx.ServerError("UpdateRelease", err) ctx.ServerError("UpdateRelease", err)
return return
} }
@ -245,7 +245,7 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) {
if form.IsPrerelease != nil { if form.IsPrerelease != nil {
rel.IsPrerelease = *form.IsPrerelease rel.IsPrerelease = *form.IsPrerelease
} }
if err := models.UpdateRelease(ctx.Repo.GitRepo, rel, nil); err != nil { if err := models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
ctx.Error(500, "UpdateRelease", err) ctx.Error(500, "UpdateRelease", err)
return return
} }

View file

@ -197,7 +197,7 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
rel.PublisherID = ctx.User.ID rel.PublisherID = ctx.User.ID
rel.IsTag = false rel.IsTag = false
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil { if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
ctx.Data["Err_TagName"] = true ctx.Data["Err_TagName"] = true
ctx.ServerError("UpdateRelease", err) ctx.ServerError("UpdateRelease", err)
return return
@ -276,7 +276,7 @@ func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) {
rel.Note = form.Content rel.Note = form.Content
rel.IsDraft = len(form.Draft) > 0 rel.IsDraft = len(form.Draft) > 0
rel.IsPrerelease = form.Prerelease rel.IsPrerelease = form.Prerelease
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil { if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
ctx.ServerError("UpdateRelease", err) ctx.ServerError("UpdateRelease", err)
return return
} }

View file

@ -327,6 +327,8 @@ type HookReleaseAction string
// all release actions // all release actions
const ( const (
HookReleasePublished HookReleaseAction = "published" HookReleasePublished HookReleaseAction = "published"
HookReleaseUpdated HookReleaseAction = "updated"
HookReleaseDeleted HookReleaseAction = "deleted"
) )
// ReleasePayload represents a payload information of release event. // ReleasePayload represents a payload information of release event.

6
vendor/vendor.json vendored
View file

@ -9,10 +9,10 @@
"revisionTime": "2018-04-21T01:08:19Z" "revisionTime": "2018-04-21T01:08:19Z"
}, },
{ {
"checksumSHA1": "LnxY/6xD4h9dCCJ5nxKEfZZs1Vk=", "checksumSHA1": "2m0bMciZiWzFbfntlaqUpMaIBSA=",
"path": "code.gitea.io/sdk/gitea", "path": "code.gitea.io/sdk/gitea",
"revision": "7fa627fa5d67d18c39d6dd3c6c4db836916bf234", "revision": "b2308e3f700875a3642a78bd3f6e5db8ef6f974d",
"revisionTime": "2018-05-10T12:54:05Z" "revisionTime": "2018-05-18T06:06:32Z"
}, },
{ {
"checksumSHA1": "bOODD4Gbw3GfcuQPU2dI40crxxk=", "checksumSHA1": "bOODD4Gbw3GfcuQPU2dI40crxxk=",