github.com/amane3/goreleaser@v0.182.0/internal/pipe/changelog/changelog_test.go (about)

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