1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-11-06 09:09:29 +02:00

fix: panic on gitlab create release (#2473)

Background
---
In 5bcfa9042d the condition was changed to
that it can support the new status code returned by GitLab. However, the
condition is now checked `resp != nil` and not `resp == nil` which causes
the condition not to trigger when the resp is nil and only returns an
error. We can reproduce this issue by running
`TestGitLabCreateReleaseUknownHost` test added in this commit.

Solution
---
If we look at other error handling
91a8abb2e6/internal/client/gitlab.go (L106)
we can see that we check if the `resp` is nil as well before continuing.

Added tests for the following use cases:
- When there is an error and no response was returned.
- When there is a 403 or 404 error so we expect to create a release
  first.
- When there is an unknown error (not 404, 403) we just bail.
This commit is contained in:
Steve Azzopardi
2021-09-10 21:35:42 +02:00
committed by GitHub
parent 91a8abb2e6
commit b0a6bf4705
2 changed files with 97 additions and 1 deletions

View File

@@ -213,7 +213,7 @@ func (c *gitlabClient) CreateRelease(ctx *context.Context, body string) (release
name := title
tagName := ctx.Git.CurrentTag
release, resp, err := c.client.Releases.GetRelease(projectID, tagName)
if err != nil && (resp != nil && resp.StatusCode != 403 && resp.StatusCode != 404) {
if err != nil && (resp == nil || (resp.StatusCode != 403 && resp.StatusCode != 404)) {
return "", err
}

View File

@@ -7,6 +7,7 @@ import (
"net/http"
"net/http/httptest"
"os"
"strconv"
"strings"
"testing"
"text/template"
@@ -227,3 +228,98 @@ func TestGitLabURLsDownloadTemplate(t *testing.T) {
})
}
}
func TestGitLabCreateReleaseUknownHost(t *testing.T) {
ctx := context.New(config.Project{
Release: config.Release{
GitLab: config.Repo{
Owner: "owner",
Name: "name",
},
},
GitLabURLs: config.GitLabURLs{
API: "http://goreleaser-notexists",
},
})
client, err := NewGitLab(ctx, "test-token")
require.NoError(t, err)
_, err = client.CreateRelease(ctx, "body")
require.Error(t, err)
}
func TestGitLabCreateReleaseReleaseNotExists(t *testing.T) {
notExistsStatusCodes := []int{http.StatusNotFound, http.StatusForbidden}
for _, tt := range notExistsStatusCodes {
t.Run(strconv.Itoa(tt), func(t *testing.T) {
totalRequests := 0
createdRelease := false
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
totalRequests++
if !strings.Contains(r.URL.Path, "releases") {
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, "{}")
return
}
// Check if release exists
if r.Method == http.MethodGet {
w.WriteHeader(tt)
fmt.Fprint(w, "{}")
return
}
// Create release if it doens't exists
if r.Method == http.MethodPost {
createdRelease = true
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, "{}")
return
}
require.FailNow(t, "should not reach here")
}))
defer srv.Close()
ctx := context.New(config.Project{
GitLabURLs: config.GitLabURLs{
API: srv.URL,
},
})
client, err := NewGitLab(ctx, "test-token")
require.NoError(t, err)
_, err = client.CreateRelease(ctx, "body")
require.NoError(t, err)
require.True(t, createdRelease)
require.Equal(t, 3, totalRequests)
})
}
}
func TestGitLabCreateReleaseUnkownHTTPError(t *testing.T) {
totalRequests := 0
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
totalRequests++
defer r.Body.Close()
w.WriteHeader(http.StatusUnprocessableEntity)
fmt.Fprint(w, "{}")
}))
defer srv.Close()
ctx := context.New(config.Project{
GitLabURLs: config.GitLabURLs{
API: srv.URL,
},
})
client, err := NewGitLab(ctx, "test-token")
require.NoError(t, err)
_, err = client.CreateRelease(ctx, "body")
require.Error(t, err)
require.Equal(t, 2, totalRequests)
}