github.com/windmeup/goreleaser@v1.21.95/internal/pipe/nfpm/nfpm_test.go (about) 1 package nfpm 2 3 import ( 4 "os" 5 "path/filepath" 6 "testing" 7 8 "github.com/goreleaser/nfpm/v2" 9 "github.com/goreleaser/nfpm/v2/files" 10 "github.com/stretchr/testify/require" 11 "github.com/windmeup/goreleaser/internal/artifact" 12 "github.com/windmeup/goreleaser/internal/skips" 13 "github.com/windmeup/goreleaser/internal/testctx" 14 "github.com/windmeup/goreleaser/internal/testlib" 15 "github.com/windmeup/goreleaser/pkg/config" 16 "github.com/windmeup/goreleaser/pkg/context" 17 ) 18 19 func TestDescription(t *testing.T) { 20 require.NotEmpty(t, Pipe{}.String()) 21 } 22 23 func TestRunPipeNoFormats(t *testing.T) { 24 ctx := testctx.NewWithCfg( 25 config.Project{ 26 NFPMs: []config.NFPM{ 27 {}, 28 }, 29 }, 30 testctx.WithCurrentTag("v1.0.1"), 31 testctx.WithVersion("1.0.1"), 32 ) 33 require.NoError(t, Pipe{}.Default(ctx)) 34 testlib.AssertSkipped(t, Pipe{}.Run(ctx)) 35 } 36 37 func TestRunPipeError(t *testing.T) { 38 ctx := testctx.NewWithCfg(config.Project{ 39 Dist: t.TempDir(), 40 NFPMs: []config.NFPM{ 41 { 42 Formats: []string{"deb"}, 43 NFPMOverridables: config.NFPMOverridables{ 44 FileNameTemplate: "{{.ConventionalFileName}}", 45 }, 46 }, 47 }, 48 }) 49 ctx.Artifacts.Add(&artifact.Artifact{ 50 Name: "mybin", 51 Path: "testdata/testfile.txt", 52 Goarch: "amd64", 53 Goos: "linux", 54 Type: artifact.Binary, 55 Extra: map[string]interface{}{ 56 artifact.ExtraID: "foo", 57 }, 58 }) 59 require.NoError(t, Pipe{}.Default(ctx)) 60 require.EqualError(t, Pipe{}.Run(ctx), "nfpm failed for _0.0.0~rc0_amd64.deb: package name must be provided") 61 } 62 63 func TestRunPipeInvalidFormat(t *testing.T) { 64 ctx := testctx.NewWithCfg(config.Project{ 65 ProjectName: "nope", 66 NFPMs: []config.NFPM{ 67 { 68 Bindir: "/usr/bin", 69 Formats: []string{"nope"}, 70 Builds: []string{"foo"}, 71 NFPMOverridables: config.NFPMOverridables{ 72 PackageName: "foo", 73 FileNameTemplate: defaultNameTemplate, 74 }, 75 }, 76 }, 77 }, testctx.WithVersion("1.2.3"), testctx.WithCurrentTag("v1.2.3")) 78 for _, goos := range []string{"linux", "darwin"} { 79 for _, goarch := range []string{"amd64", "386"} { 80 ctx.Artifacts.Add(&artifact.Artifact{ 81 Name: "mybin", 82 Path: "testdata/testfile.txt", 83 Goarch: goarch, 84 Goos: goos, 85 Type: artifact.Binary, 86 Extra: map[string]interface{}{ 87 artifact.ExtraID: "foo", 88 }, 89 }) 90 } 91 } 92 require.Contains(t, Pipe{}.Run(ctx).Error(), `no packager registered for the format nope`) 93 } 94 95 func TestRunPipe(t *testing.T) { 96 folder := t.TempDir() 97 dist := filepath.Join(folder, "dist") 98 require.NoError(t, os.Mkdir(dist, 0o755)) 99 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 100 binPath := filepath.Join(dist, "mybin", "mybin") 101 f, err := os.Create(binPath) 102 require.NoError(t, err) 103 require.NoError(t, f.Close()) 104 ctx := testctx.NewWithCfg(config.Project{ 105 ProjectName: "mybin", 106 Dist: dist, 107 Env: []string{ 108 "PRO=pro", 109 "DESC=templates", 110 "EXT=.sh", 111 }, 112 NFPMs: []config.NFPM{ 113 { 114 ID: "someid", 115 Bindir: "/usr/bin", 116 Builds: []string{"default"}, 117 Formats: []string{"deb", "rpm", "apk", "termux.deb", "archlinux"}, 118 Section: "somesection", 119 Priority: "standard", 120 Description: "Some description with {{ .Env.DESC }}", 121 License: "MIT", 122 Maintainer: "me@me", 123 Vendor: "asdf", 124 Homepage: "https://goreleaser.com/{{ .Env.PRO }}", 125 Changelog: "./testdata/changelog.yaml", 126 NFPMOverridables: config.NFPMOverridables{ 127 FileNameTemplate: defaultNameTemplate + "-{{ .Release }}-{{ .Epoch }}", 128 PackageName: "foo", 129 Dependencies: []string{"make"}, 130 Recommends: []string{"svn"}, 131 Suggests: []string{"bzr"}, 132 Replaces: []string{"fish"}, 133 Conflicts: []string{"git"}, 134 Provides: []string{"ash"}, 135 Release: "10", 136 Epoch: "20", 137 Scripts: config.NFPMScripts{ 138 PreInstall: "./testdata/pre_install{{.Env.EXT}}", 139 PostInstall: "./testdata/post_install{{.Env.EXT}}", 140 PreRemove: "./testdata/pre_remove{{.Env.EXT}}", 141 PostRemove: "./testdata/post_remove{{.Env.EXT}}", 142 }, 143 Contents: []*files.Content{ 144 { 145 Destination: "/var/log/foobar", 146 Type: "dir", 147 }, 148 { 149 Source: "./testdata/testfile.txt", 150 Destination: "/usr/share/testfile.txt", 151 }, 152 { 153 Source: "./testdata/testfile.txt", 154 Destination: "/etc/nope.conf", 155 Type: "config", 156 }, 157 { 158 Destination: "/etc/mydir", 159 Type: "dir", 160 }, 161 { 162 Source: "./testdata/testfile.txt", 163 Destination: "/etc/nope-rpm.conf", 164 Type: "config", 165 Packager: "rpm", 166 }, 167 { 168 Source: "/etc/nope.conf", 169 Destination: "/etc/nope2.conf", 170 Type: "symlink", 171 }, 172 { 173 Source: "./testdata/testfile-{{ .Arch }}{{.Amd64}}{{.Arm}}{{.Mips}}.txt", 174 Destination: "/etc/nope3_{{ .ProjectName }}.conf", 175 }, 176 { 177 Source: "./testdata/folder", 178 Destination: "/etc/folder", 179 }, 180 }, 181 }, 182 }, 183 }, 184 }, testctx.WithVersion("1.0.0"), testctx.WithCurrentTag("v1.0.0")) 185 for _, goos := range []string{"linux", "darwin", "ios"} { 186 for _, goarch := range []string{"amd64", "386", "arm64", "arm", "mips"} { 187 if goos == "ios" && goarch != "arm64" { 188 continue 189 } 190 switch goarch { 191 case "arm": 192 for _, goarm := range []string{"6", "7"} { 193 ctx.Artifacts.Add(&artifact.Artifact{ 194 Name: "subdir/mybin", 195 Path: binPath, 196 Goarch: goarch, 197 Goos: goos, 198 Goarm: goarm, 199 Type: artifact.Binary, 200 Extra: map[string]interface{}{ 201 artifact.ExtraID: "default", 202 }, 203 }) 204 } 205 case "amd64": 206 for _, goamd64 := range []string{"v1", "v2", "v3", "v4"} { 207 ctx.Artifacts.Add(&artifact.Artifact{ 208 Name: "subdir/mybin", 209 Path: binPath, 210 Goarch: goarch, 211 Goos: goos, 212 Goamd64: goamd64, 213 Type: artifact.Binary, 214 Extra: map[string]interface{}{ 215 artifact.ExtraID: "default", 216 }, 217 }) 218 } 219 case "mips": 220 for _, gomips := range []string{"softfloat", "hardfloat"} { 221 ctx.Artifacts.Add(&artifact.Artifact{ 222 Name: "subdir/mybin", 223 Path: binPath, 224 Goarch: goarch, 225 Goos: goos, 226 Gomips: gomips, 227 Type: artifact.Binary, 228 Extra: map[string]interface{}{ 229 artifact.ExtraID: "default", 230 }, 231 }) 232 } 233 default: 234 ctx.Artifacts.Add(&artifact.Artifact{ 235 Name: "subdir/mybin", 236 Path: binPath, 237 Goarch: goarch, 238 Goos: goos, 239 Type: artifact.Binary, 240 Extra: map[string]interface{}{ 241 artifact.ExtraID: "default", 242 }, 243 }) 244 } 245 } 246 } 247 require.NoError(t, Pipe{}.Run(ctx)) 248 packages := ctx.Artifacts.Filter(artifact.ByType(artifact.LinuxPackage)).List() 249 require.Len(t, packages, 47) 250 for _, pkg := range packages { 251 format := pkg.Format() 252 require.NotEmpty(t, format) 253 require.Equal(t, pkg.Format(), artifact.ExtraOr(*pkg, artifact.ExtraExt, "")) 254 arch := pkg.Goarch 255 if pkg.Goarm != "" { 256 arch += "v" + pkg.Goarm 257 } 258 if pkg.Goamd64 != "v1" { 259 arch += pkg.Goamd64 260 } 261 if pkg.Gomips != "" { 262 arch += "_" + pkg.Gomips 263 } 264 265 ext := "." + format 266 if format != "termux.deb" { 267 packager, err := nfpm.Get(format) 268 require.NoError(t, err) 269 270 if packager, ok := packager.(nfpm.PackagerWithExtension); ok { 271 ext = packager.ConventionalExtension() 272 } 273 } 274 275 if pkg.Goos == "linux" { 276 require.Equal(t, "foo_1.0.0_linux_"+arch+"-10-20"+ext, pkg.Name) 277 } else { 278 require.Equal(t, "foo_1.0.0_ios_arm64-10-20"+ext, pkg.Name) 279 } 280 require.Equal(t, "someid", pkg.ID()) 281 require.ElementsMatch(t, []string{ 282 "./testdata/testfile.txt", 283 "./testdata/testfile.txt", 284 "./testdata/testfile.txt", 285 "/etc/nope.conf", 286 "./testdata/folder", 287 "./testdata/testfile-" + pkg.Goarch + pkg.Goamd64 + pkg.Goarm + pkg.Gomips + ".txt", 288 binPath, 289 }, sources(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) 290 291 bin := "/usr/bin/subdir/" 292 if format == termuxFormat { 293 bin = filepath.Join("/data/data/com.termux/files", bin) 294 } 295 bin = filepath.Join(bin, "mybin") 296 require.ElementsMatch(t, []string{ 297 "/var/log/foobar", 298 "/usr/share/testfile.txt", 299 "/etc/mydir", 300 "/etc/nope.conf", 301 "/etc/nope-rpm.conf", 302 "/etc/nope2.conf", 303 "/etc/nope3_mybin.conf", 304 "/etc/folder", 305 bin, 306 }, destinations(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) 307 } 308 require.Len(t, ctx.Config.NFPMs[0].Contents, 8, "should not modify the config file list") 309 } 310 311 func TestRunPipeConventionalNameTemplate(t *testing.T) { 312 t.Run("regular", func(t *testing.T) { doTestRunPipeConventionalNameTemplate(t, false) }) 313 t.Run("snapshot", func(t *testing.T) { doTestRunPipeConventionalNameTemplate(t, true) }) 314 } 315 316 func doTestRunPipeConventionalNameTemplate(t *testing.T, snapshot bool) { 317 t.Helper() 318 folder := t.TempDir() 319 dist := filepath.Join(folder, "dist") 320 require.NoError(t, os.Mkdir(dist, 0o755)) 321 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 322 binPath := filepath.Join(dist, "mybin", "mybin") 323 f, err := os.Create(binPath) 324 require.NoError(t, err) 325 require.NoError(t, f.Close()) 326 ctx := testctx.NewWithCfg(config.Project{ 327 ProjectName: "mybin", 328 Dist: dist, 329 NFPMs: []config.NFPM{ 330 { 331 ID: "someid", 332 Builds: []string{"default"}, 333 Formats: []string{"deb", "rpm", "apk", "archlinux"}, 334 Section: "somesection", 335 Priority: "standard", 336 Description: "Some description ", 337 License: "MIT", 338 Maintainer: "me@me", 339 Vendor: "asdf", 340 Homepage: "https://goreleaser.com/", 341 Bindir: "/usr/bin", 342 NFPMOverridables: config.NFPMOverridables{ 343 FileNameTemplate: ` 344 {{- trimsuffix .ConventionalFileName .ConventionalExtension -}} 345 {{- if and (eq .Arm "6") (eq .ConventionalExtension ".deb") }}6{{ end -}} 346 {{- if not (eq .Amd64 "v1")}}{{ .Amd64 }}{{ end -}} 347 {{- .ConventionalExtension -}} 348 `, 349 PackageName: "foo{{ if .IsSnapshot }}-snapshot{{ end }}", 350 }, 351 }, 352 }, 353 }, testctx.WithVersion("1.0.0"), testctx.WithCurrentTag("v1.0.0")) 354 if snapshot { 355 ctx.Snapshot = true 356 } 357 for _, goos := range []string{"linux", "darwin"} { 358 for _, goarch := range []string{"amd64", "386", "arm64", "arm", "mips"} { 359 switch goarch { 360 case "arm": 361 for _, goarm := range []string{"6", "7"} { 362 ctx.Artifacts.Add(&artifact.Artifact{ 363 Name: "subdir/mybin", 364 Path: binPath, 365 Goarch: goarch, 366 Goos: goos, 367 Goarm: goarm, 368 Type: artifact.Binary, 369 Extra: map[string]interface{}{ 370 artifact.ExtraID: "default", 371 }, 372 }) 373 } 374 case "amd64": 375 for _, goamd64 := range []string{"v1", "v2", "v3", "v4"} { 376 ctx.Artifacts.Add(&artifact.Artifact{ 377 Name: "subdir/mybin", 378 Path: binPath, 379 Goarch: goarch, 380 Goos: goos, 381 Goamd64: goamd64, 382 Type: artifact.Binary, 383 Extra: map[string]interface{}{ 384 artifact.ExtraID: "default", 385 }, 386 }) 387 } 388 case "mips": 389 for _, gomips := range []string{"softfloat", "hardfloat"} { 390 ctx.Artifacts.Add(&artifact.Artifact{ 391 Name: "subdir/mybin", 392 Path: binPath, 393 Goarch: goarch, 394 Goos: goos, 395 Gomips: gomips, 396 Type: artifact.Binary, 397 Extra: map[string]interface{}{ 398 artifact.ExtraID: "default", 399 }, 400 }) 401 } 402 default: 403 ctx.Artifacts.Add(&artifact.Artifact{ 404 Name: "subdir/mybin", 405 Path: binPath, 406 Goarch: goarch, 407 Goos: goos, 408 Type: artifact.Binary, 409 Extra: map[string]interface{}{ 410 artifact.ExtraID: "default", 411 }, 412 }) 413 } 414 } 415 } 416 require.NoError(t, Pipe{}.Run(ctx)) 417 packages := ctx.Artifacts.Filter(artifact.ByType(artifact.LinuxPackage)).List() 418 require.Len(t, packages, 40) 419 prefix := "foo" 420 if snapshot { 421 prefix += "-snapshot" 422 } 423 for _, pkg := range packages { 424 format := pkg.Format() 425 require.NotEmpty(t, format) 426 require.Contains(t, []string{ 427 prefix + "-1.0.0-1.aarch64.rpm", 428 prefix + "-1.0.0-1.armv6hl.rpm", 429 prefix + "-1.0.0-1.armv7hl.rpm", 430 prefix + "-1.0.0-1.i386.rpm", 431 prefix + "-1.0.0-1.mips.rpm", 432 prefix + "-1.0.0-1.mips.rpm", 433 prefix + "-1.0.0-1.x86_64.rpm", 434 prefix + "-1.0.0-1.x86_64v2.rpm", 435 prefix + "-1.0.0-1.x86_64v3.rpm", 436 prefix + "-1.0.0-1.x86_64v4.rpm", 437 prefix + "_1.0.0_aarch64.apk", 438 prefix + "_1.0.0_amd64.deb", 439 prefix + "_1.0.0_amd64v2.deb", 440 prefix + "_1.0.0_amd64v3.deb", 441 prefix + "_1.0.0_amd64v4.deb", 442 prefix + "_1.0.0_arm64.deb", 443 prefix + "_1.0.0_armhf.apk", 444 prefix + "_1.0.0_armhf.deb", 445 prefix + "_1.0.0_armhf6.deb", 446 prefix + "_1.0.0_armv7.apk", 447 prefix + "_1.0.0_i386.deb", 448 prefix + "_1.0.0_mips.apk", 449 prefix + "_1.0.0_mips.deb", 450 prefix + "_1.0.0_mips.apk", 451 prefix + "_1.0.0_mips.deb", 452 prefix + "_1.0.0_x86.apk", 453 prefix + "_1.0.0_x86_64.apk", 454 prefix + "_1.0.0_x86_64v2.apk", 455 prefix + "_1.0.0_x86_64v3.apk", 456 prefix + "_1.0.0_x86_64v4.apk", 457 prefix + "-1.0.0-1-aarch64.pkg.tar.zst", 458 prefix + "-1.0.0-1-armv6h.pkg.tar.zst", 459 prefix + "-1.0.0-1-armv7h.pkg.tar.zst", 460 prefix + "-1.0.0-1-i686.pkg.tar.zst", 461 prefix + "-1.0.0-1-x86_64.pkg.tar.zst", 462 prefix + "-1.0.0-1-x86_64v2.pkg.tar.zst", 463 prefix + "-1.0.0-1-x86_64v3.pkg.tar.zst", 464 prefix + "-1.0.0-1-x86_64v4.pkg.tar.zst", 465 prefix + "-1.0.0-1-mips.pkg.tar.zst", 466 prefix + "-1.0.0-1-mips.pkg.tar.zst", 467 }, pkg.Name, "package name is not expected") 468 require.Equal(t, "someid", pkg.ID()) 469 require.ElementsMatch(t, []string{binPath}, sources(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) 470 require.ElementsMatch(t, []string{"/usr/bin/subdir/mybin"}, destinations(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) 471 } 472 } 473 474 func TestInvalidTemplate(t *testing.T) { 475 makeCtx := func() *context.Context { 476 ctx := testctx.NewWithCfg( 477 config.Project{ 478 ProjectName: "test", 479 NFPMs: []config.NFPM{ 480 { 481 Formats: []string{"deb"}, 482 Builds: []string{"default"}, 483 }, 484 }, 485 }, 486 testctx.WithVersion("1.2.3"), 487 ) 488 ctx.Artifacts.Add(&artifact.Artifact{ 489 Name: "mybin", 490 Goos: "linux", 491 Goarch: "amd64", 492 Type: artifact.Binary, 493 Extra: map[string]interface{}{ 494 artifact.ExtraID: "default", 495 }, 496 }) 497 return ctx 498 } 499 500 t.Run("filename_template", func(t *testing.T) { 501 ctx := makeCtx() 502 ctx.Config.NFPMs[0].Meta = true 503 ctx.Config.NFPMs[0].NFPMOverridables = config.NFPMOverridables{ 504 FileNameTemplate: "{{.Foo}", 505 } 506 require.NoError(t, Pipe{}.Default(ctx)) 507 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 508 }) 509 510 t.Run("source", func(t *testing.T) { 511 ctx := makeCtx() 512 ctx.Config.NFPMs[0].NFPMOverridables = config.NFPMOverridables{ 513 Contents: files.Contents{ 514 { 515 Source: "{{ .NOPE_SOURCE }}", 516 Destination: "/foo", 517 }, 518 }, 519 } 520 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 521 }) 522 523 t.Run("target", func(t *testing.T) { 524 ctx := makeCtx() 525 ctx.Config.NFPMs[0].NFPMOverridables = config.NFPMOverridables{ 526 Contents: files.Contents{ 527 { 528 Source: "./testdata/testfile.txt", 529 Destination: "{{ .NOPE_TARGET }}", 530 }, 531 }, 532 } 533 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 534 }) 535 536 t.Run("description", func(t *testing.T) { 537 ctx := makeCtx() 538 ctx.Config.NFPMs[0].Description = "{{ .NOPE_DESC }}" 539 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 540 }) 541 542 t.Run("maintainer", func(t *testing.T) { 543 ctx := makeCtx() 544 ctx.Config.NFPMs[0].Maintainer = "{{ .NOPE_DESC }}" 545 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 546 }) 547 548 t.Run("homepage", func(t *testing.T) { 549 ctx := makeCtx() 550 ctx.Config.NFPMs[0].Homepage = "{{ .NOPE_HOMEPAGE }}" 551 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 552 }) 553 554 t.Run("deb key file", func(t *testing.T) { 555 ctx := makeCtx() 556 ctx.Config.NFPMs[0].Deb.Signature.KeyFile = "{{ .NOPE_KEY_FILE }}" 557 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 558 }) 559 560 t.Run("rpm key file", func(t *testing.T) { 561 ctx := makeCtx() 562 ctx.Config.NFPMs[0].RPM.Signature.KeyFile = "{{ .NOPE_KEY_FILE }}" 563 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 564 }) 565 566 t.Run("apk key file", func(t *testing.T) { 567 ctx := makeCtx() 568 ctx.Config.NFPMs[0].APK.Signature.KeyFile = "{{ .NOPE_KEY_FILE }}" 569 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 570 }) 571 572 t.Run("apk key name", func(t *testing.T) { 573 ctx := makeCtx() 574 ctx.Config.NFPMs[0].APK.Signature.KeyName = "{{ .NOPE_KEY_FILE }}" 575 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 576 }) 577 578 t.Run("bindir", func(t *testing.T) { 579 ctx := makeCtx() 580 ctx.Config.NFPMs[0].Bindir = "/usr/{{ .NOPE }}" 581 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 582 }) 583 } 584 585 func TestRunPipeInvalidContentsSourceTemplate(t *testing.T) { 586 ctx := testctx.NewWithCfg(config.Project{ 587 NFPMs: []config.NFPM{ 588 { 589 NFPMOverridables: config.NFPMOverridables{ 590 PackageName: "foo", 591 Contents: []*files.Content{ 592 { 593 Source: "{{.asdsd}", 594 Destination: "testfile", 595 }, 596 }, 597 }, 598 Formats: []string{"deb"}, 599 Builds: []string{"default"}, 600 }, 601 }, 602 }) 603 ctx.Artifacts.Add(&artifact.Artifact{ 604 Name: "mybin", 605 Goos: "linux", 606 Goarch: "amd64", 607 Type: artifact.Binary, 608 Extra: map[string]interface{}{ 609 artifact.ExtraID: "default", 610 }, 611 }) 612 testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) 613 } 614 615 func TestNoBuildsFound(t *testing.T) { 616 ctx := testctx.NewWithCfg(config.Project{ 617 NFPMs: []config.NFPM{ 618 { 619 Formats: []string{"deb"}, 620 Builds: []string{"nope"}, 621 }, 622 }, 623 }) 624 ctx.Artifacts.Add(&artifact.Artifact{ 625 Name: "mybin", 626 Goos: "linux", 627 Goarch: "amd64", 628 Type: artifact.Binary, 629 Extra: map[string]interface{}{ 630 artifact.ExtraID: "default", 631 }, 632 }) 633 require.EqualError(t, Pipe{}.Run(ctx), `no linux binaries found for builds [nope]`) 634 } 635 636 func TestCreateFileDoesntExist(t *testing.T) { 637 folder := t.TempDir() 638 dist := filepath.Join(folder, "dist") 639 require.NoError(t, os.Mkdir(dist, 0o755)) 640 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 641 ctx := testctx.NewWithCfg(config.Project{ 642 Dist: dist, 643 ProjectName: "asd", 644 NFPMs: []config.NFPM{ 645 { 646 Formats: []string{"deb", "rpm"}, 647 Builds: []string{"default"}, 648 NFPMOverridables: config.NFPMOverridables{ 649 PackageName: "foo", 650 Contents: []*files.Content{ 651 { 652 Source: "testdata/testfile.txt", 653 Destination: "/var/lib/test/testfile.txt", 654 }, 655 }, 656 }, 657 }, 658 }, 659 }, testctx.WithVersion("1.2.3"), testctx.WithCurrentTag("v1.2.3")) 660 ctx.Artifacts.Add(&artifact.Artifact{ 661 Name: "mybin", 662 Path: filepath.Join(dist, "mybin", "mybin"), 663 Goos: "linux", 664 Goarch: "amd64", 665 Type: artifact.Binary, 666 Extra: map[string]interface{}{ 667 artifact.ExtraID: "default", 668 }, 669 }) 670 require.Contains(t, Pipe{}.Run(ctx).Error(), `dist/mybin/mybin": file does not exist`) 671 } 672 673 func TestInvalidConfig(t *testing.T) { 674 folder := t.TempDir() 675 dist := filepath.Join(folder, "dist") 676 require.NoError(t, os.Mkdir(dist, 0o755)) 677 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 678 ctx := testctx.NewWithCfg(config.Project{ 679 Dist: dist, 680 NFPMs: []config.NFPM{ 681 { 682 Formats: []string{"deb"}, 683 Builds: []string{"default"}, 684 }, 685 }, 686 }, testctx.WithCurrentTag("v1.2.3"), testctx.WithVersion("1.2.3")) 687 ctx.Artifacts.Add(&artifact.Artifact{ 688 Name: "mybin", 689 Path: filepath.Join(dist, "mybin", "mybin"), 690 Goos: "linux", 691 Goarch: "amd64", 692 Type: artifact.Binary, 693 Extra: map[string]interface{}{ 694 artifact.ExtraID: "default", 695 }, 696 }) 697 require.Contains(t, Pipe{}.Run(ctx).Error(), `package name must be provided`) 698 } 699 700 func TestDefault(t *testing.T) { 701 ctx := testctx.NewWithCfg(config.Project{ 702 ProjectName: "foobar", 703 NFPMs: []config.NFPM{ 704 {}, 705 }, 706 }) 707 require.NoError(t, Pipe{}.Default(ctx)) 708 require.Equal(t, "/usr/bin", ctx.Config.NFPMs[0].Bindir) 709 require.Empty(t, ctx.Config.NFPMs[0].Builds) 710 require.Equal(t, defaultNameTemplate, ctx.Config.NFPMs[0].FileNameTemplate) 711 require.Equal(t, ctx.Config.ProjectName, ctx.Config.NFPMs[0].PackageName) 712 } 713 714 func TestDefaultSet(t *testing.T) { 715 ctx := testctx.NewWithCfg(config.Project{ 716 NFPMs: []config.NFPM{ 717 { 718 Builds: []string{"foo"}, 719 Bindir: "/bin", 720 NFPMOverridables: config.NFPMOverridables{ 721 FileNameTemplate: "foo", 722 }, 723 }, 724 }, 725 }) 726 require.NoError(t, Pipe{}.Default(ctx)) 727 require.Equal(t, "/bin", ctx.Config.NFPMs[0].Bindir) 728 require.Equal(t, "foo", ctx.Config.NFPMs[0].FileNameTemplate) 729 require.Equal(t, []string{"foo"}, ctx.Config.NFPMs[0].Builds) 730 require.Equal(t, config.NFPMRPMScripts{}, ctx.Config.NFPMs[0].RPM.Scripts) 731 } 732 733 func TestOverrides(t *testing.T) { 734 ctx := testctx.NewWithCfg(config.Project{ 735 NFPMs: []config.NFPM{ 736 { 737 Bindir: "/bin", 738 NFPMOverridables: config.NFPMOverridables{ 739 FileNameTemplate: "foo", 740 }, 741 Overrides: map[string]config.NFPMOverridables{ 742 "deb": { 743 FileNameTemplate: "bar", 744 }, 745 }, 746 }, 747 }, 748 }) 749 require.NoError(t, Pipe{}.Default(ctx)) 750 merged, err := mergeOverrides(ctx.Config.NFPMs[0], "deb") 751 require.NoError(t, err) 752 require.Equal(t, "/bin", ctx.Config.NFPMs[0].Bindir) 753 require.Equal(t, "foo", ctx.Config.NFPMs[0].FileNameTemplate) 754 require.Equal(t, "bar", ctx.Config.NFPMs[0].Overrides["deb"].FileNameTemplate) 755 require.Equal(t, "bar", merged.FileNameTemplate) 756 } 757 758 func TestDebSpecificConfig(t *testing.T) { 759 setupContext := func(tb testing.TB) *context.Context { 760 tb.Helper() 761 folder := t.TempDir() 762 dist := filepath.Join(folder, "dist") 763 require.NoError(t, os.Mkdir(dist, 0o755)) 764 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 765 binPath := filepath.Join(dist, "mybin", "mybin") 766 f, err := os.Create(binPath) 767 require.NoError(t, err) 768 require.NoError(t, f.Close()) 769 ctx := testctx.NewWithCfg(config.Project{ 770 ProjectName: "mybin", 771 Dist: dist, 772 NFPMs: []config.NFPM{ 773 { 774 ID: "someid", 775 Builds: []string{"default"}, 776 Formats: []string{"deb"}, 777 Maintainer: "foo", 778 NFPMOverridables: config.NFPMOverridables{ 779 PackageName: "foo", 780 Contents: []*files.Content{ 781 { 782 Source: "testdata/testfile.txt", 783 Destination: "/usr/share/testfile.txt", 784 }, 785 }, 786 Deb: config.NFPMDeb{ 787 Signature: config.NFPMDebSignature{ 788 KeyFile: "./testdata/privkey.gpg", 789 }, 790 }, 791 }, 792 }, 793 }, 794 }, testctx.WithVersion("1.0.0"), testctx.WithCurrentTag("v1.0.0")) 795 for _, goos := range []string{"linux", "darwin"} { 796 for _, goarch := range []string{"amd64", "386"} { 797 ctx.Artifacts.Add(&artifact.Artifact{ 798 Name: "mybin", 799 Path: binPath, 800 Goarch: goarch, 801 Goos: goos, 802 Type: artifact.Binary, 803 Extra: map[string]interface{}{ 804 artifact.ExtraID: "default", 805 }, 806 }) 807 } 808 } 809 return ctx 810 } 811 812 t.Run("no passphrase set", func(t *testing.T) { 813 require.Contains( 814 t, 815 Pipe{}.Run(setupContext(t)).Error(), 816 `key is encrypted but no passphrase was provided`, 817 ) 818 }) 819 820 t.Run("general passphrase set", func(t *testing.T) { 821 ctx := setupContext(t) 822 ctx.Env = map[string]string{ 823 "NFPM_SOMEID_PASSPHRASE": "hunter2", 824 } 825 require.NoError(t, Pipe{}.Run(ctx)) 826 }) 827 828 t.Run("packager specific passphrase set", func(t *testing.T) { 829 ctx := setupContext(t) 830 ctx.Env = map[string]string{ 831 "NFPM_SOMEID_DEB_PASSPHRASE": "hunter2", 832 } 833 require.NoError(t, Pipe{}.Run(ctx)) 834 }) 835 836 t.Run("lintian", func(t *testing.T) { 837 ctx := setupContext(t) 838 ctx.Parallelism = 100 839 ctx.Env = map[string]string{ 840 "NFPM_SOMEID_DEB_PASSPHRASE": "hunter2", 841 } 842 ctx.Config.NFPMs[0].Deb.Lintian = []string{ 843 "statically-linked-binary", 844 "changelog-file-missing-in-native-package", 845 } 846 ctx.Config.NFPMs[0].Formats = []string{"apk", "rpm", "deb", "termux.deb"} 847 848 require.NoError(t, Pipe{}.Run(ctx)) 849 for _, format := range []string{"apk", "rpm"} { 850 require.NoDirExists(t, filepath.Join(ctx.Config.Dist, format)) 851 } 852 require.DirExists(t, filepath.Join(ctx.Config.Dist, "deb")) 853 for _, goarch := range []string{"amd64", "386"} { 854 bts, err := os.ReadFile(filepath.Join(ctx.Config.Dist, "deb", "foo_"+goarch, "lintian")) 855 require.NoError(t, err) 856 require.Equal(t, "foo: statically-linked-binary\nfoo: changelog-file-missing-in-native-package", string(bts)) 857 } 858 require.DirExists(t, filepath.Join(ctx.Config.Dist, "termux.deb")) 859 for _, goarch := range []string{"x86_64", "i686"} { 860 bts, err := os.ReadFile(filepath.Join(ctx.Config.Dist, "termux.deb", "foo_"+goarch, "lintian")) 861 require.NoError(t, err) 862 require.Equal(t, "foo: statically-linked-binary\nfoo: changelog-file-missing-in-native-package", string(bts)) 863 } 864 }) 865 866 t.Run("lintian no debs", func(t *testing.T) { 867 ctx := setupContext(t) 868 ctx.Parallelism = 100 869 ctx.Env = map[string]string{ 870 "NFPM_SOMEID_DEB_PASSPHRASE": "hunter2", 871 } 872 ctx.Config.NFPMs[0].Deb.Lintian = []string{ 873 "statically-linked-binary", 874 "changelog-file-missing-in-native-package", 875 } 876 ctx.Config.NFPMs[0].Formats = []string{"apk", "rpm"} 877 878 require.NoError(t, Pipe{}.Run(ctx)) 879 for _, format := range []string{"deb", "termux.deb"} { 880 require.NoDirExists(t, filepath.Join(ctx.Config.Dist, format)) 881 } 882 }) 883 } 884 885 func TestRPMSpecificConfig(t *testing.T) { 886 folder := t.TempDir() 887 dist := filepath.Join(folder, "dist") 888 require.NoError(t, os.Mkdir(dist, 0o755)) 889 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 890 binPath := filepath.Join(dist, "mybin", "mybin") 891 f, err := os.Create(binPath) 892 require.NoError(t, err) 893 require.NoError(t, f.Close()) 894 ctx := testctx.NewWithCfg(config.Project{ 895 ProjectName: "mybin", 896 Dist: dist, 897 NFPMs: []config.NFPM{ 898 { 899 ID: "someid", 900 Builds: []string{"default"}, 901 Formats: []string{"rpm"}, 902 NFPMOverridables: config.NFPMOverridables{ 903 PackageName: "foo", 904 Contents: []*files.Content{ 905 { 906 Source: "testdata/testfile.txt", 907 Destination: "/usr/share/testfile.txt", 908 }, 909 }, 910 RPM: config.NFPMRPM{ 911 Signature: config.NFPMRPMSignature{ 912 KeyFile: "./testdata/privkey.gpg", 913 }, 914 }, 915 }, 916 }, 917 }, 918 }, testctx.WithVersion("1.0.0"), testctx.WithCurrentTag("v1.0.0")) 919 for _, goos := range []string{"linux", "darwin"} { 920 for _, goarch := range []string{"amd64", "386"} { 921 ctx.Artifacts.Add(&artifact.Artifact{ 922 Name: "mybin", 923 Path: binPath, 924 Goarch: goarch, 925 Goos: goos, 926 Type: artifact.Binary, 927 Extra: map[string]interface{}{ 928 artifact.ExtraID: "default", 929 }, 930 }) 931 } 932 } 933 934 t.Run("no passphrase set", func(t *testing.T) { 935 require.Contains( 936 t, 937 Pipe{}.Run(ctx).Error(), 938 `key is encrypted but no passphrase was provided`, 939 ) 940 }) 941 942 t.Run("general passphrase set", func(t *testing.T) { 943 ctx.Env = map[string]string{ 944 "NFPM_SOMEID_PASSPHRASE": "hunter2", 945 } 946 require.NoError(t, Pipe{}.Run(ctx)) 947 }) 948 949 t.Run("packager specific passphrase set", func(t *testing.T) { 950 ctx.Env = map[string]string{ 951 "NFPM_SOMEID_RPM_PASSPHRASE": "hunter2", 952 } 953 require.NoError(t, Pipe{}.Run(ctx)) 954 }) 955 } 956 957 func TestRPMSpecificScriptsConfig(t *testing.T) { 958 folder := t.TempDir() 959 dist := filepath.Join(folder, "dist") 960 require.NoError(t, os.Mkdir(dist, 0o755)) 961 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 962 binPath := filepath.Join(dist, "mybin", "mybin") 963 f, err := os.Create(binPath) 964 require.NoError(t, err) 965 require.NoError(t, f.Close()) 966 ctx := testctx.NewWithCfg(config.Project{ 967 ProjectName: "mybin", 968 Dist: dist, 969 NFPMs: []config.NFPM{ 970 { 971 ID: "someid", 972 Builds: []string{"default"}, 973 Formats: []string{"rpm"}, 974 NFPMOverridables: config.NFPMOverridables{ 975 PackageName: "foo", 976 RPM: config.NFPMRPM{ 977 Scripts: config.NFPMRPMScripts{ 978 PreTrans: "/does/not/exist_pretrans.sh", 979 PostTrans: "/does/not/exist_posttrans.sh", 980 }, 981 }, 982 }, 983 }, 984 }, 985 }, testctx.WithVersion("1.0.0"), testctx.WithCurrentTag("v1.0.0")) 986 for _, goos := range []string{"linux", "darwin"} { 987 for _, goarch := range []string{"amd64", "386"} { 988 ctx.Artifacts.Add(&artifact.Artifact{ 989 Name: "mybin", 990 Path: binPath, 991 Goarch: goarch, 992 Goos: goos, 993 Type: artifact.Binary, 994 Extra: map[string]interface{}{ 995 artifact.ExtraID: "default", 996 }, 997 }) 998 } 999 } 1000 1001 t.Run("PreTrans script file does not exist", func(t *testing.T) { 1002 require.ErrorIs(t, Pipe{}.Run(ctx), os.ErrNotExist) 1003 }) 1004 1005 t.Run("PostTrans script file does not exist", func(t *testing.T) { 1006 ctx.Config.NFPMs[0].RPM.Scripts.PreTrans = "testdata/testfile.txt" 1007 require.ErrorIs(t, Pipe{}.Run(ctx), os.ErrNotExist) 1008 }) 1009 1010 t.Run("pretrans and posttrans scriptlets set", func(t *testing.T) { 1011 ctx.Config.NFPMs[0].RPM.Scripts.PreTrans = "testdata/testfile.txt" 1012 ctx.Config.NFPMs[0].RPM.Scripts.PostTrans = "testdata/testfile.txt" 1013 1014 require.NoError(t, Pipe{}.Run(ctx)) 1015 }) 1016 } 1017 1018 func TestAPKSpecificConfig(t *testing.T) { 1019 folder := t.TempDir() 1020 dist := filepath.Join(folder, "dist") 1021 require.NoError(t, os.Mkdir(dist, 0o755)) 1022 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 1023 binPath := filepath.Join(dist, "mybin", "mybin") 1024 f, err := os.Create(binPath) 1025 require.NoError(t, err) 1026 require.NoError(t, f.Close()) 1027 ctx := testctx.NewWithCfg(config.Project{ 1028 ProjectName: "mybin", 1029 Dist: dist, 1030 NFPMs: []config.NFPM{ 1031 { 1032 ID: "someid", 1033 Maintainer: "me@me", 1034 Builds: []string{"default"}, 1035 Formats: []string{"apk"}, 1036 NFPMOverridables: config.NFPMOverridables{ 1037 PackageName: "foo", 1038 Contents: []*files.Content{ 1039 { 1040 Source: "testdata/testfile.txt", 1041 Destination: "/usr/share/testfile.txt", 1042 }, 1043 }, 1044 APK: config.NFPMAPK{ 1045 Signature: config.NFPMAPKSignature{ 1046 KeyFile: "./testdata/rsa.priv", 1047 }, 1048 }, 1049 }, 1050 }, 1051 }, 1052 }, testctx.WithVersion("1.0.0"), testctx.WithCurrentTag("v1.0.0")) 1053 for _, goos := range []string{"linux", "darwin"} { 1054 for _, goarch := range []string{"amd64", "386"} { 1055 ctx.Artifacts.Add(&artifact.Artifact{ 1056 Name: "mybin", 1057 Path: binPath, 1058 Goarch: goarch, 1059 Goos: goos, 1060 Type: artifact.Binary, 1061 Extra: map[string]interface{}{ 1062 artifact.ExtraID: "default", 1063 }, 1064 }) 1065 } 1066 } 1067 1068 t.Run("no passphrase set", func(t *testing.T) { 1069 require.Contains( 1070 t, 1071 Pipe{}.Run(ctx).Error(), 1072 `key is encrypted but no passphrase was provided`, 1073 ) 1074 }) 1075 1076 t.Run("general passphrase set", func(t *testing.T) { 1077 ctx.Env = map[string]string{ 1078 "NFPM_SOMEID_PASSPHRASE": "hunter2", 1079 } 1080 require.NoError(t, Pipe{}.Run(ctx)) 1081 }) 1082 1083 t.Run("packager specific passphrase set", func(t *testing.T) { 1084 ctx.Env = map[string]string{ 1085 "NFPM_SOMEID_APK_PASSPHRASE": "hunter2", 1086 } 1087 require.NoError(t, Pipe{}.Run(ctx)) 1088 }) 1089 } 1090 1091 func TestAPKSpecificScriptsConfig(t *testing.T) { 1092 folder := t.TempDir() 1093 dist := filepath.Join(folder, "dist") 1094 require.NoError(t, os.Mkdir(dist, 0o755)) 1095 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 1096 binPath := filepath.Join(dist, "mybin", "mybin") 1097 f, err := os.Create(binPath) 1098 require.NoError(t, err) 1099 require.NoError(t, f.Close()) 1100 scripts := config.NFPMAPKScripts{ 1101 PreUpgrade: "/does/not/exist_preupgrade.sh", 1102 PostUpgrade: "/does/not/exist_postupgrade.sh", 1103 } 1104 ctx := testctx.NewWithCfg(config.Project{ 1105 ProjectName: "mybin", 1106 Dist: dist, 1107 NFPMs: []config.NFPM{ 1108 { 1109 ID: "someid", 1110 Maintainer: "me@me", 1111 Builds: []string{"default"}, 1112 Formats: []string{"apk"}, 1113 NFPMOverridables: config.NFPMOverridables{ 1114 PackageName: "foo", 1115 Contents: []*files.Content{ 1116 { 1117 Source: "testdata/testfile.txt", 1118 Destination: "/usr/share/testfile.txt", 1119 }, 1120 }, 1121 APK: config.NFPMAPK{ 1122 Scripts: scripts, 1123 }, 1124 }, 1125 }, 1126 }, 1127 }, testctx.WithVersion("1.0.0"), testctx.WithCurrentTag("v1.0.0")) 1128 for _, goos := range []string{"linux", "darwin"} { 1129 for _, goarch := range []string{"amd64", "386"} { 1130 ctx.Artifacts.Add(&artifact.Artifact{ 1131 Name: "mybin", 1132 Path: binPath, 1133 Goarch: goarch, 1134 Goos: goos, 1135 Type: artifact.Binary, 1136 Extra: map[string]interface{}{ 1137 artifact.ExtraID: "default", 1138 }, 1139 }) 1140 } 1141 } 1142 1143 t.Run("PreUpgrade script file does not exist", func(t *testing.T) { 1144 ctx.Config.NFPMs[0].APK.Scripts = scripts 1145 ctx.Config.NFPMs[0].APK.Scripts.PostUpgrade = "testdata/testfile.txt" 1146 require.ErrorIs(t, Pipe{}.Run(ctx), os.ErrNotExist) 1147 }) 1148 1149 t.Run("PostUpgrade script file does not exist", func(t *testing.T) { 1150 ctx.Config.NFPMs[0].APK.Scripts = scripts 1151 ctx.Config.NFPMs[0].APK.Scripts.PreUpgrade = "testdata/testfile.txt" 1152 require.ErrorIs(t, Pipe{}.Run(ctx), os.ErrNotExist) 1153 }) 1154 1155 t.Run("preupgrade and postupgrade scriptlets set", func(t *testing.T) { 1156 ctx.Config.NFPMs[0].APK.Scripts.PreUpgrade = "testdata/testfile.txt" 1157 ctx.Config.NFPMs[0].APK.Scripts.PostUpgrade = "testdata/testfile.txt" 1158 1159 require.NoError(t, Pipe{}.Run(ctx)) 1160 }) 1161 } 1162 1163 func TestSeveralNFPMsWithTheSameID(t *testing.T) { 1164 ctx := testctx.NewWithCfg(config.Project{ 1165 NFPMs: []config.NFPM{ 1166 { 1167 ID: "a", 1168 }, 1169 { 1170 ID: "a", 1171 }, 1172 }, 1173 }) 1174 require.EqualError(t, Pipe{}.Default(ctx), "found 2 nfpms with the ID 'a', please fix your config") 1175 } 1176 1177 func TestMeta(t *testing.T) { 1178 folder := t.TempDir() 1179 dist := filepath.Join(folder, "dist") 1180 require.NoError(t, os.Mkdir(dist, 0o755)) 1181 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 1182 binPath := filepath.Join(dist, "mybin", "mybin") 1183 f, err := os.Create(binPath) 1184 require.NoError(t, err) 1185 require.NoError(t, f.Close()) 1186 ctx := testctx.NewWithCfg(config.Project{ 1187 ProjectName: "mybin", 1188 Dist: dist, 1189 NFPMs: []config.NFPM{ 1190 { 1191 ID: "someid", 1192 Bindir: "/usr/bin", 1193 Builds: []string{"default"}, 1194 Formats: []string{"deb", "rpm"}, 1195 Section: "somesection", 1196 Priority: "standard", 1197 Description: "Some description", 1198 License: "MIT", 1199 Maintainer: "me@me", 1200 Vendor: "asdf", 1201 Homepage: "https://goreleaser.github.io", 1202 Meta: true, 1203 NFPMOverridables: config.NFPMOverridables{ 1204 FileNameTemplate: defaultNameTemplate + "-{{ .Release }}-{{ .Epoch }}", 1205 PackageName: "foo", 1206 Dependencies: []string{"make"}, 1207 Recommends: []string{"svn"}, 1208 Suggests: []string{"bzr"}, 1209 Replaces: []string{"fish"}, 1210 Conflicts: []string{"git"}, 1211 Release: "10", 1212 Epoch: "20", 1213 Contents: []*files.Content{ 1214 { 1215 Source: "testdata/testfile.txt", 1216 Destination: "/usr/share/testfile.txt", 1217 }, 1218 { 1219 Source: "./testdata/testfile.txt", 1220 Destination: "/etc/nope.conf", 1221 Type: "config", 1222 }, 1223 { 1224 Source: "./testdata/testfile.txt", 1225 Destination: "/etc/nope-rpm.conf", 1226 Type: "config", 1227 Packager: "rpm", 1228 }, 1229 { 1230 Destination: "/var/log/foobar", 1231 Type: "dir", 1232 }, 1233 }, 1234 }, 1235 }, 1236 }, 1237 }, testctx.WithVersion("1.0.0"), testctx.WithCurrentTag("v1.0.0")) 1238 for _, goos := range []string{"linux", "darwin"} { 1239 for _, goarch := range []string{"amd64", "386"} { 1240 ctx.Artifacts.Add(&artifact.Artifact{ 1241 Name: "mybin", 1242 Path: binPath, 1243 Goarch: goarch, 1244 Goos: goos, 1245 Type: artifact.Binary, 1246 Extra: map[string]interface{}{ 1247 artifact.ExtraID: "default", 1248 }, 1249 }) 1250 } 1251 } 1252 require.NoError(t, Pipe{}.Run(ctx)) 1253 packages := ctx.Artifacts.Filter(artifact.ByType(artifact.LinuxPackage)).List() 1254 require.Len(t, packages, 4) 1255 for _, pkg := range packages { 1256 format := pkg.Format() 1257 require.NotEmpty(t, format) 1258 require.Equal(t, pkg.Name, "foo_1.0.0_linux_"+pkg.Goarch+"-10-20."+format) 1259 require.Equal(t, pkg.ID(), "someid") 1260 require.ElementsMatch(t, []string{ 1261 "/var/log/foobar", 1262 "/usr/share/testfile.txt", 1263 "/etc/nope.conf", 1264 "/etc/nope-rpm.conf", 1265 }, destinations(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) 1266 } 1267 1268 require.Len(t, ctx.Config.NFPMs[0].Contents, 4, "should not modify the config file list") 1269 } 1270 1271 func TestSkipSign(t *testing.T) { 1272 folder := t.TempDir() 1273 dist := filepath.Join(folder, "dist") 1274 require.NoError(t, os.Mkdir(dist, 0o755)) 1275 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 1276 binPath := filepath.Join(dist, "mybin", "mybin") 1277 _, err := os.Create(binPath) 1278 require.NoError(t, err) 1279 ctx := testctx.NewWithCfg(config.Project{ 1280 ProjectName: "mybin", 1281 Dist: dist, 1282 NFPMs: []config.NFPM{ 1283 { 1284 ID: "someid", 1285 Builds: []string{"default"}, 1286 Formats: []string{"deb", "rpm", "apk"}, 1287 NFPMOverridables: config.NFPMOverridables{ 1288 PackageName: "foo", 1289 FileNameTemplate: defaultNameTemplate, 1290 Contents: []*files.Content{ 1291 { 1292 Source: "testdata/testfile.txt", 1293 Destination: "/usr/share/testfile.txt", 1294 }, 1295 }, 1296 Deb: config.NFPMDeb{ 1297 Signature: config.NFPMDebSignature{ 1298 KeyFile: "/does/not/exist.gpg", 1299 }, 1300 }, 1301 RPM: config.NFPMRPM{ 1302 Signature: config.NFPMRPMSignature{ 1303 KeyFile: "/does/not/exist.gpg", 1304 }, 1305 }, 1306 APK: config.NFPMAPK{ 1307 Signature: config.NFPMAPKSignature{ 1308 KeyFile: "/does/not/exist.gpg", 1309 }, 1310 }, 1311 }, 1312 }, 1313 }, 1314 }, testctx.WithVersion("1.0.0"), testctx.WithCurrentTag("v1.0.0")) 1315 for _, goos := range []string{"linux", "darwin"} { 1316 for _, goarch := range []string{"amd64", "386"} { 1317 ctx.Artifacts.Add(&artifact.Artifact{ 1318 Name: "mybin", 1319 Path: binPath, 1320 Goarch: goarch, 1321 Goos: goos, 1322 Type: artifact.Binary, 1323 Extra: map[string]interface{}{ 1324 artifact.ExtraID: "default", 1325 }, 1326 }) 1327 } 1328 } 1329 1330 t.Run("skip sign not set", func(t *testing.T) { 1331 // TODO: once https://github.com/goreleaser/nfpm/pull/630 is released, 1332 // use require.ErrorIs() here. 1333 require.Error(t, Pipe{}.Run(ctx)) 1334 }) 1335 1336 t.Run("skip sign set", func(t *testing.T) { 1337 skips.Set(ctx, skips.Sign) 1338 require.NoError(t, Pipe{}.Run(ctx)) 1339 }) 1340 } 1341 1342 func TestBinDirTemplating(t *testing.T) { 1343 folder := t.TempDir() 1344 dist := filepath.Join(folder, "dist") 1345 require.NoError(t, os.Mkdir(dist, 0o755)) 1346 require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) 1347 binPath := filepath.Join(dist, "mybin", "mybin") 1348 f, err := os.Create(binPath) 1349 require.NoError(t, err) 1350 require.NoError(t, f.Close()) 1351 ctx := testctx.NewWithCfg(config.Project{ 1352 ProjectName: "mybin", 1353 Dist: dist, 1354 Env: []string{ 1355 "PRO=pro", 1356 "DESC=templates", 1357 "MAINTAINER=me@me", 1358 }, 1359 NFPMs: []config.NFPM{ 1360 { 1361 ID: "someid", 1362 // Bindir should pass through the template engine 1363 Bindir: "/usr/lib/{{ .Env.PRO }}/nagios/plugins", 1364 Builds: []string{"default"}, 1365 Formats: []string{"rpm"}, 1366 Section: "somesection", 1367 Priority: "standard", 1368 Description: "Some description with {{ .Env.DESC }}", 1369 License: "MIT", 1370 Maintainer: "{{ .Env.MAINTAINER }}", 1371 Vendor: "asdf", 1372 Homepage: "https://goreleaser.com/{{ .Env.PRO }}", 1373 NFPMOverridables: config.NFPMOverridables{ 1374 PackageName: "foo", 1375 }, 1376 }, 1377 }, 1378 }, testctx.WithVersion("1.0.0"), testctx.WithCurrentTag("v1.0.0")) 1379 for _, goos := range []string{"linux"} { 1380 for _, goarch := range []string{"amd64", "386"} { 1381 ctx.Artifacts.Add(&artifact.Artifact{ 1382 Name: "subdir/mybin", 1383 Path: binPath, 1384 Goarch: goarch, 1385 Goos: goos, 1386 Type: artifact.Binary, 1387 Extra: map[string]interface{}{ 1388 artifact.ExtraID: "default", 1389 }, 1390 }) 1391 } 1392 } 1393 require.NoError(t, Pipe{}.Run(ctx)) 1394 packages := ctx.Artifacts.Filter(artifact.ByType(artifact.LinuxPackage)).List() 1395 1396 for _, pkg := range packages { 1397 format := pkg.Format() 1398 require.NotEmpty(t, format) 1399 // the final binary should contain the evaluated bindir (after template eval) 1400 require.ElementsMatch(t, []string{ 1401 "/usr/lib/pro/nagios/plugins/subdir/mybin", 1402 }, destinations(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) 1403 } 1404 } 1405 1406 func TestSkip(t *testing.T) { 1407 t.Run("skip", func(t *testing.T) { 1408 require.True(t, Pipe{}.Skip(testctx.New())) 1409 }) 1410 1411 t.Run("dont skip", func(t *testing.T) { 1412 ctx := testctx.NewWithCfg(config.Project{ 1413 NFPMs: []config.NFPM{ 1414 {}, 1415 }, 1416 }) 1417 require.False(t, Pipe{}.Skip(ctx)) 1418 }) 1419 } 1420 1421 func TestTemplateExt(t *testing.T) { 1422 ctx := testctx.NewWithCfg(config.Project{ 1423 Dist: t.TempDir(), 1424 NFPMs: []config.NFPM{ 1425 { 1426 NFPMOverridables: config.NFPMOverridables{ 1427 FileNameTemplate: "a_{{ .ConventionalExtension }}_b", 1428 PackageName: "foo", 1429 }, 1430 Meta: true, 1431 Maintainer: "foo@bar", 1432 Formats: []string{"deb", "rpm", "termux.deb", "apk", "archlinux"}, 1433 Builds: []string{"default"}, 1434 }, 1435 }, 1436 }) 1437 ctx.Artifacts.Add(&artifact.Artifact{ 1438 Name: "mybin", 1439 Goos: "linux", 1440 Goarch: "amd64", 1441 Type: artifact.Binary, 1442 Extra: map[string]interface{}{ 1443 artifact.ExtraID: "default", 1444 }, 1445 }) 1446 require.NoError(t, Pipe{}.Run(ctx)) 1447 1448 packages := ctx.Artifacts.Filter(artifact.ByType(artifact.LinuxPackage)).List() 1449 require.Len(t, packages, 5) 1450 names := make([]string, 0, 5) 1451 for _, p := range packages { 1452 names = append(names, p.Name) 1453 } 1454 1455 require.ElementsMatch(t, []string{ 1456 "a_.apk_b.apk", 1457 "a_.deb_b.deb", 1458 "a_.rpm_b.rpm", 1459 "a_.termux.deb_b.termux.deb", 1460 "a_.pkg.tar.zst_b.pkg.tar.zst", 1461 }, names) 1462 } 1463 1464 func sources(contents files.Contents) []string { 1465 result := make([]string, 0, len(contents)) 1466 for _, f := range contents { 1467 if f.Source == "" { 1468 continue 1469 } 1470 result = append(result, f.Source) 1471 } 1472 return result 1473 }