Skip to content

Commit 62eecf5

Browse files
authored
fix(changelog): resolve empty previousVersion in new contributors lookup (#264)
1 parent ae73131 commit 62eecf5

2 files changed

Lines changed: 77 additions & 0 deletions

File tree

internal/plugins/changeloggenerator/git.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,14 @@ var prNumberExtractRe = regexp.MustCompile(`#(\d+)`)
383383
// getNewContributors identifies first-time contributors in a set of commits.
384384
// It checks if the contributor has any commits before previousVersion.
385385
func (g *GitOps) getNewContributors(commits []CommitInfo, previousVersion string) ([]NewContributor, error) {
386+
// When previousVersion is empty, resolve it from the latest tag so that
387+
// historical contributor lookup covers all prior history.
388+
if previousVersion == "" {
389+
if tag, err := g.GetLatestTagFn(); err == nil {
390+
previousVersion = tag
391+
}
392+
}
393+
386394
// Get historical contributor usernames (before this release)
387395
historicalUsernames, err := g.GetHistoricalContributorsFn(previousVersion)
388396
if err != nil {

internal/plugins/changeloggenerator/git_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package changeloggenerator
22

33
import (
4+
"fmt"
45
"os"
56
"os/exec"
67
"strings"
@@ -820,6 +821,74 @@ func TestGetNewContributors(t *testing.T) {
820821
}
821822
}
822823

824+
func TestGetNewContributors_EmptyPreviousVersionResolvesTag(t *testing.T) {
825+
// Regression test: when previousVersion is "", getNewContributors must
826+
// resolve the latest tag and use it for the historical contributor lookup.
827+
// Without this, getHistoricalContributors receives "" and returns an empty
828+
// set, making every author appear as a new contributor.
829+
830+
gitOps := NewGitOps()
831+
832+
// Simulate a repo where "alice" has commits before v1.0.0 (historical).
833+
gitOps.GetLatestTagFn = func() (string, error) {
834+
return "v1.0.0", nil
835+
}
836+
gitOps.GetHistoricalContributorsFn = func(beforeRef string) (map[string]struct{}, error) {
837+
if beforeRef == "" {
838+
// This should NOT be reached after the fix.
839+
return map[string]struct{}{}, nil
840+
}
841+
// Return alice as a known historical contributor.
842+
return map[string]struct{}{"alice": {}}, nil
843+
}
844+
845+
commits := []CommitInfo{
846+
{Author: "Alice", AuthorEmail: "alice@users.noreply.github.com", ShortHash: "aaa111", Subject: "fix: update (#10)"},
847+
{Author: "NewDev", AuthorEmail: "newdev@users.noreply.github.com", ShortHash: "bbb222", Subject: "feat: feature (#11)"},
848+
}
849+
850+
got, err := gitOps.getNewContributors(commits, "")
851+
if err != nil {
852+
t.Fatalf("unexpected error: %v", err)
853+
}
854+
855+
if len(got) != 1 {
856+
t.Fatalf("expected 1 new contributor, got %d", len(got))
857+
}
858+
if got[0].Username != "newdev" {
859+
t.Errorf("expected new contributor 'newdev', got %q", got[0].Username)
860+
}
861+
}
862+
863+
func TestGetNewContributors_EmptyPreviousVersionNoTags(t *testing.T) {
864+
// When previousVersion is "" and no tags exist, all contributors are
865+
// genuinely new (first release). This must not error.
866+
867+
gitOps := NewGitOps()
868+
gitOps.GetLatestTagFn = func() (string, error) {
869+
return "", fmt.Errorf("no tags found")
870+
}
871+
gitOps.GetHistoricalContributorsFn = func(beforeRef string) (map[string]struct{}, error) {
872+
return map[string]struct{}{}, nil
873+
}
874+
875+
commits := []CommitInfo{
876+
{Author: "Alice", AuthorEmail: "alice@users.noreply.github.com", ShortHash: "aaa111", Subject: "feat: init (#1)"},
877+
}
878+
879+
got, err := gitOps.getNewContributors(commits, "")
880+
if err != nil {
881+
t.Fatalf("unexpected error: %v", err)
882+
}
883+
884+
if len(got) != 1 {
885+
t.Fatalf("expected 1 new contributor, got %d", len(got))
886+
}
887+
if got[0].Username != "alice" {
888+
t.Errorf("expected new contributor 'alice', got %q", got[0].Username)
889+
}
890+
}
891+
823892
func TestGetNewContributors_PRNumberExtraction(t *testing.T) {
824893

825894
gitOps := NewGitOps()

0 commit comments

Comments
 (0)