github.com/goreleaser/goreleaser@v1.25.1/internal/pipe/winget/winget_test.go (about)

     1  package winget
     2  
     3  import (
     4  	"html/template"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/goreleaser/goreleaser/internal/artifact"
    12  	"github.com/goreleaser/goreleaser/internal/client"
    13  	"github.com/goreleaser/goreleaser/internal/golden"
    14  	"github.com/goreleaser/goreleaser/internal/skips"
    15  	"github.com/goreleaser/goreleaser/internal/testctx"
    16  	"github.com/goreleaser/goreleaser/pkg/config"
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  func TestContinueOnError(t *testing.T) {
    21  	require.True(t, Pipe{}.ContinueOnError())
    22  }
    23  
    24  func TestString(t *testing.T) {
    25  	require.NotEmpty(t, Pipe{}.String())
    26  }
    27  
    28  func TestSkip(t *testing.T) {
    29  	t.Run("should", func(t *testing.T) {
    30  		require.True(t, Pipe{}.Skip(testctx.New()))
    31  	})
    32  	t.Run("skip flag", func(t *testing.T) {
    33  		require.True(t, Pipe{}.Skip(testctx.NewWithCfg(config.Project{
    34  			Winget: []config.Winget{{}},
    35  		}, testctx.Skip(skips.Winget))))
    36  	})
    37  	t.Run("should not", func(t *testing.T) {
    38  		require.False(t, Pipe{}.Skip(testctx.NewWithCfg(config.Project{
    39  			Winget: []config.Winget{{}},
    40  		})))
    41  	})
    42  }
    43  
    44  func TestRunPipe(t *testing.T) {
    45  	for _, tt := range []struct {
    46  		name                 string
    47  		expectRunErrorIs     error
    48  		expectPublishErrorIs error
    49  		expectPath           string
    50  		winget               config.Winget
    51  	}{
    52  		{
    53  			name:       "minimal",
    54  			expectPath: "manifests/f/Foo/min/1.2.1/Foo.min.",
    55  			winget: config.Winget{
    56  				Name:             "min",
    57  				Publisher:        "Foo",
    58  				License:          "MIT",
    59  				ShortDescription: "foo bar zaz",
    60  				IDs:              []string{"foo"},
    61  				Repository: config.RepoRef{
    62  					Owner: "foo",
    63  					Name:  "bar",
    64  				},
    65  			},
    66  		},
    67  		{
    68  			name:             "mixed-formats",
    69  			expectRunErrorIs: errMixedFormats,
    70  			winget: config.Winget{
    71  				Name:             "mixed",
    72  				Publisher:        "Foo",
    73  				License:          "MIT",
    74  				ShortDescription: "foo bar zaz",
    75  				IDs:              []string{"zaz", "bar"},
    76  				Repository: config.RepoRef{
    77  					Owner: "foo",
    78  					Name:  "bar",
    79  				},
    80  			},
    81  		},
    82  		{
    83  			name:       "full",
    84  			expectPath: "manifests/b/Beckersoft LTDA/foo/1.2.1",
    85  			winget: config.Winget{
    86  				Name:                "foo",
    87  				Publisher:           "Beckersoft",
    88  				PublisherURL:        "https://carlosbecker.com",
    89  				PublisherSupportURL: "https://carlosbecker.com/support",
    90  				Copyright:           "bla bla bla",
    91  				CopyrightURL:        "https://goreleaser.com/copyright",
    92  				Author:              "Carlos Becker",
    93  				Path:                "manifests/b/Beckersoft LTDA/foo/{{.Version}}",
    94  				Repository:          config.RepoRef{Owner: "foo", Name: "bar"},
    95  				CommitAuthor:        config.CommitAuthor{},
    96  				IDs:                 []string{"foo"},
    97  				Goamd64:             "v1",
    98  				SkipUpload:          "false",
    99  				ShortDescription:    "foo",
   100  				Description: `long foo bar
   101  
   102  				yadaa yada yada loooaaasssss
   103  
   104  				sss`,
   105  				Homepage:        "https://goreleaser.com",
   106  				License:         "MIT",
   107  				LicenseURL:      "https://goreleaser.com/eula/",
   108  				ReleaseNotesURL: "https://github.com/goreleaser/goreleaser/tags/{{.Tag}}",
   109  				ReleaseNotes:    "{{.Changelog}}",
   110  				Tags:            []string{"foo", "bar"},
   111  			},
   112  		},
   113  		{
   114  			name: "open-pr",
   115  			winget: config.Winget{
   116  				Name:             "foo",
   117  				Publisher:        "Beckersoft",
   118  				IDs:              []string{"foo"},
   119  				Description:      "my test",
   120  				Homepage:         "https://goreleaser.com",
   121  				License:          "mit",
   122  				Path:             "pkgs/foo.winget",
   123  				ShortDescription: "foo bar zaz",
   124  				Repository: config.RepoRef{
   125  					Owner:  "foo",
   126  					Name:   "bar",
   127  					Branch: "update-{{.Version}}",
   128  					PullRequest: config.PullRequest{
   129  						Enabled: true,
   130  						Base: config.PullRequestBase{
   131  							Owner: "ms",
   132  							Name:  "winget",
   133  						},
   134  					},
   135  				},
   136  			},
   137  		},
   138  		{
   139  			name: "wrapped-in-dir",
   140  			winget: config.Winget{
   141  				Name:             "wrapped-in-dir",
   142  				Publisher:        "Beckersoft",
   143  				IDs:              []string{"wrapped-in-dir"},
   144  				Description:      "my test",
   145  				Homepage:         "https://goreleaser.com",
   146  				License:          "mit",
   147  				LicenseURL:       "https://goreleaser.com/license",
   148  				ReleaseNotesURL:  "https://github.com/goreleaser/goreleaser/tags/{{.Tag}}",
   149  				ShortDescription: "foo bar zaz",
   150  				Repository: config.RepoRef{
   151  					Owner: "foo",
   152  					Name:  "bar",
   153  				},
   154  			},
   155  		},
   156  		{
   157  			name: "no-archives",
   158  			expectRunErrorIs: errNoArchivesFound{
   159  				goamd64: "v2",
   160  				ids:     []string{"nopenopenope"},
   161  			},
   162  			winget: config.Winget{
   163  				Name:             "no-archives",
   164  				Publisher:        "Beckersoft",
   165  				IDs:              []string{"nopenopenope"},
   166  				Goamd64:          "v2",
   167  				License:          "MIT",
   168  				ShortDescription: "foo bar zaz",
   169  				Repository: config.RepoRef{
   170  					Owner: "foo",
   171  					Name:  "bar",
   172  				},
   173  			},
   174  		},
   175  		{
   176  			name:             "too-many-archives",
   177  			expectRunErrorIs: errMultipleArchives,
   178  			winget: config.Winget{
   179  				Name:             "min",
   180  				Publisher:        "Foo",
   181  				License:          "MIT",
   182  				ShortDescription: "foo bar zaz",
   183  				IDs:              []string{},
   184  				Repository: config.RepoRef{
   185  					Owner: "foo",
   186  					Name:  "bar",
   187  				},
   188  			},
   189  		},
   190  		{
   191  			name: "partial",
   192  			winget: config.Winget{
   193  				Name:             "partial",
   194  				Publisher:        "Beckersoft",
   195  				IDs:              []string{"partial"},
   196  				License:          "MIT",
   197  				ShortDescription: "foo bar zaz",
   198  				Repository: config.RepoRef{
   199  					Owner: "foo",
   200  					Name:  "bar",
   201  				},
   202  			},
   203  		},
   204  		{
   205  			name:             "no-repo-name",
   206  			expectRunErrorIs: errNoRepoName,
   207  			winget: config.Winget{
   208  				Name:             "doesnotmatter",
   209  				Publisher:        "Beckersoft",
   210  				License:          "MIT",
   211  				ShortDescription: "foo bar zaz",
   212  				Repository: config.RepoRef{
   213  					Owner: "foo",
   214  				},
   215  			},
   216  		},
   217  		{
   218  			name:             "no-license",
   219  			expectRunErrorIs: errNoLicense,
   220  			winget: config.Winget{
   221  				Name:             "doesnotmatter",
   222  				Publisher:        "Beckersoft",
   223  				ShortDescription: "aa",
   224  				Repository: config.RepoRef{
   225  					Name:  "foo",
   226  					Owner: "foo",
   227  				},
   228  			},
   229  		},
   230  		{
   231  			name:             "no-short-description",
   232  			expectRunErrorIs: errNoShortDescription,
   233  			winget: config.Winget{
   234  				Name:      "doesnotmatter",
   235  				Publisher: "Beckersoft",
   236  				License:   "MIT",
   237  				Repository: config.RepoRef{
   238  					Name:  "foo",
   239  					Owner: "foo",
   240  				},
   241  			},
   242  		},
   243  		{
   244  			name:             "invalid-package-identifier",
   245  			expectRunErrorIs: errInvalidPackageIdentifier,
   246  			winget: config.Winget{
   247  				Name:              "min",
   248  				PackageIdentifier: "foobar",
   249  				Publisher:         "Foo",
   250  				License:           "MIT",
   251  				ShortDescription:  "foo bar zaz",
   252  				Repository: config.RepoRef{
   253  					Owner: "foo",
   254  					Name:  "bar",
   255  				},
   256  			},
   257  		},
   258  		{
   259  			name:             "no-publisher",
   260  			expectRunErrorIs: errNoPublisher,
   261  			winget: config.Winget{
   262  				Name:             "min",
   263  				License:          "MIT",
   264  				ShortDescription: "foo bar zaz",
   265  				Repository: config.RepoRef{
   266  					Owner: "foo",
   267  					Name:  "bar",
   268  				},
   269  			},
   270  		},
   271  		{
   272  			name:             "bad-name-tmpl",
   273  			expectRunErrorIs: &template.Error{},
   274  			winget: config.Winget{
   275  				Name:             "{{ .Nope }}",
   276  				Publisher:        "Beckersoft",
   277  				License:          "MIT",
   278  				ShortDescription: "foo bar zaz",
   279  				Repository: config.RepoRef{
   280  					Owner: "foo",
   281  					Name:  "bar",
   282  				},
   283  			},
   284  		},
   285  		{
   286  			name:             "bad-releasenotes-tmpl",
   287  			expectRunErrorIs: &template.Error{},
   288  			winget: config.Winget{
   289  				ReleaseNotes:     "{{ .Nope }}",
   290  				Publisher:        "Beckersoft",
   291  				License:          "MIT",
   292  				ShortDescription: "foo bar zaz",
   293  				Repository: config.RepoRef{
   294  					Owner: "foo",
   295  					Name:  "bar",
   296  				},
   297  			},
   298  		},
   299  		{
   300  			name:             "bad-publisher-tmpl",
   301  			expectRunErrorIs: &template.Error{},
   302  			winget: config.Winget{
   303  				Name:             "foo",
   304  				Publisher:        "{{ .Nope }}",
   305  				License:          "MIT",
   306  				ShortDescription: "foo bar zaz",
   307  				Repository: config.RepoRef{
   308  					Owner: "foo",
   309  					Name:  "bar",
   310  				},
   311  			},
   312  		},
   313  		{
   314  			name:             "bad-publisher-url-tmpl",
   315  			expectRunErrorIs: &template.Error{},
   316  			winget: config.Winget{
   317  				Name:             "foo",
   318  				Publisher:        "Beckersoft",
   319  				PublisherURL:     "{{ .Nope }}",
   320  				License:          "MIT",
   321  				ShortDescription: "foo bar zaz",
   322  				Repository: config.RepoRef{
   323  					Owner: "foo",
   324  					Name:  "bar",
   325  				},
   326  			},
   327  		},
   328  		{
   329  			name:             "bad-author-tmpl",
   330  			expectRunErrorIs: &template.Error{},
   331  			winget: config.Winget{
   332  				Name:             "foobar",
   333  				Publisher:        "Beckersoft",
   334  				Author:           "{{ .Nope }}",
   335  				License:          "MIT",
   336  				ShortDescription: "foo bar zaz",
   337  				Repository: config.RepoRef{
   338  					Owner: "foo",
   339  					Name:  "bar",
   340  				},
   341  			},
   342  		},
   343  		{
   344  			name:             "bad-homepage-tmpl",
   345  			expectRunErrorIs: &template.Error{},
   346  			winget: config.Winget{
   347  				Name:             "foobar",
   348  				Publisher:        "Beckersoft",
   349  				Homepage:         "{{ .Nope }}",
   350  				License:          "MIT",
   351  				ShortDescription: "foo bar zaz",
   352  				Repository: config.RepoRef{
   353  					Owner: "foo",
   354  					Name:  "bar",
   355  				},
   356  			},
   357  		},
   358  		{
   359  			name:             "bad-description-tmpl",
   360  			expectRunErrorIs: &template.Error{},
   361  			winget: config.Winget{
   362  				Name:             "foobar",
   363  				Publisher:        "Beckersoft",
   364  				Description:      "{{ .Nope }}",
   365  				License:          "MIT",
   366  				ShortDescription: "foo bar zaz",
   367  				Repository: config.RepoRef{
   368  					Owner: "foo",
   369  					Name:  "bar",
   370  				},
   371  			},
   372  		},
   373  		{
   374  			name:             "bad-short-description-tmpl",
   375  			expectRunErrorIs: &template.Error{},
   376  			winget: config.Winget{
   377  				Name:             "foobar",
   378  				Publisher:        "Beckersoft",
   379  				ShortDescription: "{{ .Nope }}",
   380  				License:          "MIT",
   381  				Repository: config.RepoRef{
   382  					Owner: "foo",
   383  					Name:  "bar",
   384  				},
   385  			},
   386  		},
   387  		{
   388  			name:             "bad-repo-tmpl",
   389  			expectRunErrorIs: &template.Error{},
   390  			winget: config.Winget{
   391  				Name:             "doesnotmatter",
   392  				Publisher:        "Beckersoft",
   393  				License:          "MIT",
   394  				ShortDescription: "foo bar zaz",
   395  				Repository: config.RepoRef{
   396  					Owner: "foo",
   397  					Name:  "{{ .Nope }}",
   398  				},
   399  			},
   400  		},
   401  		{
   402  			name:             "bad-skip-upload-tmpl",
   403  			expectRunErrorIs: &template.Error{},
   404  			winget: config.Winget{
   405  				Name:             "doesnotmatter",
   406  				Publisher:        "Beckersoft",
   407  				SkipUpload:       "{{ .Nope }}",
   408  				License:          "MIT",
   409  				ShortDescription: "foo bar zaz",
   410  				Repository: config.RepoRef{
   411  					Owner: "foo",
   412  					Name:  "bar",
   413  				},
   414  			},
   415  		},
   416  		{
   417  			name:             "bad-release-notes-url-tmpl",
   418  			expectRunErrorIs: &template.Error{},
   419  			winget: config.Winget{
   420  				Name:             "foo",
   421  				Publisher:        "Beckersoft",
   422  				ReleaseNotesURL:  `https://goo/bar/asdfsd/{{.nope}}`,
   423  				License:          "MIT",
   424  				ShortDescription: "foo bar zaz",
   425  				Repository: config.RepoRef{
   426  					Owner: "foo",
   427  					Name:  "bar",
   428  				},
   429  			},
   430  		},
   431  		{
   432  			name:             "bad-release-url-tmpl",
   433  			expectRunErrorIs: &template.Error{},
   434  			winget: config.Winget{
   435  				Name:             "foo",
   436  				Publisher:        "Beckersoft",
   437  				URLTemplate:      "{{.BadURL}}",
   438  				License:          "MIT",
   439  				ShortDescription: "foo bar zaz",
   440  				Repository: config.RepoRef{
   441  					Owner: "foo",
   442  					Name:  "bar",
   443  				},
   444  			},
   445  		},
   446  		{
   447  			name:             "bad-path-tmpl",
   448  			expectRunErrorIs: &template.Error{},
   449  			winget: config.Winget{
   450  				Name:             "foo",
   451  				Publisher:        "Beckersoft",
   452  				License:          "MIT",
   453  				Path:             "{{ .Nope }}",
   454  				ShortDescription: "foo bar zaz",
   455  				Repository: config.RepoRef{
   456  					Owner: "foo",
   457  					Name:  "bar",
   458  				},
   459  			},
   460  		},
   461  		{
   462  			name:                 "bad-commit-msg-tmpl",
   463  			expectPublishErrorIs: &template.Error{},
   464  			winget: config.Winget{
   465  				Name:                  "foo",
   466  				Publisher:             "Beckersoft",
   467  				License:               "MIT",
   468  				ShortDescription:      "foo bar zaz",
   469  				CommitMessageTemplate: "{{.Foo}}",
   470  				IDs:                   []string{"foo"},
   471  				Repository: config.RepoRef{
   472  					Owner: "foo",
   473  					Name:  "bar",
   474  				},
   475  			},
   476  		},
   477  		{
   478  			name:             "bad-publisher-support-url-tmpl",
   479  			expectRunErrorIs: &template.Error{},
   480  			winget: config.Winget{
   481  				Name:                "foo",
   482  				Publisher:           "Beckersoft",
   483  				PublisherSupportURL: "{{.Nope}}",
   484  				License:             "MIT",
   485  				ShortDescription:    "foo bar zaz",
   486  				Repository: config.RepoRef{
   487  					Owner: "foo",
   488  					Name:  "bar",
   489  				},
   490  			},
   491  		},
   492  		{
   493  			name:             "bad-copyright-tmpl",
   494  			expectRunErrorIs: &template.Error{},
   495  			winget: config.Winget{
   496  				Name:             "foo",
   497  				Publisher:        "Beckersoft",
   498  				License:          "MIT",
   499  				Copyright:        "{{ .Nope }}",
   500  				ShortDescription: "foo bar zaz",
   501  				Repository: config.RepoRef{
   502  					Owner: "foo",
   503  					Name:  "bar",
   504  				},
   505  			},
   506  		},
   507  		{
   508  			name:             "bad-copyright-url-tmpl",
   509  			expectRunErrorIs: &template.Error{},
   510  			winget: config.Winget{
   511  				Name:             "{{ .Nope }}",
   512  				Publisher:        "Beckersoft",
   513  				License:          "MIT",
   514  				CopyrightURL:     "{{ .Nope }}",
   515  				ShortDescription: "foo bar zaz",
   516  				Repository: config.RepoRef{
   517  					Owner: "foo",
   518  					Name:  "bar",
   519  				},
   520  			},
   521  		},
   522  		{
   523  			name:             "bad-license-tmpl",
   524  			expectRunErrorIs: &template.Error{},
   525  			winget: config.Winget{
   526  				Name:             "foo",
   527  				Publisher:        "Beckersoft",
   528  				License:          "{{ .Nope }}",
   529  				ShortDescription: "foo bar zaz",
   530  				Repository: config.RepoRef{
   531  					Owner: "foo",
   532  					Name:  "bar",
   533  				},
   534  			},
   535  		},
   536  		{
   537  			name:             "bad-license-url-tmpl",
   538  			expectRunErrorIs: &template.Error{},
   539  			winget: config.Winget{
   540  				Name:             "foo",
   541  				Publisher:        "Beckersoft",
   542  				License:          "MIT",
   543  				LicenseURL:       "{{ .Nope }}",
   544  				ShortDescription: "foo bar zaz",
   545  				Repository: config.RepoRef{
   546  					Owner: "foo",
   547  					Name:  "bar",
   548  				},
   549  			},
   550  		},
   551  		{
   552  			name:                 "skip-upload",
   553  			expectPublishErrorIs: errSkipUpload,
   554  			winget: config.Winget{
   555  				Name:             "doesnotmatter",
   556  				Publisher:        "Beckersoft",
   557  				SkipUpload:       "true",
   558  				License:          "MIT",
   559  				IDs:              []string{"foo"},
   560  				ShortDescription: "foo bar zaz",
   561  				Repository: config.RepoRef{
   562  					Owner: "foo",
   563  					Name:  "bar",
   564  				},
   565  			},
   566  		},
   567  		{
   568  			name:                 "skip-upload-auto",
   569  			expectPublishErrorIs: errSkipUploadAuto,
   570  			winget: config.Winget{
   571  				Name:             "doesnotmatter",
   572  				Publisher:        "Beckersoft",
   573  				License:          "MIT",
   574  				ShortDescription: "foo bar zaz",
   575  				IDs:              []string{"foo"},
   576  				SkipUpload:       "auto",
   577  				Repository: config.RepoRef{
   578  					Owner: "foo",
   579  					Name:  "bar",
   580  				},
   581  			},
   582  		},
   583  		{
   584  			name:       "with-deps",
   585  			expectPath: "manifests/f/Foo/deps/1.2.1/Foo.deps.",
   586  			winget: config.Winget{
   587  				Name:             "deps",
   588  				Publisher:        "Foo",
   589  				License:          "MIT",
   590  				ShortDescription: "foo bar zaz",
   591  				IDs:              []string{"foo"},
   592  				Repository: config.RepoRef{
   593  					Owner: "foo",
   594  					Name:  "bar",
   595  				},
   596  				Dependencies: []config.WingetDependency{
   597  					{
   598  						PackageIdentifier: "foo.bar",
   599  						MinimumVersion:    "1.2.3",
   600  					},
   601  					{
   602  						PackageIdentifier: "zaz.bar",
   603  					},
   604  				},
   605  			},
   606  		},
   607  		{
   608  			name:             "bad-dependency-template",
   609  			expectRunErrorIs: &template.Error{},
   610  			winget: config.Winget{
   611  				Name:             "foo",
   612  				Publisher:        "Beckersoft",
   613  				License:          "MIT",
   614  				LicenseURL:       "https://foo.bar",
   615  				ShortDescription: "foo bar zaz",
   616  				Repository: config.RepoRef{
   617  					Owner: "foo",
   618  					Name:  "bar",
   619  				},
   620  				Dependencies: []config.WingetDependency{
   621  					{PackageIdentifier: "{{.Nope}}"},
   622  				},
   623  			},
   624  		},
   625  	} {
   626  		t.Run(tt.name, func(t *testing.T) {
   627  			folder := t.TempDir()
   628  			ctx := testctx.NewWithCfg(
   629  				config.Project{
   630  					Dist:        folder,
   631  					ProjectName: "foo",
   632  					Winget:      []config.Winget{tt.winget},
   633  				},
   634  				testctx.WithVersion("1.2.1"),
   635  				testctx.WithCurrentTag("v1.2.1"),
   636  				testctx.WithSemver(1, 2, 1, "rc1"),
   637  				testctx.WithDate(time.Date(2023, 6, 12, 20, 32, 10, 12, time.Local)),
   638  			)
   639  			ctx.ReleaseNotes = "the changelog for this release..."
   640  			createFakeArtifact := func(id, goos, goarch, goamd64, goarm string, extra map[string]any) {
   641  				path := filepath.Join(folder, "dist/foo_"+goos+goarch+goamd64+goarm+".zip")
   642  				art := artifact.Artifact{
   643  					Name:    "foo_" + goos + "_" + goarch + goamd64 + goarm + ".zip",
   644  					Path:    path,
   645  					Goos:    goos,
   646  					Goarch:  goarch,
   647  					Goarm:   goarm,
   648  					Goamd64: goamd64,
   649  					Type:    artifact.UploadableArchive,
   650  					Extra: map[string]interface{}{
   651  						artifact.ExtraID:        id,
   652  						artifact.ExtraFormat:    "zip",
   653  						artifact.ExtraBinaries:  []string{"foo.exe"},
   654  						artifact.ExtraWrappedIn: "",
   655  					},
   656  				}
   657  				for k, v := range extra {
   658  					art.Extra[k] = v
   659  				}
   660  				ctx.Artifacts.Add(&art)
   661  
   662  				require.NoError(t, os.MkdirAll(filepath.Dir(path), 0o755))
   663  				f, err := os.Create(path)
   664  				require.NoError(t, err)
   665  				require.NoError(t, f.Close())
   666  			}
   667  
   668  			goos := "windows"
   669  			goarch := "amd64"
   670  			createFakeArtifact("partial", goos, goarch, "v1", "", nil)
   671  			createFakeArtifact("foo", goos, goarch, "v1", "", nil)
   672  			createFakeArtifact("zaz", goos, goarch, "v1", "", nil)
   673  			createFakeArtifact("wrapped-in-dir", goos, goarch, "v1", "", map[string]any{
   674  				artifact.ExtraWrappedIn: "foo",
   675  				artifact.ExtraBinaries:  []string{"bin/foo.exe"},
   676  			})
   677  
   678  			goarch = "386"
   679  			createFakeArtifact("foo", goos, goarch, "", "", nil)
   680  			ctx.Artifacts.Add(&artifact.Artifact{
   681  				Name:   "bar.exe",
   682  				Path:   "doesnt-matter",
   683  				Goos:   goos,
   684  				Goarch: goarch,
   685  				Type:   artifact.UploadableBinary,
   686  				Extra: map[string]interface{}{
   687  					artifact.ExtraID: "bar",
   688  				},
   689  			})
   690  			createFakeArtifact("bar", goos, goarch, "v1", "", nil)
   691  			createFakeArtifact("wrapped-in-dir", goos, goarch, "", "", map[string]any{
   692  				artifact.ExtraWrappedIn: "foo",
   693  				artifact.ExtraBinaries:  []string{"bin/foo.exe"},
   694  			})
   695  
   696  			goarch = "arm64"
   697  			createFakeArtifact("foo", goos, goarch, "", "", nil)
   698  			createFakeArtifact("wrapped-in-dir", goos, goarch, "", "", map[string]any{
   699  				artifact.ExtraWrappedIn: "foo",
   700  				artifact.ExtraBinaries:  []string{"bin/foo.exe"},
   701  			})
   702  
   703  			client := client.NewMock()
   704  			pipe := Pipe{}
   705  
   706  			// default
   707  			require.NoError(t, pipe.Default(ctx))
   708  
   709  			// run
   710  			if tt.expectRunErrorIs != nil {
   711  				err := pipe.runAll(ctx, client)
   712  				require.Error(t, err)
   713  				require.ErrorAs(t, err, &tt.expectPublishErrorIs)
   714  				return
   715  			}
   716  
   717  			require.NoError(t, pipe.runAll(ctx, client))
   718  			for _, winget := range ctx.Artifacts.Filter(artifact.Or(
   719  				artifact.ByType(artifact.WingetInstaller),
   720  				artifact.ByType(artifact.WingetVersion),
   721  				artifact.ByType(artifact.WingetDefaultLocale),
   722  			)).List() {
   723  				bts, err := os.ReadFile(winget.Path)
   724  				require.NoError(t, err)
   725  				golden.RequireEqualExtSubfolder(t, bts, extFor(winget.Type))
   726  			}
   727  
   728  			// publish
   729  			if tt.expectPublishErrorIs != nil {
   730  				err := pipe.publishAll(ctx, client)
   731  				require.Error(t, err)
   732  				require.ErrorAs(t, err, &tt.expectPublishErrorIs)
   733  				return
   734  			}
   735  			require.NoError(t, pipe.publishAll(ctx, client))
   736  			require.True(t, client.CreatedFile)
   737  
   738  			require.Len(t, client.Messages, 3)
   739  			expected := map[string]bool{
   740  				"locale":    false,
   741  				"version":   false,
   742  				"installer": false,
   743  			}
   744  			for _, msg := range client.Messages {
   745  				require.Regexp(t, "New version: \\w+\\.[\\w-]+ 1.2.1", msg)
   746  				for k, v := range expected {
   747  					if strings.Contains(msg, ": add "+k) {
   748  						require.False(t, v, "multiple commits for "+k)
   749  						expected[k] = true
   750  					}
   751  				}
   752  			}
   753  
   754  			require.NotEmpty(t, client.Path)
   755  			if tt.expectPath != "" {
   756  				require.Truef(t, strings.HasPrefix(client.Path, tt.expectPath), "expected %q to begin with %q", client.Path, tt.expectPath)
   757  			}
   758  
   759  			if tt.winget.Repository.PullRequest.Enabled {
   760  				require.True(t, client.SyncedFork)
   761  				require.True(t, client.OpenedPullRequest)
   762  			}
   763  		})
   764  	}
   765  }
   766  
   767  func TestErrNoArchivesFound(t *testing.T) {
   768  	require.EqualError(t, errNoArchivesFound{
   769  		goamd64: "v1",
   770  		ids:     []string{"foo", "bar"},
   771  	}, "no zip archives found matching goos=[windows] goarch=[amd64 386] goamd64=v1 ids=[foo bar]")
   772  }
   773  
   774  func TestDefault(t *testing.T) {
   775  	ctx := testctx.NewWithCfg(config.Project{
   776  		ProjectName: "foo",
   777  		Winget:      []config.Winget{{}},
   778  	})
   779  	require.NoError(t, Pipe{}.Default(ctx))
   780  	winget := ctx.Config.Winget[0]
   781  	require.Equal(t, "v1", winget.Goamd64)
   782  	require.NotEmpty(t, winget.CommitMessageTemplate)
   783  	require.Equal(t, "foo", winget.Name)
   784  }
   785  
   786  func TestFormatBinary(t *testing.T) {
   787  	folder := t.TempDir()
   788  	ctx := testctx.NewWithCfg(
   789  		config.Project{
   790  			Dist:        folder,
   791  			ProjectName: "foo",
   792  			Winget: []config.Winget{{
   793  				Name:             "foo",
   794  				Publisher:        "goreleaser",
   795  				License:          "MIT",
   796  				ShortDescription: "foo bar zaz",
   797  				IDs:              []string{"foo"},
   798  				Repository: config.RepoRef{
   799  					Owner: "foo",
   800  					Name:  "bar",
   801  				},
   802  			}},
   803  		},
   804  		testctx.WithVersion("1.2.1"),
   805  		testctx.WithCurrentTag("v1.2.1"),
   806  		testctx.WithSemver(1, 2, 1, "rc1"),
   807  		testctx.WithDate(time.Date(2023, 6, 12, 20, 32, 10, 12, time.Local)),
   808  	)
   809  	ctx.ReleaseNotes = "the changelog for this release..."
   810  	createFakeArtifact := func(id, goos, goarch, goamd64 string) {
   811  		path := filepath.Join(folder, "dist/foo_"+goos+goarch+goamd64+".exe")
   812  		art := artifact.Artifact{
   813  			Name:    "foo_" + goos + "_" + goarch + goamd64 + ".exe",
   814  			Path:    path,
   815  			Goos:    goos,
   816  			Goarch:  goarch,
   817  			Goamd64: goamd64,
   818  			Type:    artifact.UploadableBinary,
   819  			Extra: map[string]interface{}{
   820  				artifact.ExtraID: id,
   821  			},
   822  		}
   823  		ctx.Artifacts.Add(&art)
   824  		require.NoError(t, os.MkdirAll(filepath.Dir(path), 0o755))
   825  		f, err := os.Create(path)
   826  		require.NoError(t, err)
   827  		require.NoError(t, f.Close())
   828  	}
   829  
   830  	goos := "windows"
   831  	createFakeArtifact("foo", goos, "amd64", "v1")
   832  	createFakeArtifact("foo", goos, "386", "")
   833  	createFakeArtifact("foo", goos, "arm64", "")
   834  
   835  	client := client.NewMock()
   836  	pipe := Pipe{}
   837  
   838  	require.NoError(t, pipe.Default(ctx))
   839  	require.NoError(t, pipe.runAll(ctx, client))
   840  	for _, winget := range ctx.Artifacts.Filter(artifact.Or(
   841  		artifact.ByType(artifact.WingetInstaller),
   842  		artifact.ByType(artifact.WingetVersion),
   843  		artifact.ByType(artifact.WingetDefaultLocale),
   844  	)).List() {
   845  		bts, err := os.ReadFile(winget.Path)
   846  		require.NoError(t, err)
   847  		golden.RequireEqualExtSubfolder(t, bts, extFor(winget.Type))
   848  	}
   849  	require.NoError(t, pipe.publishAll(ctx, client))
   850  	require.True(t, client.CreatedFile)
   851  }