1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-14 03:51:24 +02:00

feat(announce): implement expected_status_codes for webhooks (#5317)

fixes #5316
This commit is contained in:
Matt Robenolt 2024-11-28 17:46:55 -08:00 committed by GitHub
parent 898c62c690
commit 77bbddf64b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 74 additions and 13 deletions

View File

@ -7,6 +7,7 @@ import (
"io"
"net/http"
"net/url"
"slices"
"strings"
"github.com/caarlos0/env/v11"
@ -24,6 +25,10 @@ const (
DefaultContentType = "application/json; charset=utf-8"
)
var defaultExepctedStatusCodes = []int{
http.StatusOK, http.StatusCreated, http.StatusAccepted, http.StatusNoContent,
}
type Pipe struct{}
func (Pipe) String() string { return "webhook" }
@ -71,6 +76,11 @@ func (p Pipe) Announce(ctx *context.Context) error {
return fmt.Errorf("webhook: %w", err)
}
expectedStatusCodes := ctx.Config.Announce.Webhook.ExpectedStatusCodes
if len(expectedStatusCodes) == 0 {
expectedStatusCodes = defaultExepctedStatusCodes
}
log.Infof("posting: '%s'", msg)
customTransport := http.DefaultTransport.(*http.Transport).Clone()
@ -107,13 +117,13 @@ func (p Pipe) Announce(ctx *context.Context) error {
}
defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK, http.StatusCreated, http.StatusAccepted, http.StatusNoContent:
log.Infof("Post OK: '%v'", resp.StatusCode)
body, _ := io.ReadAll(resp.Body)
log.Infof("Response : %v\n", string(body))
return nil
default:
if !slices.Contains(expectedStatusCodes, resp.StatusCode) {
io.Copy(io.Discard, resp.Body)
return fmt.Errorf("request failed with status %v", resp.Status)
}
body, _ := io.ReadAll(resp.Body)
log.Infof("Post OK: '%v'", resp.StatusCode)
log.Infof("Response : %v\n", string(body))
return nil
}

View File

@ -223,6 +223,39 @@ func TestAnnounceAdditionalHeadersWebhook(t *testing.T) {
require.NoError(t, Pipe{}.Announce(ctx))
}
func TestAnnounceExepectedStatusCodesWebhook(t *testing.T) {
responseServer := WebHookServerMockMessage{
Response: "Thanks for the announcement!",
UUID: uuid.New(),
}
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
body, err := io.ReadAll(r.Body)
assert.NoError(t, err)
assert.Equal(t, "webhook-test", string(body))
w.WriteHeader(418)
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(responseServer)
assert.NoError(t, err)
}))
defer srv.Close()
ctx := testctx.NewWithCfg(config.Project{
ProjectName: "webhook-test",
Announce: config.Announce{
Webhook: config.Webhook{
EndpointURL: srv.URL,
MessageTemplate: "{{ .ProjectName }}",
ExpectedStatusCodes: []int{418},
},
},
})
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()))

View File

@ -1319,12 +1319,13 @@ type Announce struct {
}
type Webhook struct {
Enabled bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`
SkipTLSVerify bool `yaml:"skip_tls_verify,omitempty" json:"skip_tls_verify,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty" json:"message_template,omitempty"`
EndpointURL string `yaml:"endpoint_url,omitempty" json:"endpoint_url,omitempty"`
Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty"`
ContentType string `yaml:"content_type,omitempty" json:"content_type,omitempty"`
Enabled bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`
SkipTLSVerify bool `yaml:"skip_tls_verify,omitempty" json:"skip_tls_verify,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty" json:"message_template,omitempty"`
EndpointURL string `yaml:"endpoint_url,omitempty" json:"endpoint_url,omitempty"`
Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty"`
ContentType string `yaml:"content_type,omitempty" json:"content_type,omitempty"`
ExpectedStatusCodes []int `yaml:"exected_status_codes,omitempty" json:"expected_status_codes,omitempty"`
}
type Twitter struct {

View File

@ -40,6 +40,11 @@ announce:
# Authorization: "Bearer <token>"
headers:
User-Agent: "goreleaser"
# HTTP status codes to be considered as a successful response.
#
# Default: 200, 201, 202, 204
expected_status_codes: [418, 200, 201]
```
<!-- md:templates -->

6
www/docs/static/schema-pro.json generated vendored
View File

@ -4592,6 +4592,12 @@
},
"content_type": {
"type": "string"
},
"expected_status_codes": {
"items": {
"type": "integer"
},
"type": "array"
}
},
"additionalProperties": false,

6
www/docs/static/schema.json generated vendored
View File

@ -3809,6 +3809,12 @@
},
"content_type": {
"type": "string"
},
"expected_status_codes": {
"items": {
"type": "integer"
},
"type": "array"
}
},
"additionalProperties": false,