Repository: goreleaser/goreleaser
Pull request #1483 (2020-05-01 15:53:31)

fix(pipe/brew): Default to GitHub
Previously `goreleaser --snapshot` (also used here in Travis CI) would fail if no token was provided, because Homebrew requires a token type for figuring out how to construct the download URLs.

This patch makes GitHub the default token type, which is in line with how releases work now.

### Before

```
      • homebrew tap formula
         • token type                type=
   ⨯ release failed after 42.51s error=homebrew tap formula: failed to publish artifacts: token type not implemented for brew pipe
```

### After

```
      • homebrew tap formula
         • token type                type=
         • writing                   formula=dist/goreleaser.rb
         • pipe skipped              error=publishing is disabled
```

--- 

I'm assuming this fix still retains the spirit of https://github.com/goreleaser/goreleaser/pull/1425 and allows inspection of formula before upload, or when the upload fails. The only downside is that the URLs in the generated formula may not match the ones that would then be used for publishing. That hopefully isn't a big deal though, because GoReleaser doesn't allow publishing of previously generated artifacts - i.e. the formula will be generated again with correct URLs before publishing.


Patch:
diff --git a/internal/pipe/brew/brew.go b/internal/pipe/brew/brew.go
index 7c633e2c..7baebdd0 100644
--- a/internal/pipe/brew/brew.go
+++ b/internal/pipe/brew/brew.go
@@ -26,8 +26,20 @@ var ErrNoArchivesFound = errors.New("no linux/macos archives found")
 // for linux or windows.
 var ErrMultipleArchivesSameOS = errors.New("one tap can handle only archive of an OS/Arch combination. Consider using ids in the brew section")
 
+// ErrEmptyTokenType indicates unknown token type
+var ErrEmptyTokenType = errors.New("no token type found")
+
 // ErrTokenTypeNotImplementedForBrew indicates that a new token type was not implemented for this pipe
-var ErrTokenTypeNotImplementedForBrew = errors.New("token type not implemented for brew pipe")
+type ErrTokenTypeNotImplementedForBrew struct {
+	TokenType context.TokenType
+}
+
+func (e ErrTokenTypeNotImplementedForBrew) Error() string {
+	if e.TokenType != "" {
+		return fmt.Sprintf("token type %q not implemented for brew pipe", e.TokenType)
+	}
+	return "token type not implemented for brew pipe"
+}
 
 // Pipe for brew deployment
 type Pipe struct{}
@@ -165,7 +177,10 @@ func doRun(ctx *context.Context, brew config.Homebrew, client client.Client) err
 	case context.TokenTypeGitLab:
 		repo = brew.GitLab
 	default:
-		return ErrTokenTypeNotImplementedForBrew
+		if string(ctx.TokenType) == "" {
+			return ErrEmptyTokenType
+		}
+		return ErrTokenTypeNotImplementedForBrew{ctx.TokenType}
 	}
 
 	var gpath = buildFormulaPath(brew.Folder, filename)
@@ -226,7 +241,8 @@ func dataFor(ctx *context.Context, cfg config.Homebrew, tokenType context.TokenT
 
 		if cfg.URLTemplate == "" {
 			switch tokenType {
-			case context.TokenTypeGitHub:
+			// we keep GitHub as default for now, in line with releases
+			case context.TokenTypeGitHub, "":
 				cfg.URLTemplate = fmt.Sprintf(
 					"%s/%s/%s/releases/download/{{ .Tag }}/{{ .ArtifactName }}",
 					ctx.Config.GitHubURLs.Download,
@@ -241,7 +257,7 @@ func dataFor(ctx *context.Context, cfg config.Homebrew, tokenType context.TokenT
 					ctx.Config.Release.GitLab.Name,
 				)
 			default:
-				return result, ErrTokenTypeNotImplementedForBrew
+				return result, ErrTokenTypeNotImplementedForBrew{tokenType}
 			}
 		}
 		url, err := tmpl.New(ctx).WithArtifact(artifact, map[string]string{}).Apply(cfg.URLTemplate)


Test patch:
diff --git a/internal/pipe/brew/brew_test.go b/internal/pipe/brew/brew_test.go
index cd21bbab..92000072 100644
--- a/internal/pipe/brew/brew_test.go
+++ b/internal/pipe/brew/brew_test.go
@@ -643,6 +643,41 @@ func TestRunPipeNoUpload(t *testing.T) {
 	})
 }
 
+func TestRunEmptyTokenType(t *testing.T) {
+	folder, err := ioutil.TempDir("", "goreleasertest")
+	assert.NoError(t, err)
+	var ctx = context.New(config.Project{
+		Dist:        folder,
+		ProjectName: "foo",
+		Release:     config.Release{},
+		Brews: []config.Homebrew{
+			{
+				GitHub: config.Repo{
+					Owner: "test",
+					Name:  "test",
+				},
+			},
+		},
+	})
+	ctx.Git = context.GitInfo{CurrentTag: "v1.0.1"}
+	var path = filepath.Join(folder, "whatever.tar.gz")
+	_, err = os.Create(path)
+	assert.NoError(t, err)
+	ctx.Artifacts.Add(&artifact.Artifact{
+		Name:   "bin",
+		Path:   path,
+		Goos:   "darwin",
+		Goarch: "amd64",
+		Type:   artifact.UploadableArchive,
+		Extra: map[string]interface{}{
+			"ID":     "foo",
+			"Format": "tar.gz",
+		},
+	})
+	client := &DummyClient{}
+	assert.Equal(t, ErrEmptyTokenType, doRun(ctx, ctx.Config.Brews[0], client))
+}
+
 func TestRunTokenTypeNotImplementedForBrew(t *testing.T) {
 	folder, err := ioutil.TempDir("", "goreleasertest")
 	assert.NoError(t, err)
@@ -659,6 +694,7 @@ func TestRunTokenTypeNotImplementedForBrew(t *testing.T) {
 			},
 		},
 	})
+	ctx.TokenType = context.TokenTypeGitea
 	ctx.Git = context.GitInfo{CurrentTag: "v1.0.1"}
 	var path = filepath.Join(folder, "whatever.tar.gz")
 	_, err = os.Create(path)
@@ -675,7 +711,7 @@ func TestRunTokenTypeNotImplementedForBrew(t *testing.T) {
 		},
 	})
 	client := &DummyClient{}
-	assert.Equal(t, ErrTokenTypeNotImplementedForBrew, doRun(ctx, ctx.Config.Brews[0], client))
+	assert.Equal(t, ErrTokenTypeNotImplementedForBrew{TokenType: "gitea"}, doRun(ctx, ctx.Config.Brews[0], client))
 }
 
 func TestDefault(t *testing.T) {