github.com/triarius/goreleaser@v1.12.5/internal/pipe/changelog/changelog_test.go (about) 1 package changelog 2 3 import ( 4 "os" 5 "path/filepath" 6 "strings" 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/triarius/goreleaser/internal/client" 12 "github.com/triarius/goreleaser/internal/testlib" 13 "github.com/triarius/goreleaser/pkg/config" 14 "github.com/triarius/goreleaser/pkg/context" 15 ) 16 17 func TestDescription(t *testing.T) { 18 require.NotEmpty(t, Pipe{}.String()) 19 } 20 21 func TestChangelogProvidedViaFlag(t *testing.T) { 22 ctx := context.New(config.Project{}) 23 ctx.ReleaseNotesFile = "testdata/changes.md" 24 require.NoError(t, Pipe{}.Run(ctx)) 25 require.Equal(t, "c0ff33 coffeee\n", ctx.ReleaseNotes) 26 } 27 28 func TestChangelogProvidedViaFlagIsAWhitespaceOnlyFile(t *testing.T) { 29 ctx := context.New(config.Project{}) 30 ctx.ReleaseNotesFile = "testdata/changes-empty.md" 31 require.NoError(t, Pipe{}.Run(ctx)) 32 require.Equal(t, "\n", ctx.ReleaseNotes) 33 } 34 35 func TestChangelogProvidedViaFlagIsReallyEmpty(t *testing.T) { 36 ctx := context.New(config.Project{}) 37 ctx.ReleaseNotesFile = "testdata/changes-really-empty.md" 38 require.NoError(t, Pipe{}.Run(ctx)) 39 require.Equal(t, "", ctx.ReleaseNotes) 40 } 41 42 func TestChangelogTmplProvidedViaFlagIsReallyEmpty(t *testing.T) { 43 ctx := context.New(config.Project{}) 44 ctx.ReleaseNotesTmpl = "testdata/changes-really-empty.md" 45 require.NoError(t, Pipe{}.Run(ctx)) 46 require.Equal(t, "", ctx.ReleaseNotes) 47 } 48 49 func TestTemplatedChangelogProvidedViaFlag(t *testing.T) { 50 ctx := context.New(config.Project{}) 51 ctx.ReleaseNotesFile = "testdata/changes.md" 52 ctx.ReleaseNotesTmpl = "testdata/changes-templated.md" 53 ctx.Git.CurrentTag = "v0.0.1" 54 require.NoError(t, Pipe{}.Run(ctx)) 55 require.Equal(t, "c0ff33 coffeee v0.0.1\n", ctx.ReleaseNotes) 56 } 57 58 func TestTemplatedChangelogProvidedViaFlagResultIsEmpty(t *testing.T) { 59 ctx := context.New(config.Project{}) 60 ctx.ReleaseNotesTmpl = "testdata/changes-templated-empty.md" 61 ctx.Git.CurrentTag = "v0.0.1" 62 require.NoError(t, Pipe{}.Run(ctx)) 63 require.Equal(t, "\n\n", ctx.ReleaseNotes) 64 } 65 66 func TestChangelogProvidedViaFlagDoesntExist(t *testing.T) { 67 ctx := context.New(config.Project{}) 68 ctx.ReleaseNotesFile = "testdata/changes.nope" 69 require.EqualError(t, Pipe{}.Run(ctx), "open testdata/changes.nope: no such file or directory") 70 } 71 72 func TestReleaseHeaderProvidedViaFlagDoesntExist(t *testing.T) { 73 ctx := context.New(config.Project{}) 74 ctx.ReleaseHeaderFile = "testdata/header.nope" 75 require.EqualError(t, Pipe{}.Run(ctx), "open testdata/header.nope: no such file or directory") 76 } 77 78 func TestReleaseFooterProvidedViaFlagDoesntExist(t *testing.T) { 79 ctx := context.New(config.Project{}) 80 ctx.ReleaseFooterFile = "testdata/footer.nope" 81 require.EqualError(t, Pipe{}.Run(ctx), "open testdata/footer.nope: no such file or directory") 82 } 83 84 func TestChangelog(t *testing.T) { 85 folder := testlib.Mktmp(t) 86 testlib.GitInit(t) 87 testlib.GitCommit(t, "first") 88 testlib.GitTag(t, "v0.0.1") 89 testlib.GitCommit(t, "added feature 1") 90 testlib.GitCommit(t, "fixed bug 2") 91 testlib.GitCommit(t, "ignored: whatever") 92 testlib.GitCommit(t, "docs: whatever") 93 testlib.GitCommit(t, "something about cArs we dont need") 94 testlib.GitCommit(t, "feat: added that thing") 95 testlib.GitCommit(t, "Merge pull request #999 from goreleaser/some-branch") 96 testlib.GitCommit(t, "this is not a Merge pull request") 97 testlib.GitTag(t, "v0.0.2") 98 ctx := context.New(config.Project{ 99 Dist: folder, 100 Changelog: config.Changelog{ 101 Use: "git", 102 Filters: config.Filters{ 103 Exclude: []string{ 104 "docs:", 105 "ignored:", 106 "(?i)cars", 107 "^Merge pull request", 108 }, 109 }, 110 }, 111 }) 112 ctx.Git.PreviousTag = "v0.0.1" 113 ctx.Git.CurrentTag = "v0.0.2" 114 require.NoError(t, Pipe{}.Run(ctx)) 115 require.Contains(t, ctx.ReleaseNotes, "## Changelog") 116 require.NotContains(t, ctx.ReleaseNotes, "first") 117 require.Contains(t, ctx.ReleaseNotes, "added feature 1") 118 require.Contains(t, ctx.ReleaseNotes, "fixed bug 2") 119 require.NotContains(t, ctx.ReleaseNotes, "docs") 120 require.NotContains(t, ctx.ReleaseNotes, "ignored") 121 require.NotContains(t, ctx.ReleaseNotes, "cArs") 122 require.NotContains(t, ctx.ReleaseNotes, "from goreleaser/some-branch") 123 124 for _, line := range strings.Split(ctx.ReleaseNotes, "\n")[1:] { 125 if line == "" { 126 continue 127 } 128 require.Truef(t, strings.HasPrefix(line, "* "), "%q: changelog commit must be a list item", line) 129 } 130 131 bts, err := os.ReadFile(filepath.Join(folder, "CHANGELOG.md")) 132 require.NoError(t, err) 133 require.NotEmpty(t, string(bts)) 134 } 135 136 func TestChangelogForGitlab(t *testing.T) { 137 folder := testlib.Mktmp(t) 138 testlib.GitInit(t) 139 testlib.GitCommit(t, "first") 140 testlib.GitTag(t, "v0.0.1") 141 testlib.GitCommit(t, "added feature 1") 142 testlib.GitCommit(t, "fixed bug 2") 143 testlib.GitCommit(t, "ignored: whatever") 144 testlib.GitCommit(t, "docs: whatever") 145 testlib.GitCommit(t, "something about cArs we dont need") 146 testlib.GitCommit(t, "feat: added that thing") 147 testlib.GitCommit(t, "Merge pull request #999 from goreleaser/some-branch") 148 testlib.GitCommit(t, "this is not a Merge pull request") 149 testlib.GitTag(t, "v0.0.2") 150 ctx := context.New(config.Project{ 151 Dist: folder, 152 Changelog: config.Changelog{ 153 Filters: config.Filters{ 154 Exclude: []string{ 155 "docs:", 156 "ignored:", 157 "(?i)cars", 158 "^Merge pull request", 159 }, 160 }, 161 }, 162 }) 163 ctx.TokenType = context.TokenTypeGitLab 164 ctx.Git.PreviousTag = "v0.0.1" 165 ctx.Git.CurrentTag = "v0.0.2" 166 require.NoError(t, Pipe{}.Run(ctx)) 167 require.Contains(t, ctx.ReleaseNotes, "## Changelog") 168 require.NotContains(t, ctx.ReleaseNotes, "first") 169 require.Contains(t, ctx.ReleaseNotes, "added feature 1") // no whitespace because its the last entry of the changelog 170 require.Contains(t, ctx.ReleaseNotes, "fixed bug 2 ") // whitespaces are on purpose 171 require.NotContains(t, ctx.ReleaseNotes, "docs") 172 require.NotContains(t, ctx.ReleaseNotes, "ignored") 173 require.NotContains(t, ctx.ReleaseNotes, "cArs") 174 require.NotContains(t, ctx.ReleaseNotes, "from goreleaser/some-branch") 175 176 bts, err := os.ReadFile(filepath.Join(folder, "CHANGELOG.md")) 177 require.NoError(t, err) 178 require.NotEmpty(t, string(bts)) 179 } 180 181 func TestChangelogSort(t *testing.T) { 182 testlib.Mktmp(t) 183 testlib.GitInit(t) 184 testlib.GitCommit(t, "whatever") 185 testlib.GitTag(t, "v0.9.9") 186 testlib.GitCommit(t, "c: commit") 187 testlib.GitCommit(t, "a: commit") 188 testlib.GitCommit(t, "b: commit") 189 testlib.GitTag(t, "v1.0.0") 190 ctx := context.New(config.Project{ 191 Changelog: config.Changelog{}, 192 }) 193 ctx.Git.PreviousTag = "v0.9.9" 194 ctx.Git.CurrentTag = "v1.0.0" 195 196 for _, cfg := range []struct { 197 Sort string 198 Entries []string 199 }{ 200 { 201 Sort: "", 202 Entries: []string{ 203 "b: commit", 204 "a: commit", 205 "c: commit", 206 }, 207 }, 208 { 209 Sort: "asc", 210 Entries: []string{ 211 "a: commit", 212 "b: commit", 213 "c: commit", 214 }, 215 }, 216 { 217 Sort: "desc", 218 Entries: []string{ 219 "c: commit", 220 "b: commit", 221 "a: commit", 222 }, 223 }, 224 } { 225 t.Run("changelog sort='"+cfg.Sort+"'", func(t *testing.T) { 226 ctx.Config.Changelog.Sort = cfg.Sort 227 entries, err := buildChangelog(ctx) 228 require.NoError(t, err) 229 require.Len(t, entries, len(cfg.Entries)) 230 var changes []string 231 for _, line := range entries { 232 changes = append(changes, extractCommitInfo(line)) 233 } 234 require.EqualValues(t, cfg.Entries, changes) 235 }) 236 } 237 } 238 239 func TestChangelogInvalidSort(t *testing.T) { 240 ctx := context.New(config.Project{ 241 Changelog: config.Changelog{ 242 Sort: "dope", 243 }, 244 }) 245 require.EqualError(t, Pipe{}.Run(ctx), ErrInvalidSortDirection.Error()) 246 } 247 248 func TestChangelogOfFirstRelease(t *testing.T) { 249 testlib.Mktmp(t) 250 testlib.GitInit(t) 251 msgs := []string{ 252 "initial commit", 253 "another one", 254 "one more", 255 "and finally this one", 256 } 257 for _, msg := range msgs { 258 testlib.GitCommit(t, msg) 259 } 260 testlib.GitTag(t, "v0.0.1") 261 ctx := context.New(config.Project{}) 262 ctx.Git.CurrentTag = "v0.0.1" 263 require.NoError(t, Pipe{}.Run(ctx)) 264 require.Contains(t, ctx.ReleaseNotes, "## Changelog") 265 for _, msg := range msgs { 266 require.Contains(t, ctx.ReleaseNotes, msg) 267 } 268 } 269 270 func TestChangelogFilterInvalidRegex(t *testing.T) { 271 testlib.Mktmp(t) 272 testlib.GitInit(t) 273 testlib.GitCommit(t, "commitssss") 274 testlib.GitTag(t, "v0.0.3") 275 testlib.GitCommit(t, "commitzzz") 276 testlib.GitTag(t, "v0.0.4") 277 ctx := context.New(config.Project{ 278 Changelog: config.Changelog{ 279 Filters: config.Filters{ 280 Exclude: []string{ 281 "(?iasdr4qasd)not a valid regex i guess", 282 }, 283 }, 284 }, 285 }) 286 ctx.Git.PreviousTag = "v0.0.3" 287 ctx.Git.CurrentTag = "v0.0.4" 288 require.EqualError(t, Pipe{}.Run(ctx), "error parsing regexp: invalid or unsupported Perl syntax: `(?ia`") 289 } 290 291 func TestChangelogNoTags(t *testing.T) { 292 testlib.Mktmp(t) 293 testlib.GitInit(t) 294 testlib.GitCommit(t, "first") 295 ctx := context.New(config.Project{}) 296 require.Error(t, Pipe{}.Run(ctx)) 297 require.Empty(t, ctx.ReleaseNotes) 298 } 299 300 func TestChangelogOnBranchWithSameNameAsTag(t *testing.T) { 301 testlib.Mktmp(t) 302 testlib.GitInit(t) 303 msgs := []string{ 304 "initial commit", 305 "another one", 306 "one more", 307 "and finally this one", 308 } 309 for _, msg := range msgs { 310 testlib.GitCommit(t, msg) 311 } 312 testlib.GitTag(t, "v0.0.1") 313 testlib.GitCheckoutBranch(t, "v0.0.1") 314 ctx := context.New(config.Project{}) 315 ctx.Git.CurrentTag = "v0.0.1" 316 require.NoError(t, Pipe{}.Run(ctx)) 317 require.Contains(t, ctx.ReleaseNotes, "## Changelog") 318 for _, msg := range msgs { 319 require.Contains(t, ctx.ReleaseNotes, msg) 320 } 321 } 322 323 func TestChangeLogWithReleaseHeader(t *testing.T) { 324 current, err := os.Getwd() 325 require.NoError(t, err) 326 tmpdir := testlib.Mktmp(t) 327 require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata")) 328 testlib.GitInit(t) 329 msgs := []string{ 330 "initial commit", 331 "another one", 332 "one more", 333 "and finally this one", 334 } 335 for _, msg := range msgs { 336 testlib.GitCommit(t, msg) 337 } 338 testlib.GitTag(t, "v0.0.1") 339 testlib.GitCheckoutBranch(t, "v0.0.1") 340 ctx := context.New(config.Project{}) 341 ctx.Git.CurrentTag = "v0.0.1" 342 ctx.ReleaseHeaderFile = "testdata/release-header.md" 343 require.NoError(t, Pipe{}.Run(ctx)) 344 require.Contains(t, ctx.ReleaseNotes, "## Changelog") 345 require.Contains(t, ctx.ReleaseNotes, "test header") 346 } 347 348 func TestChangeLogWithTemplatedReleaseHeader(t *testing.T) { 349 current, err := os.Getwd() 350 require.NoError(t, err) 351 tmpdir := testlib.Mktmp(t) 352 require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata")) 353 testlib.GitInit(t) 354 msgs := []string{ 355 "initial commit", 356 "another one", 357 "one more", 358 "and finally this one", 359 } 360 for _, msg := range msgs { 361 testlib.GitCommit(t, msg) 362 } 363 testlib.GitTag(t, "v0.0.1") 364 testlib.GitCheckoutBranch(t, "v0.0.1") 365 ctx := context.New(config.Project{}) 366 ctx.Git.CurrentTag = "v0.0.1" 367 ctx.ReleaseHeaderTmpl = "testdata/release-header-templated.md" 368 require.NoError(t, Pipe{}.Run(ctx)) 369 require.Contains(t, ctx.ReleaseNotes, "## Changelog") 370 require.Contains(t, ctx.ReleaseNotes, "test header with tag v0.0.1") 371 } 372 373 func TestChangeLogWithReleaseFooter(t *testing.T) { 374 current, err := os.Getwd() 375 require.NoError(t, err) 376 tmpdir := testlib.Mktmp(t) 377 require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata")) 378 testlib.GitInit(t) 379 msgs := []string{ 380 "initial commit", 381 "another one", 382 "one more", 383 "and finally this one", 384 } 385 for _, msg := range msgs { 386 testlib.GitCommit(t, msg) 387 } 388 testlib.GitTag(t, "v0.0.1") 389 testlib.GitCheckoutBranch(t, "v0.0.1") 390 ctx := context.New(config.Project{}) 391 ctx.Git.CurrentTag = "v0.0.1" 392 ctx.ReleaseFooterFile = "testdata/release-footer.md" 393 require.NoError(t, Pipe{}.Run(ctx)) 394 require.Contains(t, ctx.ReleaseNotes, "## Changelog") 395 require.Contains(t, ctx.ReleaseNotes, "test footer") 396 require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n') 397 } 398 399 func TestChangeLogWithTemplatedReleaseFooter(t *testing.T) { 400 current, err := os.Getwd() 401 require.NoError(t, err) 402 tmpdir := testlib.Mktmp(t) 403 require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata")) 404 testlib.GitInit(t) 405 msgs := []string{ 406 "initial commit", 407 "another one", 408 "one more", 409 "and finally this one", 410 } 411 for _, msg := range msgs { 412 testlib.GitCommit(t, msg) 413 } 414 testlib.GitTag(t, "v0.0.1") 415 testlib.GitCheckoutBranch(t, "v0.0.1") 416 ctx := context.New(config.Project{}) 417 ctx.Git.CurrentTag = "v0.0.1" 418 ctx.ReleaseFooterTmpl = "testdata/release-footer-templated.md" 419 require.NoError(t, Pipe{}.Run(ctx)) 420 require.Contains(t, ctx.ReleaseNotes, "## Changelog") 421 require.Contains(t, ctx.ReleaseNotes, "test footer with tag v0.0.1") 422 require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n') 423 } 424 425 func TestChangeLogWithoutReleaseFooter(t *testing.T) { 426 current, err := os.Getwd() 427 require.NoError(t, err) 428 tmpdir := testlib.Mktmp(t) 429 require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata")) 430 testlib.GitInit(t) 431 msgs := []string{ 432 "initial commit", 433 "another one", 434 "one more", 435 "and finally this one", 436 } 437 for _, msg := range msgs { 438 testlib.GitCommit(t, msg) 439 } 440 testlib.GitTag(t, "v0.0.1") 441 testlib.GitCheckoutBranch(t, "v0.0.1") 442 ctx := context.New(config.Project{}) 443 ctx.Git.CurrentTag = "v0.0.1" 444 require.NoError(t, Pipe{}.Run(ctx)) 445 require.Contains(t, ctx.ReleaseNotes, "## Changelog") 446 require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n') 447 } 448 449 func TestGetChangelogGitHub(t *testing.T) { 450 ctx := context.New(config.Project{ 451 Changelog: config.Changelog{ 452 Use: useGitHub, 453 }, 454 }) 455 456 expected := "c90f1085f255d0af0b055160bfff5ee40f47af79: fix: do not skip any defaults (#2521) (@caarlos0)" 457 mock := client.NewMock() 458 mock.Changes = expected 459 l := scmChangeloger{ 460 client: mock, 461 repo: client.Repo{ 462 Owner: "goreleaser", 463 Name: "goreleaser", 464 }, 465 } 466 log, err := l.Log(ctx, "v0.180.1", "v0.180.2") 467 require.NoError(t, err) 468 require.Equal(t, expected, log) 469 } 470 471 func TestGetChangelogGitHubNative(t *testing.T) { 472 ctx := context.New(config.Project{ 473 Changelog: config.Changelog{ 474 Use: useGitHubNative, 475 }, 476 }) 477 478 expected := `## What's changed 479 480 * Foo bar test 481 482 **Full Changelog**: https://github.com/gorelease/goreleaser/compare/v0.180.1...v0.180.2 483 ` 484 mock := client.NewMock() 485 mock.ReleaseNotes = expected 486 l := githubNativeChangeloger{ 487 client: mock, 488 repo: client.Repo{ 489 Owner: "goreleaser", 490 Name: "goreleaser", 491 }, 492 } 493 log, err := l.Log(ctx, "v0.180.1", "v0.180.2") 494 require.NoError(t, err) 495 require.Equal(t, expected, log) 496 } 497 498 func TestGetChangeloger(t *testing.T) { 499 t.Run("default", func(t *testing.T) { 500 c, err := getChangeloger(context.New(config.Project{})) 501 require.NoError(t, err) 502 require.IsType(t, c, gitChangeloger{}) 503 }) 504 505 t.Run(useGit, func(t *testing.T) { 506 c, err := getChangeloger(context.New(config.Project{ 507 Changelog: config.Changelog{ 508 Use: useGit, 509 }, 510 })) 511 require.NoError(t, err) 512 require.IsType(t, c, gitChangeloger{}) 513 }) 514 515 t.Run(useGitHub, func(t *testing.T) { 516 ctx := context.New(config.Project{ 517 Changelog: config.Changelog{ 518 Use: useGitHub, 519 }, 520 }) 521 ctx.TokenType = context.TokenTypeGitHub 522 c, err := getChangeloger(ctx) 523 require.NoError(t, err) 524 require.IsType(t, c, &scmChangeloger{}) 525 }) 526 527 t.Run(useGitHubNative, func(t *testing.T) { 528 ctx := context.New(config.Project{ 529 Changelog: config.Changelog{ 530 Use: useGitHubNative, 531 }, 532 }) 533 ctx.TokenType = context.TokenTypeGitHub 534 c, err := getChangeloger(ctx) 535 require.NoError(t, err) 536 require.IsType(t, c, &githubNativeChangeloger{}) 537 }) 538 539 t.Run(useGitHubNative+"-invalid-repo", func(t *testing.T) { 540 testlib.Mktmp(t) 541 testlib.GitInit(t) 542 testlib.GitRemoteAdd(t, "https://gist.github.com/") 543 ctx := context.New(config.Project{ 544 Changelog: config.Changelog{ 545 Use: useGitHubNative, 546 }, 547 }) 548 ctx.TokenType = context.TokenTypeGitHub 549 c, err := getChangeloger(ctx) 550 require.EqualError(t, err, "unsupported repository URL: https://gist.github.com/") 551 require.Nil(t, c) 552 }) 553 554 t.Run(useGitLab, func(t *testing.T) { 555 ctx := context.New(config.Project{ 556 Changelog: config.Changelog{ 557 Use: useGitLab, 558 }, 559 }) 560 ctx.TokenType = context.TokenTypeGitLab 561 c, err := getChangeloger(ctx) 562 require.NoError(t, err) 563 require.IsType(t, c, &scmChangeloger{}) 564 }) 565 566 t.Run(useGitHub+"-invalid-repo", func(t *testing.T) { 567 testlib.Mktmp(t) 568 testlib.GitInit(t) 569 testlib.GitRemoteAdd(t, "https://gist.github.com/") 570 ctx := context.New(config.Project{ 571 Changelog: config.Changelog{ 572 Use: useGitHub, 573 }, 574 }) 575 ctx.TokenType = context.TokenTypeGitHub 576 c, err := getChangeloger(ctx) 577 require.EqualError(t, err, "unsupported repository URL: https://gist.github.com/") 578 require.Nil(t, c) 579 }) 580 581 t.Run("invalid", func(t *testing.T) { 582 c, err := getChangeloger(context.New(config.Project{ 583 Changelog: config.Changelog{ 584 Use: "nope", 585 }, 586 })) 587 require.EqualError(t, err, `invalid changelog.use: "nope"`) 588 require.Nil(t, c) 589 }) 590 } 591 592 func TestSkip(t *testing.T) { 593 t.Run("skip on snapshot", func(t *testing.T) { 594 ctx := context.New(config.Project{}) 595 ctx.Snapshot = true 596 require.True(t, Pipe{}.Skip(ctx)) 597 }) 598 599 t.Run("skip", func(t *testing.T) { 600 ctx := context.New(config.Project{ 601 Changelog: config.Changelog{ 602 Skip: true, 603 }, 604 }) 605 require.True(t, Pipe{}.Skip(ctx)) 606 }) 607 608 t.Run("dont skip", func(t *testing.T) { 609 ctx := context.New(config.Project{}) 610 require.False(t, Pipe{}.Skip(ctx)) 611 }) 612 } 613 614 func TestGroup(t *testing.T) { 615 folder := testlib.Mktmp(t) 616 testlib.GitInit(t) 617 testlib.GitCommit(t, "first") 618 testlib.GitTag(t, "v0.0.1") 619 testlib.GitCommit(t, "added feature 1") 620 testlib.GitCommit(t, "fixed bug 2") 621 testlib.GitCommit(t, "ignored: whatever") 622 testlib.GitCommit(t, "feat(deps): update foobar [bot]") 623 testlib.GitCommit(t, "fix: whatever") 624 testlib.GitCommit(t, "docs: whatever") 625 testlib.GitCommit(t, "chore: something about cArs we dont need") 626 testlib.GitCommit(t, "feat: added that thing") 627 testlib.GitCommit(t, "bug: Merge pull request #999 from goreleaser/some-branch") 628 testlib.GitCommit(t, "this is not a Merge pull request") 629 testlib.GitTag(t, "v0.0.2") 630 ctx := context.New(config.Project{ 631 Dist: folder, 632 Changelog: config.Changelog{ 633 Groups: []config.ChangeLogGroup{ 634 { 635 Title: "Bots", 636 Regexp: ".*bot.*", 637 Order: 900, 638 }, 639 { 640 Title: "Features", 641 Regexp: "^.*feat[(\\w)]*:+.*$", 642 Order: 0, 643 }, 644 { 645 Title: "Bug Fixes", 646 Regexp: "^.*bug[(\\w)]*:+.*$", 647 Order: 1, 648 }, 649 { 650 Title: "Catch nothing", 651 Regexp: "yada yada yada honk the planet", 652 Order: 10, 653 }, 654 { 655 Title: "Others", 656 Order: 999, 657 }, 658 }, 659 }, 660 }) 661 ctx.Git.CurrentTag = "v0.0.2" 662 require.NoError(t, Pipe{}.Run(ctx)) 663 require.Contains(t, ctx.ReleaseNotes, "## Changelog") 664 require.Contains(t, ctx.ReleaseNotes, "### Bots") 665 require.Contains(t, ctx.ReleaseNotes, "### Features") 666 require.Contains(t, ctx.ReleaseNotes, "### Bug Fixes") 667 require.NotContains(t, ctx.ReleaseNotes, "### Catch nothing") 668 require.Contains(t, ctx.ReleaseNotes, "### Others") 669 } 670 671 func TestGroupBadRegex(t *testing.T) { 672 folder := testlib.Mktmp(t) 673 testlib.GitInit(t) 674 testlib.GitCommit(t, "first") 675 testlib.GitTag(t, "v0.0.1") 676 testlib.GitTag(t, "v0.0.2") 677 ctx := context.New(config.Project{ 678 Dist: folder, 679 Changelog: config.Changelog{ 680 Groups: []config.ChangeLogGroup{ 681 { 682 Title: "Something", 683 Regexp: "^.*feat[(\\w", // unterminated regex 684 }, 685 }, 686 }, 687 }) 688 ctx.Git.CurrentTag = "v0.0.2" 689 require.EqualError(t, Pipe{}.Run(ctx), `failed to group into "Something": error parsing regexp: missing closing ]: `+"`"+`[(\w`+"`") 690 } 691 692 func TestChangelogFormat(t *testing.T) { 693 t.Run("without groups", func(t *testing.T) { 694 makeConf := func(u string) config.Project { 695 return config.Project{Changelog: config.Changelog{Use: u}} 696 } 697 698 for _, use := range []string{useGit, useGitHub, useGitLab} { 699 t.Run(use, func(t *testing.T) { 700 out, err := formatChangelog( 701 context.New(makeConf(use)), 702 []string{ 703 "aea123 foo", 704 "aef653 bar", 705 }, 706 ) 707 require.NoError(t, err) 708 require.Equal(t, `## Changelog 709 * aea123 foo 710 * aef653 bar`, out) 711 }) 712 } 713 714 t.Run(useGitHubNative, func(t *testing.T) { 715 out, err := formatChangelog( 716 context.New(makeConf(useGitHubNative)), 717 []string{ 718 "# What's changed", 719 "* aea123 foo", 720 "* aef653 bar", 721 }, 722 ) 723 require.NoError(t, err) 724 require.Equal(t, `# What's changed 725 * aea123 foo 726 * aef653 bar`, out) 727 }) 728 }) 729 730 t.Run("with groups", func(t *testing.T) { 731 makeConf := func(u string) config.Project { 732 return config.Project{ 733 Changelog: config.Changelog{ 734 Use: u, 735 Groups: []config.ChangeLogGroup{ 736 {Title: "catch-all"}, 737 }, 738 }, 739 } 740 } 741 742 t.Run(useGitHubNative, func(t *testing.T) { 743 out, err := formatChangelog( 744 context.New(makeConf(useGitHubNative)), 745 []string{ 746 "# What's changed", 747 "* aea123 foo", 748 "* aef653 bar", 749 }, 750 ) 751 require.NoError(t, err) 752 require.Equal(t, `# What's changed 753 * aea123 foo 754 * aef653 bar`, out) 755 }) 756 for _, use := range []string{useGit, useGitHub, useGitLab} { 757 t.Run(use, func(t *testing.T) { 758 out, err := formatChangelog( 759 context.New(makeConf(use)), 760 []string{ 761 "aea123 foo", 762 "aef653 bar", 763 }, 764 ) 765 require.NoError(t, err) 766 require.Equal(t, `## Changelog 767 768 ### catch-all 769 * aea123 foo 770 * aef653 bar`, out) 771 }) 772 } 773 }) 774 } 775 776 func TestAbbrev(t *testing.T) { 777 folder := testlib.Mktmp(t) 778 testlib.GitInit(t) 779 testlib.GitCommit(t, "first") 780 testlib.GitTag(t, "v0.0.1") 781 testlib.GitCommit(t, "added feature 1") 782 testlib.GitCommit(t, "fixed bug 2") 783 testlib.GitCommit(t, "ignored: whatever") 784 testlib.GitCommit(t, "feat(deps): update foobar [bot]") 785 testlib.GitCommit(t, "fix: whatever") 786 testlib.GitCommit(t, "docs: whatever") 787 testlib.GitCommit(t, "chore: something about cArs we dont need") 788 testlib.GitCommit(t, "feat: added that thing") 789 testlib.GitCommit(t, "bug: Merge pull request #999 from goreleaser/some-branch") 790 testlib.GitCommit(t, "this is not a Merge pull request") 791 testlib.GitTag(t, "v0.0.2") 792 793 t.Run("no abbrev", func(t *testing.T) { 794 ctx := context.New(config.Project{ 795 Dist: folder, 796 Changelog: config.Changelog{}, 797 }) 798 ctx.Git.CurrentTag = "v0.0.2" 799 require.NoError(t, Pipe{}.Run(ctx)) 800 ensureCommitHashLen(t, ctx.ReleaseNotes, 7) 801 }) 802 803 t.Run("abbrev -1", func(t *testing.T) { 804 ctx := context.New(config.Project{ 805 Dist: folder, 806 Changelog: config.Changelog{ 807 Abbrev: -1, 808 }, 809 }) 810 ctx.Git.CurrentTag = "v0.0.2" 811 require.NoError(t, Pipe{}.Run(ctx)) 812 }) 813 814 t.Run("abbrev 3", func(t *testing.T) { 815 ctx := context.New(config.Project{ 816 Dist: folder, 817 Changelog: config.Changelog{ 818 Abbrev: 3, 819 }, 820 }) 821 ctx.Git.CurrentTag = "v0.0.2" 822 require.NoError(t, Pipe{}.Run(ctx)) 823 ensureCommitHashLen(t, ctx.ReleaseNotes, 3) 824 }) 825 826 t.Run("abbrev 7", func(t *testing.T) { 827 ctx := context.New(config.Project{ 828 Dist: folder, 829 Changelog: config.Changelog{ 830 Abbrev: 7, 831 }, 832 }) 833 ctx.Git.CurrentTag = "v0.0.2" 834 require.NoError(t, Pipe{}.Run(ctx)) 835 ensureCommitHashLen(t, ctx.ReleaseNotes, 7) 836 }) 837 838 t.Run("abbrev 40", func(t *testing.T) { 839 ctx := context.New(config.Project{ 840 Dist: folder, 841 Changelog: config.Changelog{ 842 Abbrev: 40, 843 }, 844 }) 845 ctx.Git.CurrentTag = "v0.0.2" 846 require.NoError(t, Pipe{}.Run(ctx)) 847 ensureCommitHashLen(t, ctx.ReleaseNotes, 7) 848 }) 849 } 850 851 func ensureCommitHashLen(tb testing.TB, log string, l int) { 852 tb.Helper() 853 for _, line := range strings.Split(log, "\n") { 854 if strings.HasPrefix(line, "#") || strings.TrimSpace(line) == "" { 855 continue 856 } 857 parts := strings.SplitN(line, " ", 3) 858 commit := strings.TrimPrefix(parts[1], "* ") 859 require.Len(tb, commit, l) 860 } 861 }