Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/strategies/java.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export class Java extends BaseStrategy {
): Promise<ReleasePullRequest> {
const component = await this.getComponent();
const newVersion = latestRelease
? await this.snapshotVersioning.bump(latestRelease.tag.version, [])
? this.snapshotVersioning.bump(latestRelease.tag.version, [])
: this.initialReleaseVersion();
const versionsMap = await this.buildVersionsMap([]);
for (const [component, version] of versionsMap.entries()) {
Expand Down
27 changes: 26 additions & 1 deletion src/versioning-strategies/java-add-snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ class AddSnapshotVersionUpdate implements VersionUpdater {
this.strategy = strategy;
}
bump(version: Version): Version {
const nextPatch = this.strategy.bump(version, [fakeCommit]);
// If the released version is a release candidate, we omit the fake commit approach and simply
// bump -rc(n) to -rc(n+1).
const [didBumpRc, bumpedRcVersion] = this.bumpReleaseCandidate(version);
const nextPatch = didBumpRc
? bumpedRcVersion
: this.strategy.bump(version, [fakeCommit]);
return new Version(
nextPatch.major,
nextPatch.minor,
Expand All @@ -43,6 +48,26 @@ class AddSnapshotVersionUpdate implements VersionUpdater {
nextPatch.build
);
}
bumpReleaseCandidate(version: Version): [boolean, Version] {
const rcRegex = /rc(?<rcNumber>\d+)/;
if (!version.preRelease?.match(rcRegex)) {
return [false, version];
}
let preRelease = version.preRelease;
const match = preRelease.match(rcRegex)!;
const newRcNumber = parseInt(match.groups!.rcNumber) + 1;
preRelease = preRelease.replace(rcRegex, `rc${newRcNumber}`);
return [
true,
new Version(
version.major,
version.minor,
version.patch,
preRelease,
version.build
),
];
}
}

/**
Expand Down
22 changes: 19 additions & 3 deletions src/versioning-strategies/java-snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,17 @@ class RemoveSnapshotVersionUpdate implements VersionUpdater {
this.parent = parent;
}
bump(version: Version): Version {
let preRelease = version.preRelease;
if (this.parent) {
version = this.parent.bump(version);
// reset the release candidate number after a bump
preRelease = version.preRelease?.replace(/rc\d+/, 'rc1');
}
return new Version(
version.major,
version.minor,
version.patch,
version.preRelease
? version.preRelease.replace(/-?SNAPSHOT/, '')
: undefined,
preRelease?.replace(/-?SNAPSHOT/, ''),
version.build
);
}
Expand All @@ -63,17 +64,32 @@ export class JavaSnapshot implements VersioningStrategy {
version: Version,
commits: ConventionalCommit[]
): VersionUpdater {
// Determine the release type from the parent strategy based on the commits.
const parentBump = this.strategy.determineReleaseType(version, commits);

// If the current version is a snapshot, we need to handle it specially.
if (version.preRelease?.match(/-?SNAPSHOT/)) {
// To check if the only change is the snapshot removal, we simulate a patch bump.
// We create a fake commit that would cause a patch bump and see what version the parent strategy would return.
const patchBumpVersion = this.strategy
.determineReleaseType(version, [fakeCommit])
.bump(version);

// We then get the version that the parent strategy would return with the actual commits.
const parentBumpVersion = parentBump.bump(version);

// If the parent bump version is the same as the patch bump version,
// it means that the commits only triggered a patch bump.
// In this case, we only need to remove the "-SNAPSHOT" from the version.
if (patchBumpVersion.toString() === parentBumpVersion.toString()) {
return new RemoveSnapshotVersionUpdate();
}
// If the parent bump version is different from the patch bump version,
// it means that the commits triggered a minor or major bump.
// In this case, we need to both apply the parent bump and remove the "-SNAPSHOT".
return new RemoveSnapshotVersionUpdate(parentBump);
}
// If the current version is not a snapshot, we just return the parent bump.
return parentBump;
}

Expand Down
28 changes: 28 additions & 0 deletions test/strategies/java.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,34 @@ describe('Java', () => {
assertNoHasUpdate(release!.updates, 'CHANGELOG.md');
});

it('returns an rc number bump snapshot PR', async () => {
const strategy = new Java({
targetBranch: 'main',
github,
});

const latestRelease = {
tag: new TagName(Version.parse('2.3.3-rc1')),
sha: 'abc123',
notes: 'some notes',
};
const release = await strategy.buildReleasePullRequest(
COMMITS_NO_SNAPSHOT,
latestRelease,
false,
DEFAULT_LABELS
);

expect(release?.version?.toString()).to.eql('2.3.3-rc2-SNAPSHOT');
expect(release?.title.toString()).to.eql(
'chore(main): release 2.3.3-rc2-SNAPSHOT'
);
expect(release?.headRefName).to.eql('release-please--branches--main');
expect(release?.draft).to.eql(false);
expect(release?.labels).to.eql(DEFAULT_SNAPSHOT_LABELS);
assertNoHasUpdate(release!.updates, 'CHANGELOG.md');
});

it('skips a snapshot bump PR', async () => {
const strategy = new Java({
targetBranch: 'main',
Expand Down
131 changes: 129 additions & 2 deletions test/versioning-strategies/java.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,34 @@ describe('JavaVersioningStrategy', () => {
new DefaultVersioningStrategy({bumpMinorPreMajor: true})
);
const oldVersion = Version.parse('0.1.2-SNAPSHOT');
const newVersion = await strategy.bump(oldVersion, breakingCommits);
const newVersion = strategy.bump(oldVersion, breakingCommits);
expect(newVersion.toString()).to.equal('0.2.0');
});

describe('with release candidate qualifier', () => {
it('can bump a major', async () => {
const strategy = new JavaSnapshot(new DefaultVersioningStrategy({}));
const oldVersion = Version.parse('1.2.0-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, breakingCommits);
expect(newVersion.toString()).to.equal('2.0.0-rc1');
});

it('can bump a major on pre major for breaking change', async () => {
const strategy = new JavaSnapshot(new DefaultVersioningStrategy({}));
const oldVersion = Version.parse('0.1.2-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, breakingCommits);
expect(newVersion.toString()).to.equal('1.0.0-rc1');
});

it('can bump a minor pre major for breaking change', async () => {
const strategy = new JavaSnapshot(
new DefaultVersioningStrategy({bumpMinorPreMajor: true})
);
const oldVersion = Version.parse('0.1.2-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, breakingCommits);
expect(newVersion.toString()).to.equal('0.2.0-rc1');
});
});
});

describe('with a feature', () => {
Expand All @@ -166,6 +191,30 @@ describe('JavaVersioningStrategy', () => {
const newVersion = await strategy.bump(oldVersion, featureCommits);
expect(newVersion.toString()).to.equal('0.1.2');
});
describe('with release candidate qualifier', () => {
it('can bump a minor', async () => {
const strategy = new JavaSnapshot(new DefaultVersioningStrategy({}));
const oldVersion = Version.parse('1.2.3-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, featureCommits);
expect(newVersion.toString()).to.equal('1.3.0-rc1');
});
it('can bump a minor pre-major', async () => {
const strategy = new JavaSnapshot(new DefaultVersioningStrategy({}));
const oldVersion = Version.parse('0.1.2-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, featureCommits);
expect(newVersion.toString()).to.equal('0.2.0-rc1');
});
it('can bump a patch pre-major', async () => {
const strategy = new JavaSnapshot(
new DefaultVersioningStrategy({
bumpPatchForMinorPreMajor: true,
})
);
const oldVersion = Version.parse('0.1.2-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, featureCommits);
expect(newVersion.toString()).to.equal('0.1.2-rc2');
});
});
});

describe('with a fix', () => {
Expand All @@ -175,6 +224,12 @@ describe('JavaVersioningStrategy', () => {
const newVersion = await strategy.bump(oldVersion, fixCommits);
expect(newVersion.toString()).to.equal('1.2.3');
});
it('can bump a patch with release candidate qualifier', async () => {
const strategy = new JavaSnapshot(new DefaultVersioningStrategy({}));
const oldVersion = Version.parse('1.2.3-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, fixCommits);
expect(newVersion.toString()).to.equal('1.2.3-rc2');
});
});
});

Expand Down Expand Up @@ -291,6 +346,30 @@ describe('JavaVersioningStrategy', () => {
const newVersion = await strategy.bump(oldVersion, breakingCommits);
expect(newVersion.toString()).to.equal('0.1.2');
});
describe('with release candidate qualifier', () => {
it('can bump a major', async () => {
const strategy = new JavaSnapshot(new AlwaysBumpPatch({}));
const oldVersion = Version.parse('1.2.3-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, breakingCommits);
expect(newVersion.toString()).to.equal('1.2.3-rc2');
});

it('can bump a major on pre major for breaking change', async () => {
const strategy = new JavaSnapshot(new AlwaysBumpPatch({}));
const oldVersion = Version.parse('0.1.2-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, breakingCommits);
expect(newVersion.toString()).to.equal('0.1.2-rc2');
});

it('can bump a minor pre major for breaking change', async () => {
const strategy = new JavaSnapshot(
new AlwaysBumpPatch({bumpMinorPreMajor: true})
);
const oldVersion = Version.parse('0.1.2-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, breakingCommits);
expect(newVersion.toString()).to.equal('0.1.2-rc2');
});
});
});

describe('with a feature', () => {
Expand All @@ -316,13 +395,37 @@ describe('JavaVersioningStrategy', () => {
const newVersion = await strategy.bump(oldVersion, featureCommits);
expect(newVersion.toString()).to.equal('0.1.2');
});
describe('with release candidate qualifier', () => {
it('can bump a minor', async () => {
const strategy = new JavaSnapshot(new AlwaysBumpPatch({}));
const oldVersion = Version.parse('1.2.3-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, featureCommits);
expect(newVersion.toString()).to.equal('1.2.3-rc2');
});

it('can bump a minor on pre major for breaking change', async () => {
const strategy = new JavaSnapshot(new AlwaysBumpPatch({}));
const oldVersion = Version.parse('0.1.2-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, featureCommits);
expect(newVersion.toString()).to.equal('0.1.2-rc2');
});

it('can bump a minor pre major for breaking change', async () => {
const strategy = new JavaSnapshot(
new AlwaysBumpPatch({bumpMinorPreMajor: true})
);
const oldVersion = Version.parse('0.1.2-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, featureCommits);
expect(newVersion.toString()).to.equal('0.1.2-rc2');
});
});
});

describe('with a fix', () => {
it('can bump a patch', async () => {
const strategy = new JavaSnapshot(new AlwaysBumpPatch({}));
const oldVersion = Version.parse('1.2.3-SNAPSHOT');
const newVersion = await strategy.bump(oldVersion, fixCommits);
const newVersion = strategy.bump(oldVersion, fixCommits);
expect(newVersion.toString()).to.equal('1.2.3');
});

Expand All @@ -341,6 +444,30 @@ describe('JavaVersioningStrategy', () => {
const newVersion = await strategy.bump(oldVersion, fixCommits);
expect(newVersion.toString()).to.equal('0.1.2');
});
describe('with release candidate qualifier', () => {
it('can bump a patch', async () => {
const strategy = new JavaSnapshot(new AlwaysBumpPatch({}));
const oldVersion = Version.parse('1.2.3-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, fixCommits);
expect(newVersion.toString()).to.equal('1.2.3-rc2');
});

it('can bump a patch on pre major for breaking change', async () => {
const strategy = new JavaSnapshot(new AlwaysBumpPatch({}));
const oldVersion = Version.parse('0.1.2-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, fixCommits);
expect(newVersion.toString()).to.equal('0.1.2-rc2');
});

it('can bump a patch pre major for breaking change', async () => {
const strategy = new JavaSnapshot(
new AlwaysBumpPatch({bumpMinorPreMajor: true})
);
const oldVersion = Version.parse('0.1.2-rc2-SNAPSHOT');
const newVersion = strategy.bump(oldVersion, fixCommits);
expect(newVersion.toString()).to.equal('0.1.2-rc2');
});
});
});
});
});
Loading