Skip to content

Commit

Permalink
feat(slack): Use blocks for releasing to Slack
Browse files Browse the repository at this point in the history
This feature should make the Slack output much nicer and will be iterated upon  to add more detail.
  • Loading branch information
fallion committed Nov 28, 2019
1 parent e5a57b2 commit 13c6206
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 41 deletions.
20 changes: 20 additions & 0 deletions internal/slack/block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package slack

type content struct {
// expected type is "mrkdwn"
Type string `json:"type"`
// markdown compliant message
Text string `json:"text"`
}

// Block holds the different blocks uses in the Slack block API, due to some unfortunate naming json:"text" actually contains subsections.
type Block struct {
// expected type is "section"
Type string `json:"type"`
Section content `json:"text"`
}

// WebhookMessage is the specific structure that Slack uses for the Webhook API
type WebhookMessage struct {
Blocks []Block `json:"blocks"`
}
8 changes: 2 additions & 6 deletions internal/slack/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ import (
"net/http"
"time"

"github.com/outillage/release-notary/internal/text"
jsoniter "github.com/json-iterator/go"
"github.com/outillage/release-notary/internal/text"
)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

type request struct {
Text string `json:"text"`
}

// Publish pushes the release notes to Slack via provided Webhook. https://api.slack.com/reference/messaging/payload
func (s *Slack) Publish(commits map[string][]text.Commit) error {
releaseNotes := GenerateReleaseNotes(commits)
Expand All @@ -23,7 +19,7 @@ func (s *Slack) Publish(commits map[string][]text.Commit) error {
Timeout: time.Second * 5,
}

jsonBody, err := json.Marshal(request{Text: releaseNotes})
jsonBody, err := json.Marshal(releaseNotes)

if err != nil {
return err
Expand Down
6 changes: 4 additions & 2 deletions internal/slack/publish_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ func TestPublish(t *testing.T) {

assert.NoError(t, err)

expectedBody := "{\"text\":\"*Features*\\r\\nci test\\r\\n\\r\\n*Bug fixes*\\r\\nhuge bug\\r\\nbug fix\\r\\n\\r\\n*Chores and Improvements*\\r\\ntesting\\r\\nthis should end up in chores\\r\\n\\r\\n*Other*\\r\\nmerge master in something\\r\\nrandom\\r\\n\\r\\n\"}"
expectedBody, err := ioutil.ReadFile("./testdata/expected_output.txt")

assert.Equal(t, expectedBody, string(body))
assert.NoError(t, err)

assert.Equal(t, string(expectedBody), string(body))

_, err = rw.Write([]byte(`ok`))

Expand Down
33 changes: 16 additions & 17 deletions internal/slack/release_notes.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,42 @@ import (
)

// GenerateReleaseNotes creates a string from release notes that conforms with the Slack formatting. Expected format can be found in testdata.
func GenerateReleaseNotes(sections map[string][]text.Commit) string {
builder := strings.Builder{}
func GenerateReleaseNotes(sections map[string][]text.Commit) WebhookMessage {
var blocks []Block

if len(sections["features"]) > 0 {
builder.WriteString("*Features*\r\n")
builder.WriteString(buildSection(sections["features"]))
builder.WriteString("\r\n")
section := Block{Type: "section", Section: buildSection("Features", sections["features"])}
blocks = append(blocks, section)
}

if len(sections["bugs"]) > 0 {
builder.WriteString("*Bug fixes*\r\n")
builder.WriteString(buildSection(sections["bugs"]))
builder.WriteString("\r\n")
section := Block{Type: "section", Section: buildSection("Bug fixes", sections["bugs"])}
blocks = append(blocks, section)
}

if len(sections["chores"]) > 0 {
builder.WriteString("*Chores and Improvements*\r\n")
builder.WriteString(buildSection(sections["chores"]))
builder.WriteString("\r\n")
section := Block{Type: "section", Section: buildSection("Chores and Improvements", sections["chores"])}
blocks = append(blocks, section)
}

if len(sections["others"]) > 0 {
builder.WriteString("*Other*\r\n")
builder.WriteString(buildSection(sections["others"]))
builder.WriteString("\r\n")
section := Block{Type: "section", Section: buildSection("Other", sections["others"])}
blocks = append(blocks, section)
}

return builder.String()
return WebhookMessage{Blocks: blocks}
}

func buildSection(commits []text.Commit) string {
func buildSection(heading string, commits []text.Commit) content {
builder := strings.Builder{}
builder.WriteString("*" + heading + "*\r\n")

for _, commit := range commits {
builder.WriteString(commit.Heading)
builder.WriteString("\r\n")
}

return builder.String()
section := content{Type: "mrkdwn", Text: builder.String()}

return section
}
10 changes: 9 additions & 1 deletion internal/slack/release_notes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,13 @@ func TestGenerateReleaseNotes(t *testing.T) {
"others": []text.Commit{text.Commit{Category: "other", Scope: "", Heading: "merge master in something"}, text.Commit{Category: "bs", Scope: "", Heading: "random"}},
}

assert.Equal(t, "*Features*\r\nci test\r\n\r\n*Bug fixes*\r\nhuge bug\r\nbug fix\r\n\r\n*Chores and Improvements*\r\ntesting\r\nthis should end up in chores\r\n\r\n*Other*\r\nmerge master in something\r\nrandom\r\n\r\n", GenerateReleaseNotes(testData))
expectedOutput := WebhookMessage(WebhookMessage{
Blocks: []Block{
Block{Type: "section", Section: content{Type: "mrkdwn", Text: "*Features*\r\nci test\r\n"}},
Block{Type: "section", Section: content{Type: "mrkdwn", Text: "*Bug fixes*\r\nhuge bug\r\nbug fix\r\n"}},
Block{Type: "section", Section: content{Type: "mrkdwn", Text: "*Chores and Improvements*\r\ntesting\r\nthis should end up in chores\r\n"}},
Block{Type: "section", Section: content{Type: "mrkdwn", Text: "*Other*\r\nmerge master in something\r\nrandom\r\n"}}},
})

assert.Equal(t, expectedOutput, GenerateReleaseNotes(testData))
}
15 changes: 0 additions & 15 deletions internal/slack/testdata/expected_format.md

This file was deleted.

1 change: 1 addition & 0 deletions internal/slack/testdata/expected_output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"blocks":[{"type":"section","text":{"type":"mrkdwn","text":"*Features*\r\nci test\r\n"}},{"type":"section","text":{"type":"mrkdwn","text":"*Bug fixes*\r\nhuge bug\r\nbug fix\r\n"}},{"type":"section","text":{"type":"mrkdwn","text":"*Chores and Improvements*\r\ntesting\r\nthis should end up in chores\r\n"}},{"type":"section","text":{"type":"mrkdwn","text":"*Other*\r\nmerge master in something\r\nrandom\r\n"}}]}

0 comments on commit 13c6206

Please sign in to comment.