diff options
Diffstat (limited to 'models')
-rw-r--r-- | models/issue.go | 3 | ||||
-rw-r--r-- | models/release.go | 73 | ||||
-rw-r--r-- | models/webhook.go | 9 | ||||
-rw-r--r-- | models/webhook_discord.go | 18 | ||||
-rw-r--r-- | models/webhook_slack.go | 11 |
5 files changed, 106 insertions, 8 deletions
diff --git a/models/issue.go b/models/issue.go index 89c72f48..8cf5add3 100644 --- a/models/issue.go +++ b/models/issue.go @@ -12,9 +12,10 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" - api "github.com/gogits/go-gogs-client" log "gopkg.in/clog.v1" + api "github.com/gogits/go-gogs-client" + "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/setting" ) diff --git a/models/release.go b/models/release.go index 53b2e631..08192370 100644 --- a/models/release.go +++ b/models/release.go @@ -11,8 +11,10 @@ import ( "time" "github.com/go-xorm/xorm" + log "gopkg.in/clog.v1" "github.com/gogits/git-module" + api "github.com/gogits/go-gogs-client" "github.com/gogits/gogs/modules/process" ) @@ -21,6 +23,7 @@ import ( type Release struct { ID int64 `xorm:"pk autoincr"` RepoID int64 + Repo *Repository `xorm:"-"` PublisherID int64 Publisher *User `xorm:"-"` TagName string @@ -52,6 +55,13 @@ func (r *Release) AfterSet(colName string, _ xorm.Cell) { } func (r *Release) loadAttributes(e Engine) (err error) { + if r.Repo == nil { + r.Repo, err = getRepositoryByID(e, r.RepoID) + if err != nil { + return fmt.Errorf("getRepositoryByID [repo_id: %d]: %v", r.RepoID, err) + } + } + if r.Publisher == nil { r.Publisher, err = getUserByID(e, r.PublisherID) if err != nil { @@ -59,7 +69,7 @@ func (r *Release) loadAttributes(e Engine) (err error) { r.PublisherID = -1 r.Publisher = NewGhostUser() } else { - return fmt.Errorf("getUserByID.(Publisher) [%d]: %v", r.PublisherID, err) + return fmt.Errorf("getUserByID.(Publisher) [publisher_id: %d]: %v", r.PublisherID, err) } } } @@ -71,6 +81,22 @@ func (r *Release) LoadAttributes() error { return r.loadAttributes(x) } +// This method assumes some fields assigned with values: +// Required - Publisher +func (r *Release) APIFormat() *api.Release { + return &api.Release{ + ID: r.ID, + TagName: r.TagName, + TargetCommitish: r.Target, + Name: r.Title, + Body: r.Note, + Draft: r.IsDraft, + Prerelease: r.IsPrerelease, + Author: r.Publisher.APIFormat(), + Created: r.Created, + } +} + // IsReleaseExist returns true if release with given tag name already exists. func IsReleaseExist(repoID int64, tagName string) (bool, error) { if len(tagName) == 0 { @@ -113,6 +139,17 @@ func createTag(gitRepo *git.Repository, r *Release) error { return nil } +func (r *Release) preparePublishWebhooks() { + if err := PrepareWebhooks(r.Repo, HOOK_EVENT_RELEASE, &api.ReleasePayload{ + Action: api.HOOK_RELEASE_PUBLISHED, + Release: r.APIFormat(), + Repository: r.Repo.APIFormat(nil), + Sender: r.Publisher.APIFormat(), + }); err != nil { + log.Error(2, "PrepareWebhooks: %v", err) + } +} + // CreateRelease creates a new release of repository. func CreateRelease(gitRepo *git.Repository, r *Release) error { isExist, err := IsReleaseExist(r.RepoID, r.TagName) @@ -126,8 +163,20 @@ func CreateRelease(gitRepo *git.Repository, r *Release) error { return err } r.LowerTagName = strings.ToLower(r.TagName) - _, err = x.InsertOne(r) - return err + if _, err = x.Insert(r); err != nil { + return fmt.Errorf("Insert: %v", err) + } + + // Only send webhook when actually published, skip drafts + if r.IsDraft { + return nil + } + r, err = GetReleaseByID(r.ID) + if err != nil { + return fmt.Errorf("GetReleaseByID: %v", err) + } + r.preparePublishWebhooks() + return nil } // GetRelease returns release by given ID. @@ -205,12 +254,22 @@ func SortReleases(rels []*Release) { } // UpdateRelease updates information of a release. -func UpdateRelease(gitRepo *git.Repository, rel *Release) (err error) { - if err = createTag(gitRepo, rel); err != nil { +func UpdateRelease(doer *User, gitRepo *git.Repository, r *Release, isPublish bool) (err error) { + if err = createTag(gitRepo, r); err != nil { + return fmt.Errorf("createTag: %v", err) + } + + r.PublisherID = doer.ID + if _, err = x.Id(r.ID).AllCols().Update(r); err != nil { return err } - _, err = x.Id(rel.ID).AllCols().Update(rel) - return err + + if !isPublish { + return nil + } + r.Publisher = doer + r.preparePublishWebhooks() + return nil } // DeleteReleaseOfRepoByID deletes a release and corresponding Git tag by given ID. diff --git a/models/webhook.go b/models/webhook.go index 32c3ab34..86beeb87 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -69,6 +69,7 @@ type HookEvents struct { Issues bool `json:"issues"` IssueComment bool `json:"issue_comment"` PullRequest bool `json:"pull_request"` + Release bool `json:"release"` } // HookEvent represents events that will delivery hook. @@ -196,6 +197,12 @@ func (w *Webhook) HasPullRequestEvent() bool { (w.ChooseEvents && w.HookEvents.PullRequest) } +// HasReleaseEvent returns true if hook enabled release event. +func (w *Webhook) HasReleaseEvent() bool { + return w.SendEverything || + (w.ChooseEvents && w.HookEvents.Release) +} + type eventChecker struct { checker func() bool typ HookEventType @@ -211,6 +218,7 @@ func (w *Webhook) EventsArray() []string { {w.HasIssuesEvent, HOOK_EVENT_ISSUES}, {w.HasIssueCommentEvent, HOOK_EVENT_ISSUE_COMMENT}, {w.HasPullRequestEvent, HOOK_EVENT_PULL_REQUEST}, + {w.HasReleaseEvent, HOOK_EVENT_RELEASE}, } for _, c := range eventCheckers { if c.checker() { @@ -381,6 +389,7 @@ const ( HOOK_EVENT_ISSUES HookEventType = "issues" HOOK_EVENT_ISSUE_COMMENT HookEventType = "issue_comment" HOOK_EVENT_PULL_REQUEST HookEventType = "pull_request" + HOOK_EVENT_RELEASE HookEventType = "release" ) // HookRequest represents hook task request information. diff --git a/models/webhook_discord.go b/models/webhook_discord.go index 0e9a36f2..e403399a 100644 --- a/models/webhook_discord.go +++ b/models/webhook_discord.go @@ -353,6 +353,22 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) ( }, nil } +func getDiscordReleasePayload(p *api.ReleasePayload) (*DiscordPayload, error) { + repoLink := DiscordLinkFormatter(p.Repository.HTMLURL, p.Repository.Name) + refLink := DiscordLinkFormatter(p.Repository.HTMLURL+"/src/"+p.Release.TagName, p.Release.TagName) + content := fmt.Sprintf("Published new release %s of %s", refLink, repoLink) + return &DiscordPayload{ + Embeds: []*DiscordEmbedObject{{ + Description: content, + URL: setting.AppUrl + p.Sender.UserName, + Author: &DiscordEmbedAuthorObject{ + Name: p.Sender.UserName, + IconURL: p.Sender.AvatarUrl, + }, + }}, + }, nil +} + func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (payload *DiscordPayload, err error) { slack := &SlackMeta{} if err := json.Unmarshal([]byte(meta), &slack); err != nil { @@ -374,6 +390,8 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (paylo payload, err = getDiscordIssueCommentPayload(p.(*api.IssueCommentPayload), slack) case HOOK_EVENT_PULL_REQUEST: payload, err = getDiscordPullRequestPayload(p.(*api.PullRequestPayload), slack) + case HOOK_EVENT_RELEASE: + payload, err = getDiscordReleasePayload(p.(*api.ReleasePayload)) } if err != nil { return nil, fmt.Errorf("event '%s': %v", event, err) diff --git a/models/webhook_slack.go b/models/webhook_slack.go index d1134ed8..46e8ef9a 100644 --- a/models/webhook_slack.go +++ b/models/webhook_slack.go @@ -277,6 +277,15 @@ func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*S }, nil } +func getSlackReleasePayload(p *api.ReleasePayload) (*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{ + Text: text, + }, nil +} + func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (payload *SlackPayload, err error) { slack := &SlackMeta{} if err := json.Unmarshal([]byte(meta), &slack); err != nil { @@ -298,6 +307,8 @@ func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (payload payload, err = getSlackIssueCommentPayload(p.(*api.IssueCommentPayload), slack) case HOOK_EVENT_PULL_REQUEST: payload, err = getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack) + case HOOK_EVENT_RELEASE: + payload, err = getSlackReleasePayload(p.(*api.ReleasePayload)) } if err != nil { return nil, fmt.Errorf("event '%s': %v", event, err) |