1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-08 03:31:59 +02:00
goreleaser/internal/pipe/mattermost/mattermost.go
Carlos Alexandro Becker 262c8dcbfe
chore(deps): update env from v9 to v11 (#4789)
updated env to latest

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
2024-04-16 22:51:47 -03:00

148 lines
4.1 KiB
Go

package mattermost
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/caarlos0/env/v11"
"github.com/caarlos0/log"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
)
const (
defaultColor = "#2D313E"
defaultUsername = `GoReleaser`
defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}`
defaultMessageTitle = `{{ .ProjectName }} {{ .Tag }} is out!`
)
type Pipe struct{}
func (Pipe) String() string { return "mattermost" }
func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Config.Announce.Mattermost.Enabled }
type Config struct {
Webhook string `env:"MATTERMOST_WEBHOOK,notEmpty"`
}
func (Pipe) Default(ctx *context.Context) error {
if ctx.Config.Announce.Mattermost.MessageTemplate == "" {
ctx.Config.Announce.Mattermost.MessageTemplate = defaultMessageTemplate
}
if ctx.Config.Announce.Mattermost.TitleTemplate == "" {
ctx.Config.Announce.Mattermost.TitleTemplate = defaultMessageTitle
}
if ctx.Config.Announce.Mattermost.Username == "" {
ctx.Config.Announce.Mattermost.Username = defaultUsername
}
if ctx.Config.Announce.Teams.Color == "" {
ctx.Config.Announce.Teams.Color = defaultColor
}
return nil
}
func (Pipe) Announce(ctx *context.Context) error {
msg, err := tmpl.New(ctx).Apply(ctx.Config.Announce.Mattermost.MessageTemplate)
if err != nil {
return fmt.Errorf("mattermost: %w", err)
}
title, err := tmpl.New(ctx).Apply(ctx.Config.Announce.Mattermost.TitleTemplate)
if err != nil {
return fmt.Errorf("teams: %w", err)
}
cfg, err := env.ParseAs[Config]()
if err != nil {
return fmt.Errorf("mattermost: %w", err)
}
log.Infof("posting: %q", msg)
wm := &incomingWebhookRequest{
Username: ctx.Config.Announce.Mattermost.Username,
IconEmoji: ctx.Config.Announce.Mattermost.IconEmoji,
IconURL: ctx.Config.Announce.Mattermost.IconURL,
ChannelName: ctx.Config.Announce.Mattermost.Channel,
Attachments: []*mattermostAttachment{
{
Title: title,
Text: msg,
Color: ctx.Config.Announce.Teams.Color,
},
},
}
err = postWebhook(ctx, cfg.Webhook, wm)
if err != nil {
return fmt.Errorf("mattermost: %w", err)
}
return nil
}
func postWebhook(ctx *context.Context, url string, msg *incomingWebhookRequest) error {
payload, err := json.Marshal(msg)
if err != nil {
return fmt.Errorf("failed to marshal the message: %w", err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(payload))
if err != nil {
return fmt.Errorf("failed new request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
r, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("mattermost: %w", err)
}
closeBody(r)
return nil
}
func closeBody(r *http.Response) {
if r.Body != nil {
_, _ = io.Copy(io.Discard, r.Body)
_ = r.Body.Close()
}
}
type incomingWebhookRequest struct {
Text string `json:"text"`
Username string `json:"username"`
IconURL string `json:"icon_url"`
ChannelName string `json:"channel"`
Attachments []*mattermostAttachment `json:"attachments"`
IconEmoji string `json:"icon_emoji"`
}
type mattermostAttachment struct {
Fallback string `json:"fallback"`
Color string `json:"color"`
Pretext string `json:"pretext"`
AuthorName string `json:"author_name"`
AuthorLink string `json:"author_link"`
AuthorIcon string `json:"author_icon"`
Title string `json:"title"`
TitleLink string `json:"title_link"`
Text string `json:"text"`
Fields []*mattermostAttachmentField `json:"fields"`
Footer string `json:"footer"`
FooterIcon string `json:"footer_icon"`
}
type mattermostAttachmentField struct {
Title string `json:"title"`
Value interface{} `json:"value"`
Short bool `json:"short"`
}