github.com/goreleaser/goreleaser@v1.25.1/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/goreleaser/goreleaser/internal/artifact"
    13  	"github.com/goreleaser/goreleaser/internal/client"
    14  	"github.com/goreleaser/goreleaser/internal/golden"
    15  	"github.com/goreleaser/goreleaser/internal/testctx"
    16  	"github.com/goreleaser/goreleaser/internal/testlib"
    17  	"github.com/goreleaser/goreleaser/internal/tmpl"
    18  	"github.com/goreleaser/goreleaser/pkg/config"
    19  	"github.com/goreleaser/goreleaser/pkg/context"
    20  	"github.com/stretchr/testify/require"
    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  							Base: config.PullRequestBase{
   372  								Owner: "og",
   373  								Name:  "bar",
   374  							},
   375  						},
   376  					},
   377  				},
   378  			},
   379  		},
   380  		testctx.WithVersion("1.2.1"),
   381  		testctx.WithCurrentTag("v1.2.1"),
   382  	)
   383  	path := filepath.Join(folder, "dist/foo_darwin_all/foo")
   384  	ctx.Artifacts.Add(&artifact.Artifact{
   385  		Name:   "foo_macos.tar.gz",
   386  		Path:   path,
   387  		Goos:   "darwin",
   388  		Goarch: "all",
   389  		Type:   artifact.UploadableArchive,
   390  		Extra: map[string]interface{}{
   391  			artifact.ExtraID:       "foo",
   392  			artifact.ExtraFormat:   "tar.gz",
   393  			artifact.ExtraBinaries: []string{"foo"},
   394  		},
   395  	})
   396  
   397  	require.NoError(t, os.MkdirAll(filepath.Dir(path), 0o755))
   398  	f, err := os.Create(path)
   399  	require.NoError(t, err)
   400  	require.NoError(t, f.Close())
   401  
   402  	client := client.NewMock()
   403  	require.NoError(t, runAll(ctx, client))
   404  	require.NoError(t, publishAll(ctx, client))
   405  	require.True(t, client.CreatedFile)
   406  	require.True(t, client.OpenedPullRequest)
   407  	require.True(t, client.SyncedFork)
   408  	golden.RequireEqualYaml(t, []byte(client.Content))
   409  }
   410  
   411  func TestRunPipeUniversalBinary(t *testing.T) {
   412  	folder := t.TempDir()
   413  
   414  	ctx := testctx.NewWithCfg(
   415  		config.Project{
   416  			Dist:        folder,
   417  			ProjectName: "unibin",
   418  			Krews: []config.Krew{
   419  				{
   420  					Name:             manifestName(t),
   421  					Description:      "Some desc",
   422  					ShortDescription: "Short desc",
   423  					Repository: config.RepoRef{
   424  						Owner: "unibin",
   425  						Name:  "bar",
   426  					},
   427  					IDs: []string{
   428  						"unibin",
   429  					},
   430  				},
   431  			},
   432  		},
   433  		testctx.WithCurrentTag("v1.0.1"),
   434  		testctx.WithVersion("1.0.1"),
   435  	)
   436  
   437  	path := filepath.Join(folder, "bin.tar.gz")
   438  	ctx.Artifacts.Add(&artifact.Artifact{
   439  		Name:   "unibin.tar.gz",
   440  		Path:   path,
   441  		Goos:   "darwin",
   442  		Goarch: "all",
   443  		Type:   artifact.UploadableArchive,
   444  		Extra: map[string]interface{}{
   445  			artifact.ExtraID:       "unibin",
   446  			artifact.ExtraFormat:   "tar.gz",
   447  			artifact.ExtraBinaries: []string{"unibin"},
   448  			artifact.ExtraReplaces: true,
   449  		},
   450  	})
   451  
   452  	f, err := os.Create(path)
   453  	require.NoError(t, err)
   454  	require.NoError(t, f.Close())
   455  	client := client.NewMock()
   456  	distFile := filepath.Join(folder, "krew", manifestName(t)+".yaml")
   457  
   458  	require.NoError(t, runAll(ctx, client))
   459  	require.NoError(t, publishAll(ctx, client))
   460  	require.True(t, client.CreatedFile)
   461  	golden.RequireEqualYaml(t, []byte(client.Content))
   462  	requireValidManifest(t)
   463  	distBts, err := os.ReadFile(distFile)
   464  	require.NoError(t, err)
   465  	require.Equal(t, client.Content, string(distBts))
   466  }
   467  
   468  func TestRunPipeUniversalBinaryNotReplacing(t *testing.T) {
   469  	folder := t.TempDir()
   470  	ctx := testctx.NewWithCfg(
   471  		config.Project{
   472  			Dist:        folder,
   473  			ProjectName: "unibin",
   474  			Krews: []config.Krew{
   475  				{
   476  					Name:             manifestName(t),
   477  					Description:      "Some desc",
   478  					ShortDescription: "Short desc",
   479  					Repository: config.RepoRef{
   480  						Owner: "unibin",
   481  						Name:  "bar",
   482  					},
   483  					IDs: []string{
   484  						"unibin",
   485  					},
   486  				},
   487  			},
   488  		},
   489  		testctx.WithCurrentTag("v1.0.1"),
   490  		testctx.WithVersion("1.0.1"),
   491  	)
   492  	path := filepath.Join(folder, "bin.tar.gz")
   493  	ctx.Artifacts.Add(&artifact.Artifact{
   494  		Name:    "unibin_amd64.tar.gz",
   495  		Path:    path,
   496  		Goos:    "darwin",
   497  		Goarch:  "amd64",
   498  		Goamd64: "v1",
   499  		Type:    artifact.UploadableArchive,
   500  		Extra: map[string]interface{}{
   501  			artifact.ExtraID:       "unibin",
   502  			artifact.ExtraFormat:   "tar.gz",
   503  			artifact.ExtraBinaries: []string{"unibin"},
   504  		},
   505  	})
   506  	ctx.Artifacts.Add(&artifact.Artifact{
   507  		Name:    "unibin_amd64.tar.gz",
   508  		Path:    path,
   509  		Goos:    "darwin",
   510  		Goarch:  "arm64",
   511  		Goamd64: "v1",
   512  		Type:    artifact.UploadableArchive,
   513  		Extra: map[string]interface{}{
   514  			artifact.ExtraID:       "unibin",
   515  			artifact.ExtraFormat:   "tar.gz",
   516  			artifact.ExtraBinaries: []string{"unibin"},
   517  		},
   518  	})
   519  	ctx.Artifacts.Add(&artifact.Artifact{
   520  		Name:   "unibin.tar.gz",
   521  		Path:   path,
   522  		Goos:   "darwin",
   523  		Goarch: "all",
   524  		Type:   artifact.UploadableArchive,
   525  		Extra: map[string]interface{}{
   526  			artifact.ExtraID:       "unibin",
   527  			artifact.ExtraFormat:   "tar.gz",
   528  			artifact.ExtraBinaries: []string{"unibin"},
   529  			artifact.ExtraReplaces: false,
   530  		},
   531  	})
   532  
   533  	f, err := os.Create(path)
   534  	require.NoError(t, err)
   535  	require.NoError(t, f.Close())
   536  	client := client.NewMock()
   537  	distFile := filepath.Join(folder, "krew", manifestName(t)+".yaml")
   538  
   539  	require.NoError(t, Pipe{}.Default(ctx))
   540  	require.NoError(t, runAll(ctx, client))
   541  	require.NoError(t, publishAll(ctx, client))
   542  	require.True(t, client.CreatedFile)
   543  	golden.RequireEqualYaml(t, []byte(client.Content))
   544  	requireValidManifest(t)
   545  	distBts, err := os.ReadFile(distFile)
   546  	require.NoError(t, err)
   547  	require.Equal(t, client.Content, string(distBts))
   548  }
   549  
   550  func TestRunPipeNameTemplate(t *testing.T) {
   551  	folder := t.TempDir()
   552  	ctx := testctx.NewWithCfg(
   553  		config.Project{
   554  			Dist:        folder,
   555  			ProjectName: "foo",
   556  			Krews: []config.Krew{
   557  				{
   558  					Name:             "{{ .Env.FOO_BAR }}",
   559  					Description:      "Some desc",
   560  					ShortDescription: "Short desc",
   561  					Repository: config.RepoRef{
   562  						Owner: "foo",
   563  						Name:  "bar",
   564  					},
   565  					IDs: []string{
   566  						"foo",
   567  					},
   568  				},
   569  			},
   570  			Env: []string{"FOO_BAR=" + t.Name()},
   571  		},
   572  		testctx.WithCurrentTag("v1.0.1"),
   573  		testctx.WithVersion("1.0.1"),
   574  	)
   575  	path := filepath.Join(folder, "bin.tar.gz")
   576  	ctx.Artifacts.Add(&artifact.Artifact{
   577  		Name:    "bin.tar.gz",
   578  		Path:    path,
   579  		Goos:    "darwin",
   580  		Goarch:  "amd64",
   581  		Goamd64: "v1",
   582  		Type:    artifact.UploadableArchive,
   583  		Extra: map[string]interface{}{
   584  			artifact.ExtraID:       "foo",
   585  			artifact.ExtraFormat:   "tar.gz",
   586  			artifact.ExtraBinaries: []string{"foo"},
   587  		},
   588  	})
   589  
   590  	f, err := os.Create(path)
   591  	require.NoError(t, err)
   592  	require.NoError(t, f.Close())
   593  	client := client.NewMock()
   594  	distFile := filepath.Join(folder, "krew", t.Name()+".yaml")
   595  
   596  	require.NoError(t, Pipe{}.Default(ctx))
   597  	require.NoError(t, runAll(ctx, client))
   598  	require.NoError(t, publishAll(ctx, client))
   599  	require.True(t, client.CreatedFile)
   600  	golden.RequireEqualYaml(t, []byte(client.Content))
   601  	requireValidManifest(t)
   602  	distBts, err := os.ReadFile(distFile)
   603  	require.NoError(t, err)
   604  	require.Equal(t, client.Content, string(distBts))
   605  }
   606  
   607  func TestRunPipeMultipleKrewWithSkip(t *testing.T) {
   608  	folder := t.TempDir()
   609  	ctx := testctx.NewWithCfg(
   610  		config.Project{
   611  			Dist:        folder,
   612  			ProjectName: "foo",
   613  			Krews: []config.Krew{
   614  				{
   615  					Name:             "foo",
   616  					Description:      "Some desc",
   617  					ShortDescription: "Short desc",
   618  					Repository: config.RepoRef{
   619  						Owner: "foo",
   620  						Name:  "bar",
   621  					},
   622  					IDs: []string{
   623  						"foo",
   624  					},
   625  					SkipUpload: "true",
   626  				},
   627  				{
   628  					Name:             "bar",
   629  					Description:      "Some desc",
   630  					ShortDescription: "Short desc",
   631  					Repository: config.RepoRef{
   632  						Owner: "foo",
   633  						Name:  "bar",
   634  					},
   635  					IDs: []string{
   636  						"foo",
   637  					},
   638  				},
   639  				{
   640  					Name:             "foobar",
   641  					Description:      "Some desc",
   642  					ShortDescription: "Short desc",
   643  					Repository: config.RepoRef{
   644  						Owner: "foo",
   645  						Name:  "bar",
   646  					},
   647  					IDs: []string{
   648  						"foo",
   649  					},
   650  					SkipUpload: "true",
   651  				},
   652  			},
   653  			Env: []string{"FOO_BAR=is_bar"},
   654  		},
   655  		testctx.WithCurrentTag("v1.0.1"),
   656  		testctx.WithVersion("1.0.1"),
   657  	)
   658  	path := filepath.Join(folder, "bin.tar.gz")
   659  	ctx.Artifacts.Add(&artifact.Artifact{
   660  		Name:    "bin.tar.gz",
   661  		Path:    path,
   662  		Goos:    "darwin",
   663  		Goarch:  "amd64",
   664  		Goamd64: "v1",
   665  		Type:    artifact.UploadableArchive,
   666  		Extra: map[string]interface{}{
   667  			artifact.ExtraID:       "foo",
   668  			artifact.ExtraFormat:   "tar.gz",
   669  			artifact.ExtraBinaries: []string{"foo"},
   670  		},
   671  	})
   672  
   673  	f, err := os.Create(path)
   674  	require.NoError(t, err)
   675  	require.NoError(t, f.Close())
   676  
   677  	cli := client.NewMock()
   678  	require.NoError(t, Pipe{}.Default(ctx))
   679  	require.NoError(t, runAll(ctx, cli))
   680  	require.EqualError(t, publishAll(ctx, cli), `krews.skip_upload is set`)
   681  	require.True(t, cli.CreatedFile)
   682  
   683  	for _, manifest := range ctx.Config.Krews {
   684  		distFile := filepath.Join(folder, "krew", manifest.Name+".yaml")
   685  		_, err := os.Stat(distFile)
   686  		require.NoError(t, err, "file should exist: "+distFile)
   687  	}
   688  }
   689  
   690  func TestRunPipeForMultipleArmVersions(t *testing.T) {
   691  	for name, fn := range map[string]func(ctx *context.Context){
   692  		"multiple_armv5": func(ctx *context.Context) {
   693  			ctx.Config.Krews[0].Goarm = "5"
   694  		},
   695  		"multiple_armv6": func(ctx *context.Context) {
   696  			ctx.Config.Krews[0].Goarm = "6"
   697  		},
   698  		"multiple_armv7": func(ctx *context.Context) {
   699  			ctx.Config.Krews[0].Goarm = "7"
   700  		},
   701  	} {
   702  		t.Run(name, func(t *testing.T) {
   703  			folder := t.TempDir()
   704  			ctx := testctx.NewWithCfg(
   705  				config.Project{
   706  					Dist:        folder,
   707  					ProjectName: name,
   708  					Krews: []config.Krew{
   709  						{
   710  							Name:             name,
   711  							ShortDescription: "Short desc",
   712  							Description:      "A run pipe test krew manifest and FOO={{ .Env.FOO }}",
   713  							Repository: config.RepoRef{
   714  								Owner: "test",
   715  								Name:  "test",
   716  							},
   717  							Homepage: "https://github.com/goreleaser",
   718  						},
   719  					},
   720  					GitHubURLs: config.GitHubURLs{
   721  						Download: "https://github.com",
   722  					},
   723  					Release: config.Release{
   724  						GitHub: config.Repo{
   725  							Owner: "test",
   726  							Name:  "test",
   727  						},
   728  					},
   729  					Env: []string{"FOO=foo_is_bar"},
   730  				},
   731  				testctx.GitHubTokenType,
   732  				testctx.WithVersion("1.0.1"),
   733  				testctx.WithCurrentTag("v1.0.1"),
   734  			)
   735  			fn(ctx)
   736  			for _, a := range []struct {
   737  				name   string
   738  				goos   string
   739  				goarch string
   740  				goarm  string
   741  			}{
   742  				{
   743  					name:   "bin",
   744  					goos:   "darwin",
   745  					goarch: "amd64",
   746  				},
   747  				{
   748  					name:   "arm64",
   749  					goos:   "linux",
   750  					goarch: "arm64",
   751  				},
   752  				{
   753  					name:   "armv5",
   754  					goos:   "linux",
   755  					goarch: "arm",
   756  					goarm:  "5",
   757  				},
   758  				{
   759  					name:   "armv6",
   760  					goos:   "linux",
   761  					goarch: "arm",
   762  					goarm:  "6",
   763  				},
   764  				{
   765  					name:   "armv7",
   766  					goos:   "linux",
   767  					goarch: "arm",
   768  					goarm:  "7",
   769  				},
   770  			} {
   771  				path := filepath.Join(folder, fmt.Sprintf("%s.tar.gz", a.name))
   772  				ctx.Artifacts.Add(&artifact.Artifact{
   773  					Name:    fmt.Sprintf("%s.tar.gz", a.name),
   774  					Path:    path,
   775  					Goos:    a.goos,
   776  					Goarch:  a.goarch,
   777  					Goarm:   a.goarm,
   778  					Goamd64: "v1",
   779  					Type:    artifact.UploadableArchive,
   780  					Extra: map[string]interface{}{
   781  						artifact.ExtraID:       a.name,
   782  						artifact.ExtraFormat:   "tar.gz",
   783  						artifact.ExtraBinaries: []string{"foo"},
   784  					},
   785  				})
   786  				f, err := os.Create(path)
   787  				require.NoError(t, err)
   788  				require.NoError(t, f.Close())
   789  			}
   790  
   791  			client := client.NewMock()
   792  			distFile := filepath.Join(folder, "krew", name+".yaml")
   793  
   794  			require.NoError(t, Pipe{}.Default(ctx))
   795  			require.NoError(t, runAll(ctx, client))
   796  			require.NoError(t, publishAll(ctx, client))
   797  			require.True(t, client.CreatedFile)
   798  			golden.RequireEqualYaml(t, []byte(client.Content))
   799  			requireValidManifest(t)
   800  
   801  			distBts, err := os.ReadFile(distFile)
   802  			require.NoError(t, err)
   803  			require.Equal(t, client.Content, string(distBts))
   804  		})
   805  	}
   806  }
   807  
   808  func TestRunPipeNoBuilds(t *testing.T) {
   809  	ctx := testctx.NewWithCfg(config.Project{
   810  		Krews: []config.Krew{
   811  			{
   812  				Name:             manifestName(t),
   813  				Description:      "Some desc",
   814  				ShortDescription: "Short desc",
   815  				Repository: config.RepoRef{
   816  					Owner: "test",
   817  					Name:  "test",
   818  				},
   819  			},
   820  		},
   821  	}, testctx.GitHubTokenType)
   822  	client := client.NewMock()
   823  	require.Equal(t, ErrNoArchivesFound, runAll(ctx, client))
   824  	require.False(t, client.CreatedFile)
   825  }
   826  
   827  func TestRunPipeNoUpload(t *testing.T) {
   828  	folder := t.TempDir()
   829  	ctx := testctx.NewWithCfg(config.Project{
   830  		Dist:        folder,
   831  		ProjectName: "foo",
   832  		Release:     config.Release{},
   833  		Krews: []config.Krew{
   834  			{
   835  				Name:             manifestName(t),
   836  				Description:      "Some desc",
   837  				ShortDescription: "Short desc",
   838  				Repository: config.RepoRef{
   839  					Owner: "test",
   840  					Name:  "test",
   841  				},
   842  			},
   843  		},
   844  	}, testctx.GitHubTokenType, testctx.WithCurrentTag("v1.0.1"))
   845  	path := filepath.Join(folder, "whatever.tar.gz")
   846  	f, err := os.Create(path)
   847  	require.NoError(t, err)
   848  	require.NoError(t, f.Close())
   849  	ctx.Artifacts.Add(&artifact.Artifact{
   850  		Name:    "bin",
   851  		Path:    path,
   852  		Goos:    "darwin",
   853  		Goarch:  "amd64",
   854  		Goamd64: "v1",
   855  		Type:    artifact.UploadableArchive,
   856  		Extra: map[string]interface{}{
   857  			artifact.ExtraID:       "foo",
   858  			artifact.ExtraFormat:   "tar.gz",
   859  			artifact.ExtraBinaries: []string{"foo"},
   860  		},
   861  	})
   862  	client := client.NewMock()
   863  	require.NoError(t, Pipe{}.Default(ctx))
   864  
   865  	assertNoPublish := func(t *testing.T) {
   866  		t.Helper()
   867  		require.NoError(t, runAll(ctx, client))
   868  		testlib.AssertSkipped(t, publishAll(ctx, client))
   869  		require.False(t, client.CreatedFile)
   870  	}
   871  	t.Run("skip upload true", func(t *testing.T) {
   872  		ctx.Config.Krews[0].SkipUpload = "true"
   873  		ctx.Semver.Prerelease = ""
   874  		assertNoPublish(t)
   875  	})
   876  	t.Run("skip upload auto", func(t *testing.T) {
   877  		ctx.Config.Krews[0].SkipUpload = "auto"
   878  		ctx.Semver.Prerelease = "beta1"
   879  		assertNoPublish(t)
   880  	})
   881  }
   882  
   883  func TestRunEmptyTokenType(t *testing.T) {
   884  	folder := t.TempDir()
   885  	ctx := testctx.NewWithCfg(config.Project{
   886  		Dist:        folder,
   887  		ProjectName: "foo",
   888  		Release:     config.Release{},
   889  		Krews: []config.Krew{
   890  			{
   891  				Name:             manifestName(t),
   892  				Description:      "Some desc",
   893  				ShortDescription: "Short desc",
   894  				Repository: config.RepoRef{
   895  					Owner: "test",
   896  					Name:  "test",
   897  				},
   898  			},
   899  		},
   900  	}, testctx.WithCurrentTag("v1.0.1"))
   901  	path := filepath.Join(folder, "whatever.tar.gz")
   902  	f, err := os.Create(path)
   903  	require.NoError(t, err)
   904  	require.NoError(t, f.Close())
   905  	ctx.Artifacts.Add(&artifact.Artifact{
   906  		Name:    "bin",
   907  		Path:    path,
   908  		Goos:    "darwin",
   909  		Goarch:  "amd64",
   910  		Goamd64: "v1",
   911  		Type:    artifact.UploadableArchive,
   912  		Extra: map[string]interface{}{
   913  			artifact.ExtraID:       "foo",
   914  			artifact.ExtraFormat:   "tar.gz",
   915  			artifact.ExtraBinaries: []string{"bin"},
   916  		},
   917  	})
   918  	client := client.NewMock()
   919  	require.NoError(t, Pipe{}.Default(ctx))
   920  	require.NoError(t, runAll(ctx, client))
   921  }
   922  
   923  func TestRunMultipleBinaries(t *testing.T) {
   924  	folder := t.TempDir()
   925  	ctx := testctx.NewWithCfg(config.Project{
   926  		Dist:        folder,
   927  		ProjectName: "foo",
   928  		Release:     config.Release{},
   929  		Krews: []config.Krew{
   930  			{
   931  				Name:             manifestName(t),
   932  				Description:      "Some desc",
   933  				ShortDescription: "Short desc",
   934  				Repository: config.RepoRef{
   935  					Owner: "test",
   936  					Name:  "test",
   937  				},
   938  			},
   939  		},
   940  	}, testctx.WithCurrentTag("v1.0.1"))
   941  	path := filepath.Join(folder, "whatever.tar.gz")
   942  	f, err := os.Create(path)
   943  	require.NoError(t, err)
   944  	require.NoError(t, f.Close())
   945  	ctx.Artifacts.Add(&artifact.Artifact{
   946  		Name:    "bin.tar.gz",
   947  		Path:    path,
   948  		Goos:    "darwin",
   949  		Goarch:  "amd64",
   950  		Goamd64: "v1",
   951  		Type:    artifact.UploadableArchive,
   952  		Extra: map[string]interface{}{
   953  			artifact.ExtraID:       "foo",
   954  			artifact.ExtraFormat:   "tar.gz",
   955  			artifact.ExtraBinaries: []string{"bin1", "bin2"},
   956  		},
   957  	})
   958  	require.NoError(t, Pipe{}.Default(ctx))
   959  	client := client.NewMock()
   960  	require.EqualError(t, runAll(ctx, client), `krew: only one binary per archive allowed, got 2 on "bin.tar.gz"`)
   961  }
   962  
   963  func TestDefault(t *testing.T) {
   964  	testlib.Mktmp(t)
   965  
   966  	ctx := testctx.NewWithCfg(config.Project{
   967  		ProjectName: "myproject",
   968  		Krews: []config.Krew{
   969  			{
   970  				Index: config.RepoRef{
   971  					Git: config.GitRepoRef{
   972  						URL: "foo/bar",
   973  					},
   974  				},
   975  			},
   976  		},
   977  	}, testctx.GitHubTokenType)
   978  	require.NoError(t, Pipe{}.Default(ctx))
   979  	require.Equal(t, ctx.Config.ProjectName, ctx.Config.Krews[0].Name)
   980  	require.NotEmpty(t, ctx.Config.Krews[0].CommitAuthor.Name)
   981  	require.NotEmpty(t, ctx.Config.Krews[0].CommitAuthor.Email)
   982  	require.NotEmpty(t, ctx.Config.Krews[0].CommitMessageTemplate)
   983  	require.Equal(t, "foo/bar", ctx.Config.Krews[0].Repository.Git.URL)
   984  	require.True(t, ctx.Deprecated)
   985  }
   986  
   987  func TestGHFolder(t *testing.T) {
   988  	require.Equal(t, "bar.yaml", buildManifestPath("", "bar.yaml"))
   989  	require.Equal(t, "fooo/bar.yaml", buildManifestPath("fooo", "bar.yaml"))
   990  }
   991  
   992  func TestSkip(t *testing.T) {
   993  	t.Run("skip", func(t *testing.T) {
   994  		require.True(t, Pipe{}.Skip(testctx.New()))
   995  	})
   996  
   997  	t.Run("dont skip", func(t *testing.T) {
   998  		ctx := testctx.NewWithCfg(config.Project{
   999  			Krews: []config.Krew{
  1000  				{},
  1001  			},
  1002  		})
  1003  		require.False(t, Pipe{}.Skip(ctx))
  1004  	})
  1005  }
  1006  
  1007  func TestRunSkipNoName(t *testing.T) {
  1008  	ctx := testctx.NewWithCfg(config.Project{
  1009  		Krews: []config.Krew{{}},
  1010  	})
  1011  
  1012  	client := client.NewMock()
  1013  	testlib.AssertSkipped(t, runAll(ctx, client))
  1014  }
  1015  
  1016  func manifestName(tb testing.TB) string {
  1017  	tb.Helper()
  1018  	return path.Base(tb.Name())
  1019  }
  1020  
  1021  func requireValidManifest(t *testing.T) {
  1022  	t.Helper()
  1023  	t.Run("valid", func(t *testing.T) {
  1024  		// needs to be the one on https://github.com/kubernetes-sigs/krew/pull/736
  1025  		testlib.CheckPath(t, "validate-krew-manifest")
  1026  		out, err := exec.Command(
  1027  			"validate-krew-manifest",
  1028  			"-skip-install",
  1029  			"-manifest=testdata/"+strings.TrimSuffix(t.Name(), "/valid")+".yaml",
  1030  		).CombinedOutput()
  1031  		require.NoError(t, err, string(out))
  1032  	})
  1033  }