github.com/ahmet2mir/goreleaser@v0.180.3-0.20210927151101-8e5ee5a9b8c5/internal/pipe/changelog/changelog_test.go (about)

     1  package changelog
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/goreleaser/goreleaser/internal/testlib"
    11  	"github.com/goreleaser/goreleaser/pkg/config"
    12  	"github.com/goreleaser/goreleaser/pkg/context"
    13  )
    14  
    15  func TestDescription(t *testing.T) {
    16  	require.NotEmpty(t, Pipe{}.String())
    17  }
    18  
    19  func TestChangelogProvidedViaFlag(t *testing.T) {
    20  	ctx := context.New(config.Project{})
    21  	ctx.ReleaseNotesFile = "testdata/changes.md"
    22  	require.NoError(t, Pipe{}.Run(ctx))
    23  	require.Equal(t, "c0ff33 coffeee\n", ctx.ReleaseNotes)
    24  }
    25  
    26  func TestTemplatedChangelogProvidedViaFlag(t *testing.T) {
    27  	ctx := context.New(config.Project{})
    28  	ctx.ReleaseNotesFile = "testdata/changes.md"
    29  	ctx.ReleaseNotesTmpl = "testdata/changes-templated.md"
    30  	ctx.Git.CurrentTag = "v0.0.1"
    31  	require.NoError(t, Pipe{}.Run(ctx))
    32  	require.Equal(t, "c0ff33 coffeee v0.0.1\n", ctx.ReleaseNotes)
    33  }
    34  
    35  func TestChangelogProvidedViaFlagDoesntExist(t *testing.T) {
    36  	ctx := context.New(config.Project{})
    37  	ctx.ReleaseNotesFile = "testdata/changes.nope"
    38  	require.EqualError(t, Pipe{}.Run(ctx), "open testdata/changes.nope: no such file or directory")
    39  }
    40  
    41  func TestReleaseHeaderProvidedViaFlagDoesntExist(t *testing.T) {
    42  	ctx := context.New(config.Project{})
    43  	ctx.ReleaseHeaderFile = "testdata/header.nope"
    44  	require.EqualError(t, Pipe{}.Run(ctx), "open testdata/header.nope: no such file or directory")
    45  }
    46  
    47  func TestReleaseFooterProvidedViaFlagDoesntExist(t *testing.T) {
    48  	ctx := context.New(config.Project{})
    49  	ctx.ReleaseFooterFile = "testdata/footer.nope"
    50  	require.EqualError(t, Pipe{}.Run(ctx), "open testdata/footer.nope: no such file or directory")
    51  }
    52  
    53  func TestChangelog(t *testing.T) {
    54  	folder := testlib.Mktmp(t)
    55  	testlib.GitInit(t)
    56  	testlib.GitCommit(t, "first")
    57  	testlib.GitTag(t, "v0.0.1")
    58  	testlib.GitCommit(t, "added feature 1")
    59  	testlib.GitCommit(t, "fixed bug 2")
    60  	testlib.GitCommit(t, "ignored: whatever")
    61  	testlib.GitCommit(t, "docs: whatever")
    62  	testlib.GitCommit(t, "something about cArs we dont need")
    63  	testlib.GitCommit(t, "feat: added that thing")
    64  	testlib.GitCommit(t, "Merge pull request #999 from goreleaser/some-branch")
    65  	testlib.GitCommit(t, "this is not a Merge pull request")
    66  	testlib.GitTag(t, "v0.0.2")
    67  	ctx := context.New(config.Project{
    68  		Dist: folder,
    69  		Changelog: config.Changelog{
    70  			Filters: config.Filters{
    71  				Exclude: []string{
    72  					"docs:",
    73  					"ignored:",
    74  					"(?i)cars",
    75  					"^Merge pull request",
    76  				},
    77  			},
    78  		},
    79  	})
    80  	ctx.Git.CurrentTag = "v0.0.2"
    81  	require.NoError(t, Pipe{}.Run(ctx))
    82  	require.Contains(t, ctx.ReleaseNotes, "## Changelog")
    83  	require.NotContains(t, ctx.ReleaseNotes, "first")
    84  	require.Contains(t, ctx.ReleaseNotes, "added feature 1")
    85  	require.Contains(t, ctx.ReleaseNotes, "fixed bug 2")
    86  	require.NotContains(t, ctx.ReleaseNotes, "docs")
    87  	require.NotContains(t, ctx.ReleaseNotes, "ignored")
    88  	require.NotContains(t, ctx.ReleaseNotes, "cArs")
    89  	require.NotContains(t, ctx.ReleaseNotes, "from goreleaser/some-branch")
    90  
    91  	bts, err := os.ReadFile(filepath.Join(folder, "CHANGELOG.md"))
    92  	require.NoError(t, err)
    93  	require.NotEmpty(t, string(bts))
    94  }
    95  
    96  func TestChangelogPreviousTagEnv(t *testing.T) {
    97  	folder := testlib.Mktmp(t)
    98  	testlib.GitInit(t)
    99  	testlib.GitCommit(t, "first")
   100  	testlib.GitTag(t, "v0.0.1")
   101  	testlib.GitCommit(t, "second")
   102  	testlib.GitTag(t, "v0.0.2")
   103  	testlib.GitCommit(t, "third")
   104  	testlib.GitTag(t, "v0.0.3")
   105  	ctx := context.New(config.Project{
   106  		Dist:      folder,
   107  		Changelog: config.Changelog{Filters: config.Filters{}},
   108  	})
   109  	ctx.Git.CurrentTag = "v0.0.3"
   110  	require.NoError(t, os.Setenv("GORELEASER_PREVIOUS_TAG", "v0.0.1"))
   111  	require.NoError(t, Pipe{}.Run(ctx))
   112  	require.NoError(t, os.Setenv("GORELEASER_PREVIOUS_TAG", ""))
   113  	require.Contains(t, ctx.ReleaseNotes, "## Changelog")
   114  	require.NotContains(t, ctx.ReleaseNotes, "first")
   115  	require.Contains(t, ctx.ReleaseNotes, "second")
   116  	require.Contains(t, ctx.ReleaseNotes, "third")
   117  }
   118  
   119  func TestChangelogForGitlab(t *testing.T) {
   120  	folder := testlib.Mktmp(t)
   121  	testlib.GitInit(t)
   122  	testlib.GitCommit(t, "first")
   123  	testlib.GitTag(t, "v0.0.1")
   124  	testlib.GitCommit(t, "added feature 1")
   125  	testlib.GitCommit(t, "fixed bug 2")
   126  	testlib.GitCommit(t, "ignored: whatever")
   127  	testlib.GitCommit(t, "docs: whatever")
   128  	testlib.GitCommit(t, "something about cArs we dont need")
   129  	testlib.GitCommit(t, "feat: added that thing")
   130  	testlib.GitCommit(t, "Merge pull request #999 from goreleaser/some-branch")
   131  	testlib.GitCommit(t, "this is not a Merge pull request")
   132  	testlib.GitTag(t, "v0.0.2")
   133  	ctx := context.New(config.Project{
   134  		Dist: folder,
   135  		Changelog: config.Changelog{
   136  			Filters: config.Filters{
   137  				Exclude: []string{
   138  					"docs:",
   139  					"ignored:",
   140  					"(?i)cars",
   141  					"^Merge pull request",
   142  				},
   143  			},
   144  		},
   145  	})
   146  	ctx.TokenType = context.TokenTypeGitLab
   147  	ctx.Git.CurrentTag = "v0.0.2"
   148  	require.NoError(t, Pipe{}.Run(ctx))
   149  	require.Contains(t, ctx.ReleaseNotes, "## Changelog")
   150  	require.NotContains(t, ctx.ReleaseNotes, "first")
   151  	require.Contains(t, ctx.ReleaseNotes, "added feature 1") // no whitespace because its the last entry of the changelog
   152  	require.Contains(t, ctx.ReleaseNotes, "fixed bug 2   ")  // whitespaces are on purpose
   153  	require.NotContains(t, ctx.ReleaseNotes, "docs")
   154  	require.NotContains(t, ctx.ReleaseNotes, "ignored")
   155  	require.NotContains(t, ctx.ReleaseNotes, "cArs")
   156  	require.NotContains(t, ctx.ReleaseNotes, "from goreleaser/some-branch")
   157  
   158  	bts, err := os.ReadFile(filepath.Join(folder, "CHANGELOG.md"))
   159  	require.NoError(t, err)
   160  	require.NotEmpty(t, string(bts))
   161  }
   162  
   163  func TestChangelogSort(t *testing.T) {
   164  	testlib.Mktmp(t)
   165  	testlib.GitInit(t)
   166  	testlib.GitCommit(t, "whatever")
   167  	testlib.GitTag(t, "v0.9.9")
   168  	testlib.GitCommit(t, "c: commit")
   169  	testlib.GitCommit(t, "a: commit")
   170  	testlib.GitCommit(t, "b: commit")
   171  	testlib.GitTag(t, "v1.0.0")
   172  	ctx := context.New(config.Project{
   173  		Changelog: config.Changelog{},
   174  	})
   175  	ctx.Git.CurrentTag = "v1.0.0"
   176  
   177  	for _, cfg := range []struct {
   178  		Sort    string
   179  		Entries []string
   180  	}{
   181  		{
   182  			Sort: "",
   183  			Entries: []string{
   184  				"b: commit",
   185  				"a: commit",
   186  				"c: commit",
   187  			},
   188  		},
   189  		{
   190  			Sort: "asc",
   191  			Entries: []string{
   192  				"a: commit",
   193  				"b: commit",
   194  				"c: commit",
   195  			},
   196  		},
   197  		{
   198  			Sort: "desc",
   199  			Entries: []string{
   200  				"c: commit",
   201  				"b: commit",
   202  				"a: commit",
   203  			},
   204  		},
   205  	} {
   206  		t.Run("changelog sort='"+cfg.Sort+"'", func(t *testing.T) {
   207  			ctx.Config.Changelog.Sort = cfg.Sort
   208  			entries, err := buildChangelog(ctx)
   209  			require.NoError(t, err)
   210  			require.Len(t, entries, len(cfg.Entries))
   211  			var changes []string
   212  			for _, line := range entries {
   213  				changes = append(changes, extractCommitInfo(line))
   214  			}
   215  			require.EqualValues(t, cfg.Entries, changes)
   216  		})
   217  	}
   218  }
   219  
   220  func TestChangelogInvalidSort(t *testing.T) {
   221  	ctx := context.New(config.Project{
   222  		Changelog: config.Changelog{
   223  			Sort: "dope",
   224  		},
   225  	})
   226  	require.EqualError(t, Pipe{}.Run(ctx), ErrInvalidSortDirection.Error())
   227  }
   228  
   229  func TestChangelogOfFirstRelease(t *testing.T) {
   230  	testlib.Mktmp(t)
   231  	testlib.GitInit(t)
   232  	msgs := []string{
   233  		"initial commit",
   234  		"another one",
   235  		"one more",
   236  		"and finally this one",
   237  	}
   238  	for _, msg := range msgs {
   239  		testlib.GitCommit(t, msg)
   240  	}
   241  	testlib.GitTag(t, "v0.0.1")
   242  	ctx := context.New(config.Project{})
   243  	ctx.Git.CurrentTag = "v0.0.1"
   244  	require.NoError(t, Pipe{}.Run(ctx))
   245  	require.Contains(t, ctx.ReleaseNotes, "## Changelog")
   246  	for _, msg := range msgs {
   247  		require.Contains(t, ctx.ReleaseNotes, msg)
   248  	}
   249  }
   250  
   251  func TestChangelogFilterInvalidRegex(t *testing.T) {
   252  	testlib.Mktmp(t)
   253  	testlib.GitInit(t)
   254  	testlib.GitCommit(t, "commitssss")
   255  	testlib.GitTag(t, "v0.0.3")
   256  	testlib.GitCommit(t, "commitzzz")
   257  	testlib.GitTag(t, "v0.0.4")
   258  	ctx := context.New(config.Project{
   259  		Changelog: config.Changelog{
   260  			Filters: config.Filters{
   261  				Exclude: []string{
   262  					"(?iasdr4qasd)not a valid regex i guess",
   263  				},
   264  			},
   265  		},
   266  	})
   267  	ctx.Git.CurrentTag = "v0.0.4"
   268  	require.EqualError(t, Pipe{}.Run(ctx), "error parsing regexp: invalid or unsupported Perl syntax: `(?ia`")
   269  }
   270  
   271  func TestChangelogNoTags(t *testing.T) {
   272  	testlib.Mktmp(t)
   273  	testlib.GitInit(t)
   274  	testlib.GitCommit(t, "first")
   275  	ctx := context.New(config.Project{})
   276  	require.Error(t, Pipe{}.Run(ctx))
   277  	require.Empty(t, ctx.ReleaseNotes)
   278  }
   279  
   280  func TestChangelogOnBranchWithSameNameAsTag(t *testing.T) {
   281  	testlib.Mktmp(t)
   282  	testlib.GitInit(t)
   283  	msgs := []string{
   284  		"initial commit",
   285  		"another one",
   286  		"one more",
   287  		"and finally this one",
   288  	}
   289  	for _, msg := range msgs {
   290  		testlib.GitCommit(t, msg)
   291  	}
   292  	testlib.GitTag(t, "v0.0.1")
   293  	testlib.GitCheckoutBranch(t, "v0.0.1")
   294  	ctx := context.New(config.Project{})
   295  	ctx.Git.CurrentTag = "v0.0.1"
   296  	require.NoError(t, Pipe{}.Run(ctx))
   297  	require.Contains(t, ctx.ReleaseNotes, "## Changelog")
   298  	for _, msg := range msgs {
   299  		require.Contains(t, ctx.ReleaseNotes, msg)
   300  	}
   301  }
   302  
   303  func TestChangeLogWithReleaseHeader(t *testing.T) {
   304  	current, err := os.Getwd()
   305  	require.NoError(t, err)
   306  	tmpdir := testlib.Mktmp(t)
   307  	require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata"))
   308  	testlib.GitInit(t)
   309  	msgs := []string{
   310  		"initial commit",
   311  		"another one",
   312  		"one more",
   313  		"and finally this one",
   314  	}
   315  	for _, msg := range msgs {
   316  		testlib.GitCommit(t, msg)
   317  	}
   318  	testlib.GitTag(t, "v0.0.1")
   319  	testlib.GitCheckoutBranch(t, "v0.0.1")
   320  	ctx := context.New(config.Project{})
   321  	ctx.Git.CurrentTag = "v0.0.1"
   322  	ctx.ReleaseHeaderFile = "testdata/release-header.md"
   323  	require.NoError(t, Pipe{}.Run(ctx))
   324  	require.Contains(t, ctx.ReleaseNotes, "## Changelog")
   325  	require.Contains(t, ctx.ReleaseNotes, "test header")
   326  }
   327  
   328  func TestChangeLogWithTemplatedReleaseHeader(t *testing.T) {
   329  	current, err := os.Getwd()
   330  	require.NoError(t, err)
   331  	tmpdir := testlib.Mktmp(t)
   332  	require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata"))
   333  	testlib.GitInit(t)
   334  	msgs := []string{
   335  		"initial commit",
   336  		"another one",
   337  		"one more",
   338  		"and finally this one",
   339  	}
   340  	for _, msg := range msgs {
   341  		testlib.GitCommit(t, msg)
   342  	}
   343  	testlib.GitTag(t, "v0.0.1")
   344  	testlib.GitCheckoutBranch(t, "v0.0.1")
   345  	ctx := context.New(config.Project{})
   346  	ctx.Git.CurrentTag = "v0.0.1"
   347  	ctx.ReleaseHeaderTmpl = "testdata/release-header-templated.md"
   348  	require.NoError(t, Pipe{}.Run(ctx))
   349  	require.Contains(t, ctx.ReleaseNotes, "## Changelog")
   350  	require.Contains(t, ctx.ReleaseNotes, "test header with tag v0.0.1")
   351  }
   352  
   353  func TestChangeLogWithReleaseFooter(t *testing.T) {
   354  	current, err := os.Getwd()
   355  	require.NoError(t, err)
   356  	tmpdir := testlib.Mktmp(t)
   357  	require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata"))
   358  	testlib.GitInit(t)
   359  	msgs := []string{
   360  		"initial commit",
   361  		"another one",
   362  		"one more",
   363  		"and finally this one",
   364  	}
   365  	for _, msg := range msgs {
   366  		testlib.GitCommit(t, msg)
   367  	}
   368  	testlib.GitTag(t, "v0.0.1")
   369  	testlib.GitCheckoutBranch(t, "v0.0.1")
   370  	ctx := context.New(config.Project{})
   371  	ctx.Git.CurrentTag = "v0.0.1"
   372  	ctx.ReleaseFooterFile = "testdata/release-footer.md"
   373  	require.NoError(t, Pipe{}.Run(ctx))
   374  	require.Contains(t, ctx.ReleaseNotes, "## Changelog")
   375  	require.Contains(t, ctx.ReleaseNotes, "test footer")
   376  	require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n')
   377  }
   378  
   379  func TestChangeLogWithTemplatedReleaseFooter(t *testing.T) {
   380  	current, err := os.Getwd()
   381  	require.NoError(t, err)
   382  	tmpdir := testlib.Mktmp(t)
   383  	require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata"))
   384  	testlib.GitInit(t)
   385  	msgs := []string{
   386  		"initial commit",
   387  		"another one",
   388  		"one more",
   389  		"and finally this one",
   390  	}
   391  	for _, msg := range msgs {
   392  		testlib.GitCommit(t, msg)
   393  	}
   394  	testlib.GitTag(t, "v0.0.1")
   395  	testlib.GitCheckoutBranch(t, "v0.0.1")
   396  	ctx := context.New(config.Project{})
   397  	ctx.Git.CurrentTag = "v0.0.1"
   398  	ctx.ReleaseFooterTmpl = "testdata/release-footer-templated.md"
   399  	require.NoError(t, Pipe{}.Run(ctx))
   400  	require.Contains(t, ctx.ReleaseNotes, "## Changelog")
   401  	require.Contains(t, ctx.ReleaseNotes, "test footer with tag v0.0.1")
   402  	require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n')
   403  }
   404  
   405  func TestChangeLogWithoutReleaseFooter(t *testing.T) {
   406  	current, err := os.Getwd()
   407  	require.NoError(t, err)
   408  	tmpdir := testlib.Mktmp(t)
   409  	require.NoError(t, os.Symlink(current+"/testdata", tmpdir+"/testdata"))
   410  	testlib.GitInit(t)
   411  	msgs := []string{
   412  		"initial commit",
   413  		"another one",
   414  		"one more",
   415  		"and finally this one",
   416  	}
   417  	for _, msg := range msgs {
   418  		testlib.GitCommit(t, msg)
   419  	}
   420  	testlib.GitTag(t, "v0.0.1")
   421  	testlib.GitCheckoutBranch(t, "v0.0.1")
   422  	ctx := context.New(config.Project{})
   423  	ctx.Git.CurrentTag = "v0.0.1"
   424  	require.NoError(t, Pipe{}.Run(ctx))
   425  	require.Contains(t, ctx.ReleaseNotes, "## Changelog")
   426  	require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n')
   427  }
   428  
   429  func TestSkip(t *testing.T) {
   430  	t.Run("skip on snapshot", func(t *testing.T) {
   431  		ctx := context.New(config.Project{})
   432  		ctx.Snapshot = true
   433  		require.True(t, Pipe{}.Skip(ctx))
   434  	})
   435  
   436  	t.Run("skip", func(t *testing.T) {
   437  		ctx := context.New(config.Project{
   438  			Changelog: config.Changelog{
   439  				Skip: true,
   440  			},
   441  		})
   442  		require.True(t, Pipe{}.Skip(ctx))
   443  	})
   444  
   445  	t.Run("dont skip", func(t *testing.T) {
   446  		ctx := context.New(config.Project{})
   447  		require.False(t, Pipe{}.Skip(ctx))
   448  	})
   449  }