Skip to content

Commit 2056a77

Browse files
authored
[MM-352] Add feature to publish release create and delete events (#762)
* [MM-352] Add feature to publish release create and delete events * [MM-352] Update readme for updated webhook events * [MM-352] Update logic of creating post for the release events * [MM-352] Update indentation in template * [MM-352] Add release event in command help text
1 parent 936e5c3 commit 2056a77

File tree

6 files changed

+98
-3
lines changed

6 files changed

+98
-3
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ As a system admin, you must create a webhook for each organization you want to r
9595
- **Content Type:** `application/json`
9696
- **Secret:** the webhook secret you copied previously.
9797
6. Select **Let me select individual events** for "Which events would you like to trigger this webhook?".
98-
7. Select the following events: `Branch or Tag creation`, `Branch or Tag deletion`, `Issue comments`, `Issues`, `Pull requests`, `Pull request review`, `Pull request review comments`, `Pushes`, `Stars`.
98+
7. Select the following events: `Branch or Tag creation`, `Branch or Tag deletion`, `Issue comments`, `Issues`, `Pull requests`, `Pull request review`, `Pull request review comments`, `Pushes`, `Stars`, `Releases`.
9999
7. Hit **Add Webhook** to save it.
100100

101101
If you have multiple organizations, repeat the process starting from step 3 to create a webhook for each organization.
@@ -150,7 +150,7 @@ When you’ve tested the plugin and confirmed it’s working, notify your team s
150150
/github subscriptions add mattermost/mattermost-server --features issues,pulls,issue_comments,label:"Help Wanted"
151151
```
152152
- The following flags are supported:
153-
- `--features`: comma-delimited list of one or more of: issues, pulls, pulls_merged, pulls_created, pushes, creates, deletes, issue_creations, issue_comments, pull_reviews, label:"labelname". Defaults to pulls,issues,creates,deletes.
153+
- `--features`: comma-delimited list of one or more of: issues, pulls, pulls_merged, pulls_created, pushes, creates, deletes, issue_creations, issue_comments, pull_reviews, releases, label:"labelname". Defaults to pulls,issues,creates,deletes.
154154
- `--exclude-org-member`: events triggered by organization members will not be delivered. It will be locked to the organization provided in the plugin configuration and it will only work for users whose membership is public. Note that organization members and collaborators are not the same.
155155
- `--render-style`: notifications will be delivered in the specified style (for example, the body of a pull request will not be displayed). Supported
156156
values are `collapsed`, `skip-body` or `default` (same as omitting the flag).

server/plugin/command.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const (
2626
featureIssueComments = "issue_comments"
2727
featurePullReviews = "pull_reviews"
2828
featureStars = "stars"
29+
featureReleases = "releases"
2930
)
3031

3132
const (
@@ -44,6 +45,7 @@ var validFeatures = map[string]bool{
4445
featureIssueComments: true,
4546
featurePullReviews: true,
4647
featureStars: true,
48+
featureReleases: true,
4749
}
4850

4951
type Features string
@@ -894,7 +896,7 @@ func getAutocompleteData(config *Configuration) *model.AutocompleteData {
894896

895897
subscriptionsAdd := model.NewAutocompleteData("add", "[owner/repo] [features] [flags]", "Subscribe the current channel to receive notifications about opened pull requests and issues for an organization or repository. [features] and [flags] are optional arguments")
896898
subscriptionsAdd.AddTextArgument("Owner/repo to subscribe to", "[owner/repo]", "")
897-
subscriptionsAdd.AddNamedTextArgument("features", "Comma-delimited list of one or more of: issues, pulls, pulls_merged, pulls_created, pushes, creates, deletes, issue_creations, issue_comments, pull_reviews, label:\"<labelname>\". Defaults to pulls,issues,creates,deletes", "", `/[^,-\s]+(,[^,-\s]+)*/`, false)
899+
subscriptionsAdd.AddNamedTextArgument("features", "Comma-delimited list of one or more of: issues, pulls, pulls_merged, pulls_created, pushes, creates, deletes, issue_creations, issue_comments, pull_reviews, releases, label:\"<labelname>\". Defaults to pulls,issues,creates,deletes", "", `/[^,-\s]+(,[^,-\s]+)*/`, false)
898900

899901
if config.GitHubOrg != "" {
900902
subscriptionsAdd.AddNamedStaticListArgument("exclude-org-member", "Events triggered by organization members will not be delivered (the organization config should be set, otherwise this flag has not effect)", false, []model.AutocompleteListItem{

server/plugin/subscriptions.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ func (s *Subscription) Stars() bool {
123123
return strings.Contains(s.Features.String(), featureStars)
124124
}
125125

126+
func (s *Subscription) Release() bool {
127+
return strings.Contains(s.Features.String(), featureReleases)
128+
}
129+
126130
func (s *Subscription) Label() string {
127131
if !strings.Contains(s.Features.String(), "label:") {
128132
return ""

server/plugin/template.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ func init() {
158158
`[#{{.GetNumber}} {{.GetTitle}}]({{.GetHTMLURL}})`,
159159
))
160160

