github.com/triarius/goreleaser@v1.12.5/internal/pipe/krew/krew_test.go (about)

     1  package krew
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  	"path"
     8  	"path/filepath"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/triarius/goreleaser/internal/artifact"
    13  	"github.com/triarius/goreleaser/internal/client"
    14  	"github.com/triarius/goreleaser/internal/golden"
    15  	"github.com/triarius/goreleaser/internal/testlib"
    16  	"github.com/triarius/goreleaser/pkg/config"
    17  	"github.com/triarius/goreleaser/pkg/context"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func TestDescription(t *testing.T) {
    22  	require.NotEmpty(t, Pipe{}.String())
    23  }
    24  
    25  func createTemplateData() Manifest {
    26  	return Manifest{
    27  		APIVersion: apiVersion,
    28  		Kind:       kind,
    29  		Metadata: Metadata{
    30  			Name: "Test",
    31  		},
    32  		Spec: Spec{
    33  			Description:      "Some desc",
    34  			Homepage:         "https://google.com",
    35  			Version:          "v0.1.3",
    36  			ShortDescription: "Short desc",
    37  			Caveats:          "some caveat",
    38  			Platforms: []Platform{
    39  				{
    40  					Selector: Selector{
    41  						MatchLabels: MatchLabels{
    42  							Arch: "amd64",
    43  							Os:   "darwin",
    44  						},
    45  					},
    46  					URI:    "https://github.com/caarlos0/test/releases/download/v0.1.3/test_Darwin_x86_64.tar.gz",
    47  					Sha256: "1633f61598ab0791e213135923624eb342196b3494909c91899bcd0560f84c68",
    48  					Bin:    "test",
    49  				},
    50  				{
    51  					Selector: Selector{
    52  						MatchLabels: MatchLabels{
    53  							Arch: "arm64",
    54  							Os:   "darwin",
    55  						},
    56  					},
    57  					URI:    "https://github.com/caarlos0/test/releases/download/v0.1.3/test_Darwin_arm64.tar.gz",
    58  					Sha256: "1633f61598ab0791e213135923624eb342196b3494909c91899bcd0560f84c68",
    59  					Bin:    "test",
    60  				},
    61  				{
    62  					Selector: Selector{
    63  						MatchLabels: MatchLabels{
    64  							Arch: "amd64",
    65  							Os:   "linux",
    66  						},
    67  					},
    68  					URI:    "https://github.com/caarlos0/test/releases/download/v0.1.3/test_Linux_x86_64.tar.gz",
    69  					Sha256: "1633f61598ab0791e213135923624eb342196b3494909c91899bcd0560f84c67",
    70  					Bin:    "test",
    71  				},
    72  				{
    73  					Selector: Selector{
    74  						MatchLabels: MatchLabels{
    75  							Arch: "arm",
    76  							Os:   "linux",
    77  						},
    78  					},
    79  					URI:    "https://github.com/caarlos0/test/releases/download/v0.1.3/test_Arm6.tar.gz",
    80  					Sha256: "1633f61598ab0791e213135923624eb342196b3494909c91899bcd0560f84c67",
    81  					Bin:    "test",
    82  				},
    83  				{
    84  					Selector: Selector{
    85  						MatchLabels: MatchLabels{
    86  							Arch: "arm64",
    87  							Os:   "linux",
    88  						},
    89  					},
    90  					URI:    "https://github.com/caarlos0/test/releases/download/v0.1.3/test_Arm64.tar.gz",
    91  					Sha256: "1633f61598ab0791e213135923624eb342196b3494909c91899bcd0560f84c67",
    92  					Bin:    "test",
    93  				},
    94  				{
    95  					Selector: Selector{
    96  						MatchLabels: MatchLabels{
    97  							Arch: "amd64",
    98  							Os:   "windows",
    99  						},
   100  					},
   101  					URI:    "https://github.com/caarlos0/test/releases/download/v0.1.3/test_windows_amd64.zip",
   102  					Sha256: "1633f61598ab0791e213135923624eb342196b3494909c91899bcd0560f84c67",
   103  					Bin:    "test.exe",
   104  				},
   105  			},
   106  		},
   107  	}
   108  }
   109  
   110  func TestFullManifest(t *testing.T) {
   111  	data := createTemplateData()
   112  	data.Metadata.Name = manifestName(t)
   113  	manifest, err := doBuildManifest(data)
   114  	require.NoError(t, err)
   115  
   116  	golden.RequireEqualYaml(t, []byte(manifest))
   117  	requireValidManifest(t)
   118  }
   119  
   120  func TestSimple(t *testing.T) {
   121  	data := createTemplateData()
   122  	data.Metadata.Name = manifestName(t)
   123  	manifest, err := doBuildManifest(data)
   124  	require.NoError(t, err)
   125  	golden.RequireEqualYaml(t, []byte(manifest))
   126  	requireValidManifest(t)
   127  }
   128  
   129  func TestFullPipe(t *testing.T) {
   130  	type testcase struct {
   131  		prepare              func(ctx *context.Context)
   132  		expectedRunError     string
   133  		expectedPublishError string
   134  	}
   135  	for name, tt := range map[string]testcase{
   136  		"default": {
   137  			prepare: func(ctx *context.Context) {
   138  				ctx.TokenType = context.TokenTypeGitHub
   139  				ctx.Config.Krews[0].Index.Owner = "test"
   140  				ctx.Config.Krews[0].Index.Name = "test"
   141  				ctx.Config.Krews[0].Homepage = "https://github.com/goreleaser"
   142  			},
   143  		},
   144  		"default_gitlab": {
   145  			prepare: func(ctx *context.Context) {
   146  				ctx.TokenType = context.TokenTypeGitLab
   147  				ctx.Config.Krews[0].Index.Owner = "test"
   148  				ctx.Config.Krews[0].Index.Name = "test"
   149  				ctx.Config.Krews[0].Homepage = "https://gitlab.com/goreleaser"
   150  			},
   151  		},
   152  		"invalid_commit_template": {
   153  			prepare: func(ctx *context.Context) {
   154  				ctx.Config.Krews[0].Index.Owner = "test"
   155  				ctx.Config.Krews[0].Index.Name = "test"
   156  				ctx.Config.Krews[0].CommitMessageTemplate = "{{ .Asdsa }"
   157  			},
   158  			expectedPublishError: `template: tmpl:1: unexpected "}" in operand`,
   159  		},
   160  		"invalid desc": {
   161  			prepare: func(ctx *context.Context) {
   162  				ctx.Config.Krews[0].Index.Owner = "test"
   163  				ctx.Config.Krews[0].Index.Name = "test"
   164  				ctx.Config.Krews[0].Description = "{{ .Asdsa }"
   165  			},
   166  			expectedRunError: `template: tmpl:1: unexpected "}" in operand`,
   167  		},
   168  		"invalid short desc": {
   169  			prepare: func(ctx *context.Context) {
   170  				ctx.Config.Krews[0].Index.Owner = "test"
   171  				ctx.Config.Krews[0].Index.Name = "test"
   172  				ctx.Config.Krews[0].ShortDescription = "{{ .Asdsa }"
   173  			},
   174  			expectedRunError: `template: tmpl:1: unexpected "}" in operand`,
   175  		},
   176  		"invalid homepage": {
   177  			prepare: func(ctx *context.Context) {
   178  				ctx.Config.Krews[0].Index.Owner = "test"
   179  				ctx.Config.Krews[0].Index.Name = "test"
   180  				ctx.Config.Krews[0].Homepage = "{{ .Asdsa }"
   181  			},
   182  			expectedRunError: `template: tmpl:1: unexpected "}" in operand`,
   183  		},
   184  		"invalid name": {
   185  			prepare: func(ctx *context.Context) {
   186  				ctx.Config.Krews[0].Index.Owner = "test"
   187  				ctx.Config.Krews[0].Index.Name = "test"
   188  				ctx.Config.Krews[0].Name = "{{ .Asdsa }"
   189  			},
   190  			expectedRunError: `template: tmpl:1: unexpected "}" in operand`,
   191  		},
   192  		"invalid caveats": {
   193  			prepare: func(ctx *context.Context) {
   194  				ctx.Config.Krews[0].Index.Owner = "test"
   195  				ctx.Config.Krews[0].Index.Name = "test"
   196  				ctx.Config.Krews[0].Caveats = "{{ .Asdsa }"
   197  			},
   198  			expectedRunError: `template: tmpl:1: unexpected "}" in operand`,
   199  		},
   200  		"no short desc": {
   201  			prepare: func(ctx *context.Context) {
   202  				ctx.Config.Krews[0].Index.Owner = "test"
   203  				ctx.Config.Krews[0].Index.Name = "test"
   204  				ctx.Config.Krews[0].Description = "lalala"
   205  				ctx.Config.Krews[0].ShortDescription = ""
   206  			},
   207  			expectedRunError: `krew: manifest short description is not set`,
   208  		},
   209  		"no desc": {
   210  			prepare: func(ctx *context.Context) {
   211  				ctx.Config.Krews[0].Index.Owner = "test"
   212  				ctx.Config.Krews[0].Index.Name = "test"
   213  				ctx.Config.Krews[0].Description = ""
   214  				ctx.Config.Krews[0].ShortDescription = "lalala"
   215  			},
   216  			expectedRunError: `krew: manifest description is not set`,
   217  		},
   218  	} {
   219  		t.Run(name, func(t *testing.T) {
   220  			folder := t.TempDir()
   221  			ctx := &context.Context{
   222  				Git: context.GitInfo{
   223  					CurrentTag: "v1.0.1",
   224  				},
   225  				Version:   "1.0.1",
   226  				Artifacts: artifact.New(),
   227  				Env: map[string]string{
   228  					"FOO": "foo_is_bar",
   229  					"BAR": "honk",
   230  				},
   231  				Config: config.Project{
   232  					Dist:        folder,
   233  					ProjectName: name,
   234  					Krews: []config.Krew{
   235  						{
   236  							Name:             name,
   237  							IDs:              []string{"foo"},
   238  							Description:      "A run pipe test krew manifest and FOO={{ .Env.FOO }}",
   239  							ShortDescription: "short desc {{.Env.BAR}}",
   240  						},
   241  					},
   242  				},
   243  			}
   244  			tt.prepare(ctx)
   245  			ctx.Artifacts.Add(&artifact.Artifact{
   246  				Name:    "bar_bin.tar.gz",
   247  				Path:    "doesnt matter",
   248  				Goos:    "darwin",
   249  				Goarch:  "amd64",
   250  				Goamd64: "v1",
   251  				Type:    artifact.UploadableArchive,
   252  				Extra: map[string]interface{}{
   253  					artifact.ExtraID:     "bar",
   254  					artifact.ExtraFormat: "tar.gz",
   255  				},
   256  			})
   257  			path := filepath.Join(folder, "bin.tar.gz")
   258  			ctx.Artifacts.Add(&artifact.Artifact{
   259  				Name:    "bin.tar.gz",
   260  				Path:    path,
   261  				Goos:    "darwin",
   262  				Goarch:  "amd64",
   263  				Goamd64: "v1",
   264  				Type:    artifact.UploadableArchive,
   265  				Extra: map[string]interface{}{
   266  					artifact.ExtraID:       "foo",
   267  					artifact.ExtraFormat:   "tar.gz",
   268  					artifact.ExtraBinaries: []string{"name"},
   269  				},
   270  			})
   271  			ctx.Artifacts.Add(&artifact.Artifact{
   272  				Name:    "this-should-be-ignored.tar.gz",
   273  				Path:    path,
   274  				Goos:    "darwin",
   275  				Goarch:  "amd64",
   276  				Goamd64: "v3",
   277  				Type:    artifact.UploadableArchive,
   278  				Extra: map[string]interface{}{
   279  					artifact.ExtraID:       "foo",
   280  					artifact.ExtraFormat:   "tar.gz",
   281  					artifact.ExtraBinaries: []string{"name"},
   282  				},
   283  			})
   284  
   285  			f, err := os.Create(path)
   286  			require.NoError(t, err)
   287  			require.NoError(t, f.Close())
   288  			client := client.NewMock()
   289  			distFile := filepath.Join(folder, name+".yaml")
   290  
   291  			require.NoError(t, Pipe{}.Default(ctx))
   292  			err = runAll(ctx, client)
   293  			if tt.expectedRunError != "" {
   294  				require.EqualError(t, err, tt.expectedRunError)
   295  				return
   296  			}
   297  			require.NoError(t, err)
   298  
   299  			err = publishAll(ctx, client)
   300  			if tt.expectedPublishError != "" {
   301  				require.EqualError(t, err, tt.expectedPublishError)
   302  				return
   303  			}
   304  
   305  			require.NoError(t, err)
   306  			require.True(t, client.CreatedFile)
   307  			golden.RequireEqualYaml(t, []byte(client.Content))
   308  			requireValidManifest(t)
   309  
   310  			distBts, err := os.ReadFile(distFile)
   311  			require.NoError(t, err)
   312  			require.Equal(t, client.Content, string(distBts))
   313  		})
   314  	}
   315  }
   316  
   317  func TestRunPipeUniversalBinary(t *testing.T) {
   318  	folder := t.TempDir()
   319  	ctx := &context.Context{
   320  		Git: context.GitInfo{
   321  			CurrentTag: "v1.0.1",
   322  		},
   323  		Version:   "1.0.1",
   324  		Artifacts: artifact.New(),
   325  		Config: config.Project{
   326  			Dist:        folder,
   327  			ProjectName: "unibin",
   328  			Krews: []config.Krew{
   329  				{
   330  					Name:             manifestName(t),
   331  					Description:      "Some desc",
   332  					ShortDescription: "Short desc",
   333  					Index: config.RepoRef{
   334  						Owner: "unibin",
   335  						Name:  "bar",
   336  					},
   337  					IDs: []string{
   338  						"unibin",
   339  					},
   340  				},
   341  			},
   342  		},
   343  	}
   344  	path := filepath.Join(folder, "bin.tar.gz")
   345  	ctx.Artifacts.Add(&artifact.Artifact{
   346  		Name:   "unibin.tar.gz",
   347  		Path:   path,
   348  		Goos:   "darwin",
   349  		Goarch: "all",
   350  		Type:   artifact.UploadableArchive,
   351  		Extra: map[string]interface{}{
   352  			artifact.ExtraID:       "unibin",
   353  			artifact.ExtraFormat:   "tar.gz",
   354  			artifact.ExtraBinaries: []string{"unibin"},
   355  			artifact.ExtraReplaces: true,
   356  		},
   357  	})
   358  
   359  	f, err := os.Create(path)
   360  	require.NoError(t, err)
   361  	require.NoError(t, f.Close())
   362  	client := client.NewMock()
   363  	distFile := filepath.Join(folder, manifestName(t)+".yaml")
   364  
   365  	require.NoError(t, runAll(ctx, client))
   366  	require.NoError(t, publishAll(ctx, client))
   367  	require.True(t, client.CreatedFile)
   368  	golden.RequireEqualYaml(t, []byte(client.Content))
   369  	requireValidManifest(t)
   370  	distBts, err := os.ReadFile(distFile)
   371  	require.NoError(t, err)
   372  	require.Equal(t, client.Content, string(distBts))
   373  }
   374  
   375  func TestRunPipeUniversalBinaryNotReplacing(t *testing.T) {
   376  	folder := t.TempDir()
   377  	ctx := &context.Context{
   378  		Git: context.GitInfo{
   379  			CurrentTag: "v1.0.1",
   380  		},
   381  		Version:   "1.0.1",
   382  		Artifacts: artifact.New(),
   383  		Config: config.Project{
   384  			Dist:        folder,
   385  			ProjectName: "unibin",
   386  			Krews: []config.Krew{
   387  				{
   388  					Name:             manifestName(t),
   389  					Description:      "Some desc",
   390  					ShortDescription: "Short desc",
   391  					Index: config.RepoRef{
   392  						Owner: "unibin",
   393  						Name:  "bar",
   394  					},
   395  					IDs: []string{
   396  						"unibin",
   397  					},
   398  				},
   399  			},
   400  		},
   401  	}
   402  	path := filepath.Join(folder, "bin.tar.gz")
   403  	ctx.Artifacts.Add(&artifact.Artifact{
   404  		Name:    "unibin_amd64.tar.gz",
   405  		Path:    path,
   406  		Goos:    "darwin",
   407  		Goarch:  "amd64",
   408  		Goamd64: "v1",
   409  		Type:    artifact.UploadableArchive,
   410  		Extra: map[string]interface{}{
   411  			artifact.ExtraID:       "unibin",
   412  			artifact.ExtraFormat:   "tar.gz",
   413  			artifact.ExtraBinaries: []string{"unibin"},
   414  		},
   415  	})
   416  	ctx.Artifacts.Add(&artifact.Artifact{
   417  		Name:    "unibin_amd64.tar.gz",
   418  		Path:    path,
   419  		Goos:    "darwin",
   420  		Goarch:  "arm64",
   421  		Goamd64: "v1",
   422  		Type:    artifact.UploadableArchive,
   423  		Extra: map[string]interface{}{
   424  			artifact.ExtraID:       "unibin",
   425  			artifact.ExtraFormat:   "tar.gz",
   426  			artifact.ExtraBinaries: []string{"unibin"},
   427  		},
   428  	})
   429  	ctx.Artifacts.Add(&artifact.Artifact{
   430  		Name:   "unibin.tar.gz",
   431  		Path:   path,
   432  		Goos:   "darwin",
   433  		Goarch: "all",
   434  		Type:   artifact.UploadableArchive,
   435  		Extra: map[string]interface{}{
   436  			artifact.ExtraID:       "unibin",
   437  			artifact.ExtraFormat:   "tar.gz",
   438  			artifact.ExtraBinaries: []string{"unibin"},
   439  			artifact.ExtraReplaces: false,
   440  		},
   441  	})
   442  
   443  	f, err := os.Create(path)
   444  	require.NoError(t, err)
   445  	require.NoError(t, f.Close())
   446  	client := client.NewMock()
   447  	distFile := filepath.Join(folder, manifestName(t)+".yaml")
   448  
   449  	require.NoError(t, Pipe{}.Default(ctx))
   450  	require.NoError(t, runAll(ctx, client))
   451  	require.NoError(t, publishAll(ctx, client))
   452  	require.True(t, client.CreatedFile)
   453  	golden.RequireEqualYaml(t, []byte(client.Content))
   454  	requireValidManifest(t)
   455  	distBts, err := os.ReadFile(distFile)
   456  	require.NoError(t, err)
   457  	require.Equal(t, client.Content, string(distBts))
   458  }
   459  
   460  func TestRunPipeNameTemplate(t *testing.T) {
   461  	folder := t.TempDir()
   462  	ctx := &context.Context{
   463  		Git: context.GitInfo{
   464  			CurrentTag: "v1.0.1",
   465  		},
   466  		Version:   "1.0.1",
   467  		Artifacts: artifact.New(),
   468  		Env: map[string]string{
   469  			"FOO_BAR": t.Name(),
   470  		},
   471  		Config: config.Project{
   472  			Dist:        folder,
   473  			ProjectName: "foo",
   474  			Krews: []config.Krew{
   475  				{
   476  					Name:             "{{ .Env.FOO_BAR }}",
   477  					Description:      "Some desc",
   478  					ShortDescription: "Short desc",
   479  					Index: config.RepoRef{
   480  						Owner: "foo",
   481  						Name:  "bar",
   482  					},
   483  					IDs: []string{
   484  						"foo",
   485  					},
   486  				},
   487  			},
   488  		},
   489  	}
   490  	path := filepath.Join(folder, "bin.tar.gz")
   491  	ctx.Artifacts.Add(&artifact.Artifact{
   492  		Name:    "bin.tar.gz",
   493  		Path:    path,
   494  		Goos:    "darwin",
   495  		Goarch:  "amd64",
   496  		Goamd64: "v1",
   497  		Type:    artifact.UploadableArchive,
   498  		Extra: map[string]interface{}{
   499  			artifact.ExtraID:       "foo",
   500  			artifact.ExtraFormat:   "tar.gz",
   501  			artifact.ExtraBinaries: []string{"foo"},
   502  		},
   503  	})
   504  
   505  	f, err := os.Create(path)
   506  	require.NoError(t, err)
   507  	require.NoError(t, f.Close())
   508  	client := client.NewMock()
   509  	distFile := filepath.Join(folder, t.Name()+".yaml")
   510  
   511  	require.NoError(t, Pipe{}.Default(ctx))
   512  	require.NoError(t, runAll(ctx, client))
   513  	require.NoError(t, publishAll(ctx, client))
   514  	require.True(t, client.CreatedFile)
   515  	golden.RequireEqualYaml(t, []byte(client.Content))
   516  	requireValidManifest(t)
   517  	distBts, err := os.ReadFile(distFile)
   518  	require.NoError(t, err)
   519  	require.Equal(t, client.Content, string(distBts))
   520  }
   521  
   522  func TestRunPipeMultipleKrewWithSkip(t *testing.T) {
   523  	folder := t.TempDir()
   524  	ctx := &context.Context{
   525  		Git: context.GitInfo{
   526  			CurrentTag: "v1.0.1",
   527  		},
   528  		Version:   "1.0.1",
   529  		Artifacts: artifact.New(),
   530  		Env: map[string]string{
   531  			"FOO_BAR": "is_bar",
   532  		},
   533  		Config: config.Project{
   534  			Dist:        folder,
   535  			ProjectName: "foo",
   536  			Krews: []config.Krew{
   537  				{
   538  					Name:             "foo",
   539  					Description:      "Some desc",
   540  					ShortDescription: "Short desc",
   541  					Index: config.RepoRef{
   542  						Owner: "foo",
   543  						Name:  "bar",
   544  					},
   545  					IDs: []string{
   546  						"foo",
   547  					},
   548  					SkipUpload: "true",
   549  				},
   550  				{
   551  					Name:             "bar",
   552  					Description:      "Some desc",
   553  					ShortDescription: "Short desc",
   554  					Index: config.RepoRef{
   555  						Owner: "foo",
   556  						Name:  "bar",
   557  					},
   558  					IDs: []string{
   559  						"foo",
   560  					},
   561  				},
   562  				{
   563  					Name:             "foobar",
   564  					Description:      "Some desc",
   565  					ShortDescription: "Short desc",
   566  					Index: config.RepoRef{
   567  						Owner: "foo",
   568  						Name:  "bar",
   569  					},
   570  					IDs: []string{
   571  						"foo",
   572  					},
   573  					SkipUpload: "true",
   574  				},
   575  			},
   576  		},
   577  	}
   578  	path := filepath.Join(folder, "bin.tar.gz")
   579  	ctx.Artifacts.Add(&artifact.Artifact{
   580  		Name:    "bin.tar.gz",
   581  		Path:    path,
   582  		Goos:    "darwin",
   583  		Goarch:  "amd64",
   584  		Goamd64: "v1",
   585  		Type:    artifact.UploadableArchive,
   586  		Extra: map[string]interface{}{
   587  			artifact.ExtraID:       "foo",
   588  			artifact.ExtraFormat:   "tar.gz",
   589  			artifact.ExtraBinaries: []string{"foo"},
   590  		},
   591  	})
   592  
   593  	f, err := os.Create(path)
   594  	require.NoError(t, err)
   595  	require.NoError(t, f.Close())
   596  
   597  	cli := client.NewMock()
   598  	require.NoError(t, Pipe{}.Default(ctx))
   599  	require.NoError(t, runAll(ctx, cli))
   600  	require.EqualError(t, publishAll(ctx, cli), `krews.skip_upload is set`)
   601  	require.True(t, cli.CreatedFile)
   602  
   603  	for _, manifest := range ctx.Config.Krews {
   604  		distFile := filepath.Join(folder, manifest.Name+".yaml")
   605  		_, err := os.Stat(distFile)
   606  		require.NoError(t, err, "file should exist: "+distFile)
   607  	}
   608  }
   609  
   610  func TestRunPipeForMultipleArmVersions(t *testing.T) {
   611  	for name, fn := range map[string]func(ctx *context.Context){
   612  		"multiple_armv5": func(ctx *context.Context) {
   613  			ctx.Config.Krews[0].Goarm = "5"
   614  		},
   615  		"multiple_armv6": func(ctx *context.Context) {
   616  			ctx.Config.Krews[0].Goarm = "6"
   617  		},
   618  		"multiple_armv7": func(ctx *context.Context) {
   619  			ctx.Config.Krews[0].Goarm = "7"
   620  		},
   621  	} {
   622  		t.Run(name, func(t *testing.T) {
   623  			folder := t.TempDir()
   624  			ctx := &context.Context{
   625  				TokenType: context.TokenTypeGitHub,
   626  				Git: context.GitInfo{
   627  					CurrentTag: "v1.0.1",
   628  				},
   629  				Version:   "1.0.1",
   630  				Artifacts: artifact.New(),
   631  				Env: map[string]string{
   632  					"FOO": "foo_is_bar",
   633  				},
   634  				Config: config.Project{
   635  					Dist:        folder,
   636  					ProjectName: name,
   637  					Krews: []config.Krew{
   638  						{
   639  							Name:             name,
   640  							ShortDescription: "Short desc",
   641  							Description:      "A run pipe test krew manifest and FOO={{ .Env.FOO }}",
   642  							Index: config.RepoRef{
   643  								Owner: "test",
   644  								Name:  "test",
   645  							},
   646  							Homepage: "https://github.com/goreleaser",
   647  						},
   648  					},
   649  					GitHubURLs: config.GitHubURLs{
   650  						Download: "https://github.com",
   651  					},
   652  					Release: config.Release{
   653  						GitHub: config.Repo{
   654  							Owner: "test",
   655  							Name:  "test",
   656  						},
   657  					},
   658  				},
   659  			}
   660  			fn(ctx)
   661  			for _, a := range []struct {
   662  				name   string
   663  				goos   string
   664  				goarch string
   665  				goarm  string
   666  			}{
   667  				{
   668  					name:   "bin",
   669  					goos:   "darwin",
   670  					goarch: "amd64",
   671  				},
   672  				{
   673  					name:   "arm64",
   674  					goos:   "linux",
   675  					goarch: "arm64",
   676  				},
   677  				{
   678  					name:   "armv5",
   679  					goos:   "linux",
   680  					goarch: "arm",
   681  					goarm:  "5",
   682  				},
   683  				{
   684  					name:   "armv6",
   685  					goos:   "linux",
   686  					goarch: "arm",
   687  					goarm:  "6",
   688  				},
   689  				{
   690  					name:   "armv7",
   691  					goos:   "linux",
   692  					goarch: "arm",
   693  					goarm:  "7",
   694  				},
   695  			} {
   696  				path := filepath.Join(folder, fmt.Sprintf("%s.tar.gz", a.name))
   697  				ctx.Artifacts.Add(&artifact.Artifact{
   698  					Name:    fmt.Sprintf("%s.tar.gz", a.name),
   699  					Path:    path,
   700  					Goos:    a.goos,
   701  					Goarch:  a.goarch,
   702  					Goarm:   a.goarm,
   703  					Goamd64: "v1",
   704  					Type:    artifact.UploadableArchive,
   705  					Extra: map[string]interface{}{
   706  						artifact.ExtraID:       a.name,
   707  						artifact.ExtraFormat:   "tar.gz",
   708  						artifact.ExtraBinaries: []string{"foo"},
   709  					},
   710  				})
   711  				f, err := os.Create(path)
   712  				require.NoError(t, err)
   713  				require.NoError(t, f.Close())
   714  			}
   715  
   716  			client := client.NewMock()
   717  			distFile := filepath.Join(folder, name+".yaml")
   718  
   719  			require.NoError(t, Pipe{}.Default(ctx))
   720  			require.NoError(t, runAll(ctx, client))
   721  			require.NoError(t, publishAll(ctx, client))
   722  			require.True(t, client.CreatedFile)
   723  			golden.RequireEqualYaml(t, []byte(client.Content))
   724  			requireValidManifest(t)
   725  
   726  			distBts, err := os.ReadFile(distFile)
   727  			require.NoError(t, err)
   728  			require.Equal(t, client.Content, string(distBts))
   729  		})
   730  	}
   731  }
   732  
   733  func TestRunPipeNoBuilds(t *testing.T) {
   734  	ctx := context.New(
   735  		config.Project{
   736  			Krews: []config.Krew{
   737  				{
   738  					Name:             manifestName(t),
   739  					Description:      "Some desc",
   740  					ShortDescription: "Short desc",
   741  					Index: config.RepoRef{
   742  						Owner: "test",
   743  						Name:  "test",
   744  					},
   745  				},
   746  			},
   747  		},
   748  	)
   749  	ctx.TokenType = context.TokenTypeGitHub
   750  	client := client.NewMock()
   751  	require.Equal(t, ErrNoArchivesFound, runAll(ctx, client))
   752  	require.False(t, client.CreatedFile)
   753  }
   754  
   755  func TestRunPipeNoUpload(t *testing.T) {
   756  	folder := t.TempDir()
   757  	ctx := context.New(config.Project{
   758  		Dist:        folder,
   759  		ProjectName: "foo",
   760  		Release:     config.Release{},
   761  		Krews: []config.Krew{
   762  			{
   763  				Name:             manifestName(t),
   764  				Description:      "Some desc",
   765  				ShortDescription: "Short desc",
   766  				Index: config.RepoRef{
   767  					Owner: "test",
   768  					Name:  "test",
   769  				},
   770  			},
   771  		},
   772  	})
   773  	ctx.TokenType = context.TokenTypeGitHub
   774  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.1"}
   775  	path := filepath.Join(folder, "whatever.tar.gz")
   776  	f, err := os.Create(path)
   777  	require.NoError(t, err)
   778  	require.NoError(t, f.Close())
   779  	ctx.Artifacts.Add(&artifact.Artifact{
   780  		Name:    "bin",
   781  		Path:    path,
   782  		Goos:    "darwin",
   783  		Goarch:  "amd64",
   784  		Goamd64: "v1",
   785  		Type:    artifact.UploadableArchive,
   786  		Extra: map[string]interface{}{
   787  			artifact.ExtraID:       "foo",
   788  			artifact.ExtraFormat:   "tar.gz",
   789  			artifact.ExtraBinaries: []string{"foo"},
   790  		},
   791  	})
   792  	client := client.NewMock()
   793  	require.NoError(t, Pipe{}.Default(ctx))
   794  
   795  	assertNoPublish := func(t *testing.T) {
   796  		t.Helper()
   797  		require.NoError(t, runAll(ctx, client))
   798  		testlib.AssertSkipped(t, publishAll(ctx, client))
   799  		require.False(t, client.CreatedFile)
   800  	}
   801  	t.Run("skip upload true", func(t *testing.T) {
   802  		ctx.Config.Krews[0].SkipUpload = "true"
   803  		ctx.Semver.Prerelease = ""
   804  		assertNoPublish(t)
   805  	})
   806  	t.Run("skip upload auto", func(t *testing.T) {
   807  		ctx.Config.Krews[0].SkipUpload = "auto"
   808  		ctx.Semver.Prerelease = "beta1"
   809  		assertNoPublish(t)
   810  	})
   811  }
   812  
   813  func TestRunEmptyTokenType(t *testing.T) {
   814  	folder := t.TempDir()
   815  	ctx := context.New(config.Project{
   816  		Dist:        folder,
   817  		ProjectName: "foo",
   818  		Release:     config.Release{},
   819  		Krews: []config.Krew{
   820  			{
   821  				Name:             manifestName(t),
   822  				Description:      "Some desc",
   823  				ShortDescription: "Short desc",
   824  				Index: config.RepoRef{
   825  					Owner: "test",
   826  					Name:  "test",
   827  				},
   828  			},
   829  		},
   830  	})
   831  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.1"}
   832  	path := filepath.Join(folder, "whatever.tar.gz")
   833  	f, err := os.Create(path)
   834  	require.NoError(t, err)
   835  	require.NoError(t, f.Close())
   836  	ctx.Artifacts.Add(&artifact.Artifact{
   837  		Name:    "bin",
   838  		Path:    path,
   839  		Goos:    "darwin",
   840  		Goarch:  "amd64",
   841  		Goamd64: "v1",
   842  		Type:    artifact.UploadableArchive,
   843  		Extra: map[string]interface{}{
   844  			artifact.ExtraID:       "foo",
   845  			artifact.ExtraFormat:   "tar.gz",
   846  			artifact.ExtraBinaries: []string{"bin"},
   847  		},
   848  	})
   849  	client := client.NewMock()
   850  	require.NoError(t, Pipe{}.Default(ctx))
   851  	require.NoError(t, runAll(ctx, client))
   852  }
   853  
   854  func TestRunMultipleBinaries(t *testing.T) {
   855  	folder := t.TempDir()
   856  	ctx := context.New(config.Project{
   857  		Dist:        folder,
   858  		ProjectName: "foo",
   859  		Release:     config.Release{},
   860  		Krews: []config.Krew{
   861  			{
   862  				Name:             manifestName(t),
   863  				Description:      "Some desc",
   864  				ShortDescription: "Short desc",
   865  				Index: config.RepoRef{
   866  					Owner: "test",
   867  					Name:  "test",
   868  				},
   869  			},
   870  		},
   871  	})
   872  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.1"}
   873  	path := filepath.Join(folder, "whatever.tar.gz")
   874  	f, err := os.Create(path)
   875  	require.NoError(t, err)
   876  	require.NoError(t, f.Close())
   877  	ctx.Artifacts.Add(&artifact.Artifact{
   878  		Name:    "bin.tar.gz",
   879  		Path:    path,
   880  		Goos:    "darwin",
   881  		Goarch:  "amd64",
   882  		Goamd64: "v1",
   883  		Type:    artifact.UploadableArchive,
   884  		Extra: map[string]interface{}{
   885  			artifact.ExtraID:       "foo",
   886  			artifact.ExtraFormat:   "tar.gz",
   887  			artifact.ExtraBinaries: []string{"bin1", "bin2"},
   888  		},
   889  	})
   890  	require.NoError(t, Pipe{}.Default(ctx))
   891  	client := client.NewMock()
   892  	require.EqualError(t, runAll(ctx, client), `krew: only one binary per archive allowed, got 2 on "bin.tar.gz"`)
   893  }
   894  
   895  func TestDefault(t *testing.T) {
   896  	testlib.Mktmp(t)
   897  
   898  	ctx := &context.Context{
   899  		TokenType: context.TokenTypeGitHub,
   900  		Config: config.Project{
   901  			ProjectName: "myproject",
   902  			Krews: []config.Krew{
   903  				{},
   904  			},
   905  		},
   906  	}
   907  	require.NoError(t, Pipe{}.Default(ctx))
   908  	require.Equal(t, ctx.Config.ProjectName, ctx.Config.Krews[0].Name)
   909  	require.NotEmpty(t, ctx.Config.Krews[0].CommitAuthor.Name)
   910  	require.NotEmpty(t, ctx.Config.Krews[0].CommitAuthor.Email)
   911  	require.NotEmpty(t, ctx.Config.Krews[0].CommitMessageTemplate)
   912  }
   913  
   914  func TestGHFolder(t *testing.T) {
   915  	require.Equal(t, "bar.yaml", buildManifestPath("", "bar.yaml"))
   916  	require.Equal(t, "fooo/bar.yaml", buildManifestPath("fooo", "bar.yaml"))
   917  }
   918  
   919  func TestSkip(t *testing.T) {
   920  	t.Run("skip", func(t *testing.T) {
   921  		require.True(t, Pipe{}.Skip(context.New(config.Project{})))
   922  	})
   923  
   924  	t.Run("dont skip", func(t *testing.T) {
   925  		ctx := context.New(config.Project{
   926  			Krews: []config.Krew{
   927  				{},
   928  			},
   929  		})
   930  		require.False(t, Pipe{}.Skip(ctx))
   931  	})
   932  }
   933  
   934  func TestRunSkipNoName(t *testing.T) {
   935  	ctx := context.New(config.Project{
   936  		Krews: []config.Krew{{}},
   937  	})
   938  
   939  	client := client.NewMock()
   940  	testlib.AssertSkipped(t, runAll(ctx, client))
   941  }
   942  
   943  func manifestName(tb testing.TB) string {
   944  	tb.Helper()
   945  	return path.Base(tb.Name())
   946  }
   947  
   948  func requireValidManifest(t *testing.T) {
   949  	t.Helper()
   950  	t.Run("valid", func(t *testing.T) {
   951  		// needs to be the one on https://github.com/kubernetes-sigs/krew/pull/736
   952  		testlib.CheckPath(t, "validate-krew-manifest")
   953  		out, err := exec.Command(
   954  			"validate-krew-manifest",
   955  			"-skip-install",
   956  			"-manifest=testdata/"+strings.TrimSuffix(t.Name(), "/valid")+".yaml",
   957  		).CombinedOutput()
   958  		require.NoError(t, err, string(out))
   959  	})
   960  }