From 42b65fe2639f5207994205c7421fa51a2e1821a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20T=C3=B6lle?= Date: Thu, 22 May 2025 14:52:20 +0200 Subject: [PATCH] fix: invalid version for subsequent pre-releases If two pre-releases were cut in a row, the second pre-release version would only consider the semantic changes since the previous pre-release, but base its new version of the latest tag. Example: - stable tag: `1.2.0` - latest tag: `1.3.0-rc.1` - 1 commit since with `fix:` tag The resulting releaser-pleaser tag would be: `1.2.1-rc.2`. It should be `1.3.0-rc.2` instead. This is now fixed by considering different commit ranges for versioning and changelog. For a stable version we want the list of changes since the stable tag. For a prerelease version we want the list of changes since the latest tag. To avoid repeating the same features over and over in a series of multiple pre-releases. This behaviour already existed and worked. For a stable version, we want to consider all changes since the stable tag. For a prerelease version, we also want to consider all changes since the stable tag. This was broken and only used the changes since the latest tag. --- releaserpleaser.go | 67 ++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/releaserpleaser.go b/releaserpleaser.go index 88b2dbb..f2f4064 100644 --- a/releaserpleaser.go +++ b/releaserpleaser.go @@ -179,34 +179,16 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error { logger.InfoContext(ctx, "no latest tag found") } - // By default, we want to show everything that has happened since the last stable release - lastReleaseCommit := releases.Stable - if releaseOverrides.NextVersionType.IsPrerelease() { - // if the new release will be a prerelease, - // only show changes since the latest release (stable or prerelease) - lastReleaseCommit = releases.Latest - } - - commits, err := rp.forge.CommitsSince(ctx, lastReleaseCommit) + // For stable releases, we want to consider all changes since the last stable release for version and changelog. + // For prereleases, we want to consider all changes... + // - since the last stable release for the version + // - since the latest release (stable or prerelease) for the changelog + analyzedCommitsForVersioning, err := rp.analyzedCommitsSince(ctx, releases.Stable) if err != nil { return err } - commits, err = parsePRBodyForCommitOverrides(commits) - if err != nil { - return err - } - - logger.InfoContext(ctx, "Found releasable commits", "length", len(commits)) - - analyzedCommits, err := rp.commitParser.Analyze(commits) - if err != nil { - return err - } - - logger.InfoContext(ctx, "Analyzed commits", "length", len(analyzedCommits)) - - if len(analyzedCommits) == 0 { + if len(analyzedCommitsForVersioning) == 0 { if pr != nil { logger.InfoContext(ctx, "closing existing pull requests, no commits available", "pr.id", pr.ID, "pr.title", pr.Title) err = rp.forge.ClosePullRequest(ctx, pr) @@ -220,7 +202,7 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error { return nil } - versionBump := versioning.BumpFromCommits(analyzedCommits) + versionBump := versioning.BumpFromCommits(analyzedCommitsForVersioning) // TODO: Set version in release pr nextVersion, err := rp.versioning.NextVersion(releases, versionBump, releaseOverrides.NextVersionType) if err != nil { @@ -228,6 +210,14 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error { } logger.InfoContext(ctx, "next version", "version", nextVersion) + analyzedCommitsForChangelog := analyzedCommitsForVersioning + if releaseOverrides.NextVersionType.IsPrerelease() && releases.Latest != releases.Stable { + analyzedCommitsForChangelog, err = rp.analyzedCommitsSince(ctx, releases.Latest) + if err != nil { + return err + } + } + logger.DebugContext(ctx, "cloning repository", "clone.url", rp.forge.CloneURL()) repo, err := git.CloneRepo(ctx, logger, rp.forge.CloneURL(), rp.targetBranch, rp.forge.GitAuth()) if err != nil { @@ -242,7 +232,7 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error { return err } - changelogData := changelog.New(commitparser.ByType(analyzedCommits), nextVersion, rp.forge.ReleaseURL(nextVersion), releaseOverrides.Prefix, releaseOverrides.Suffix) + changelogData := changelog.New(commitparser.ByType(analyzedCommitsForChangelog), nextVersion, rp.forge.ReleaseURL(nextVersion), releaseOverrides.Prefix, releaseOverrides.Suffix) changelogEntry, err := changelog.Entry(logger, changelog.DefaultTemplate(), changelogData, changelog.Formatting{}) if err != nil { @@ -330,3 +320,28 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error { return nil } + +func (rp *ReleaserPleaser) analyzedCommitsSince(ctx context.Context, since *git.Tag) ([]commitparser.AnalyzedCommit, error) { + logger := rp.logger.With("method", "analyzedCommitsSince", "tag.hash", since.Hash, "tag.name", since.Name) + + commits, err := rp.forge.CommitsSince(ctx, since) + if err != nil { + return nil, err + } + + commits, err = parsePRBodyForCommitOverrides(commits) + if err != nil { + return nil, err + } + + logger.InfoContext(ctx, "Found releasable commits", "length", len(commits)) + + analyzedCommits, err := rp.commitParser.Analyze(commits) + if err != nil { + return nil, err + } + + logger.InfoContext(ctx, "Analyzed commits", "length", len(analyzedCommits)) + + return analyzedCommits, nil +}