161+
// The release links to the corresponding release.
162+
template.Must(masterTemplate.New("release").Parse(
163+
`[{{.GetTagName}}]({{.GetHTMLURL}})`,
164+
))
165+
161166
// The eventRepoIssue links to the corresponding issue. Note that, for some events, the
162167
// issue *is* a pull request, and so we still use .GetIssue and this template accordingly.
163168
template.Must(masterTemplate.New("eventRepoIssue").Parse(
@@ -408,6 +413,7 @@ Assignees: {{range $i, $el := .Assignees -}} {{- if $i}}, {{end}}{{template "use
408413
" * `issue_comments` - includes new issue comments\n" +
409414
" * `issue_creations` - includes new issues only \n" +
410415
" * `pull_reviews` - includes pull request reviews\n" +
416+
" * `releases` - includes release created and deleted\n" +
411417
" * `label:<labelname>` - limit pull request and issue events to only this label. Must include `pulls` or `issues` in feature list when using a label.\n" +
412418
" * Defaults to `pulls,issues,creates,deletes`\n\n" +
413419
" * `--exclude-org-member` - events triggered by organization members will not be delivered (the GitHub organization config should be set, otherwise this flag has not effect)\n" +
@@ -429,6 +435,12 @@ Assignees: {{range $i, $el := .Assignees -}} {{- if $i}}, {{end}}{{template "use
429435
{{- else }} unstarred
430436
{{- end }} by {{template "user" .GetSender}}
431437
It now has **{{.GetRepo.GetStargazersCount}}** stars.`))
438+
439+
template.Must(masterTemplate.New("newReleaseEvent").Funcs(funcMap).Parse(`
440+
{{template "repo" .GetRepo}} {{template "user" .GetSender}}
441+
{{- if eq .GetAction "created" }} created a release {{template "release" .GetRelease}}
442+
{{- else if eq .GetAction "deleted" }} deleted a release {{template "release" .GetRelease}}
443+
{{- end -}}`))
432444
}
433445

434446
func registerGitHubToUsernameMappingCallback(callback func(string) string) {

server/plugin/template_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,42 @@ func TestPullRequestReviewNotification(t *testing.T) {
14071407
}))
14081408
}
14091409

1410+
func TestReleaseNotification(t *testing.T) {
1411+
t.Run("created", func(t *testing.T) {
1412+
expected := `
1413+
[\[mattermost-plugin-github\]](https://github.com/mattermost/mattermost-plugin-github) [panda](https://github.com/panda) created a release [v0.0.1](https://github.com/mattermost/mattermost-plugin-github/releases/tag/v0.0.1)`
1414+
1415+
actual, err := renderTemplate("newReleaseEvent", &github.ReleaseEvent{
1416+
Repo: &repo,
1417+
Sender: &user,
1418+
Action: sToP(actionCreated),
1419+
Release: &github.RepositoryRelease{
1420+
TagName: sToP("v0.0.1"),
1421+
HTMLURL: sToP("https://github.com/mattermost/mattermost-plugin-github/releases/tag/v0.0.1"),
1422+
},
1423+
})
1424+
require.NoError(t, err)
1425+
require.Equal(t, expected, actual)
1426+
})
1427+
1428+
t.Run("deleted", func(t *testing.T) {
1429+
expected := `
1430+
[\[mattermost-plugin-github\]](https://github.com/mattermost/mattermost-plugin-github) [panda](https://github.com/panda) deleted a release [v0.0.1](https://github.com/mattermost/mattermost-plugin-github/releases/tag/v0.0.1)`
1431+
1432+
actual, err := renderTemplate("newReleaseEvent", &github.ReleaseEvent{
1433+
Repo: &repo,
1434+
Sender: &user,
1435+
Action: sToP(actionDeleted),
1436+
Release: &github.RepositoryRelease{
1437+
TagName: sToP("v0.0.1"),
1438+
HTMLURL: sToP("https://github.com/mattermost/mattermost-plugin-github/releases/tag/v0.0.1"),
1439+
},
1440+
})
1441+
require.NoError(t, err)
1442+
require.Equal(t, expected, actual)
1443+
})
1444+
}
1445+
14101446
func TestGitHubUsernameRegex(t *testing.T) {
14111447
stringAndMatchMap := map[string]string{
14121448
// Contain valid usernames

server/plugin/webhook.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,11 @@ func (p *Plugin) handleWebhook(w http.ResponseWriter, r *http.Request) {
282282
handler = func() {
283283
p.postStarEvent(event)
284284
}
285+
case *github.ReleaseEvent:
286+
repo = event.GetRepo()
287+
handler = func() {
288+
p.postReleaseEvent(event)
289+
}
285290
}
286291

287292
if handler == nil {
@@ -1377,3 +1382,39 @@ func (p *Plugin) postStarEvent(event *github.StarEvent) {
13771382
}
13781383
}
13791384
}
1385+
1386+
func (p *Plugin) postReleaseEvent(event *github.ReleaseEvent) {
1387+
if event.GetAction() != actionCreated && event.GetAction() != actionDeleted {
1388+
return
1389+
}
1390+
1391+
repo := event.GetRepo()
1392+
subs := p.GetSubscribedChannelsForRepository(repo)
1393+
1394+
if len(subs) == 0 {
1395+
return
1396+
}
1397+
1398+
newReleaseMessage, err := renderTemplate("newReleaseEvent", event)
1399+
if err != nil {
1400+
p.client.Log.Warn("Failed to render template", "Error", err.Error())
1401+
return
1402+
}
1403+
1404+
for _, sub := range subs {
1405+
if !sub.Release() {
1406+
continue
1407+
}
1408+
1409+
post := &model.Post{
1410+
UserId: p.BotUserID,
1411+
Type: "custom_git_release",
1412+
Message: newReleaseMessage,
1413+
ChannelId: sub.ChannelID,
1414+
}
1415+
1416+
if err = p.client.Post.CreatePost(post); err != nil {
1417+
p.client.Log.Warn("Error webhook post", "Post", post, "Error", err.Error())
1418+
}
1419+
}
1420+
}

0 commit comments

Comments
 (0)