github.com/windmeup/goreleaser@v1.21.95/internal/pipe/docker/docker_test.go (about)

     1  package docker
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  	"path/filepath"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  	"github.com/windmeup/goreleaser/internal/artifact"
    13  	"github.com/windmeup/goreleaser/internal/pipe"
    14  	"github.com/windmeup/goreleaser/internal/skips"
    15  	"github.com/windmeup/goreleaser/internal/testctx"
    16  	"github.com/windmeup/goreleaser/internal/testlib"
    17  	"github.com/windmeup/goreleaser/pkg/config"
    18  	"github.com/windmeup/goreleaser/pkg/context"
    19  )
    20  
    21  const (
    22  	registryPort    = "5050"
    23  	registry        = "localhost:5050/"
    24  	altRegistryPort = "5051"
    25  	altRegistry     = "localhost:5051/"
    26  )
    27  
    28  func start(tb testing.TB) {
    29  	tb.Helper()
    30  	tb.Log("starting registries")
    31  	testlib.StartRegistry(tb, "registry", registryPort)
    32  	testlib.StartRegistry(tb, "alt_registry", altRegistryPort)
    33  }
    34  
    35  // TODO: this test is too big... split in smaller tests? Mainly the manifest ones...
    36  func TestRunPipe(t *testing.T) {
    37  	testlib.CheckPath(t, "docker")
    38  	type errChecker func(*testing.T, error)
    39  	shouldErr := func(msg string) errChecker {
    40  		return func(t *testing.T, err error) {
    41  			t.Helper()
    42  			require.Error(t, err)
    43  			require.Contains(t, err.Error(), msg)
    44  		}
    45  	}
    46  	shouldNotErr := func(t *testing.T, err error) {
    47  		t.Helper()
    48  		require.NoError(t, err)
    49  	}
    50  	shouldTemplateErr := func(t *testing.T, err error) {
    51  		t.Helper()
    52  		testlib.RequireTemplateError(t, err)
    53  	}
    54  	type imageLabelFinder func(*testing.T, string)
    55  	shouldFindImagesWithLabels := func(image string, filters ...string) func(*testing.T, string) {
    56  		return func(t *testing.T, use string) {
    57  			t.Helper()
    58  			for _, filter := range filters {
    59  				cmd := exec.Command("docker", "images", "-q", "--filter", "reference=*/"+image, "--filter", filter)
    60  				// t.Log("running", cmd)
    61  				output, err := cmd.CombinedOutput()
    62  				require.NoError(t, err, string(output))
    63  				uniqueIDs := map[string]string{}
    64  				for _, id := range strings.Split(strings.TrimSpace(string(output)), "\n") {
    65  					uniqueIDs[id] = id
    66  				}
    67  				require.Equal(t, 1, len(uniqueIDs))
    68  			}
    69  		}
    70  	}
    71  	noLabels := func(t *testing.T, _ string) {
    72  		t.Helper()
    73  	}
    74  
    75  	table := map[string]struct {
    76  		dockers             []config.Docker
    77  		manifests           []config.DockerManifest
    78  		env                 map[string]string
    79  		expect              []string
    80  		assertImageLabels   imageLabelFinder
    81  		assertError         errChecker
    82  		pubAssertError      errChecker
    83  		manifestAssertError errChecker
    84  		extraPrepare        func(t *testing.T, ctx *context.Context)
    85  	}{
    86  		"multiarch": {
    87  			dockers: []config.Docker{
    88  				{
    89  					ImageTemplates:     []string{registry + "goreleaser/test_multiarch:test-amd64"},
    90  					Goos:               "linux",
    91  					Goarch:             "amd64",
    92  					Dockerfile:         "testdata/Dockerfile.arch",
    93  					BuildFlagTemplates: []string{"--build-arg", "ARCH=amd64"},
    94  				},
    95  				{
    96  					ImageTemplates:     []string{registry + "goreleaser/test_multiarch:test-arm64v8"},
    97  					Goos:               "linux",
    98  					Goarch:             "arm64",
    99  					Dockerfile:         "testdata/Dockerfile.arch",
   100  					BuildFlagTemplates: []string{"--build-arg", "ARCH=arm64v8"},
   101  				},
   102  			},
   103  			manifests: []config.DockerManifest{
   104  				{
   105  					NameTemplate: registry + "goreleaser/test_multiarch:test",
   106  					ImageTemplates: []string{
   107  						registry + "goreleaser/test_multiarch:test-amd64",
   108  						registry + "goreleaser/test_multiarch:test-arm64v8",
   109  					},
   110  				},
   111  			},
   112  			expect: []string{
   113  				registry + "goreleaser/test_multiarch:test-amd64",
   114  				registry + "goreleaser/test_multiarch:test-arm64v8",
   115  			},
   116  			assertError:         shouldNotErr,
   117  			pubAssertError:      shouldNotErr,
   118  			manifestAssertError: shouldNotErr,
   119  			assertImageLabels:   noLabels,
   120  		},
   121  		"manifest autoskip no prerelease": {
   122  			env: map[string]string{"AUTO": "auto"},
   123  			dockers: []config.Docker{
   124  				{
   125  					ImageTemplates: []string{registry + "goreleaser/test_manifestskip:test-amd64"},
   126  					Goos:           "linux",
   127  					Goarch:         "amd64",
   128  					Dockerfile:     "testdata/Dockerfile",
   129  				},
   130  			},
   131  			manifests: []config.DockerManifest{
   132  				{
   133  					NameTemplate: registry + "goreleaser/test_manifestskip:test",
   134  					ImageTemplates: []string{
   135  						registry + "goreleaser/test_manifestskip:test-amd64",
   136  					},
   137  					SkipPush: "{{ .Env.AUTO }}",
   138  				},
   139  			},
   140  			expect: []string{
   141  				registry + "goreleaser/test_manifestskip:test-amd64",
   142  			},
   143  			assertError:         shouldNotErr,
   144  			pubAssertError:      shouldNotErr,
   145  			manifestAssertError: shouldNotErr,
   146  			assertImageLabels:   noLabels,
   147  		},
   148  		"manifest autoskip prerelease": {
   149  			dockers: []config.Docker{
   150  				{
   151  					ImageTemplates: []string{registry + "goreleaser/test_manifestskip-prerelease:test-amd64"},
   152  					Goos:           "linux",
   153  					Goarch:         "amd64",
   154  					Dockerfile:     "testdata/Dockerfile",
   155  				},
   156  			},
   157  			manifests: []config.DockerManifest{
   158  				{
   159  					NameTemplate: registry + "goreleaser/test_manifestskip-prerelease:test",
   160  					ImageTemplates: []string{
   161  						registry + "goreleaser/test_manifestskip-prerelease:test-amd64",
   162  					},
   163  					SkipPush: "auto",
   164  				},
   165  			},
   166  			expect: []string{
   167  				registry + "goreleaser/test_manifestskip-prerelease:test-amd64",
   168  			},
   169  			assertError:         shouldNotErr,
   170  			pubAssertError:      shouldNotErr,
   171  			manifestAssertError: testlib.AssertSkipped,
   172  			assertImageLabels:   noLabels,
   173  			extraPrepare: func(t *testing.T, ctx *context.Context) {
   174  				t.Helper()
   175  				ctx.Semver.Prerelease = "beta"
   176  			},
   177  		},
   178  		"manifest skip": {
   179  			dockers: []config.Docker{
   180  				{
   181  					ImageTemplates: []string{registry + "goreleaser/test_manifestskip-true:test-amd64"},
   182  					Goos:           "linux",
   183  					Goarch:         "amd64",
   184  					Dockerfile:     "testdata/Dockerfile",
   185  				},
   186  			},
   187  			manifests: []config.DockerManifest{
   188  				{
   189  					NameTemplate: registry + "goreleaser/test_manifestskip-true:test",
   190  					ImageTemplates: []string{
   191  						registry + "goreleaser/test_manifestskip-true:test-amd64",
   192  					},
   193  					SkipPush: "true",
   194  				},
   195  			},
   196  			expect: []string{
   197  				registry + "goreleaser/test_manifestskip-true:test-amd64",
   198  			},
   199  			assertError:         shouldNotErr,
   200  			pubAssertError:      shouldNotErr,
   201  			manifestAssertError: testlib.AssertSkipped,
   202  			assertImageLabels:   noLabels,
   203  		},
   204  		"multiarch with previous existing manifest": {
   205  			dockers: []config.Docker{
   206  				{
   207  					ImageTemplates:     []string{registry + "goreleaser/test_multiarch:2test-amd64"},
   208  					Goos:               "linux",
   209  					Goarch:             "amd64",
   210  					Dockerfile:         "testdata/Dockerfile.arch",
   211  					BuildFlagTemplates: []string{"--build-arg", "ARCH=amd64"},
   212  				},
   213  				{
   214  					ImageTemplates:     []string{registry + "goreleaser/test_multiarch:2test-arm64v8"},
   215  					Goos:               "linux",
   216  					Goarch:             "arm64",
   217  					Dockerfile:         "testdata/Dockerfile.arch",
   218  					BuildFlagTemplates: []string{"--build-arg", "ARCH=arm64v8"},
   219  				},
   220  			},
   221  			manifests: []config.DockerManifest{
   222  				{
   223  					NameTemplate: registry + "goreleaser/test_multiarch:2test",
   224  					ImageTemplates: []string{
   225  						registry + "goreleaser/test_multiarch:2test-amd64",
   226  						registry + "goreleaser/test_multiarch:2test-arm64v8",
   227  					},
   228  				},
   229  			},
   230  			expect: []string{
   231  				registry + "goreleaser/test_multiarch:2test-amd64",
   232  				registry + "goreleaser/test_multiarch:2test-arm64v8",
   233  			},
   234  			assertError:         shouldNotErr,
   235  			pubAssertError:      shouldNotErr,
   236  			manifestAssertError: shouldNotErr,
   237  			assertImageLabels:   noLabels,
   238  			extraPrepare: func(t *testing.T, ctx *context.Context) {
   239  				t.Helper()
   240  				for _, cmd := range []string{
   241  					fmt.Sprintf("docker manifest rm %sgoreleaser/test_multiarch:2test || true", registry),
   242  					fmt.Sprintf("docker build -t %sgoreleaser/dummy:v1 --platform linux/amd64 -f testdata/Dockerfile.dummy .", registry),
   243  					fmt.Sprintf("docker push %sgoreleaser/dummy:v1", registry),
   244  					fmt.Sprintf("docker manifest create %sgoreleaser/test_multiarch:2test --amend %sgoreleaser/dummy:v1 --insecure", registry, registry),
   245  				} {
   246  					parts := strings.Fields(strings.TrimSuffix(cmd, " || true"))
   247  					out, err := exec.CommandContext(ctx, parts[0], parts[1:]...).CombinedOutput()
   248  					if !strings.HasSuffix(cmd, " || true") {
   249  						require.NoError(t, err, cmd+": "+string(out))
   250  					}
   251  				}
   252  			},
   253  		},
   254  		"multiarch image not found": {
   255  			dockers: []config.Docker{
   256  				{
   257  					ImageTemplates:     []string{registry + "goreleaser/test_multiarch_fail:latest-arm64v8"},
   258  					Goos:               "linux",
   259  					Goarch:             "arm64",
   260  					Dockerfile:         "testdata/Dockerfile.arch",
   261  					BuildFlagTemplates: []string{"--build-arg", "ARCH=arm64v8"},
   262  				},
   263  			},
   264  			manifests: []config.DockerManifest{
   265  				{
   266  					NameTemplate:   registry + "goreleaser/test_multiarch_fail:test",
   267  					ImageTemplates: []string{registry + "goreleaser/test_multiarch_fail:latest-amd64"},
   268  				},
   269  			},
   270  			expect:              []string{registry + "goreleaser/test_multiarch_fail:latest-arm64v8"},
   271  			assertError:         shouldNotErr,
   272  			pubAssertError:      shouldNotErr,
   273  			manifestAssertError: shouldErr("failed to create localhost:5050/goreleaser/test_multiarch_fail:test"),
   274  			assertImageLabels:   noLabels,
   275  		},
   276  		"multiarch manifest template error": {
   277  			dockers: []config.Docker{
   278  				{
   279  					ImageTemplates: []string{registry + "goreleaser/test_multiarch_manifest_tmpl_error"},
   280  					Goos:           "linux",
   281  					Goarch:         "arm64",
   282  					Dockerfile:     "testdata/Dockerfile",
   283  				},
   284  			},
   285  			manifests: []config.DockerManifest{
   286  				{
   287  					NameTemplate:   registry + "goreleaser/test_multiarch_manifest_tmpl_error:{{ .Goos }",
   288  					ImageTemplates: []string{registry + "goreleaser/test_multiarch_manifest_tmpl_error"},
   289  				},
   290  			},
   291  			expect:              []string{registry + "goreleaser/test_multiarch_manifest_tmpl_error"},
   292  			assertError:         shouldNotErr,
   293  			pubAssertError:      shouldNotErr,
   294  			manifestAssertError: shouldTemplateErr,
   295  			assertImageLabels:   noLabels,
   296  		},
   297  		"multiarch image template error": {
   298  			dockers: []config.Docker{
   299  				{
   300  					ImageTemplates: []string{registry + "goreleaser/test_multiarch_img_tmpl_error"},
   301  					Goos:           "linux",
   302  					Goarch:         "arm64",
   303  					Dockerfile:     "testdata/Dockerfile",
   304  				},
   305  			},
   306  			manifests: []config.DockerManifest{
   307  				{
   308  					NameTemplate:   registry + "goreleaser/test_multiarch_img_tmpl_error",
   309  					ImageTemplates: []string{registry + "goreleaser/test_multiarch_img_tmpl_error:{{ .Goos }"},
   310  				},
   311  			},
   312  			expect:              []string{registry + "goreleaser/test_multiarch_img_tmpl_error"},
   313  			assertError:         shouldNotErr,
   314  			pubAssertError:      shouldNotErr,
   315  			manifestAssertError: shouldTemplateErr,
   316  			assertImageLabels:   noLabels,
   317  		},
   318  		"multiarch missing manifest name": {
   319  			dockers: []config.Docker{
   320  				{
   321  					ImageTemplates: []string{registry + "goreleaser/test_multiarch_no_manifest_name"},
   322  					Goos:           "linux",
   323  					Goarch:         "arm64",
   324  					Dockerfile:     "testdata/Dockerfile",
   325  				},
   326  			},
   327  			manifests: []config.DockerManifest{
   328  				{
   329  					NameTemplate:   "  ",
   330  					ImageTemplates: []string{registry + "goreleaser/test_multiarch_no_manifest_name"},
   331  				},
   332  			},
   333  			expect:              []string{registry + "goreleaser/test_multiarch_no_manifest_name"},
   334  			assertError:         shouldNotErr,
   335  			pubAssertError:      shouldNotErr,
   336  			manifestAssertError: testlib.AssertSkipped,
   337  			assertImageLabels:   noLabels,
   338  		},
   339  		"multiarch missing images": {
   340  			dockers: []config.Docker{
   341  				{
   342  					ImageTemplates: []string{registry + "goreleaser/test_multiarch_no_manifest_images"},
   343  					Dockerfile:     "testdata/Dockerfile",
   344  					Goos:           "linux",
   345  					Goarch:         "arm64",
   346  				},
   347  			},
   348  			manifests: []config.DockerManifest{
   349  				{
   350  					NameTemplate:   "ignored",
   351  					ImageTemplates: []string{" ", "   ", ""},
   352  				},
   353  			},
   354  			expect:              []string{registry + "goreleaser/test_multiarch_no_manifest_images"},
   355  			assertError:         shouldNotErr,
   356  			pubAssertError:      shouldNotErr,
   357  			manifestAssertError: testlib.AssertSkipped,
   358  			assertImageLabels:   noLabels,
   359  		},
   360  		"valid": {
   361  			env: map[string]string{
   362  				"FOO": "123",
   363  			},
   364  			dockers: []config.Docker{
   365  				{
   366  					ImageTemplates: []string{
   367  						registry + "goreleaser/test_run_pipe:{{.Tag}}-{{.Env.FOO}}",
   368  						registry + "goreleaser/test_run_pipe:v{{.Major}}",
   369  						registry + "goreleaser/test_run_pipe:v{{.Major}}.{{.Minor}}",
   370  						registry + "goreleaser/test_run_pipe:commit-{{.Commit}}",
   371  						registry + "goreleaser/test_run_pipe:latest",
   372  						altRegistry + "goreleaser/test_run_pipe:{{.Tag}}-{{.Env.FOO}}",
   373  						altRegistry + "goreleaser/test_run_pipe:v{{.Major}}",
   374  						altRegistry + "goreleaser/test_run_pipe:v{{.Major}}.{{.Minor}}",
   375  						altRegistry + "goreleaser/test_run_pipe:commit-{{.Commit}}",
   376  						altRegistry + "goreleaser/test_run_pipe:latest",
   377  					},
   378  					Goos:       "linux",
   379  					Goarch:     "amd64",
   380  					Dockerfile: "testdata/Dockerfile",
   381  					BuildFlagTemplates: []string{
   382  						"--label=org.label-schema.schema-version=1.0",
   383  						"--label=org.label-schema.version={{.Version}}",
   384  						"--label=org.label-schema.vcs-ref={{.Commit}}",
   385  						"--label=org.label-schema.name={{.ProjectName}}",
   386  						"--build-arg=FRED={{.Tag}}",
   387  					},
   388  					Files: []string{
   389  						"testdata/extra_file.txt",
   390  					},
   391  				},
   392  			},
   393  			expect: []string{
   394  				registry + "goreleaser/test_run_pipe:v1.0.0-123",
   395  				registry + "goreleaser/test_run_pipe:v1",
   396  				registry + "goreleaser/test_run_pipe:v1.0",
   397  				registry + "goreleaser/test_run_pipe:commit-a1b2c3d4",
   398  				registry + "goreleaser/test_run_pipe:latest",
   399  				altRegistry + "goreleaser/test_run_pipe:v1.0.0-123",
   400  				altRegistry + "goreleaser/test_run_pipe:v1",
   401  				altRegistry + "goreleaser/test_run_pipe:v1.0",
   402  				altRegistry + "goreleaser/test_run_pipe:commit-a1b2c3d4",
   403  				altRegistry + "goreleaser/test_run_pipe:latest",
   404  			},
   405  			assertImageLabels: shouldFindImagesWithLabels(
   406  				"goreleaser/test_run_pipe",
   407  				"label=org.label-schema.schema-version=1.0",
   408  				"label=org.label-schema.version=1.0.0",
   409  				"label=org.label-schema.vcs-ref=a1b2c3d4",
   410  				"label=org.label-schema.name=mybin",
   411  			),
   412  			assertError:         shouldNotErr,
   413  			pubAssertError:      shouldNotErr,
   414  			manifestAssertError: shouldNotErr,
   415  		},
   416  		"templated-dockerfile": {
   417  			env: map[string]string{
   418  				"Dockerfile": "testdata/Dockerfile",
   419  			},
   420  			dockers: []config.Docker{
   421  				{
   422  					ImageTemplates: []string{
   423  						registry + "goreleaser/templated_dockerfile:v1",
   424  					},
   425  					Goos:       "linux",
   426  					Goarch:     "amd64",
   427  					Dockerfile: "{{ .Env.Dockerfile }}",
   428  					Files: []string{
   429  						"testdata/extra_file.txt",
   430  					},
   431  				},
   432  			},
   433  			expect: []string{
   434  				registry + "goreleaser/templated_dockerfile:v1",
   435  			},
   436  			assertError:         shouldNotErr,
   437  			assertImageLabels:   noLabels,
   438  			pubAssertError:      shouldNotErr,
   439  			manifestAssertError: shouldNotErr,
   440  		},
   441  		"wrong binary name": {
   442  			dockers: []config.Docker{
   443  				{
   444  					ImageTemplates: []string{
   445  						registry + "goreleaser/wrong_bin_name:v1",
   446  					},
   447  					Goos:       "linux",
   448  					Goarch:     "amd64",
   449  					Dockerfile: "testdata/Dockerfile.wrongbin",
   450  				},
   451  			},
   452  			assertError:       shouldErr("seems like you tried to copy a file that is not available in the build context"),
   453  			assertImageLabels: noLabels,
   454  		},
   455  		"templated-dockerfile-invalid": {
   456  			dockers: []config.Docker{
   457  				{
   458  					ImageTemplates: []string{
   459  						registry + "goreleaser/invalid-templated-dockerfile:v1",
   460  					},
   461  					Goos:       "linux",
   462  					Goarch:     "amd64",
   463  					Dockerfile: "{{ .Env.Dockerfile }}",
   464  				},
   465  			},
   466  			expect:              []string{},
   467  			assertError:         shouldTemplateErr,
   468  			assertImageLabels:   noLabels,
   469  			pubAssertError:      shouldNotErr,
   470  			manifestAssertError: shouldNotErr,
   471  		},
   472  		"image template with env": {
   473  			env: map[string]string{
   474  				"FOO": "test_run_pipe_template",
   475  			},
   476  			dockers: []config.Docker{
   477  				{
   478  					ImageTemplates: []string{
   479  						registry + "goreleaser/{{.Env.FOO}}:{{.Tag}}",
   480  					},
   481  					Goos:       "linux",
   482  					Goarch:     "amd64",
   483  					Dockerfile: "testdata/Dockerfile",
   484  				},
   485  			},
   486  			expect: []string{
   487  				registry + "goreleaser/test_run_pipe_template:v1.0.0",
   488  			},
   489  			assertImageLabels:   noLabels,
   490  			assertError:         shouldNotErr,
   491  			pubAssertError:      shouldNotErr,
   492  			manifestAssertError: shouldNotErr,
   493  		},
   494  		"image template uppercase": {
   495  			env: map[string]string{
   496  				"FOO": "test_run_pipe_template_UPPERCASE",
   497  			},
   498  			dockers: []config.Docker{
   499  				{
   500  					ImageTemplates: []string{
   501  						registry + "goreleaser/{{.Env.FOO}}:{{.Tag}}",
   502  					},
   503  					Goos:       "linux",
   504  					Goarch:     "amd64",
   505  					Dockerfile: "testdata/Dockerfile",
   506  				},
   507  			},
   508  			expect:              []string{},
   509  			assertImageLabels:   noLabels,
   510  			assertError:         shouldErr(`failed to build localhost:5050/goreleaser/test_run_pipe_template_UPPERCASE:v1.0.0`),
   511  			pubAssertError:      shouldNotErr,
   512  			manifestAssertError: shouldNotErr,
   513  		},
   514  		"empty image tag": {
   515  			dockers: []config.Docker{
   516  				{
   517  					ImageTemplates: []string{
   518  						"",
   519  						registry + "goreleaser/empty_tag:latest",
   520  					},
   521  					Goos:       "linux",
   522  					Goarch:     "amd64",
   523  					Dockerfile: "testdata/Dockerfile",
   524  				},
   525  			},
   526  			expect: []string{
   527  				registry + "goreleaser/empty_tag:latest",
   528  			},
   529  			assertImageLabels:   noLabels,
   530  			assertError:         shouldNotErr,
   531  			pubAssertError:      shouldNotErr,
   532  			manifestAssertError: shouldNotErr,
   533  		},
   534  		"no image tags": {
   535  			dockers: []config.Docker{
   536  				{
   537  					ImageTemplates: []string{
   538  						"",
   539  					},
   540  					Goos:       "linux",
   541  					Goarch:     "amd64",
   542  					Dockerfile: "testdata/Dockerfile",
   543  				},
   544  			},
   545  			expect:              []string{},
   546  			assertImageLabels:   noLabels,
   547  			assertError:         shouldErr("no image templates found"),
   548  			pubAssertError:      shouldNotErr,
   549  			manifestAssertError: shouldNotErr,
   550  		},
   551  		"valid with ids": {
   552  			dockers: []config.Docker{
   553  				{
   554  					ImageTemplates: []string{
   555  						registry + "goreleaser/test_run_pipe_build:latest",
   556  					},
   557  					Goos:       "linux",
   558  					Goarch:     "amd64",
   559  					Dockerfile: "testdata/Dockerfile",
   560  					IDs:        []string{"mybin"},
   561  				},
   562  			},
   563  			expect: []string{
   564  				registry + "goreleaser/test_run_pipe_build:latest",
   565  			},
   566  			assertImageLabels:   noLabels,
   567  			assertError:         shouldNotErr,
   568  			pubAssertError:      shouldNotErr,
   569  			manifestAssertError: shouldNotErr,
   570  		},
   571  		"multiple images with same extra file": {
   572  			dockers: []config.Docker{
   573  				{
   574  					ImageTemplates: []string{
   575  						registry + "goreleaser/multiplefiles1:latest",
   576  					},
   577  					Goos:       "linux",
   578  					Goarch:     "amd64",
   579  					Dockerfile: "testdata/Dockerfile",
   580  					Files:      []string{"testdata/extra_file.txt"},
   581  				},
   582  				{
   583  					ImageTemplates: []string{
   584  						registry + "goreleaser/multiplefiles2:latest",
   585  					},
   586  					Goos:       "linux",
   587  					Goarch:     "amd64",
   588  					Dockerfile: "testdata/Dockerfile",
   589  					Files:      []string{"testdata/extra_file.txt"},
   590  				},
   591  			},
   592  			expect: []string{
   593  				registry + "goreleaser/multiplefiles1:latest",
   594  				registry + "goreleaser/multiplefiles2:latest",
   595  			},
   596  			assertImageLabels:   noLabels,
   597  			assertError:         shouldNotErr,
   598  			pubAssertError:      shouldNotErr,
   599  			manifestAssertError: shouldNotErr,
   600  		},
   601  		"multiple images with same dockerfile": {
   602  			dockers: []config.Docker{
   603  				{
   604  					ImageTemplates: []string{
   605  						registry + "goreleaser/test_run_pipe:latest",
   606  					},
   607  					Goos:       "linux",
   608  					Goarch:     "amd64",
   609  					Dockerfile: "testdata/Dockerfile",
   610  				},
   611  				{
   612  					ImageTemplates: []string{
   613  						registry + "goreleaser/test_run_pipe2:latest",
   614  					},
   615  					Goos:       "linux",
   616  					Goarch:     "amd64",
   617  					Dockerfile: "testdata/Dockerfile",
   618  				},
   619  			},
   620  			assertImageLabels: noLabels,
   621  			expect: []string{
   622  				registry + "goreleaser/test_run_pipe:latest",
   623  				registry + "goreleaser/test_run_pipe2:latest",
   624  			},
   625  			assertError:         shouldNotErr,
   626  			pubAssertError:      shouldNotErr,
   627  			manifestAssertError: shouldNotErr,
   628  		},
   629  		"valid_skip_push": {
   630  			env: map[string]string{"TRUE": "true"},
   631  			dockers: []config.Docker{
   632  				{
   633  					ImageTemplates: []string{
   634  						registry + "goreleaser/test_run_pipe:latest",
   635  					},
   636  					Goos:       "linux",
   637  					Goarch:     "amd64",
   638  					Dockerfile: "testdata/Dockerfile",
   639  					SkipPush:   "{{.Env.TRUE}}",
   640  				},
   641  			},
   642  			expect: []string{
   643  				registry + "goreleaser/test_run_pipe:latest",
   644  			},
   645  			assertImageLabels:   noLabels,
   646  			assertError:         shouldNotErr,
   647  			pubAssertError:      testlib.AssertSkipped,
   648  			manifestAssertError: shouldNotErr,
   649  		},
   650  		"one_img_error_with_skip_push": {
   651  			dockers: []config.Docker{
   652  				{
   653  					ImageTemplates: []string{
   654  						registry + "goreleaser/one_img_error_with_skip_push:true",
   655  					},
   656  					Goos:       "linux",
   657  					Goarch:     "amd64",
   658  					Dockerfile: "testdata/Dockerfile.true",
   659  					SkipPush:   "true",
   660  				},
   661  				{
   662  					ImageTemplates: []string{
   663  						registry + "goreleaser/one_img_error_with_skip_push:false",
   664  					},
   665  					Goos:       "linux",
   666  					Goarch:     "amd64",
   667  					Dockerfile: "testdata/Dockerfile.false",
   668  					SkipPush:   "true",
   669  				},
   670  			},
   671  			expect: []string{
   672  				registry + "goreleaser/one_img_error_with_skip_push:true",
   673  			},
   674  			assertImageLabels: noLabels,
   675  			assertError:       shouldErr("failed to build localhost:5050/goreleaser/one_img_error_with_skip_push:false"),
   676  		},
   677  		"valid_no_latest": {
   678  			dockers: []config.Docker{
   679  				{
   680  					ImageTemplates: []string{
   681  						registry + "goreleaser/test_run_pipe:{{.Version}}",
   682  					},
   683  					Goos:       "linux",
   684  					Goarch:     "amd64",
   685  					Dockerfile: "testdata/Dockerfile",
   686  				},
   687  			},
   688  			expect: []string{
   689  				registry + "goreleaser/test_run_pipe:1.0.0",
   690  			},
   691  			assertImageLabels:   noLabels,
   692  			assertError:         shouldNotErr,
   693  			pubAssertError:      shouldNotErr,
   694  			manifestAssertError: shouldNotErr,
   695  		},
   696  		"valid build args": {
   697  			dockers: []config.Docker{
   698  				{
   699  					ImageTemplates: []string{
   700  						registry + "goreleaser/test_build_args:latest",
   701  					},
   702  					Goos:       "linux",
   703  					Goarch:     "amd64",
   704  					Dockerfile: "testdata/Dockerfile",
   705  					BuildFlagTemplates: []string{
   706  						"--label=foo=bar",
   707  					},
   708  				},
   709  			},
   710  			expect: []string{
   711  				registry + "goreleaser/test_build_args:latest",
   712  			},
   713  			assertImageLabels:   noLabels,
   714  			assertError:         shouldNotErr,
   715  			pubAssertError:      shouldNotErr,
   716  			manifestAssertError: shouldNotErr,
   717  		},
   718  		"bad build args": {
   719  			dockers: []config.Docker{
   720  				{
   721  					ImageTemplates: []string{
   722  						registry + "goreleaser/test_build_args:latest",
   723  					},
   724  					Goos:       "linux",
   725  					Goarch:     "amd64",
   726  					Dockerfile: "testdata/Dockerfile",
   727  					BuildFlagTemplates: []string{
   728  						"--bad-flag",
   729  					},
   730  				},
   731  			},
   732  			assertImageLabels: noLabels,
   733  			assertError:       shouldErr("failed to build localhost:5050/goreleaser/test_build_args:latest"),
   734  		},
   735  		"bad_dockerfile": {
   736  			dockers: []config.Docker{
   737  				{
   738  					ImageTemplates: []string{
   739  						registry + "goreleaser/bad_dockerfile:latest",
   740  					},
   741  					Goos:       "linux",
   742  					Goarch:     "amd64",
   743  					Dockerfile: "testdata/Dockerfile.bad",
   744  				},
   745  			},
   746  			assertImageLabels: noLabels,
   747  			assertError:       shouldErr("failed to build localhost:5050/goreleaser/bad_dockerfile:latest"),
   748  		},
   749  		"tag_template_error": {
   750  			dockers: []config.Docker{
   751  				{
   752  					ImageTemplates: []string{
   753  						registry + "goreleaser/test_run_pipe:{{.Tag}",
   754  					},
   755  					Goos:       "linux",
   756  					Goarch:     "amd64",
   757  					Dockerfile: "testdata/Dockerfile",
   758  				},
   759  			},
   760  			assertImageLabels: noLabels,
   761  			assertError:       shouldTemplateErr,
   762  		},
   763  		"build_flag_template_error": {
   764  			dockers: []config.Docker{
   765  				{
   766  					ImageTemplates: []string{
   767  						registry + "goreleaser/test_run_pipe:latest",
   768  					},
   769  					Goos:       "linux",
   770  					Goarch:     "amd64",
   771  					Dockerfile: "testdata/Dockerfile",
   772  					BuildFlagTemplates: []string{
   773  						"--label=tag={{.Tag}",
   774  					},
   775  				},
   776  			},
   777  			assertImageLabels: noLabels,
   778  			assertError:       shouldTemplateErr,
   779  		},
   780  		"missing_env_on_tag_template": {
   781  			dockers: []config.Docker{
   782  				{
   783  					ImageTemplates: []string{
   784  						registry + "goreleaser/test_run_pipe:{{.Env.NOPE}}",
   785  					},
   786  					Goos:       "linux",
   787  					Goarch:     "amd64",
   788  					Dockerfile: "testdata/Dockerfile",
   789  				},
   790  			},
   791  			assertImageLabels: noLabels,
   792  			assertError:       shouldTemplateErr,
   793  		},
   794  		"missing_env_on_build_flag_template": {
   795  			dockers: []config.Docker{
   796  				{
   797  					ImageTemplates: []string{
   798  						registry + "goreleaser/test_run_pipe:latest",
   799  					},
   800  					Goos:       "linux",
   801  					Goarch:     "amd64",
   802  					Dockerfile: "testdata/Dockerfile",
   803  					BuildFlagTemplates: []string{
   804  						"--label=nope={{.Env.NOPE}}",
   805  					},
   806  				},
   807  			},
   808  			assertImageLabels: noLabels,
   809  			assertError:       shouldTemplateErr,
   810  		},
   811  		"image_has_projectname_template_variable": {
   812  			dockers: []config.Docker{
   813  				{
   814  					ImageTemplates: []string{
   815  						registry + "goreleaser/{{.ProjectName}}:{{.Tag}}-{{.Env.FOO}}",
   816  						registry + "goreleaser/{{.ProjectName}}:latest",
   817  					},
   818  					Goos:       "linux",
   819  					Goarch:     "amd64",
   820  					Dockerfile: "testdata/Dockerfile",
   821  					SkipPush:   "true",
   822  				},
   823  			},
   824  			env: map[string]string{
   825  				"FOO": "123",
   826  			},
   827  			expect: []string{
   828  				registry + "goreleaser/mybin:v1.0.0-123",
   829  				registry + "goreleaser/mybin:latest",
   830  			},
   831  			assertImageLabels:   noLabels,
   832  			assertError:         shouldNotErr,
   833  			pubAssertError:      testlib.AssertSkipped,
   834  			manifestAssertError: shouldNotErr,
   835  		},
   836  		"no_permissions": {
   837  			dockers: []config.Docker{
   838  				{
   839  					ImageTemplates: []string{"docker.io/nope:latest"},
   840  					Goos:           "linux",
   841  					Goarch:         "amd64",
   842  					Dockerfile:     "testdata/Dockerfile",
   843  				},
   844  			},
   845  			expect: []string{
   846  				"docker.io/nope:latest",
   847  			},
   848  			assertImageLabels:   noLabels,
   849  			assertError:         shouldNotErr,
   850  			pubAssertError:      shouldErr(`failed to push docker.io/nope:latest`),
   851  			manifestAssertError: shouldNotErr,
   852  		},
   853  		"dockerfile_doesnt_exist": {
   854  			dockers: []config.Docker{
   855  				{
   856  					ImageTemplates: []string{"whatever:latest"},
   857  					Goos:           "linux",
   858  					Goarch:         "amd64",
   859  					Dockerfile:     "testdata/Dockerfilezzz",
   860  				},
   861  			},
   862  			assertImageLabels: noLabels,
   863  			assertError:       shouldErr(`failed to copy dockerfile`),
   864  		},
   865  		"extra_file_doesnt_exist": {
   866  			dockers: []config.Docker{
   867  				{
   868  					ImageTemplates: []string{"whatever:latest"},
   869  					Goos:           "linux",
   870  					Goarch:         "amd64",
   871  					Dockerfile:     "testdata/Dockerfile",
   872  					Files: []string{
   873  						"testdata/nope.txt",
   874  					},
   875  				},
   876  			},
   877  			assertImageLabels: noLabels,
   878  			assertError:       shouldErr(`failed to copy extra file 'testdata/nope.txt'`),
   879  		},
   880  		"binary doesnt exist": {
   881  			dockers: []config.Docker{
   882  				{
   883  					ImageTemplates: []string{"whatever:latest"},
   884  					Goos:           "linux",
   885  					Goarch:         "amd64",
   886  					Dockerfile:     "testdata/Dockerfile",
   887  					IDs:            []string{"nope"},
   888  				},
   889  			},
   890  			assertImageLabels: noLabels,
   891  			assertError:       shouldErr(`failed to copy wont-exist`),
   892  			extraPrepare: func(t *testing.T, ctx *context.Context) {
   893  				t.Helper()
   894  				ctx.Artifacts.Add(&artifact.Artifact{
   895  					Name:   "wont-exist",
   896  					Path:   "wont-exist",
   897  					Goarch: "amd64",
   898  					Goos:   "linux",
   899  					Type:   artifact.Binary,
   900  					Extra: map[string]interface{}{
   901  						artifact.ExtraID: "nope",
   902  					},
   903  				})
   904  			},
   905  		},
   906  		"multiple_ids": {
   907  			dockers: []config.Docker{
   908  				{
   909  					ImageTemplates: []string{registry + "goreleaser/multiple:latest"},
   910  					Goos:           "darwin",
   911  					Goarch:         "amd64",
   912  					IDs:            []string{"mybin", "anotherbin", "subdir/subbin"},
   913  					Dockerfile:     "testdata/Dockerfile.multiple",
   914  				},
   915  			},
   916  			assertImageLabels:   noLabels,
   917  			assertError:         shouldNotErr,
   918  			pubAssertError:      shouldNotErr,
   919  			manifestAssertError: shouldNotErr,
   920  			expect: []string{
   921  				registry + "goreleaser/multiple:latest",
   922  			},
   923  		},
   924  		"nfpm and multiple binaries": {
   925  			dockers: []config.Docker{
   926  				{
   927  					ImageTemplates: []string{registry + "goreleaser/test_nfpm:latest"},
   928  					Goos:           "linux",
   929  					Goarch:         "amd64",
   930  					IDs:            []string{"mybin", "anotherbin"},
   931  					Dockerfile:     "testdata/Dockerfile.nfpm",
   932  				},
   933  			},
   934  			assertImageLabels:   noLabels,
   935  			assertError:         shouldNotErr,
   936  			pubAssertError:      shouldNotErr,
   937  			manifestAssertError: shouldNotErr,
   938  			expect: []string{
   939  				registry + "goreleaser/test_nfpm:latest",
   940  			},
   941  		},
   942  		"nfpm and multiple binaries on arm64": {
   943  			dockers: []config.Docker{
   944  				{
   945  					ImageTemplates: []string{registry + "goreleaser/test_nfpm_arm:latest"},
   946  					Goos:           "linux",
   947  					Goarch:         "arm64",
   948  					IDs:            []string{"mybin", "anotherbin"},
   949  					Dockerfile:     "testdata/Dockerfile.nfpm",
   950  				},
   951  			},
   952  			assertImageLabels:   noLabels,
   953  			assertError:         shouldNotErr,
   954  			pubAssertError:      shouldNotErr,
   955  			manifestAssertError: shouldNotErr,
   956  			expect: []string{
   957  				registry + "goreleaser/test_nfpm_arm:latest",
   958  			},
   959  		},
   960  	}
   961  
   962  	start(t)
   963  
   964  	for name, docker := range table {
   965  		for imager := range imagers {
   966  			t.Run(name+" on "+imager, func(t *testing.T) {
   967  				folder := t.TempDir()
   968  				dist := filepath.Join(folder, "dist")
   969  				require.NoError(t, os.MkdirAll(filepath.Join(dist, "mybin", "subdir"), 0o755))
   970  				f, err := os.Create(filepath.Join(dist, "mybin", "mybin"))
   971  				require.NoError(t, err)
   972  				require.NoError(t, f.Close())
   973  				f, err = os.Create(filepath.Join(dist, "mybin", "anotherbin"))
   974  				require.NoError(t, err)
   975  				require.NoError(t, f.Close())
   976  				f, err = os.Create(filepath.Join(dist, "mybin", "subdir", "subbin"))
   977  				require.NoError(t, err)
   978  				require.NoError(t, f.Close())
   979  				f, err = os.Create(filepath.Join(dist, "mynfpm.apk"))
   980  				require.NoError(t, err)
   981  				require.NoError(t, f.Close())
   982  				for _, arch := range []string{"amd64", "386", "arm64"} {
   983  					f, err = os.Create(filepath.Join(dist, fmt.Sprintf("mybin_%s.apk", arch)))
   984  					require.NoError(t, err)
   985  					require.NoError(t, f.Close())
   986  				}
   987  
   988  				ctx := testctx.NewWithCfg(
   989  					config.Project{
   990  						ProjectName:     "mybin",
   991  						Dist:            dist,
   992  						Dockers:         docker.dockers,
   993  						DockerManifests: docker.manifests,
   994  					},
   995  					testctx.WithEnv(docker.env),
   996  					testctx.WithVersion("1.0.0"),
   997  					testctx.WithCurrentTag("v1.0.0"),
   998  					testctx.WithCommit("a1b2c3d4"),
   999  					testctx.WithSemver(1, 0, 0, ""),
  1000  				)
  1001  				for _, os := range []string{"linux", "darwin"} {
  1002  					for _, arch := range []string{"amd64", "386", "arm64"} {
  1003  						for _, bin := range []string{"mybin", "anotherbin", "subdir/subbin"} {
  1004  							ctx.Artifacts.Add(&artifact.Artifact{
  1005  								Name:   bin,
  1006  								Path:   filepath.Join(dist, "mybin", bin),
  1007  								Goarch: arch,
  1008  								Goos:   os,
  1009  								Type:   artifact.Binary,
  1010  								Extra: map[string]interface{}{
  1011  									artifact.ExtraID: bin,
  1012  								},
  1013  							})
  1014  						}
  1015  					}
  1016  				}
  1017  				for _, arch := range []string{"amd64", "386", "arm64"} {
  1018  					name := fmt.Sprintf("mybin_%s.apk", arch)
  1019  					ctx.Artifacts.Add(&artifact.Artifact{
  1020  						Name:   name,
  1021  						Path:   filepath.Join(dist, name),
  1022  						Goarch: arch,
  1023  						Goos:   "linux",
  1024  						Type:   artifact.LinuxPackage,
  1025  						Extra: map[string]interface{}{
  1026  							artifact.ExtraID: "mybin",
  1027  						},
  1028  					})
  1029  				}
  1030  
  1031  				if docker.extraPrepare != nil {
  1032  					docker.extraPrepare(t, ctx)
  1033  				}
  1034  
  1035  				rmi := func(img string) error {
  1036  					return exec.Command("docker", "rmi", "--force", img).Run()
  1037  				}
  1038  
  1039  				// this might fail as the image doesnt exist yet, so lets ignore the error
  1040  				for _, img := range docker.expect {
  1041  					_ = rmi(img)
  1042  				}
  1043  
  1044  				for i := range ctx.Config.Dockers {
  1045  					docker := &ctx.Config.Dockers[i]
  1046  					docker.Use = imager
  1047  					docker.PushFlags = []string{}
  1048  				}
  1049  				for i := range ctx.Config.DockerManifests {
  1050  					manifest := &ctx.Config.DockerManifests[i]
  1051  					manifest.Use = useDocker
  1052  					manifest.PushFlags = []string{"--insecure"}
  1053  					manifest.CreateFlags = []string{"--insecure"}
  1054  				}
  1055  				err = Pipe{}.Run(ctx)
  1056  				docker.assertError(t, err)
  1057  				if err == nil {
  1058  					docker.pubAssertError(t, Pipe{}.Publish(ctx))
  1059  					docker.manifestAssertError(t, ManifestPipe{}.Publish(ctx))
  1060  				}
  1061  
  1062  				for _, d := range docker.dockers {
  1063  					docker.assertImageLabels(t, d.Use)
  1064  				}
  1065  
  1066  				// this might should not fail as the image should have been created when
  1067  				// the step ran
  1068  				for _, img := range docker.expect {
  1069  					// t.Log("removing docker image", img)
  1070  					require.NoError(t, rmi(img), "could not delete image %s", img)
  1071  				}
  1072  
  1073  				_ = ctx.Artifacts.Filter(
  1074  					artifact.Or(
  1075  						artifact.ByType(artifact.DockerImage),
  1076  						artifact.ByType(artifact.DockerManifest),
  1077  					),
  1078  				).Visit(func(a *artifact.Artifact) error {
  1079  					digest, err := artifact.Extra[string](*a, artifact.ExtraDigest)
  1080  					require.NoError(t, err)
  1081  					require.NotEmpty(t, digest, "missing digest for "+a.Name)
  1082  					return nil
  1083  				})
  1084  			})
  1085  		}
  1086  	}
  1087  }
  1088  
  1089  func TestBuildCommand(t *testing.T) {
  1090  	images := []string{"goreleaser/test_build_flag", "goreleaser/test_multiple_tags"}
  1091  	tests := []struct {
  1092  		name   string
  1093  		flags  []string
  1094  		buildx bool
  1095  		expect []string
  1096  	}{
  1097  		{
  1098  			name:   "no flags",
  1099  			flags:  []string{},
  1100  			expect: []string{"build", ".", "-t", images[0], "-t", images[1]},
  1101  		},
  1102  		{
  1103  			name:   "single flag",
  1104  			flags:  []string{"--label=foo"},
  1105  			expect: []string{"build", ".", "-t", images[0], "-t", images[1], "--label=foo"},
  1106  		},
  1107  		{
  1108  			name:   "multiple flags",
  1109  			flags:  []string{"--label=foo", "--build-arg=bar=baz"},
  1110  			expect: []string{"build", ".", "-t", images[0], "-t", images[1], "--label=foo", "--build-arg=bar=baz"},
  1111  		},
  1112  		{
  1113  			name:   "buildx",
  1114  			buildx: true,
  1115  			flags:  []string{"--label=foo", "--build-arg=bar=baz"},
  1116  			expect: []string{"buildx", "--builder", "default", "build", ".", "--load", "-t", images[0], "-t", images[1], "--label=foo", "--build-arg=bar=baz"},
  1117  		},
  1118  	}
  1119  	for _, tt := range tests {
  1120  		t.Run(tt.name, func(t *testing.T) {
  1121  			imager := dockerImager{
  1122  				buildx: tt.buildx,
  1123  			}
  1124  			require.Equal(t, tt.expect, imager.buildCommand(images, tt.flags))
  1125  		})
  1126  	}
  1127  }
  1128  
  1129  func TestDescription(t *testing.T) {
  1130  	require.NotEmpty(t, Pipe{}.String())
  1131  }
  1132  
  1133  func TestNoDockerWithoutImageName(t *testing.T) {
  1134  	testlib.AssertSkipped(t, Pipe{}.Run(testctx.NewWithCfg(config.Project{
  1135  		Dockers: []config.Docker{
  1136  			{
  1137  				Goos: "linux",
  1138  			},
  1139  		},
  1140  	})))
  1141  }
  1142  
  1143  func TestDefault(t *testing.T) {
  1144  	ctx := testctx.NewWithCfg(config.Project{
  1145  		Dockers: []config.Docker{
  1146  			{
  1147  				IDs: []string{"aa"},
  1148  			},
  1149  			{
  1150  				Use: useBuildx,
  1151  			},
  1152  		},
  1153  		DockerManifests: []config.DockerManifest{
  1154  			{},
  1155  			{
  1156  				Use: useDocker,
  1157  			},
  1158  		},
  1159  	})
  1160  	require.NoError(t, Pipe{}.Default(ctx))
  1161  	require.Len(t, ctx.Config.Dockers, 2)
  1162  	docker := ctx.Config.Dockers[0]
  1163  	require.Equal(t, "linux", docker.Goos)
  1164  	require.Equal(t, "amd64", docker.Goarch)
  1165  	require.Equal(t, "6", docker.Goarm)
  1166  	require.Equal(t, []string{"aa"}, docker.IDs)
  1167  	require.Equal(t, useDocker, docker.Use)
  1168  	docker = ctx.Config.Dockers[1]
  1169  	require.Equal(t, useBuildx, docker.Use)
  1170  
  1171  	require.NoError(t, ManifestPipe{}.Default(ctx))
  1172  	require.Len(t, ctx.Config.DockerManifests, 2)
  1173  	require.Equal(t, useDocker, ctx.Config.DockerManifests[0].Use)
  1174  	require.Equal(t, useDocker, ctx.Config.DockerManifests[1].Use)
  1175  }
  1176  
  1177  func TestDefaultDuplicateID(t *testing.T) {
  1178  	ctx := testctx.NewWithCfg(config.Project{
  1179  		Dockers: []config.Docker{
  1180  			{ID: "foo"},
  1181  			{ /* empty */ },
  1182  			{ID: "bar"},
  1183  			{ID: "foo"},
  1184  		},
  1185  		DockerManifests: []config.DockerManifest{
  1186  			{ID: "bar"},
  1187  			{ /* empty */ },
  1188  			{ID: "bar"},
  1189  			{ID: "foo"},
  1190  		},
  1191  	})
  1192  	require.EqualError(t, Pipe{}.Default(ctx), "found 2 dockers with the ID 'foo', please fix your config")
  1193  	require.EqualError(t, ManifestPipe{}.Default(ctx), "found 2 docker_manifests with the ID 'bar', please fix your config")
  1194  }
  1195  
  1196  func TestDefaultInvalidUse(t *testing.T) {
  1197  	ctx := testctx.NewWithCfg(config.Project{
  1198  		Dockers: []config.Docker{
  1199  			{
  1200  				Use: "something",
  1201  			},
  1202  		},
  1203  		DockerManifests: []config.DockerManifest{
  1204  			{
  1205  				Use: "something",
  1206  			},
  1207  		},
  1208  	})
  1209  	err := Pipe{}.Default(ctx)
  1210  	require.Error(t, err)
  1211  	require.True(t, strings.HasPrefix(err.Error(), `docker: invalid use: something, valid options are`))
  1212  
  1213  	err = ManifestPipe{}.Default(ctx)
  1214  	require.Error(t, err)
  1215  	require.True(t, strings.HasPrefix(err.Error(), `docker manifest: invalid use: something, valid options are`))
  1216  }
  1217  
  1218  func TestDefaultDockerfile(t *testing.T) {
  1219  	ctx := testctx.NewWithCfg(config.Project{
  1220  		Builds: []config.Build{
  1221  			{},
  1222  		},
  1223  		Dockers: []config.Docker{
  1224  			{},
  1225  			{},
  1226  		},
  1227  	})
  1228  	require.NoError(t, Pipe{}.Default(ctx))
  1229  	require.Len(t, ctx.Config.Dockers, 2)
  1230  	require.Equal(t, "Dockerfile", ctx.Config.Dockers[0].Dockerfile)
  1231  	require.Equal(t, "Dockerfile", ctx.Config.Dockers[1].Dockerfile)
  1232  }
  1233  
  1234  func TestDraftRelease(t *testing.T) {
  1235  	ctx := testctx.NewWithCfg(config.Project{
  1236  		Release: config.Release{
  1237  			Draft: true,
  1238  		},
  1239  	})
  1240  
  1241  	require.False(t, pipe.IsSkip(Pipe{}.Publish(ctx)))
  1242  }
  1243  
  1244  func TestDefaultNoDockers(t *testing.T) {
  1245  	ctx := testctx.NewWithCfg(config.Project{
  1246  		Dockers: []config.Docker{},
  1247  	})
  1248  	require.NoError(t, Pipe{}.Default(ctx))
  1249  	require.Empty(t, ctx.Config.Dockers)
  1250  }
  1251  
  1252  func TestDefaultFilesDot(t *testing.T) {
  1253  	ctx := testctx.NewWithCfg(config.Project{
  1254  		Dist: "/tmp/distt",
  1255  		Dockers: []config.Docker{
  1256  			{
  1257  				Files: []string{"./lala", "./lolsob", "."},
  1258  			},
  1259  		},
  1260  	})
  1261  	require.NoError(t, Pipe{}.Default(ctx))
  1262  }
  1263  
  1264  func TestDefaultFilesDis(t *testing.T) {
  1265  	ctx := testctx.NewWithCfg(config.Project{
  1266  		Dist: "/tmp/dist",
  1267  		Dockers: []config.Docker{
  1268  			{
  1269  				Files: []string{"./fooo", "/tmp/dist/asdasd/asd", "./bar"},
  1270  			},
  1271  		},
  1272  	})
  1273  	require.NoError(t, Pipe{}.Default(ctx))
  1274  }
  1275  
  1276  func TestDefaultSet(t *testing.T) {
  1277  	ctx := testctx.NewWithCfg(config.Project{
  1278  		Dockers: []config.Docker{
  1279  			{
  1280  				IDs:        []string{"foo"},
  1281  				Goos:       "windows",
  1282  				Goarch:     "i386",
  1283  				Dockerfile: "Dockerfile.foo",
  1284  			},
  1285  		},
  1286  	})
  1287  	require.NoError(t, Pipe{}.Default(ctx))
  1288  	require.Len(t, ctx.Config.Dockers, 1)
  1289  	docker := ctx.Config.Dockers[0]
  1290  	require.Equal(t, "windows", docker.Goos)
  1291  	require.Equal(t, "i386", docker.Goarch)
  1292  	require.Equal(t, []string{"foo"}, docker.IDs)
  1293  	require.Equal(t, "Dockerfile.foo", docker.Dockerfile)
  1294  }
  1295  
  1296  func Test_processImageTemplates(t *testing.T) {
  1297  	ctx := testctx.NewWithCfg(
  1298  		config.Project{
  1299  			Builds: []config.Build{
  1300  				{
  1301  					ID: "default",
  1302  				},
  1303  			},
  1304  			Dockers: []config.Docker{
  1305  				{
  1306  					Dockerfile: "Dockerfile.foo",
  1307  					ImageTemplates: []string{
  1308  						"user/image:{{.Tag}}",
  1309  						"gcr.io/image:{{.Tag}}-{{.Env.FOO}}",
  1310  						"gcr.io/image:v{{.Major}}.{{.Minor}}",
  1311  					},
  1312  					SkipPush: "true",
  1313  				},
  1314  			},
  1315  			Env: []string{"FOO=123"},
  1316  		},
  1317  		testctx.WithVersion("1.0.0"),
  1318  		testctx.WithCurrentTag("v1.0.0"),
  1319  		testctx.WithCommit("a1b2c3d4"),
  1320  		testctx.WithSemver(1, 0, 0, ""),
  1321  	)
  1322  
  1323  	require.NoError(t, Pipe{}.Default(ctx))
  1324  	require.Len(t, ctx.Config.Dockers, 1)
  1325  
  1326  	docker := ctx.Config.Dockers[0]
  1327  	require.Equal(t, "Dockerfile.foo", docker.Dockerfile)
  1328  
  1329  	images, err := processImageTemplates(ctx, docker)
  1330  	require.NoError(t, err)
  1331  	require.Equal(t, []string{
  1332  		"user/image:v1.0.0",
  1333  		"gcr.io/image:v1.0.0-123",
  1334  		"gcr.io/image:v1.0",
  1335  	}, images)
  1336  }
  1337  
  1338  func TestSkip(t *testing.T) {
  1339  	t.Run("image", func(t *testing.T) {
  1340  		t.Run("skip", func(t *testing.T) {
  1341  			require.True(t, Pipe{}.Skip(testctx.New()))
  1342  		})
  1343  
  1344  		t.Run("skip docker", func(t *testing.T) {
  1345  			ctx := testctx.NewWithCfg(config.Project{
  1346  				Dockers: []config.Docker{{}},
  1347  			}, testctx.Skip(skips.Docker))
  1348  			require.True(t, Pipe{}.Skip(ctx))
  1349  		})
  1350  
  1351  		t.Run("dont skip", func(t *testing.T) {
  1352  			ctx := testctx.NewWithCfg(config.Project{
  1353  				Dockers: []config.Docker{{}},
  1354  			})
  1355  			require.False(t, Pipe{}.Skip(ctx))
  1356  		})
  1357  	})
  1358  
  1359  	t.Run("manifest", func(t *testing.T) {
  1360  		t.Run("skip", func(t *testing.T) {
  1361  			require.True(t, ManifestPipe{}.Skip(testctx.New()))
  1362  		})
  1363  
  1364  		t.Run("skip docker", func(t *testing.T) {
  1365  			ctx := testctx.NewWithCfg(config.Project{
  1366  				DockerManifests: []config.DockerManifest{{}},
  1367  			}, testctx.Skip(skips.Docker))
  1368  			require.True(t, ManifestPipe{}.Skip(ctx))
  1369  		})
  1370  
  1371  		t.Run("dont skip", func(t *testing.T) {
  1372  			ctx := testctx.NewWithCfg(config.Project{
  1373  				DockerManifests: []config.DockerManifest{{}},
  1374  			})
  1375  			require.False(t, ManifestPipe{}.Skip(ctx))
  1376  		})
  1377  	})
  1378  }
  1379  
  1380  func TestWithDigest(t *testing.T) {
  1381  	artifacts := artifact.New()
  1382  	artifacts.Add(&artifact.Artifact{
  1383  		Name: "localhost:5050/owner/img:t1",
  1384  		Type: artifact.DockerImage,
  1385  		Extra: artifact.Extras{
  1386  			artifact.ExtraDigest: "sha256:d1",
  1387  		},
  1388  	})
  1389  	artifacts.Add(&artifact.Artifact{
  1390  		Name: "localhost:5050/owner/img:t2",
  1391  		Type: artifact.DockerImage,
  1392  		Extra: artifact.Extras{
  1393  			artifact.ExtraDigest: "sha256:d2",
  1394  		},
  1395  	})
  1396  	artifacts.Add(&artifact.Artifact{
  1397  		Name: "localhost:5050/owner/img:t3",
  1398  		Type: artifact.DockerImage,
  1399  	})
  1400  
  1401  	for _, use := range []string{useDocker, useBuildx} {
  1402  		use := use
  1403  		t.Run(use, func(t *testing.T) {
  1404  			t.Run("good", func(t *testing.T) {
  1405  				require.Equal(t, "localhost:5050/owner/img:t1@sha256:d1", withDigest(use, "localhost:5050/owner/img:t1", artifacts.List()))
  1406  			})
  1407  
  1408  			t.Run("no digest", func(t *testing.T) {
  1409  				require.Equal(t, "localhost:5050/owner/img:t3", withDigest(use, "localhost:5050/owner/img:t3", artifacts.List()))
  1410  			})
  1411  
  1412  			t.Run("no match", func(t *testing.T) {
  1413  				require.Equal(t, "localhost:5050/owner/img:t4", withDigest(use, "localhost:5050/owner/img:t4", artifacts.List()))
  1414  			})
  1415  		})
  1416  	}
  1417  }
  1418  
  1419  func TestDependencies(t *testing.T) {
  1420  	ctx := testctx.NewWithCfg(config.Project{
  1421  		Dockers: []config.Docker{
  1422  			{Use: useBuildx},
  1423  			{Use: useDocker},
  1424  			{Use: "nope"},
  1425  		},
  1426  		DockerManifests: []config.DockerManifest{
  1427  			{Use: useBuildx},
  1428  			{Use: useDocker},
  1429  			{Use: "nope"},
  1430  		},
  1431  	})
  1432  	require.Equal(t, []string{"docker", "docker"}, Pipe{}.Dependencies(ctx))
  1433  	require.Equal(t, []string{"docker", "docker"}, ManifestPipe{}.Dependencies(ctx))
  1434  }
  1435  
  1436  func TestIsFileNotFoundError(t *testing.T) {
  1437  	t.Run("executable not in path", func(t *testing.T) {
  1438  		require.False(t, isFileNotFoundError(`error getting credentials - err: exec: "docker-credential-desktop": executable file not found in $PATH, out:`))
  1439  	})
  1440  
  1441  	t.Run("file not found", func(t *testing.T) {
  1442  		require.True(t, isFileNotFoundError(`./foo: file not found`))
  1443  		require.True(t, isFileNotFoundError(`./foo: not found: not found`))
  1444  	})
  1445  }