fix: invalid version for subsequent pre-releases (#174)

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.
This commit is contained in:
Julian Tölle 2025-05-22 15:27:49 +02:00 committed by GitHub
parent 9c95dd558b
commit d9c081d280
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -179,34 +179,16 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
logger.InfoContext(ctx, "no latest tag found") logger.InfoContext(ctx, "no latest tag found")
} }
// By default, we want to show everything that has happened since the last stable release // For stable releases, we want to consider all changes since the last stable release for version and changelog.
lastReleaseCommit := releases.Stable // For prereleases, we want to consider all changes...
if releaseOverrides.NextVersionType.IsPrerelease() { // - since the last stable release for the version
// if the new release will be a prerelease, // - since the latest release (stable or prerelease) for the changelog
// only show changes since the latest release (stable or prerelease) analyzedCommitsForVersioning, err := rp.analyzedCommitsSince(ctx, releases.Stable)
lastReleaseCommit = releases.Latest
}
commits, err := rp.forge.CommitsSince(ctx, lastReleaseCommit)
if err != nil { if err != nil {
return err return err
} }
commits, err = parsePRBodyForCommitOverrides(commits) if len(analyzedCommitsForVersioning) == 0 {
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 pr != nil { if pr != nil {
logger.InfoContext(ctx, "closing existing pull requests, no commits available", "pr.id", pr.ID, "pr.title", pr.Title) logger.InfoContext(ctx, "closing existing pull requests, no commits available", "pr.id", pr.ID, "pr.title", pr.Title)
err = rp.forge.ClosePullRequest(ctx, pr) err = rp.forge.ClosePullRequest(ctx, pr)
@ -220,7 +202,7 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
return nil return nil
} }
versionBump := versioning.BumpFromCommits(analyzedCommits) versionBump := versioning.BumpFromCommits(analyzedCommitsForVersioning)
// TODO: Set version in release pr // TODO: Set version in release pr
nextVersion, err := rp.versioning.NextVersion(releases, versionBump, releaseOverrides.NextVersionType) nextVersion, err := rp.versioning.NextVersion(releases, versionBump, releaseOverrides.NextVersionType)
if err != nil { if err != nil {
@ -228,6 +210,14 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
} }
logger.InfoContext(ctx, "next version", "version", nextVersion) 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()) logger.DebugContext(ctx, "cloning repository", "clone.url", rp.forge.CloneURL())
repo, err := git.CloneRepo(ctx, logger, rp.forge.CloneURL(), rp.targetBranch, rp.forge.GitAuth()) repo, err := git.CloneRepo(ctx, logger, rp.forge.CloneURL(), rp.targetBranch, rp.forge.GitAuth())
if err != nil { if err != nil {
@ -242,7 +232,7 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
return err 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{}) changelogEntry, err := changelog.Entry(logger, changelog.DefaultTemplate(), changelogData, changelog.Formatting{})
if err != nil { if err != nil {
@ -330,3 +320,28 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
return nil 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
}