Browse Source

#2246 add HTMLURL to webhook type

- Fill Milestone and Assignee field when available in webhook payload
tags/v0.9.99
Unknwon 7 years ago
parent
commit
6f9a95f830

+ 1
- 1
.gopmfile View File

github.com/gogits/chardet = commit:2404f77 github.com/gogits/chardet = commit:2404f77
github.com/gogits/cron = commit:7f3990a github.com/gogits/cron = commit:7f3990a
github.com/gogits/git-module = commit:f78bf3b github.com/gogits/git-module = commit:f78bf3b
github.com/gogits/go-gogs-client = commit:e363d3f
github.com/gogits/go-gogs-client = commit:51c4df8
github.com/issue9/identicon = commit:d36b545 github.com/issue9/identicon = commit:d36b545
github.com/jaytaylor/html2text = commit:52d9b78 github.com/jaytaylor/html2text = commit:52d9b78
github.com/kardianos/minwinsvc = commit:cad6b2b github.com/kardianos/minwinsvc = commit:cad6b2b

+ 1
- 1
README.md View File



![](https://github.com/gogits/gogs/blob/master/public/img/gogs-large-resize.png?raw=true) ![](https://github.com/gogits/gogs/blob/master/public/img/gogs-large-resize.png?raw=true)


##### Current tip version: 0.9.81 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions)
##### Current tip version: 0.9.82 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions)


| Web | UI | Preview | | Web | UI | Preview |
|:-------------:|:-------:|:-------:| |:-------------:|:-------:|:-------:|

+ 2
- 2
cmd/web.go View File

{"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"}, {"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"},
{"gopkg.in/ini.v1", ini.Version, "1.8.4"}, {"gopkg.in/ini.v1", ini.Version, "1.8.4"},
{"gopkg.in/macaron.v1", macaron.Version, "1.1.7"}, {"gopkg.in/macaron.v1", macaron.Version, "1.1.7"},
{"github.com/gogits/git-module", git.Version, "0.3.6"},
{"github.com/gogits/go-gogs-client", gogs.Version, "0.12.0"},
{"github.com/gogits/git-module", git.Version, "0.3.7"},
{"github.com/gogits/go-gogs-client", gogs.Version, "0.12.1"},
} }
for _, c := range checkers { for _, c := range checkers {
if !version.Compare(c.Version(), c.Expected, ">=") { if !version.Compare(c.Version(), c.Expected, ">=") {

+ 1
- 1
glide.lock View File

- name: github.com/gogits/git-module - name: github.com/gogits/git-module
version: f78bf3bf703cb3eb0e85a9475d26826939feda4f version: f78bf3bf703cb3eb0e85a9475d26826939feda4f
- name: github.com/gogits/go-gogs-client - name: github.com/gogits/go-gogs-client
version: e363d3ff8f70d0fe813324eedf228684af41c29c
version: 51c4df8c350b32f095c8eb236aae2e306025eead
- name: github.com/issue9/identicon - name: github.com/issue9/identicon
version: d36b54562f4cf70c83653e13dc95c220c79ef521 version: d36b54562f4cf70c83653e13dc95c220c79ef521
- name: github.com/jaytaylor/html2text - name: github.com/jaytaylor/html2text

+ 1
- 1
gogs.go View File

"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )


const APP_VER = "0.9.81.0816"
const APP_VER = "0.9.82.0816"


func init() { func init() {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())

+ 1
- 1
models/action.go View File

Before: oldCommitID, Before: oldCommitID,
After: newCommitID, After: newCommitID,
CompareURL: setting.AppUrl + commit.CompareURL, CompareURL: setting.AppUrl + commit.CompareURL,
Commits: commit.ToApiPayloadCommits(repo.FullLink()),
Commits: commit.ToApiPayloadCommits(repo.HTMLURL()),
Repo: apiRepo, Repo: apiRepo,
Pusher: apiPusher, Pusher: apiPusher,
Sender: apiPusher, Sender: apiPusher,

+ 54
- 32
models/issue.go View File

type Issue struct { type Issue struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX UNIQUE(repo_index)"` RepoID int64 `xorm:"INDEX UNIQUE(repo_index)"`
Index int64 `xorm:"UNIQUE(repo_index)"` // Index in one repository.
Title string `xorm:"name"`
Repo *Repository `xorm:"-"` Repo *Repository `xorm:"-"`
Index int64 `xorm:"UNIQUE(repo_index)"` // Index in one repository.
PosterID int64 PosterID int64
Poster *User `xorm:"-"` Poster *User `xorm:"-"`
Title string `xorm:"name"`
Content string `xorm:"TEXT"`
RenderedContent string `xorm:"-"`
Labels []*Label `xorm:"-"` Labels []*Label `xorm:"-"`
MilestoneID int64 MilestoneID int64
Milestone *Milestone `xorm:"-"` Milestone *Milestone `xorm:"-"`
Priority int
AssigneeID int64 AssigneeID int64
Assignee *User `xorm:"-"` Assignee *User `xorm:"-"`
IsRead bool `xorm:"-"`
IsPull bool // Indicates whether is a pull request or not.
*PullRequest `xorm:"-"`
IsClosed bool IsClosed bool
Content string `xorm:"TEXT"`
RenderedContent string `xorm:"-"`
Priority int
IsRead bool `xorm:"-"`
IsPull bool // Indicates whether is a pull request or not.
PullRequest *PullRequest `xorm:"-"`
NumComments int NumComments int


Deadline time.Time `xorm:"-"` Deadline time.Time `xorm:"-"`
return issue.loadAttributes(x) return issue.loadAttributes(x)
} }


func (issue *Issue) HTMLURL() string {
var path string
if issue.IsPull {
path = "pulls"
} else {
path = "issues"
}
return fmt.Sprintf("%s/%s/%d", issue.Repo.HTMLURL(), path, issue.Index)
}

// State returns string representation of issue status. // State returns string representation of issue status.
func (i *Issue) State() api.StateType { func (i *Issue) State() api.StateType {
if i.IsClosed { if i.IsClosed {
apiIssue := &api.Issue{ apiIssue := &api.Issue{
ID: issue.ID, ID: issue.ID,
Index: issue.Index, Index: issue.Index,
State: issue.State(),
Poster: issue.Poster.APIFormat(),
Title: issue.Title, Title: issue.Title,
Body: issue.Content, Body: issue.Content,
User: issue.Poster.APIFormat(),
Labels: apiLabels, Labels: apiLabels,
State: issue.State(),
Comments: issue.NumComments, Comments: issue.NumComments,
Created: issue.Created, Created: issue.Created,
Updated: issue.Updated, Updated: issue.Updated,
return "issue-" + com.ToStr(i.ID) return "issue-" + com.ToStr(i.ID)
} }


func (issue *Issue) FullLink() string {
var path string
if issue.IsPull {
path = "pulls"
} else {
path = "issues"
}
return fmt.Sprintf("%s/%s/%d", issue.Repo.FullLink(), path, issue.Index)
}

// IsPoster returns true if given user by ID is the poster. // IsPoster returns true if given user by ID is the poster.
func (i *Issue) IsPoster(uid int64) bool { func (i *Issue) IsPoster(uid int64) bool {
return i.PosterID == uid return i.PosterID == uid
opts.Issue.Title = strings.TrimSpace(opts.Issue.Title) opts.Issue.Title = strings.TrimSpace(opts.Issue.Title)
opts.Issue.Index = opts.Repo.NextIssueIndex() opts.Issue.Index = opts.Repo.NextIssueIndex()


if opts.Issue.MilestoneID > 0 {
milestone, err := getMilestoneByID(e, opts.Issue.MilestoneID)
if err != nil && !IsErrMilestoneNotExist(err) {
return fmt.Errorf("getMilestoneByID: %v", err)
}

// Assume milestone is invalid and drop silently.
opts.Issue.MilestoneID = 0
if milestone != nil {
opts.Issue.MilestoneID = milestone.ID
opts.Issue.Milestone = milestone
if err = changeMilestoneAssign(e, opts.Issue, -1); err != nil {
return err
}
}
}

if opts.Issue.AssigneeID > 0 { if opts.Issue.AssigneeID > 0 {
// Silently drop invalid assignee.
valid, err := hasAccess(e, &User{ID: opts.Issue.AssigneeID}, opts.Repo, ACCESS_MODE_WRITE)
if err != nil {
return fmt.Errorf("hasAccess [user_id: %d, repo_id: %d]: %v", opts.Issue.AssigneeID, opts.Repo.ID, err)
} else if !valid {
opts.Issue.AssigneeID = 0
assignee, err := getUserByID(e, opts.Issue.AssigneeID)
if err != nil && !IsErrUserNotExist(err) {
return fmt.Errorf("getUserByID: %v", err)
}

// Assume assignee is invalid and drop silently.
opts.Issue.AssigneeID = 0
if assignee != nil {
valid, err := hasAccess(e, assignee, opts.Repo, ACCESS_MODE_WRITE)
if err != nil {
return fmt.Errorf("hasAccess [user_id: %d, repo_id: %d]: %v", assignee.ID, opts.Repo.ID, err)
}
if valid {
opts.Issue.AssigneeID = assignee.ID
opts.Issue.Assignee = assignee
}
} }
} }


// Milestone and assignee validation should happen before insert actual object.
if _, err = e.Insert(opts.Issue); err != nil { if _, err = e.Insert(opts.Issue); err != nil {
return err return err
} }
} }
} }


if opts.Issue.MilestoneID > 0 {
if err = changeMilestoneAssign(e, opts.Issue, -1); err != nil {
return err
}
}

if err = newIssueUsers(e, opts.Repo, opts.Issue); err != nil { if err = newIssueUsers(e, opts.Repo, opts.Issue); err != nil {
return err return err
} }

+ 3
- 3
models/mail.go View File

data := map[string]interface{}{ data := map[string]interface{}{
"Subject": subject, "Subject": subject,
"RepoName": repoName, "RepoName": repoName,
"Link": repo.FullLink(),
"Link": repo.HTMLURL(),
} }
body, err := mailRender.HTMLString(string(MAIL_NOTIFY_COLLABORATOR), data) body, err := mailRender.HTMLString(string(MAIL_NOTIFY_COLLABORATOR), data)
if err != nil { if err != nil {


func composeIssueMessage(issue *Issue, doer *User, tplName base.TplName, tos []string, info string) *mailer.Message { func composeIssueMessage(issue *Issue, doer *User, tplName base.TplName, tos []string, info string) *mailer.Message {
subject := issue.MailSubject() subject := issue.MailSubject()
body := string(markdown.RenderSpecialLink([]byte(issue.Content), issue.Repo.FullLink(), issue.Repo.ComposeMetas()))
data := composeTplData(subject, body, issue.FullLink())
body := string(markdown.RenderSpecialLink([]byte(issue.Content), issue.Repo.HTMLURL(), issue.Repo.ComposeMetas()))
data := composeTplData(subject, body, issue.HTMLURL())
data["Doer"] = doer data["Doer"] = doer
content, err := mailRender.HTMLString(string(tplName), data) content, err := mailRender.HTMLString(string(tplName), data)
if err != nil { if err != nil {

+ 8
- 3
models/pull.go View File

} }


func (pr *PullRequest) LoadIssue() (err error) { func (pr *PullRequest) LoadIssue() (err error) {
if pr.Issue != nil {
return nil
}

pr.Issue, err = GetIssueByID(pr.IssueID) pr.Issue, err = GetIssueByID(pr.IssueID)
return err return err
} }
apiPullRequest := &api.PullRequest{ apiPullRequest := &api.PullRequest{
ID: pr.ID, ID: pr.ID,
Index: pr.Index, Index: pr.Index,
State: apiIssue.State,
Poster: apiIssue.Poster,
Title: apiIssue.Title, Title: apiIssue.Title,
Body: apiIssue.Body, Body: apiIssue.Body,
User: apiIssue.User,
Labels: apiIssue.Labels, Labels: apiIssue.Labels,
Milestone: apiIssue.Milestone, Milestone: apiIssue.Milestone,
Assignee: apiIssue.Assignee, Assignee: apiIssue.Assignee,
State: apiIssue.State,
Comments: apiIssue.Comments, Comments: apiIssue.Comments,
HTMLURL: pr.Issue.HTMLURL(),
HasMerged: pr.HasMerged, HasMerged: pr.HasMerged,
} }


Before: pr.MergeBase, Before: pr.MergeBase,
After: pr.MergedCommitID, After: pr.MergedCommitID,
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.FullLink()),
Commits: ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.HTMLURL()),
Repo: pr.BaseRepo.APIFormat(nil), Repo: pr.BaseRepo.APIFormat(nil),
Pusher: pr.HeadRepo.MustOwner().APIFormat(), Pusher: pr.HeadRepo.MustOwner().APIFormat(),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),

+ 2
- 2
models/repo.go View File

return repo.MustOwner().Name + "/" + repo.Name return repo.MustOwner().Name + "/" + repo.Name
} }


func (repo *Repository) FullLink() string {
func (repo *Repository) HTMLURL() string {
return setting.AppUrl + repo.FullName() return setting.AppUrl + repo.FullName()
} }


Description: repo.Description, Description: repo.Description,
Private: repo.IsPrivate, Private: repo.IsPrivate,
Fork: repo.IsFork, Fork: repo.IsFork,
HTMLURL: repo.FullLink(),
HTMLURL: repo.HTMLURL(),
SSHURL: cloneLink.SSH, SSHURL: cloneLink.SSH,
CloneURL: cloneLink.HTTPS, CloneURL: cloneLink.HTTPS,
Website: repo.Website, Website: repo.Website,

+ 5
- 5
routers/repo/issue.go View File



// Get more information if it's a pull request. // Get more information if it's a pull request.
if issue.IsPull { if issue.IsPull {
if issue.HasMerged {
ctx.Data["DisableStatusChange"] = issue.HasMerged
if issue.PullRequest.HasMerged {
ctx.Data["DisableStatusChange"] = issue.PullRequest.HasMerged
PrepareMergedViewPullInfo(ctx, issue) PrepareMergedViewPullInfo(ctx, issue)
} else { } else {
PrepareViewPullInfo(ctx, issue) PrepareViewPullInfo(ctx, issue)
// Check if issue admin/poster changes the status of issue. // Check if issue admin/poster changes the status of issue.
if (ctx.Repo.IsWriter() || (ctx.IsSigned && issue.IsPoster(ctx.User.ID))) && if (ctx.Repo.IsWriter() || (ctx.IsSigned && issue.IsPoster(ctx.User.ID))) &&
(form.Status == "reopen" || form.Status == "close") && (form.Status == "reopen" || form.Status == "close") &&
!(issue.IsPull && issue.HasMerged) {
!(issue.IsPull && issue.PullRequest.HasMerged) {


// Duplication and conflict check should apply to reopen pull request. // Duplication and conflict check should apply to reopen pull request.
var pr *models.PullRequest var pr *models.PullRequest


// Regenerate patch and test conflict. // Regenerate patch and test conflict.
if pr == nil { if pr == nil {
if err = issue.UpdatePatch(); err != nil {
if err = issue.PullRequest.UpdatePatch(); err != nil {
ctx.Handle(500, "UpdatePatch", err) ctx.Handle(500, "UpdatePatch", err)
return return
} }


issue.AddToTaskQueue()
issue.PullRequest.AddToTaskQueue()
} }
} }



+ 14
- 10
routers/repo/pull.go View File

return nil return nil
} }


if err = issue.GetHeadRepo(); err != nil {
if err = issue.PullRequest.GetHeadRepo(); err != nil {
ctx.Handle(500, "GetHeadRepo", err) ctx.Handle(500, "GetHeadRepo", err)
return nil return nil
} }
return issue return issue
} }


func PrepareMergedViewPullInfo(ctx *context.Context, pull *models.Issue) {
func PrepareMergedViewPullInfo(ctx *context.Context, issue *models.Issue) {
pull := issue.PullRequest
ctx.Data["HasMerged"] = true ctx.Data["HasMerged"] = true
ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBranch
ctx.Data["HeadTarget"] = issue.PullRequest.HeadUserName + "/" + pull.HeadBranch
ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.BaseBranch ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.BaseBranch


var err error var err error
} }
} }


func PrepareViewPullInfo(ctx *context.Context, pull *models.Issue) *git.PullRequestInfo {
func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.PullRequestInfo {
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
pull := issue.PullRequest


ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBranch ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBranch
ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.BaseBranch ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.BaseBranch
ctx.Data["PageIsPullList"] = true ctx.Data["PageIsPullList"] = true
ctx.Data["PageIsPullCommits"] = true ctx.Data["PageIsPullCommits"] = true


pull := checkPullInfo(ctx)
issue := checkPullInfo(ctx)
if ctx.Written() { if ctx.Written() {
return return
} }
pull := issue.PullRequest
ctx.Data["Username"] = pull.HeadUserName ctx.Data["Username"] = pull.HeadUserName
ctx.Data["Reponame"] = pull.HeadRepo.Name ctx.Data["Reponame"] = pull.HeadRepo.Name


var commits *list.List var commits *list.List
if pull.HasMerged { if pull.HasMerged {
PrepareMergedViewPullInfo(ctx, pull)
PrepareMergedViewPullInfo(ctx, issue)
if ctx.Written() { if ctx.Written() {
return return
} }
} }


} else { } else {
prInfo := PrepareViewPullInfo(ctx, pull)
prInfo := PrepareViewPullInfo(ctx, issue)
if ctx.Written() { if ctx.Written() {
return return
} else if prInfo == nil { } else if prInfo == nil {
ctx.Data["PageIsPullList"] = true ctx.Data["PageIsPullList"] = true
ctx.Data["PageIsPullFiles"] = true ctx.Data["PageIsPullFiles"] = true


pull := checkPullInfo(ctx)
issue := checkPullInfo(ctx)
if ctx.Written() { if ctx.Written() {
return return
} }
pull := issue.PullRequest


var ( var (
diffRepoPath string diffRepoPath string
) )


if pull.HasMerged { if pull.HasMerged {
PrepareMergedViewPullInfo(ctx, pull)
PrepareMergedViewPullInfo(ctx, issue)
if ctx.Written() { if ctx.Written() {
return return
} }
endCommitID = pull.MergedCommitID endCommitID = pull.MergedCommitID
gitRepo = ctx.Repo.GitRepo gitRepo = ctx.Repo.GitRepo
} else { } else {
prInfo := PrepareViewPullInfo(ctx, pull)
prInfo := PrepareViewPullInfo(ctx, issue)
if ctx.Written() { if ctx.Written() {
return return
} else if prInfo == nil { } else if prInfo == nil {

+ 1
- 1
routers/repo/webhook.go View File

{ {
ID: commit.ID.String(), ID: commit.ID.String(),
Message: commit.Message(), Message: commit.Message(),
URL: ctx.Repo.Repository.FullLink() + "/commit/" + commit.ID.String(),
URL: ctx.Repo.Repository.HTMLURL() + "/commit/" + commit.ID.String(),
Author: &api.PayloadUser{ Author: &api.PayloadUser{
Name: commit.Author.Name, Name: commit.Author.Name,
Email: commit.Author.Email, Email: commit.Author.Email,

+ 1
- 1
templates/.VERSION View File

0.9.81.0816
0.9.82.0816

+ 6
- 6
templates/repo/issue/view_content.tmpl View File

{{if .Issue.IsPull}} {{if .Issue.IsPull}}
<div class="comment merge box"> <div class="comment merge box">
<a class="avatar text <a class="avatar text
{{if .Issue.HasMerged}}purple
{{if .Issue.PullRequest.HasMerged}}purple
{{else if .Issue.IsClosed}}grey {{else if .Issue.IsClosed}}grey
{{else if .IsPullReuqestBroken}}red {{else if .IsPullReuqestBroken}}red
{{else if .Issue.IsChecking}}yellow
{{else if .Issue.CanAutoMerge}}green
{{else if .Issue.PullRequest.IsChecking}}yellow
{{else if .Issue.PullRequest.CanAutoMerge}}green
{{else}}red{{end}}"><span class="mega-octicon octicon-git-merge"></span></a> {{else}}red{{end}}"><span class="mega-octicon octicon-git-merge"></span></a>
<div class="content"> <div class="content">
<div class="ui merge segment"> <div class="ui merge segment">
{{if .Issue.HasMerged}}
{{if .Issue.PullRequest.HasMerged}}
<div class="item text purple"> <div class="item text purple">
{{$.i18n.Tr "repo.pulls.has_merged"}} {{$.i18n.Tr "repo.pulls.has_merged"}}
</div> </div>
<span class="octicon octicon-x"></span> <span class="octicon octicon-x"></span>
{{$.i18n.Tr "repo.pulls.data_broken"}} {{$.i18n.Tr "repo.pulls.data_broken"}}
</div> </div>
{{else if .Issue.IsChecking}}
{{else if .Issue.PullRequest.IsChecking}}
<div class="item text yellow"> <div class="item text yellow">
<span class="octicon octicon-sync"></span> <span class="octicon octicon-sync"></span>
{{$.i18n.Tr "repo.pulls.is_checking"}} {{$.i18n.Tr "repo.pulls.is_checking"}}
</div> </div>
{{else if .Issue.CanAutoMerge}}
{{else if .Issue.PullRequest.CanAutoMerge}}
<div class="item text green"> <div class="item text green">
<span class="octicon octicon-check"></span> <span class="octicon octicon-check"></span>
{{$.i18n.Tr "repo.pulls.can_auto_merge_desc"}} {{$.i18n.Tr "repo.pulls.can_auto_merge_desc"}}

+ 3
- 3
templates/repo/issue/view_title.tmpl View File

{{end}} {{end}}


{{if .Issue.IsPull}} {{if .Issue.IsPull}}
{{if .Issue.HasMerged}}
{{ $mergedStr:= TimeSince .Issue.Merged $.Lang }}
<a {{if gt .Issue.Merger.ID 0}}href="{{.Issue.Merger.HomeLink}}"{{end}}>{{.Issue.Merger.Name}}</a>
{{if .Issue.PullRequest.HasMerged}}
{{ $mergedStr:= TimeSince .Issue.PullRequest.Merged $.Lang }}
<a {{if gt .Issue.PullRequest.Merger.ID 0}}href="{{.Issue.PullRequest.Merger.HomeLink}}"{{end}}>{{.Issue.PullRequest.Merger.Name}}</a>
<span class="pull-desc">{{$.i18n.Tr "repo.pulls.merged_title_desc" .NumCommits .HeadTarget .BaseTarget $mergedStr | Safe}}</span> <span class="pull-desc">{{$.i18n.Tr "repo.pulls.merged_title_desc" .NumCommits .HeadTarget .BaseTarget $mergedStr | Safe}}</span>
{{else}} {{else}}
<a {{if gt .Issue.Poster.ID 0}}href="{{.Issue.Poster.HomeLink}}"{{end}}>{{.Issue.Poster.Name}}</a> <a {{if gt .Issue.Poster.ID 0}}href="{{.Issue.Poster.HomeLink}}"{{end}}>{{.Issue.Poster.Name}}</a>

Loading…
Cancel
Save