github.com/triarius/goreleaser@v1.12.5/internal/exec/exec_test.go (about)

     1  package exec
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/triarius/goreleaser/internal/artifact"
    10  	"github.com/triarius/goreleaser/pkg/config"
    11  	"github.com/triarius/goreleaser/pkg/context"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestExecute(t *testing.T) {
    16  	ctx := context.New(config.Project{
    17  		ProjectName: "blah",
    18  		Archives: []config.Archive{
    19  			{
    20  				Replacements: map[string]string{
    21  					"linux": "Linux",
    22  				},
    23  			},
    24  		},
    25  	})
    26  	ctx.Env["TEST_A_SECRET"] = "x"
    27  	ctx.Env["TEST_A_USERNAME"] = "u2"
    28  	ctx.Version = "2.1.0"
    29  
    30  	// Preload artifacts
    31  	ctx.Artifacts = artifact.New()
    32  	folder := t.TempDir()
    33  	for _, a := range []struct {
    34  		id  string
    35  		ext string
    36  		typ artifact.Type
    37  	}{
    38  		{"debpkg", "deb", artifact.LinuxPackage},
    39  		{"binary", "bin", artifact.Binary},
    40  		{"archive", "tar", artifact.UploadableArchive},
    41  		{"ubinary", "ubi", artifact.UploadableBinary},
    42  		{"checksum", "sum", artifact.Checksum},
    43  		{"signature", "sig", artifact.Signature},
    44  		{"signature", "pem", artifact.Certificate},
    45  	} {
    46  		file := filepath.Join(folder, "a."+a.ext)
    47  		require.NoError(t, os.WriteFile(file, []byte("lorem ipsum"), 0o644))
    48  		ctx.Artifacts.Add(&artifact.Artifact{
    49  			Name:   "a." + a.ext,
    50  			Goos:   "linux",
    51  			Goarch: "amd64",
    52  			Path:   file,
    53  			Type:   a.typ,
    54  			Extra: map[string]interface{}{
    55  				artifact.ExtraID: a.id,
    56  			},
    57  		})
    58  	}
    59  
    60  	ctx.Artifacts.Add(&artifact.Artifact{
    61  		Name:   "foo/bar:amd64",
    62  		Goos:   "linux",
    63  		Goarch: "amd64",
    64  		Path:   "foo/bar:amd64",
    65  		Type:   artifact.DockerImage,
    66  		Extra: map[string]interface{}{
    67  			artifact.ExtraID: "img",
    68  		},
    69  	})
    70  	ctx.Artifacts.Add(&artifact.Artifact{
    71  		Name: "foo/bar",
    72  		Path: "foo/bar",
    73  		Type: artifact.DockerManifest,
    74  		Extra: map[string]interface{}{
    75  			artifact.ExtraID: "mnf",
    76  		},
    77  	})
    78  
    79  	osEnv := func(ignores ...string) []string {
    80  		var result []string
    81  	outer:
    82  		for _, key := range passthroughEnvVars {
    83  			for _, ignore := range ignores {
    84  				if key == ignore {
    85  					continue outer
    86  				}
    87  			}
    88  			if value := os.Getenv(key); value != "" {
    89  				result = append(result, key+"="+value)
    90  			}
    91  		}
    92  		return result
    93  	}
    94  
    95  	testCases := []struct {
    96  		name       string
    97  		publishers []config.Publisher
    98  		expectErr  error
    99  	}{
   100  		{
   101  			"filter by IDs",
   102  			[]config.Publisher{
   103  				{
   104  					Name: "test",
   105  					IDs:  []string{"archive"},
   106  					Cmd:  MockCmd + " {{ .ArtifactName }}",
   107  					Env: []string{
   108  						MarshalMockEnv(&MockData{
   109  							AnyOf: []MockCall{
   110  								{ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   111  							},
   112  						}),
   113  					},
   114  				},
   115  			},
   116  			nil,
   117  		},
   118  		{
   119  			"no filter",
   120  			[]config.Publisher{
   121  				{
   122  					Name: "test",
   123  					Cmd:  MockCmd + " {{ .ArtifactName }}",
   124  					Env: []string{
   125  						MarshalMockEnv(&MockData{
   126  							AnyOf: []MockCall{
   127  								{ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()},
   128  								{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()},
   129  								{ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   130  								{ExpectedArgs: []string{"foo/bar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   131  								{ExpectedArgs: []string{"foo/bar:amd64"}, ExitCode: 0, ExpectedEnv: osEnv()},
   132  							},
   133  						}),
   134  					},
   135  				},
   136  			},
   137  			nil,
   138  		},
   139  		{
   140  			"include checksum",
   141  			[]config.Publisher{
   142  				{
   143  					Name:     "test",
   144  					Checksum: true,
   145  					Cmd:      MockCmd + " {{ .ArtifactName }}",
   146  					Env: []string{
   147  						MarshalMockEnv(&MockData{
   148  							AnyOf: []MockCall{
   149  								{ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()},
   150  								{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()},
   151  								{ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   152  								{ExpectedArgs: []string{"a.sum"}, ExitCode: 0, ExpectedEnv: osEnv()},
   153  								{ExpectedArgs: []string{"foo/bar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   154  								{ExpectedArgs: []string{"foo/bar:amd64"}, ExitCode: 0, ExpectedEnv: osEnv()},
   155  							},
   156  						}),
   157  					},
   158  				},
   159  			},
   160  			nil,
   161  		},
   162  		{
   163  			"include signatures",
   164  			[]config.Publisher{
   165  				{
   166  					Name:      "test",
   167  					Signature: true,
   168  					Cmd:       MockCmd + " {{ .ArtifactName }}",
   169  					Env: []string{
   170  						MarshalMockEnv(&MockData{
   171  							AnyOf: []MockCall{
   172  								{ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()},
   173  								{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()},
   174  								{ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   175  								{ExpectedArgs: []string{"a.sig"}, ExitCode: 0, ExpectedEnv: osEnv()},
   176  								{ExpectedArgs: []string{"a.pem"}, ExitCode: 0, ExpectedEnv: osEnv()},
   177  								{ExpectedArgs: []string{"foo/bar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   178  								{ExpectedArgs: []string{"foo/bar:amd64"}, ExitCode: 0, ExpectedEnv: osEnv()},
   179  							},
   180  						}),
   181  					},
   182  				},
   183  			},
   184  			nil,
   185  		},
   186  		{
   187  			"docker",
   188  			[]config.Publisher{
   189  				{
   190  					Name: "test",
   191  					IDs:  []string{"img", "mnf"},
   192  					Cmd:  MockCmd + " {{ .ArtifactName }}",
   193  					Env: []string{
   194  						MarshalMockEnv(&MockData{
   195  							AnyOf: []MockCall{
   196  								{ExpectedArgs: []string{"foo/bar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   197  								{ExpectedArgs: []string{"foo/bar:amd64"}, ExitCode: 0, ExpectedEnv: osEnv()},
   198  							},
   199  						}),
   200  					},
   201  				},
   202  			},
   203  			nil,
   204  		},
   205  		{
   206  			"extra files",
   207  			[]config.Publisher{
   208  				{
   209  					Name: "test",
   210  					Cmd:  MockCmd + " {{ .ArtifactName }}",
   211  					Env: []string{
   212  						MarshalMockEnv(&MockData{
   213  							AnyOf: []MockCall{
   214  								{ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()},
   215  								{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()},
   216  								{ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   217  								{ExpectedArgs: []string{"a.txt"}, ExitCode: 0, ExpectedEnv: osEnv()},
   218  								{ExpectedArgs: []string{"foo/bar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   219  								{ExpectedArgs: []string{"foo/bar:amd64"}, ExitCode: 0, ExpectedEnv: osEnv()},
   220  							},
   221  						}),
   222  					},
   223  					ExtraFiles: []config.ExtraFile{
   224  						{Glob: filepath.Join("testdata", "*.txt")},
   225  					},
   226  				},
   227  			},
   228  			nil,
   229  		},
   230  		{
   231  			"extra files with rename",
   232  			[]config.Publisher{
   233  				{
   234  					Name: "test",
   235  					Cmd:  MockCmd + " {{ .ArtifactName }}",
   236  					Env: []string{
   237  						MarshalMockEnv(&MockData{
   238  							AnyOf: []MockCall{
   239  								{ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()},
   240  								{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()},
   241  								{ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   242  								{ExpectedArgs: []string{"b.txt"}, ExitCode: 0, ExpectedEnv: osEnv()},
   243  								{ExpectedArgs: []string{"foo/bar"}, ExitCode: 0, ExpectedEnv: osEnv()},
   244  								{ExpectedArgs: []string{"foo/bar:amd64"}, ExitCode: 0, ExpectedEnv: osEnv()},
   245  							},
   246  						}),
   247  					},
   248  					ExtraFiles: []config.ExtraFile{
   249  						{
   250  							Glob:         filepath.Join("testdata", "*.txt"),
   251  							NameTemplate: "b.txt",
   252  						},
   253  					},
   254  				},
   255  			},
   256  			nil,
   257  		},
   258  		{
   259  			"try dir templating",
   260  			[]config.Publisher{
   261  				{
   262  					Name:      "test",
   263  					Signature: true,
   264  					IDs:       []string{"debpkg"},
   265  					Dir:       "{{ dir .ArtifactPath }}",
   266  					Cmd:       MockCmd + " {{ .ArtifactName }}",
   267  					Env: []string{
   268  						MarshalMockEnv(&MockData{
   269  							AnyOf: []MockCall{
   270  								{ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()},
   271  							},
   272  						}),
   273  					},
   274  				},
   275  			},
   276  			nil,
   277  		},
   278  		{
   279  			"check env templating",
   280  			[]config.Publisher{
   281  				{
   282  					Name: "test",
   283  					IDs:  []string{"debpkg"},
   284  					Cmd:  MockCmd,
   285  					Env: []string{
   286  						"PROJECT={{.ProjectName}}",
   287  						"ARTIFACT={{.ArtifactName}}",
   288  						"SECRET={{.Env.TEST_A_SECRET}}",
   289  						MarshalMockEnv(&MockData{
   290  							AnyOf: []MockCall{
   291  								{
   292  									ExpectedEnv: append(
   293  										[]string{"PROJECT=blah", "ARTIFACT=a.deb", "SECRET=x"},
   294  										osEnv()...,
   295  									),
   296  									ExitCode: 0,
   297  								},
   298  							},
   299  						}),
   300  					},
   301  				},
   302  			},
   303  			nil,
   304  		},
   305  		{
   306  			"override path",
   307  			[]config.Publisher{
   308  				{
   309  					Name: "test",
   310  					IDs:  []string{"debpkg"},
   311  					Cmd:  MockCmd,
   312  					Env: []string{
   313  						"PATH=/something-else",
   314  						MarshalMockEnv(&MockData{
   315  							AnyOf: []MockCall{
   316  								{
   317  									ExpectedEnv: append(
   318  										[]string{"PATH=/something-else"},
   319  										osEnv("PATH")...,
   320  									),
   321  									ExitCode: 0,
   322  								},
   323  							},
   324  						}),
   325  					},
   326  				},
   327  			},
   328  			nil,
   329  		},
   330  		{
   331  			"command error",
   332  			[]config.Publisher{
   333  				{
   334  					Name: "test",
   335  					IDs:  []string{"debpkg"},
   336  					Cmd:  MockCmd + " {{.ArtifactName}}",
   337  					Env: []string{
   338  						MarshalMockEnv(&MockData{
   339  							AnyOf: []MockCall{
   340  								{
   341  									ExpectedArgs: []string{"a.deb"},
   342  									ExpectedEnv:  osEnv(),
   343  									Stderr:       "test error",
   344  									ExitCode:     1,
   345  								},
   346  							},
   347  						}),
   348  					},
   349  				},
   350  			},
   351  			// stderr is sent to output via logger
   352  			fmt.Errorf(`publishing: %s failed: exit status 1: test error`, MockCmd),
   353  		},
   354  	}
   355  
   356  	for i, tc := range testCases {
   357  		t.Run(fmt.Sprintf("%d-%s", i, tc.name), func(t *testing.T) {
   358  			err := Execute(ctx, tc.publishers)
   359  			if tc.expectErr == nil {
   360  				require.NoError(t, err)
   361  				return
   362  			}
   363  			require.Error(t, err)
   364  			require.Equal(t, tc.expectErr.Error(), err.Error())
   365  		})
   366  	}
   367  }