Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/use global version #342

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
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
35 changes: 35 additions & 0 deletions docs/configuration/version.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,41 @@ You can also active this option using command line:
# ./gradlew currentVersion -Prelease.useHighestVersion
1.5.0

### Search tags globally
Search all tags, in all branches to find the next release number. Use this if you want incrementing numbers across branches.

In order to activate this feature:

scmVersion {
useGlobalVersion = true
}

Take this tree as an example:

```
[T1]
|
|     |
[T2] [T3]
|     |
[C] [_]
```

Let `T*` be a tagged commit and `C` the current commit. After releasing
version with tag `T1`, we have been working on two separate branches.
Then, branch on the right has been released and marked with `T3` tag, and the branch on the left has been released with `T2` tag.
When traversing *all* tags in this tree, `T3` will be reported as the highest tag, and so reported version will come from parsing `T3` tag, even though tag `T2` is the highest number on the *current* branch.

If you had been using `useHighestVersion`, the reported version would have come from `T2`

When using `useGlobalVersion`, the reported version will come from `T3`

You can also activate this feature in command line form

```
# ./gradlew currentVersion -Prelease.useGlobalVersion
```

## Parsing

Having current tag name, we can deserialize it to extract raw version.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package pl.allegro.tech.build.axion.release

import org.gradle.testkit.runner.TaskOutcome

