github.com/windmeup/goreleaser@v1.21.95/internal/pipe/checksums/checksums_test.go (about) 1 package checksums 2 3 import ( 4 "os" 5 "path/filepath" 6 "strings" 7 "syscall" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 "github.com/windmeup/goreleaser/internal/artifact" 12 "github.com/windmeup/goreleaser/internal/testctx" 13 "github.com/windmeup/goreleaser/internal/testlib" 14 "github.com/windmeup/goreleaser/pkg/config" 15 ) 16 17 func TestDescription(t *testing.T) { 18 require.NotEmpty(t, Pipe{}.String()) 19 } 20 21 func TestPipe(t *testing.T) { 22 const binary = "binary" 23 const archive = binary + ".tar.gz" 24 const linuxPackage = binary + ".rpm" 25 const checksums = binary + "_bar_checksums.txt" 26 const sum = "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc " 27 28 tests := map[string]struct { 29 ids []string 30 want string 31 }{ 32 "default": { 33 want: strings.Join([]string{ 34 sum + binary, 35 sum + linuxPackage, 36 sum + archive, 37 }, "\n") + "\n", 38 }, 39 "select ids": { 40 ids: []string{ 41 "id-1", 42 "id-2", 43 }, 44 want: strings.Join([]string{ 45 sum + binary, 46 sum + archive, 47 }, "\n") + "\n", 48 }, 49 } 50 for name, tt := range tests { 51 t.Run(name, func(t *testing.T) { 52 folder := t.TempDir() 53 file := filepath.Join(folder, binary) 54 require.NoError(t, os.WriteFile(file, []byte("some string"), 0o644)) 55 ctx := testctx.NewWithCfg( 56 config.Project{ 57 Dist: folder, 58 ProjectName: binary, 59 Checksum: config.Checksum{ 60 NameTemplate: "{{ .ProjectName }}_{{ .Env.FOO }}_checksums.txt", 61 Algorithm: "sha256", 62 IDs: tt.ids, 63 }, 64 Env: []string{"FOO=bar"}, 65 }, 66 testctx.WithCurrentTag("1.2.3"), 67 ) 68 ctx.Artifacts.Add(&artifact.Artifact{ 69 Name: binary, 70 Path: file, 71 Type: artifact.UploadableBinary, 72 Extra: map[string]interface{}{ 73 artifact.ExtraID: "id-1", 74 }, 75 }) 76 ctx.Artifacts.Add(&artifact.Artifact{ 77 Name: archive, 78 Path: file, 79 Type: artifact.UploadableArchive, 80 Extra: map[string]interface{}{ 81 artifact.ExtraID: "id-2", 82 }, 83 }) 84 ctx.Artifacts.Add(&artifact.Artifact{ 85 Name: linuxPackage, 86 Path: file, 87 Type: artifact.LinuxPackage, 88 Extra: map[string]interface{}{ 89 artifact.ExtraID: "id-3", 90 }, 91 }) 92 require.NoError(t, Pipe{}.Run(ctx)) 93 var artifacts []string 94 for _, a := range ctx.Artifacts.List() { 95 artifacts = append(artifacts, a.Name) 96 require.NoError(t, a.Refresh(), "refresh should not fail and yield same results as nothing changed") 97 } 98 require.Contains(t, artifacts, checksums, binary) 99 bts, err := os.ReadFile(filepath.Join(folder, checksums)) 100 require.NoError(t, err) 101 require.Contains(t, tt.want, string(bts)) 102 }) 103 } 104 } 105 106 func TestRefreshModifying(t *testing.T) { 107 const binary = "binary" 108 folder := t.TempDir() 109 file := filepath.Join(folder, binary) 110 require.NoError(t, os.WriteFile(file, []byte("some string"), 0o644)) 111 ctx := testctx.NewWithCfg(config.Project{ 112 Dist: folder, 113 ProjectName: binary, 114 Checksum: config.Checksum{ 115 NameTemplate: "{{ .ProjectName }}_{{ .Env.FOO }}_checksums.txt", 116 Algorithm: "sha256", 117 }, 118 Env: []string{"FOO=bar"}, 119 }, testctx.WithCurrentTag("1.2.3")) 120 ctx.Artifacts.Add(&artifact.Artifact{ 121 Name: binary, 122 Path: file, 123 Type: artifact.UploadableBinary, 124 }) 125 require.NoError(t, Pipe{}.Run(ctx)) 126 checks := ctx.Artifacts.Filter(artifact.ByType(artifact.Checksum)).List() 127 require.Len(t, checks, 1) 128 previous, err := os.ReadFile(checks[0].Path) 129 require.NoError(t, err) 130 require.NoError(t, os.WriteFile(file, []byte("some other string"), 0o644)) 131 require.NoError(t, checks[0].Refresh()) 132 current, err := os.ReadFile(checks[0].Path) 133 require.NoError(t, err) 134 require.NotEqual(t, string(previous), string(current)) 135 } 136 137 func TestPipeFileNotExist(t *testing.T) { 138 folder := t.TempDir() 139 ctx := testctx.NewWithCfg( 140 config.Project{ 141 Dist: folder, 142 Checksum: config.Checksum{ 143 NameTemplate: "checksums.txt", 144 }, 145 }, 146 testctx.WithCurrentTag("1.2.3"), 147 ) 148 ctx.Artifacts.Add(&artifact.Artifact{ 149 Name: "nope", 150 Path: "/nope", 151 Type: artifact.UploadableBinary, 152 }) 153 require.ErrorIs(t, Pipe{}.Run(ctx), os.ErrNotExist) 154 } 155 156 func TestPipeInvalidNameTemplate(t *testing.T) { 157 binFile, err := os.CreateTemp(t.TempDir(), "goreleasertest-bin") 158 require.NoError(t, err) 159 t.Cleanup(func() { require.NoError(t, binFile.Close()) }) 160 _, err = binFile.WriteString("fake artifact") 161 require.NoError(t, err) 162 163 for _, template := range []string{ 164 "{{ .Pro }_checksums.txt", 165 "{{.Env.NOPE}}", 166 } { 167 t.Run(template, func(t *testing.T) { 168 folder := t.TempDir() 169 ctx := testctx.NewWithCfg( 170 config.Project{ 171 Dist: folder, 172 ProjectName: "name", 173 Checksum: config.Checksum{ 174 NameTemplate: template, 175 Algorithm: "sha256", 176 }, 177 }, 178 testctx.WithCurrentTag("1.2.3"), 179 ) 180 ctx.Artifacts.Add(&artifact.Artifact{ 181 Name: "whatever", 182 Type: artifact.UploadableBinary, 183 Path: binFile.Name(), 184 }) 185 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 186 }) 187 } 188 } 189 190 func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) { 191 folder := t.TempDir() 192 binFile, err := os.CreateTemp(folder, "goreleasertest-bin") 193 require.NoError(t, err) 194 t.Cleanup(func() { require.NoError(t, binFile.Close()) }) 195 _, err = binFile.WriteString("fake artifact") 196 require.NoError(t, err) 197 198 file := filepath.Join(folder, "checksums.txt") 199 require.NoError(t, os.WriteFile(file, []byte("some string"), 0o000)) 200 ctx := testctx.NewWithCfg( 201 config.Project{ 202 Dist: folder, 203 Checksum: config.Checksum{ 204 NameTemplate: "checksums.txt", 205 Algorithm: "sha256", 206 }, 207 }, 208 testctx.WithCurrentTag("1.2.3"), 209 ) 210 ctx.Artifacts.Add(&artifact.Artifact{ 211 Name: "whatever", 212 Type: artifact.UploadableBinary, 213 Path: binFile.Name(), 214 }) 215 err = Pipe{}.Run(ctx) 216 require.Error(t, err) 217 require.ErrorIs(t, Pipe{}.Run(ctx), syscall.EACCES) 218 } 219 220 func TestPipeWhenNoArtifacts(t *testing.T) { 221 ctx := testctx.New() 222 require.NoError(t, Pipe{}.Run(ctx)) 223 require.Len(t, ctx.Artifacts.List(), 0) 224 } 225 226 func TestDefault(t *testing.T) { 227 ctx := testctx.NewWithCfg(config.Project{ 228 Checksum: config.Checksum{}, 229 }) 230 require.NoError(t, Pipe{}.Default(ctx)) 231 require.Equal( 232 t, 233 "{{ .ProjectName }}_{{ .Version }}_checksums.txt", 234 ctx.Config.Checksum.NameTemplate, 235 ) 236 require.Equal(t, "sha256", ctx.Config.Checksum.Algorithm) 237 } 238 239 func TestDefaultSet(t *testing.T) { 240 ctx := testctx.NewWithCfg(config.Project{ 241 Checksum: config.Checksum{ 242 NameTemplate: "checksums.txt", 243 }, 244 }) 245 require.NoError(t, Pipe{}.Default(ctx)) 246 require.Equal(t, "checksums.txt", ctx.Config.Checksum.NameTemplate) 247 } 248 249 func TestPipeChecksumsSortByFilename(t *testing.T) { 250 const binary = "binary" 251 const checksums = "checksums.txt" 252 const filePaths = "./testdata/order/*.txt" 253 254 folder := t.TempDir() 255 file := filepath.Join(folder, binary) 256 require.NoError(t, os.WriteFile(file, []byte("some string"), 0o644)) 257 258 ctx := testctx.NewWithCfg( 259 config.Project{ 260 Dist: folder, 261 ProjectName: binary, 262 Checksum: config.Checksum{ 263 Algorithm: "sha256", 264 NameTemplate: "checksums.txt", 265 ExtraFiles: []config.ExtraFile{ 266 {Glob: filePaths}, 267 }, 268 }, 269 }, 270 ) 271 272 ctx.Artifacts.Add(&artifact.Artifact{ 273 Name: binary, 274 Path: file, 275 Type: artifact.UploadableBinary, 276 }) 277 278 require.NoError(t, Pipe{}.Run(ctx)) 279 280 bts, err := os.ReadFile(filepath.Join(folder, checksums)) 281 require.NoError(t, err) 282 283 lines := strings.Split(string(bts), "\n") 284 285 wantLinesOrder := []string{ 286 "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb a.txt", 287 "3b64db95cb55c763391c707108489ae18b4112d783300de38e033b4c98c3deaf b.txt", 288 "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc binary", 289 "64daa44ad493ff28a96effab6e77f1732a3d97d83241581b37dbd70a7a4900fe c.txt", 290 "5bf8aa57fc5a6bc547decf1cc6db63f10deb55a3c6c5df497d631fb3d95e1abf d.txt", 291 } 292 293 for i, want := range wantLinesOrder { 294 require.Equal(t, want, lines[i]) 295 } 296 } 297 298 func TestPipeCheckSumsWithExtraFiles(t *testing.T) { 299 const binary = "binary" 300 const checksums = "checksums.txt" 301 const extraFileFooRelPath = "./testdata/foo.txt" 302 const extraFileBarRelPath = "./testdata/**/bar.txt" 303 const extraFileFoo = "foo.txt" 304 const extraFileBar = "bar.txt" 305 306 tests := map[string]struct { 307 extraFiles []config.ExtraFile 308 ids []string 309 want []string 310 }{ 311 "default": { 312 extraFiles: nil, 313 want: []string{ 314 binary, 315 }, 316 }, 317 "one extra file": { 318 extraFiles: []config.ExtraFile{ 319 {Glob: extraFileFooRelPath}, 320 }, 321 want: []string{ 322 extraFileFoo, 323 }, 324 }, 325 "multiple extra files": { 326 extraFiles: []config.ExtraFile{ 327 {Glob: extraFileFooRelPath}, 328 {Glob: extraFileBarRelPath}, 329 }, 330 want: []string{ 331 extraFileFoo, 332 extraFileBar, 333 }, 334 }, 335 "one extra file with no builds": { 336 extraFiles: []config.ExtraFile{ 337 {Glob: extraFileFooRelPath}, 338 }, 339 ids: []string{"yada yada yada"}, 340 want: []string{ 341 extraFileFoo, 342 }, 343 }, 344 } 345 346 for name, tt := range tests { 347 t.Run(name, func(t *testing.T) { 348 folder := t.TempDir() 349 file := filepath.Join(folder, binary) 350 require.NoError(t, os.WriteFile(file, []byte("some string"), 0o644)) 351 ctx := testctx.NewWithCfg( 352 config.Project{ 353 Dist: folder, 354 ProjectName: binary, 355 Checksum: config.Checksum{ 356 Algorithm: "sha256", 357 NameTemplate: "checksums.txt", 358 ExtraFiles: tt.extraFiles, 359 IDs: tt.ids, 360 }, 361 }, 362 ) 363 364 ctx.Artifacts.Add(&artifact.Artifact{ 365 Name: binary, 366 Path: file, 367 Type: artifact.UploadableBinary, 368 Extra: map[string]interface{}{ 369 artifact.ExtraID: "id-1", 370 }, 371 }) 372 373 require.NoError(t, Pipe{}.Run(ctx)) 374 375 bts, err := os.ReadFile(filepath.Join(folder, checksums)) 376 377 require.NoError(t, err) 378 for _, want := range tt.want { 379 if tt.extraFiles == nil { 380 require.Contains(t, string(bts), "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc "+want) 381 } else { 382 require.Contains(t, string(bts), "3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 "+want) 383 } 384 } 385 386 _ = ctx.Artifacts.Visit(func(a *artifact.Artifact) error { 387 if a.Path != file { 388 return nil 389 } 390 if len(tt.ids) > 0 { 391 return nil 392 } 393 checkSum, err := artifact.Extra[string](*a, artifactChecksumExtra) 394 require.Nil(t, err) 395 require.NotEmptyf(t, checkSum, "failed: %v", a.Path) 396 return nil 397 }) 398 }) 399 } 400 } 401 402 func TestExtraFilesNoMatch(t *testing.T) { 403 dir := t.TempDir() 404 ctx := testctx.NewWithCfg( 405 config.Project{ 406 Dist: dir, 407 ProjectName: "fake", 408 Checksum: config.Checksum{ 409 Algorithm: "sha256", 410 NameTemplate: "checksums.txt", 411 ExtraFiles: []config.ExtraFile{{Glob: "./nope/nope.txt"}}, 412 }, 413 }, 414 ) 415 416 ctx.Artifacts.Add(&artifact.Artifact{ 417 Name: "fake", 418 Path: "fake-path", 419 Type: artifact.UploadableBinary, 420 }) 421 422 require.NoError(t, Pipe{}.Default(ctx)) 423 require.EqualError(t, Pipe{}.Run(ctx), `globbing failed for pattern ./nope/nope.txt: matching "./nope/nope.txt": file does not exist`) 424 } 425 426 func TestSkip(t *testing.T) { 427 t.Run("skip", func(t *testing.T) { 428 ctx := testctx.NewWithCfg(config.Project{ 429 Checksum: config.Checksum{ 430 Disable: true, 431 }, 432 }) 433 require.True(t, Pipe{}.Skip(ctx)) 434 }) 435 436 t.Run("dont skip", func(t *testing.T) { 437 require.False(t, Pipe{}.Skip(testctx.New())) 438 }) 439 } 440 441 // TODO: add tests for LinuxPackage and UploadableSourceArchive