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