class GlobalVersionIntegrationTest extends BaseIntegrationTest {
def "should return tag with highest version if useGlobalVersion is set to true"() {
given:
buildFile('')

runGradle('release', '-Prelease.version=1.0.0', '-Prelease.localOnly', '-Prelease.disableChecks')
runGradle('release', '-Prelease.version=1.5.0', '-Prelease.localOnly', '-Prelease.disableChecks')

repository.commit(['*'], "commit after release-1.5.0")

runGradle('release', '-Prelease.version=1.2.0', '-Prelease.localOnly', '-Prelease.disableChecks')

when:
def result = runGradle('currentVersion', '-Prelease.useGlobalVersion')

then:
result.output.contains('1.5.1-SNAPSHOT')
result.task(":currentVersion").outcome == TaskOutcome.SUCCESS
}

def "should resolve higher global version when on branch with higher version"() {
given:
buildFile('')
Fixtures.FixtureUseGlobalVersion.setupABranchWithHighTagAndBBranchWithLowTag(repository)
repository.checkout('high')

when:
def result = runGradle('currentVersion', '-Prelease.useGlobalVersion')

then:
result.output.contains('2.0.0')
result.task(":currentVersion").outcome == TaskOutcome.SUCCESS
}

def "should resolve higher global version when on branch with lower version"() {
given: 'I am on a branch with a low release tag'
buildFile('')
Fixtures.FixtureUseGlobalVersion.setupABranchWithHighTagAndBBranchWithLowTag(repository)
repository.checkout('low')

when:
def result = runGradle('currentVersion', '-Prelease.useGlobalVersion')

then:
result.output.contains('2.0.1')
result.task(":currentVersion").outcome == TaskOutcome.SUCCESS
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class VersionConfig {
@Input
boolean useHighestVersion = false

@Input
boolean useGlobalVersion = false

@Nested
RepositoryConfig repository

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ class DryRepository implements ScmRepository {
return new ScmPushResult(true, Optional.empty())
}

@Override
void branch(String name) {
log("creating branch: ${name}")
}

@Override
void checkout(String name) {
log("switching to branch: ${name}")
}

@Override
void commit(List patterns, String message) {
log("commiting files matching $patterns with message: $message")
Expand Down Expand Up @@ -81,6 +91,11 @@ class DryRepository implements ScmRepository {
return delegateRepository.taggedCommits(pattern)
}

@Override
List<TagsOnCommit> taggedCommitsGlobally(Pattern pattern) {
return delegateRepository.taggedCommitsGlobally(pattern)
}

@Override
boolean remoteAttached(String remoteName) {
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ class DummyRepository implements ScmRepository {
return new ScmPushResult(true, Optional.empty())
}

@Override
void branch(String name) {
log("creating branch: ${name}")
}

@Override
void checkout(String name) {
log("switching to branch: ${name}")
}

@Override
void commit(List patterns, String message) {
log('commit')
Expand Down Expand Up @@ -80,6 +90,11 @@ class DummyRepository implements ScmRepository {
return [new TagsOnCommit(null, [])]
}

@Override
List<TagsOnCommit> taggedCommitsGlobally(Pattern pattern) {
logger.quiet("Could not resolve current position on uninitialized repository, returning default")
return [new TagsOnCommit(null, [])]
}

@Override
boolean remoteAttached(String remoteName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class VersionPropertiesFactory {

private static final String USE_HIGHEST_VERSION_PROPERTY = 'release.useHighestVersion'

private static final String USE_GLOBAL_VERSION_PROPERTY = 'release.useGlobalVersion'

private static final String VERSION_INCREMENTER_PROPERTY = 'release.versionIncrementer'

private static final String VERSION_CREATOR_PROPERTY = 'release.versionCreator'
Expand All @@ -35,6 +37,8 @@ class VersionPropertiesFactory {

boolean useHighestVersion = project.hasProperty(USE_HIGHEST_VERSION_PROPERTY) ?: config.useHighestVersion

boolean useGlobalVersion = project.hasProperty(USE_GLOBAL_VERSION_PROPERTY) ?: config.useGlobalVersion

return new VersionProperties(
forceVersionValue?.trim() ? forceVersionValue.trim() : null,
forceSnapshot,
Expand All @@ -43,6 +47,7 @@ class VersionPropertiesFactory {
findVersionIncrementer(project, config, currentBranch),
config.sanitizeVersion,
useHighestVersion,
useGlobalVersion,
MonorepoPropertiesFactory.create(project, config.monorepoConfig, currentBranch)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
* * version read from last release tag when on tag
*/
public class VersionResolver {
private enum VersionReadingStrategy {
HIGHEST_VERSION,
GLOBAL_VERSION
}

private final ScmRepository repository;
private final VersionSorter sorter;
Expand All @@ -44,10 +48,12 @@ public VersionContext resolveVersion(VersionProperties versionProperties, TagPro
VersionFactory versionFactory = new VersionFactory(versionProperties, tagProperties, nextVersionProperties, latestChangePosition, repository.isLegacyDefTagnameRepo());

VersionInfo versions;
if (versionProperties.isUseHighestVersion()) {
versions = readVersionsByHighestVersion(versionFactory, tagProperties, nextVersionProperties, versionProperties, latestChangePosition);
if (versionProperties.isUseGlobalVersion()) {
versions = readVersionsByGlobalOrHighestVersion(versionFactory, tagProperties, nextVersionProperties, versionProperties, latestChangePosition, VersionReadingStrategy.GLOBAL_VERSION);
} else if (versionProperties.isUseHighestVersion()) {
versions = readVersionsByGlobalOrHighestVersion(versionFactory, tagProperties, nextVersionProperties, versionProperties, latestChangePosition, VersionReadingStrategy.HIGHEST_VERSION);
} else {
versions = readVersions(versionFactory, tagProperties, nextVersionProperties, versionProperties, latestChangePosition);
versions = readVersionsByFirstVersion(versionFactory, tagProperties, nextVersionProperties, versionProperties, latestChangePosition);
}


Expand All @@ -63,7 +69,7 @@ public VersionContext resolveVersion(VersionProperties versionProperties, TagPro
return new VersionContext(finalVersion.version, finalVersion.snapshot, versions.previous, latestChangePosition);
}

private VersionInfo readVersions(
private VersionInfo readVersionsByFirstVersion(
VersionFactory versionFactory,
TagProperties tagProperties,
NextVersionProperties nextVersionProperties,
Expand Down Expand Up @@ -106,19 +112,24 @@ private VersionInfo readVersions(
);
}

private VersionInfo readVersionsByHighestVersion(
private VersionInfo readVersionsByGlobalOrHighestVersion(
VersionFactory versionFactory,
final TagProperties tagProperties,
final NextVersionProperties nextVersionProperties,
VersionProperties versionProperties,
ScmPosition latestChangePosition
ScmPosition latestChangePosition,
VersionReadingStrategy versionReadingStrategy
) {

Pattern releaseTagPattern = Pattern.compile("^" + tagProperties.getPrefix() + ".*");
Pattern nextVersionTagPattern = Pattern.compile(".*" + nextVersionProperties.getSuffix() + "$");
boolean forceSnapshot = versionProperties.isForceSnapshot();

TaggedCommits allTaggedCommits = TaggedCommits.fromAllCommits(repository, releaseTagPattern, latestChangePosition);
TaggedCommits allTaggedCommits;
if (versionReadingStrategy == VersionReadingStrategy.HIGHEST_VERSION) {
allTaggedCommits = TaggedCommits.fromAllCommits(repository, releaseTagPattern, latestChangePosition);
} else {
allTaggedCommits = TaggedCommits.fromAllCommitsGlobally(repository, releaseTagPattern, latestChangePosition);
}

VersionSorter.Result currentVersionInfo = versionFromTaggedCommits(allTaggedCommits, false, nextVersionTagPattern, versionFactory, forceSnapshot);
VersionSorter.Result previousVersionInfo = versionFromTaggedCommits(allTaggedCommits, true, nextVersionTagPattern, versionFactory, forceSnapshot);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class VersionProperties {
private final Closure<Version> versionIncrementer;
private final boolean sanitizeVersion;
private final boolean useHighestVersion;
private final boolean useGlobalVersion;
private final MonorepoProperties monorepoProperties;

public VersionProperties(
Expand All @@ -22,6 +23,7 @@ public VersionProperties(
Closure<Version> versionIncrementer,
boolean sanitizeVersion,
boolean useHighestVersion,
boolean useGlobalVersion,
MonorepoProperties monorepoProperties
) {
this.forcedVersion = forcedVersion;
Expand All @@ -31,6 +33,7 @@ public VersionProperties(
this.versionIncrementer = versionIncrementer;
this.sanitizeVersion = sanitizeVersion;
this.useHighestVersion = useHighestVersion;
this.useGlobalVersion = useGlobalVersion;
this.monorepoProperties = monorepoProperties;
}

Expand Down Expand Up @@ -66,6 +69,8 @@ public final boolean isUseHighestVersion() {
return useHighestVersion;
}

public final boolean isUseGlobalVersion() { return useGlobalVersion; }

public MonorepoProperties getMonorepoProperties() {
return monorepoProperties;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ public interface ScmRepository {

ScmPushResult push(ScmIdentity identity, ScmPushOptions pushOptions);

void branch(String name);

void checkout(String name);

void commit(List<String> patterns, String message);

void attachRemote(String remoteName, String url);
Expand All @@ -27,6 +31,8 @@ public interface ScmRepository {

List<TagsOnCommit> taggedCommits(Pattern pattern);

List<TagsOnCommit> taggedCommitsGlobally(Pattern pattern);

boolean remoteAttached(String remoteName);

boolean checkUncommittedChanges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ public static TaggedCommits fromAllCommits(ScmRepository repository, Pattern tag
return new TaggedCommits(latestTagPosition, taggedCommits);
}

public static TaggedCommits fromAllCommitsGlobally(ScmRepository repository, Pattern tagPattern, ScmPosition latestTagPosition) {
List<TagsOnCommit> taggedCommits = repository.taggedCommitsGlobally(tagPattern);
return new TaggedCommits(latestTagPosition, taggedCommits);
}

public static TaggedCommits fromLatestCommitBeforeNextVersion(ScmRepository repository, Pattern releaseTagPattern, Pattern nextVersionTagPattern, ScmPosition latestTagPosition) {
TagsOnCommit previousTags = repository.latestTags(releaseTagPattern);
while (previousTags.hasOnlyMatching(nextVersionTagPattern)) {
Expand Down
Loading