Skip to content

Commit 2508725

Browse files
Implement support for fallback tag prefixes (#793)
* Implement support for fallback tag prefixes * Update docs
1 parent 91ce0b9 commit 2508725

File tree

16 files changed

+185
-72
lines changed

16 files changed

+185
-72
lines changed

docs/configuration/version.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ calculating current version. Prefix can be set using
3333

3434
Default prefix is `v`.
3535

36+
In case a tag does not match the main prefix, fallback prefixes will be examined. You can use fallback prefixes to migrate from one prefix to another. For example, if you use prefix `my-service-` but want to migrate to prefix `v`, you can configure it like that:
37+
38+
scmVersion {
39+
tag {
40+
prefix.set("v")
41+
fallbackPrefixes.set(listOf("my-service-"))
42+
}
43+
}
44+
45+
Axion will use fallback prefixes to calculate latest version, but the next release tag will be created using the main prefix.
46+
3647
There is also an option to set prefix per-branch (i.e. to use different
3748
version prefix on `legacy-` branches):
3849

src/main/groovy/pl/allegro/tech/build/axion/release/domain/TagNameSerializationConfig.groovy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package pl.allegro.tech.build.axion.release.domain
22

3+
import org.gradle.api.provider.ListProperty
34
import org.gradle.api.provider.MapProperty
45
import org.gradle.api.provider.Property
56
import org.gradle.api.tasks.Input
@@ -15,6 +16,7 @@ abstract class TagNameSerializationConfig extends BaseExtension {
1516
deserialize.convention(TagNameSerializer.DEFAULT.deserializer)
1617
initialVersion.convention(defaultInitialVersion())
1718
prefix.convention(TagPrefixConf.defaultPrefix())
19+
fallbackPrefixes.convention(Collections.emptyList())
1820
versionSeparator.convention(TagPrefixConf.defaultSeparator())
1921
}
2022

@@ -24,6 +26,9 @@ abstract class TagNameSerializationConfig extends BaseExtension {
2426
@Input
2527
abstract MapProperty<String, String> getBranchPrefix()
2628

29+
@Input
30+
abstract ListProperty<String> getFallbackPrefixes()
31+
2732
@Input
2833
abstract Property<String> getVersionSeparator()
2934

src/main/groovy/pl/allegro/tech/build/axion/release/domain/TagNameSerializer.groovy

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@ import pl.allegro.tech.build.axion.release.domain.scm.ScmPosition
66
enum TagNameSerializer {
77

88
DEFAULT('default',
9-
{ TagProperties rules, String version ->
10-
return rules.prefix ? rules.prefix + rules.versionSeparator + version : version
11-
},
12-
{ TagProperties rules, ScmPosition position, String tagName ->
13-
if (rules.prefix.isEmpty()) {
14-
return tagName
9+
{ TagProperties rules, String version ->
10+
return rules.prefix ? rules.prefix + rules.versionSeparator + version : version
11+
},
12+
{ TagProperties rules, ScmPosition position, String tagName ->
13+
if (rules.prefix.isEmpty()) {
14+
return tagName
15+
}
16+
for (String prefix : rules.allPrefixes) {
17+
if (tagName.matches("^" + prefix + rules.versionSeparator + ".*")) {
18+
return tagName.substring(prefix.length() + rules.versionSeparator.length())
1519
}
16-
return tagName.substring(rules.prefix.length() + rules.versionSeparator.length())
1720
}
21+
}
1822
)
1923

2024
private final String type

src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/DummyRepository.groovy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,19 @@ class DummyRepository implements ScmRepository {
6969
}
7070

7171
@Override
72-
TagsOnCommit latestTags(Pattern pattern) {
72+
TagsOnCommit latestTags(List<Pattern> patterns) {
7373
logger.quiet("Could not resolve current position on uninitialized repository, returning default")
7474
return new TagsOnCommit(null, [])
7575
}
7676

7777
@Override
78-
TagsOnCommit latestTags(Pattern pattern, String sinceCommit) {
78+
TagsOnCommit latestTags(List<Pattern> patterns, String sinceCommit) {
7979
logger.quiet("Could not resolve current position on uninitialized repository, returning default")
8080
return new TagsOnCommit(null, [])
8181
}
8282

8383
@Override
84-
List<TagsOnCommit> taggedCommits(Pattern pattern) {
84+
List<TagsOnCommit> taggedCommits(List<Pattern> patterns) {
8585
logger.quiet("Could not resolve current position on uninitialized repository, returning default")
8686
return [new TagsOnCommit(null, [])]
8787
}

src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/NoOpRepository.groovy

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,22 @@ class NoOpRepository implements ScmRepository {
6464
}
6565

6666
@Override
67-
TagsOnCommit latestTags(Pattern pattern) {
68-
TagsOnCommit tags = delegateRepository.latestTags(pattern)
67+
TagsOnCommit latestTags(List<Pattern> patterns) {
68+
TagsOnCommit tags = delegateRepository.latestTags(patterns)
6969
log("Latest tags: ${tags.tags}")
7070
return tags
7171
}
7272

7373
@Override
74-
TagsOnCommit latestTags(Pattern pattern, String sinceCommit) {
75-
TagsOnCommit tags = delegateRepository.latestTags(pattern, sinceCommit)
74+
TagsOnCommit latestTags(List<Pattern> patterns, String sinceCommit) {
75+
TagsOnCommit tags = delegateRepository.latestTags(patterns, sinceCommit)
7676
log("Latest tags: ${tags.tags}")
7777
return tags
7878
}
7979

8080
@Override
81-
List<TagsOnCommit> taggedCommits(Pattern pattern) {
82-
return delegateRepository.taggedCommits(pattern)
81+
List<TagsOnCommit> taggedCommits(List<Pattern> patterns) {
82+
return delegateRepository.taggedCommits(patterns)
8383
}
8484

8585
@Override

src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/TagPropertiesFactory.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class TagPropertiesFactory {
1010
static TagProperties create(TagNameSerializationConfig config, String currentBranch) {
1111
return new TagProperties(
1212
findPrefix(config, currentBranch),
13+
config.fallbackPrefixes.get(),
1314
config.versionSeparator.get(),
1415
config.serialize.get(),
1516
config.deserialize.get(),

src/main/java/pl/allegro/tech/build/axion/release/domain/VersionResolver.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
import pl.allegro.tech.build.axion.release.domain.scm.ScmRepository;
99
import pl.allegro.tech.build.axion.release.domain.scm.TaggedCommits;
1010

11+
import java.util.List;
1112
import java.util.regex.Pattern;
1213

14+
import static java.util.stream.Collectors.toList;
15+
1316
/**
1417
* Returned structure is:
1518
* * previousVersion: version read from last release tag
@@ -65,25 +68,23 @@ private VersionInfo readVersions(
6568
ScmPosition latestChangePosition
6669
) {
6770

68-
String releaseTagPatternString = tagProperties.getPrefix();
69-
if (!releaseTagPatternString.isEmpty()) {
70-
releaseTagPatternString += tagProperties.getVersionSeparator();
71-
}
72-
73-
Pattern releaseTagPattern = Pattern.compile("^" + releaseTagPatternString + ".*");
71+
List<Pattern> releaseTagPatterns = tagProperties.getAllPrefixes().stream()
72+
.map(prefix -> prefix.isEmpty() ? "" : prefix + tagProperties.getVersionSeparator())
73+
.map(pattern -> Pattern.compile("^" + pattern + ".*"))
74+
.collect(toList());
7475
Pattern nextVersionTagPattern = Pattern.compile(".*" + nextVersionProperties.getSuffix() + "$");
7576
boolean forceSnapshot = versionProperties.isForceSnapshot();
7677
boolean useHighestVersion = versionProperties.isUseHighestVersion();
7778

7879
TaggedCommits latestTaggedCommit;
7980
TaggedCommits previousTaggedCommit;
8081
if (useHighestVersion) {
81-
TaggedCommits allTaggedCommits = TaggedCommits.fromAllCommits(repository, releaseTagPattern, latestChangePosition);
82+
TaggedCommits allTaggedCommits = TaggedCommits.fromAllCommits(repository, releaseTagPatterns, latestChangePosition);
8283
latestTaggedCommit = allTaggedCommits;
8384
previousTaggedCommit = allTaggedCommits;
8485
} else {
85-
latestTaggedCommit = TaggedCommits.fromLatestCommit(repository, releaseTagPattern, latestChangePosition);
86-
previousTaggedCommit = TaggedCommits.fromLatestCommitBeforeNextVersion(repository, releaseTagPattern, nextVersionTagPattern, latestChangePosition);
86+
latestTaggedCommit = TaggedCommits.fromLatestCommit(repository, releaseTagPatterns, latestChangePosition);
87+
previousTaggedCommit = TaggedCommits.fromLatestCommitBeforeNextVersion(repository, releaseTagPatterns, nextVersionTagPattern, latestChangePosition);
8788
}
8889

8990
VersionSorter.Result currentVersionInfo = versionFromTaggedCommits(latestTaggedCommit, false, nextVersionTagPattern, versionFactory, forceSnapshot);

src/main/java/pl/allegro/tech/build/axion/release/domain/properties/TagProperties.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
import pl.allegro.tech.build.axion.release.domain.scm.ScmPosition;
44

5+
import java.util.List;
6+
import java.util.stream.Stream;
7+
8+
import static java.util.stream.Collectors.toList;
9+
510
public class TagProperties {
611

712
public interface Serializer {
@@ -17,19 +22,22 @@ public interface InitialVersionSupplier {
1722
}
1823

1924
private final String prefix;
25+
private final List<String> fallbackPrefixes;
2026
private final String versionSeparator;
2127
private final Serializer serialize;
2228
private final Deserializer deserialize;
2329
private final InitialVersionSupplier initialVersion;
2430

2531
public TagProperties(
2632
String prefix,
33+
List<String> fallbackPrefixes,
2734
String versionSeparator,
2835
Serializer serialize,
2936
Deserializer deserialize,
3037
InitialVersionSupplier initialVersion
3138
) {
3239
this.prefix = prefix;
40+
this.fallbackPrefixes = fallbackPrefixes;
3341
this.versionSeparator = versionSeparator;
3442
this.serialize = serialize;
3543
this.deserialize = deserialize;
@@ -40,6 +48,17 @@ public final String getPrefix() {
4048
return prefix;
4149
}
4250

51+
public final List<String> getFallbackPrefixes() {
52+
return fallbackPrefixes;
53+
}
54+
55+
public final List<String> getAllPrefixes() {
56+
return Stream.concat(
57+
Stream.of(prefix), // main prefix takes precedence
58+
fallbackPrefixes.stream()
59+
).collect(toList());
60+
}
61+
4362
public final String getVersionSeparator() {
4463
return versionSeparator;
4564
}

src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmRepository.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ public interface ScmRepository {
2424

2525
Boolean isIdenticalForPath(String path, String latestChangeRevision, String tagCommitRevision);
2626

27-
TagsOnCommit latestTags(Pattern pattern);
27+
TagsOnCommit latestTags(List<Pattern> patterns);
2828

29-
TagsOnCommit latestTags(Pattern pattern, String sinceCommit);
29+
TagsOnCommit latestTags(List<Pattern> patterns, String sinceCommit);
3030

31-
List<TagsOnCommit> taggedCommits(Pattern pattern);
31+
List<TagsOnCommit> taggedCommits(List<Pattern> patterns);
3232

3333
boolean remoteAttached(String remoteName);
3434

src/main/java/pl/allegro/tech/build/axion/release/domain/scm/TaggedCommits.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,20 @@ public static TaggedCommits fromListOfCommits(ScmPosition latestTagPosition, Lis
1818
return new TaggedCommits(latestTagPosition, taggedCommits);
1919
}
2020

21-
public static TaggedCommits fromLatestCommit(ScmRepository repository, Pattern tagPattern, ScmPosition latestTagPosition) {
22-
TagsOnCommit latestTags = repository.latestTags(tagPattern);
21+
public static TaggedCommits fromLatestCommit(ScmRepository repository, List<Pattern> relaseTagPatterns, ScmPosition latestTagPosition) {
22+
TagsOnCommit latestTags = repository.latestTags(relaseTagPatterns);
2323
return new TaggedCommits(latestTagPosition, Arrays.asList(latestTags));
2424
}
2525

26-
public static TaggedCommits fromAllCommits(ScmRepository repository, Pattern tagPattern, ScmPosition latestTagPosition) {
27-
List<TagsOnCommit> taggedCommits = repository.taggedCommits(tagPattern);
26+
public static TaggedCommits fromAllCommits(ScmRepository repository, List<Pattern> releaseTagPatterns, ScmPosition latestTagPosition) {
27+
List<TagsOnCommit> taggedCommits = repository.taggedCommits(releaseTagPatterns);
2828
return new TaggedCommits(latestTagPosition, taggedCommits);
2929
}
3030

31-
public static TaggedCommits fromLatestCommitBeforeNextVersion(ScmRepository repository, Pattern releaseTagPattern, Pattern nextVersionTagPattern, ScmPosition latestTagPosition) {
32-
TagsOnCommit previousTags = repository.latestTags(releaseTagPattern);
31+
public static TaggedCommits fromLatestCommitBeforeNextVersion(ScmRepository repository, List<Pattern> releaseTagPatterns, Pattern nextVersionTagPattern, ScmPosition latestTagPosition) {
32+
TagsOnCommit previousTags = repository.latestTags(releaseTagPatterns);
3333
while (previousTags.hasOnlyMatching(nextVersionTagPattern)) {
34-
previousTags = repository.latestTags(releaseTagPattern, previousTags.getCommitId());
34+
previousTags = repository.latestTags(releaseTagPatterns, previousTags.getCommitId());
3535
}
3636
return new TaggedCommits(latestTagPosition, Arrays.asList(previousTags));
3737
}

src/main/java/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepository.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -399,26 +399,26 @@ private String branchNameFromGit() {
399399
}
400400

401401
@Override
402-
public TagsOnCommit latestTags(Pattern pattern) {
403-
return latestTagsInternal(pattern, null, true);
402+
public TagsOnCommit latestTags(List<Pattern> patterns) {
403+
return latestTagsInternal(patterns, null, true);
404404
}
405405

406406
@Override
407-
public TagsOnCommit latestTags(Pattern pattern, String sinceCommit) {
408-
return latestTagsInternal(pattern, sinceCommit, false);
407+
public TagsOnCommit latestTags(List<Pattern> patterns, String sinceCommit) {
408+
return latestTagsInternal(patterns, sinceCommit, false);
409409
}
410410

411-
private TagsOnCommit latestTagsInternal(Pattern pattern, String maybeSinceCommit, boolean inclusive) {
412-
List<TagsOnCommit> taggedCommits = taggedCommitsInternal(pattern, maybeSinceCommit, inclusive, true);
411+
private TagsOnCommit latestTagsInternal(List<Pattern> patterns, String maybeSinceCommit, boolean inclusive) {
412+
List<TagsOnCommit> taggedCommits = taggedCommitsInternal(patterns, maybeSinceCommit, inclusive, true);
413413
return taggedCommits.isEmpty() ? TagsOnCommit.empty() : taggedCommits.get(0);
414414
}
415415

416416
@Override
417-
public List<TagsOnCommit> taggedCommits(Pattern pattern) {
418-
return taggedCommitsInternal(pattern, null, true, false);
417+
public List<TagsOnCommit> taggedCommits(List<Pattern> patterns) {
418+
return taggedCommitsInternal(patterns, null, true, false);
419419
}
420420

421-
private List<TagsOnCommit> taggedCommitsInternal(Pattern pattern, String maybeSinceCommit, boolean inclusive, boolean stopOnFirstTag) {
421+
private List<TagsOnCommit> taggedCommitsInternal(List<Pattern> patterns, String maybeSinceCommit, boolean inclusive, boolean stopOnFirstTag) {
422422
List<TagsOnCommit> taggedCommits = new ArrayList<>();
423423
if (!hasCommits()) {
424424
return taggedCommits;
@@ -440,7 +440,7 @@ private List<TagsOnCommit> taggedCommitsInternal(Pattern pattern, String maybeSi
440440
walk.next();
441441
}
442442

443-
Map<String, List<String>> allTags = tagsMatching(pattern, walk);
443+
Map<String, List<String>> allTags = tagsMatching(patterns, walk);
444444

445445
while (true) {
446446
RevCommit currentCommit = walk.next();
@@ -484,15 +484,15 @@ private RevWalk walker(ObjectId startingCommit) throws IOException {
484484
return walk;
485485
}
486486

487-
private Map<String, List<String>> tagsMatching(Pattern pattern, RevWalk walk) throws GitAPIException {
487+
private Map<String, List<String>> tagsMatching(List<Pattern> patterns, RevWalk walk) throws GitAPIException {
488488
List<Ref> tags = jgitRepository.tagList().call();
489489

490490
return tags.stream()
491491
.map(tag -> new TagNameAndId(
492492
tag.getName().substring(GIT_TAG_PREFIX.length()),
493493
parseCommitSafe(walk, tag.getObjectId())
494494
))
495-
.filter(t -> pattern.matcher(t.name).matches())
495+
.filter(t -> patterns.stream().anyMatch(pattern -> pattern.matcher(t.name).matches()))
496496
.collect(
497497
HashMap::new,
498498
(m, t) -> m.computeIfAbsent(t.id, (s) -> new ArrayList<>()).add(t.name),

src/test/groovy/pl/allegro/tech/build/axion/release/domain/NextVersionMarkerTest.groovy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class NextVersionMarkerTest extends RepositoryBasedTest {
4444
nextVersionMarker.markNextVersion(rules, tagRules, config)
4545

4646
then:
47-
repository.latestTags(~/.*/).tags == [fullPrefix() + '2.0.0-alpha']
47+
repository.latestTags(List.of(~/.*/)).tags == [fullPrefix() + '2.0.0-alpha']
4848
}
4949

5050
def "should create next version with default incrementer"() {
@@ -56,7 +56,7 @@ class NextVersionMarkerTest extends RepositoryBasedTest {
5656
nextVersionMarker.markNextVersion(rules, tagRules, config)
5757

5858
then:
59-
repository.latestTags(~/.*/).tags == [fullPrefix() + '0.1.1-alpha']
59+
repository.latestTags(List.of(~/.*/)).tags == [fullPrefix() + '0.1.1-alpha']
6060
}
6161

6262
def "should create next version with major incrementer"() {
@@ -70,6 +70,6 @@ class NextVersionMarkerTest extends RepositoryBasedTest {
7070
nextVersionMarker.markNextVersion(rules, tagRules, config)
7171

7272
then:
73-
repository.latestTags(~/.*/).tags == [fullPrefix() + '1.0.0-alpha']
73+
repository.latestTags(List.of(~/.*/)).tags == [fullPrefix() + '1.0.0-alpha']
7474
}
7575
}

0 commit comments

Comments
 (0)