From b269cc9229671acd5644257c77fd523c6e9a3840 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko <oleksandr.red+github@gmail.com> Date: Thu, 31 Oct 2024 13:57:46 +0200 Subject: [PATCH] feat: use context for HTTP request in discord (#5232) The PR adds using `context.Context` in the `POST` request. Context is a request scoped paradigm according to [the doc](https://pkg.go.dev/context). The PR adds `API` field into the `Config` for utilizing it in tests. --- internal/pipe/discord/discord.go | 11 ++++-- internal/pipe/discord/discord_test.go | 50 +++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/internal/pipe/discord/discord.go b/internal/pipe/discord/discord.go index 670d342e8..f867c09b6 100644 --- a/internal/pipe/discord/discord.go +++ b/internal/pipe/discord/discord.go @@ -27,6 +27,7 @@ func (Pipe) String() string { return "discord" } func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Config.Announce.Discord.Enabled } type Config struct { + API string `env:"DISCORD_API" envDefault:"https://discord.com/api"` WebhookID string `env:"DISCORD_WEBHOOK_ID,notEmpty"` WebhookToken string `env:"DISCORD_WEBHOOK_TOKEN,notEmpty"` } @@ -65,7 +66,7 @@ func (p Pipe) Announce(ctx *context.Context) error { return fmt.Errorf("discord: %w", err) } - u, err := url.Parse("https://discord.com/api") + u, err := url.Parse(cfg.API) if err != nil { return fmt.Errorf("discord: %w", err) } @@ -87,7 +88,13 @@ func (p Pipe) Announce(ctx *context.Context) error { return fmt.Errorf("discord: %w", err) } - resp, err := http.Post(u.String(), "application/json", bytes.NewReader(bts)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), bytes.NewReader(bts)) + if err != nil { + return fmt.Errorf("discord: %w", err) + } + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) if err != nil { return fmt.Errorf("discord: %w", err) } diff --git a/internal/pipe/discord/discord_test.go b/internal/pipe/discord/discord_test.go index d7aaf198a..042af7b0e 100644 --- a/internal/pipe/discord/discord_test.go +++ b/internal/pipe/discord/discord_test.go @@ -1,11 +1,17 @@ package discord import ( + "encoding/json" + "io" + "net/http" + "net/http/httptest" + "strconv" "testing" "github.com/goreleaser/goreleaser/v2/internal/testctx" "github.com/goreleaser/goreleaser/v2/internal/testlib" "github.com/goreleaser/goreleaser/v2/pkg/config" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -40,6 +46,50 @@ func TestAnnounceMissingEnv(t *testing.T) { require.EqualError(t, Pipe{}.Announce(ctx), `discord: env: environment variable "DISCORD_WEBHOOK_ID" should not be empty; environment variable "DISCORD_WEBHOOK_TOKEN" should not be empty`) } +func TestAnnounce(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + if r.URL.Path != "/webhooks/id/token" { + w.WriteHeader(http.StatusNotFound) + return + } + + wm := &WebhookMessageCreate{} + + body, _ := io.ReadAll(r.Body) + err := json.Unmarshal(body, wm) + assert.NoError(t, err) + assert.Equal(t, defaultColor, strconv.Itoa(wm.Embeds[0].Color)) + assert.Equal(t, "Honk v1.0.0 is out! Check it out at https://github.com/honk/honk/releases/tag/v1.0.0", wm.Embeds[0].Description) + + w.WriteHeader(http.StatusNoContent) + })) + defer ts.Close() + + ctx := testctx.NewWithCfg(config.Project{ + ProjectName: "Honk", + Announce: config.Announce{ + Discord: config.Discord{ + Enabled: true, + }, + }, + }) + + ctx.Git.CurrentTag = "v1.0.0" + ctx.ReleaseURL = "https://github.com/honk/honk/releases/tag/v1.0.0" + ctx.Git.URL = "https://github.com/honk/honk" + + t.Setenv("DISCORD_API", ts.URL) + t.Setenv("DISCORD_WEBHOOK_ID", "id") + t.Setenv("DISCORD_WEBHOOK_TOKEN", "token") + + require.NoError(t, Pipe{}.Default(ctx)) + require.NoError(t, Pipe{}.Announce(ctx)) +} + func TestSkip(t *testing.T) { t.Run("skip", func(t *testing.T) { require.True(t, Pipe{}.Skip(testctx.New()))