From 46143b6b74618599a2e27002bbb8252772eb2a9f Mon Sep 17 00:00:00 2001 From: Bartosz Galek Date: Sat, 24 Aug 2024 21:06:21 +0200 Subject: [PATCH 1/4] #796 | releaseOnlyOnDefaultBranches & releaseBranchNames properties added --- docs/configuration/overview.md | 3 + docs/configuration/version.md | 92 +++++++++++++------ .../release/SimpleIntegrationTest.groovy | 45 +++++++++ .../build/axion/release/ReleaseTask.groovy | 15 ++- .../axion/release/domain/VersionConfig.groovy | 12 ++- .../config/ScmPropertiesFactory.groovy | 4 +- .../release/domain/scm/ScmProperties.java | 17 +++- .../axion/release/domain/scm/ScmService.java | 9 ++ .../axion/release/RepositoryBasedTest.groovy | 36 +++++--- .../release/TestConfigSystemReader.groovy | 65 +++++++++++++ .../domain/scm/ScmPropertiesBuilder.groovy | 4 +- .../git/GitRepositoryTest.groovy | 2 + 12 files changed, 258 insertions(+), 46 deletions(-) create mode 100644 src/test/groovy/pl/allegro/tech/build/axion/release/TestConfigSystemReader.groovy diff --git a/docs/configuration/overview.md b/docs/configuration/overview.md index 096b2212..8a47e9fb 100644 --- a/docs/configuration/overview.md +++ b/docs/configuration/overview.md @@ -74,6 +74,9 @@ All `axion-release-plugin` configuration options: uncommittedChanges.set(false) // permanently disable uncommitted changes check aheadOfRemote.set(false) // permanently disable ahead of remote check } + + // doc: + releaseOnlyOnReleaseBranches = false } All `axion-release-plugin` configuration flags: diff --git a/docs/configuration/version.md b/docs/configuration/version.md index df01fbe7..cfabbb30 100644 --- a/docs/configuration/version.md +++ b/docs/configuration/version.md @@ -4,15 +4,15 @@ parsing and decorating. Extracting version information from repository can be split in six phases: -- reading - read tags from repository -- parsing - extracting version from tag (serializing version to tag) -- incrementing - when not on tag, version patch (least significant) - number is incremented -- decorating - adding additional transformations to create final - version -- appending snapshot - when not on tag, -SNAPSHOT suffix is appended (can be customized) -- sanitization - making sure there are no unwanted characters in - version +- reading - read tags from repository +- parsing - extracting version from tag (serializing version to tag) +- incrementing - when not on tag, version patch (least significant) + number is incremented +- decorating - adding additional transformations to create final + version +- appending snapshot - when not on tag, -SNAPSHOT suffix is appended (can be customized) +- sanitization - making sure there are no unwanted characters in + version ## Reading @@ -33,7 +33,9 @@ calculating current version. Prefix can be set using Default prefix is `v`. -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: +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: scmVersion { tag { @@ -42,7 +44,8 @@ In case a tag does not match the main prefix, fallback prefixes will be examined } } -Axion will use fallback prefixes to calculate latest version, but the next release tag will be created using the main prefix. +Axion will use fallback prefixes to calculate latest version, but the next release tag will be created using the main +prefix. There is also an option to set prefix per-branch (i.e. to use different version prefix on `legacy-` branches): @@ -149,12 +152,12 @@ deserialization config object and position in SCM: `config` object is instance of `TagNameSerializationRules` class. Useful properties are: -- `prefix`: tag prefix -- `separator`: separator between prefix and version +- `prefix`: tag prefix +- `separator`: separator between prefix and version `position` object contains: -- `branch` - the name of the current branch +- `branch` - the name of the current branch Last but not least, `tagName` contains prepared tag name that should be used to extract version. `position.latestTag` might point to next @@ -200,13 +203,14 @@ Incrementing phase does increment the version in accordance with *version incrementer*. By default, version patch (least significant) number is incremented. There are other predefined rules: -- *incrementPatch* - increment patch number -- *incrementMinor* - increment minor (middle) number -- *incrementMajor* - increment major number -- *incrementMinorIfNotOnRelease* - increment patch number if on - release branch. Increment minor otherwise -- *incrementPrerelease* - increment pre-release suffix if possible - (-rc1 to -rc2). Add `initialPreReleaseIfNotOnPrerelease` to increment patch with pre-release version. Increment patch otherwise +- *incrementPatch* - increment patch number +- *incrementMinor* - increment minor (middle) number +- *incrementMajor* - increment major number +- *incrementMinorIfNotOnRelease* - increment patch number if on + release branch. Increment minor otherwise +- *incrementPrerelease* - increment pre-release suffix if possible + (-rc1 to -rc2). Add `initialPreReleaseIfNotOnPrerelease` to increment patch with pre-release version. Increment patch + otherwise You can set one of predefined rules via `scmVersion.versionIncrementer` method: @@ -235,10 +239,11 @@ would accept a context object and return a `Version` object: The context object passed to closure contains the following: -- *currentVersion* - current `Version` object that should be used to - calculate next version ([Version - API](https://github.com/zafarkhaja/jsemver/blob/1f4996ea3dab06193c378fd66fd4f8fdc8334cc6/src/main/java/com/github/zafarkhaja/semver/Version.java)) -- *position* - widely used position object, for more see [ScmPosition](https://github.com/allegro/axion-release-plugin/blob/main/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmPosition.java) +- *currentVersion* - current `Version` object that should be used to + calculate next version ([Version + API](https://github.com/zafarkhaja/jsemver/blob/1f4996ea3dab06193c378fd66fd4f8fdc8334cc6/src/main/java/com/github/zafarkhaja/semver/Version.java)) +- *position* - widely used position object, for more + see [ScmPosition](https://github.com/allegro/axion-release-plugin/blob/main/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmPosition.java) You can also specify different incrementers per branch. They can be either closure, name of predefined incrementer or name and list of @@ -273,6 +278,30 @@ This rule uses additional parameter `initialPreReleaseIfNotOnPrerelease` versionIncrementer('incrementPrerelease', [initialPreReleaseIfNotOnPrerelease: 'rc1']) } +### releaseOnlyOnReleaseBranches + +You can set this flag to true to prevent releasing on branches that are +not marked as release branches. By default, this flag is set to false. + + scmVersion { + releaseOnlyOnReleaseBranches = true + } + +This flag can also be set via command line: + + ./gradlew release -Prelease.releaseOnlyOnReleaseBranches + +And works well in combination with `releaseBranchNames` option + + scmVersion { + releaseOnlyOnReleaseBranches = true + releaseBranchNames = 'main,release' + } + +or as command line + + ./gradlew release -Prelease.releaseOnlyOnReleaseBranches -Prelease.releaseBranchNames=main,release + ## Decorating Decorating phase happens only when version is read (and deserialized). @@ -361,8 +390,11 @@ Custom version creators can be implemented by creating closure: {version, position -> ...} -- version - string version resolved by previous steps -- position - [ScmPosition](https://github.com/allegro/axion-release-plugin/blob/main/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmPosition.java) object +- version - string version resolved by previous steps +- + +position - [ScmPosition](https://github.com/allegro/axion-release-plugin/blob/main/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmPosition.java) +object ### Snapshot @@ -378,9 +410,11 @@ Snapshot creator can be implemented by creating closure: {version, position -> ...} -- version - string version resolved by previous steps -- position - [ScmPosition](https://github.com/allegro/axion-release-plugin/blob/main/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmPosition.java) object +- version - string version resolved by previous steps +- +position - [ScmPosition](https://github.com/allegro/axion-release-plugin/blob/main/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmPosition.java) +object ## Sanitization diff --git a/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy b/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy index e1ad245a..2a52b90f 100644 --- a/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy +++ b/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy @@ -140,4 +140,49 @@ class SimpleIntegrationTest extends BaseIntegrationTest { result.output.contains('Project version: 0.0.1-SNAPSHOT') result.task(":currentVersion").outcome == TaskOutcome.SUCCESS } + + def "should skip release when releaseOnlyOnReleaseBranches is true and current branch is not on releaseBranchNames list"() { + given: + buildFile(""" + scmVersion { + releaseOnlyOnReleaseBranches = true + releaseBranchNames = "develop" + } + """) + + when: + def releaseResult = runGradle('release', '-Prelease.version=1.0.0', '-Prelease.localOnly', '-Prelease.disableChecks') + + then: + releaseResult.task(':release').outcome == TaskOutcome.SUCCESS + releaseResult.output.contains('Release step skipped since \'releaseOnlyOnDefaultBranches\' option is set, and \'master\' was not in \'releaseBranchNames\' list [\'develop\']') + } + + def "should skip release when releaseOnlyOnReleaseBranches is set by gradle task property and current branch is not on releaseBranchNames list"() { + given: + buildFile("") + + when: + def releaseResult = runGradle('release', '-Prelease.releaseOnlyOnReleaseBranches', '-Prelease.releaseBranchNames=develop', '-Prelease.version=1.0.0', '-Prelease.localOnly', '-Prelease.disableChecks') + + then: + releaseResult.task(':release').outcome == TaskOutcome.SUCCESS + releaseResult.output.contains('Release step skipped since \'releaseOnlyOnDefaultBranches\' option is set, and \'master\' was not in \'releaseBranchNames\' list [\'develop\']') + } + + def "should not skip release when releaseOnlyOnReleaseBranches is true when on master branch (default releaseBranches list)"() { + given: + buildFile(""" + scmVersion { + releaseOnlyOnReleaseBranches = true + } + """) + + when: + def releaseResult = runGradle('release', '-Prelease.version=1.0.0', '-Prelease.localOnly', '-Prelease.disableChecks') + + then: + releaseResult.task(':release').outcome == TaskOutcome.SUCCESS + releaseResult.output.contains('Creating tag: ' + fullPrefix() + '1.0.0') + } } diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy index 4a64fe69..627fbdeb 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy @@ -1,8 +1,10 @@ package pl.allegro.tech.build.axion.release + import org.gradle.api.tasks.TaskAction import pl.allegro.tech.build.axion.release.domain.Releaser import pl.allegro.tech.build.axion.release.domain.scm.ScmPushResult +import pl.allegro.tech.build.axion.release.domain.scm.ScmService import pl.allegro.tech.build.axion.release.infrastructure.di.VersionResolutionContext import java.nio.file.Files @@ -15,10 +17,21 @@ abstract class ReleaseTask extends BaseAxionTask { void release() { VersionResolutionContext context = resolutionContext() Releaser releaser = context.releaser() + ScmService scmService = context.scmService() + + if (scmService.isReleaseOnlyOnDefaultBranches()) { + def releaseBranchNames = scmService.getReleaseBranchNames() + def currentBranch = context.repository().currentPosition().getBranch() + if (!releaseBranchNames.contains(currentBranch)) { + logger.quiet("Release step skipped since 'releaseOnlyOnDefaultBranches' option is set, and '${currentBranch}' was not in 'releaseBranchNames' list ['${releaseBranchNames.join(', ')}']") + return + } + } + ScmPushResult result = releaser.releaseAndPush(context.rules()) if (!result.success) { - def status = result.failureStatus.orElse("Unknown status of push") + def status = result.failureStatus def message = result.remoteMessage.orElse("Unknown error during push") logger.error("remote status: ${status}") logger.error("remote message: ${message}") diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy index 5b66129e..eadb091e 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy @@ -33,6 +33,8 @@ abstract class VersionConfig extends BaseExtension { private static final String DEPRECATED_FORCE_VERSION_PROPERTY = 'release.forceVersion' private static final String VERSION_INCREMENTER_PROPERTY = 'release.versionIncrementer' private static final String VERSION_CREATOR_PROPERTY = 'release.versionCreator' + private static final String RELEASE_ONLY_ON_RELEASE_BRANCHES_PROPERTY = 'release.releaseOnlyOnReleaseBranches' + private static final String RELEASE_BRANCH_NAMES_PROPERTY = 'release.releaseBranchNames' @Inject VersionConfig(Directory repositoryDirectory) { @@ -41,6 +43,8 @@ abstract class VersionConfig extends BaseExtension { getIgnoreUncommittedChanges().convention(true) getUseHighestVersion().convention(false) getUnshallowRepoOnCI().convention(false) + getReleaseBranchNames().convention(gradleProperty(RELEASE_BRANCH_NAMES_PROPERTY).orElse('master,main')) + getReleaseOnlyOnReleaseBranches().convention(gradlePropertyPresent(RELEASE_ONLY_ON_RELEASE_BRANCHES_PROPERTY).orElse(false)) getReleaseBranchPattern().convention(Pattern.compile('^' + defaultPrefix() + '(/.*)?$')) getSanitizeVersion().convention(true) getCreateReleaseCommit().convention(false) @@ -79,7 +83,10 @@ abstract class VersionConfig extends BaseExtension { abstract Property getIgnoreUncommittedChanges() @Internal - abstract Property getUseHighestVersion(); + abstract Property getReleaseBranchNames() + + @Internal + abstract Property getReleaseOnlyOnReleaseBranches() @Internal @Incubating @@ -112,6 +119,9 @@ abstract class VersionConfig extends BaseExtension { @Internal abstract Property getReleaseCommitMessage() + @Internal + abstract Property getUseHighestVersion(); + Provider ignoreUncommittedChanges() { gradlePropertyPresent(IGNORE_UNCOMMITTED_CHANGES_PROPERTY) .orElse(ignoreUncommittedChanges) diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy index fd9a4e70..145010d7 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy @@ -17,7 +17,9 @@ class ScmPropertiesFactory { config.repository.overriddenBranch().getOrNull(), config.repository.overriddenIsClean().getOrNull(), ScmIdentityFactory.create(config.repository, config.repository.disableSshAgent().get()), - config.getUnshallowRepoOnCI().get() + config.getUnshallowRepoOnCI().get(), + config.getReleaseBranchNames().get().split(",") as Set, + config.getReleaseOnlyOnReleaseBranches().get() ) } } diff --git a/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmProperties.java b/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmProperties.java index f202c510..6c1791fd 100644 --- a/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmProperties.java +++ b/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmProperties.java @@ -2,6 +2,7 @@ import java.io.File; import java.util.Optional; +import java.util.Set; public class ScmProperties { @@ -16,6 +17,8 @@ public class ScmProperties { private final Boolean overriddenIsClean; private final ScmIdentity identity; private final Boolean unshallowRepoOnCI; + private final Set releaseBranchNames; + private final boolean releaseOnlyOnReleaseBranches; public ScmProperties( String type, @@ -28,7 +31,9 @@ public ScmProperties( String overriddenBranchName, Boolean overriddenIsClean, ScmIdentity identity, - Boolean unshallowRepoOnCI + Boolean unshallowRepoOnCI, + Set releaseBranchNames, + boolean releaseOnlyOnReleaseBranches ) { this.type = type; this.directory = directory; @@ -41,6 +46,8 @@ public ScmProperties( this.overriddenIsClean = overriddenIsClean; this.identity = identity; this.unshallowRepoOnCI = unshallowRepoOnCI; + this.releaseBranchNames = releaseBranchNames; + this.releaseOnlyOnReleaseBranches = releaseOnlyOnReleaseBranches; } public ScmPushOptions pushOptions() { @@ -90,4 +97,12 @@ public final ScmIdentity getIdentity() { public Boolean isUnshallowRepoOnCI() { return unshallowRepoOnCI; } + + public Set getReleaseBranchNames() { + return releaseBranchNames; + } + + public boolean isReleaseOnlyOnReleaseBranches() { + return releaseOnlyOnReleaseBranches; + } } diff --git a/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmService.java b/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmService.java index 9669af09..56158c42 100644 --- a/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmService.java +++ b/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmService.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Optional; +import java.util.Set; public class ScmService { private static final Logger logger = Logging.getLogger(ScmService.class); @@ -69,4 +70,12 @@ public List lastLogMessages(int messageCount) { public boolean isLegacyDefTagnameRepo() { return repository.isLegacyDefTagnameRepo(); } + + public Set getReleaseBranchNames() { + return scmProperties.getReleaseBranchNames(); + } + + public boolean isReleaseOnlyOnDefaultBranches(){ + return scmProperties.isReleaseOnlyOnReleaseBranches(); + } } diff --git a/src/test/groovy/pl/allegro/tech/build/axion/release/RepositoryBasedTest.groovy b/src/test/groovy/pl/allegro/tech/build/axion/release/RepositoryBasedTest.groovy index c06f2cb2..8c213d29 100644 --- a/src/test/groovy/pl/allegro/tech/build/axion/release/RepositoryBasedTest.groovy +++ b/src/test/groovy/pl/allegro/tech/build/axion/release/RepositoryBasedTest.groovy @@ -1,12 +1,13 @@ package pl.allegro.tech.build.axion.release import org.ajoberstar.grgit.Grgit +import org.eclipse.jgit.util.SystemReader import pl.allegro.tech.build.axion.release.domain.LocalOnlyResolver import pl.allegro.tech.build.axion.release.domain.properties.PropertiesBuilder import pl.allegro.tech.build.axion.release.domain.scm.ScmProperties import pl.allegro.tech.build.axion.release.domain.scm.ScmRepository -import pl.allegro.tech.build.axion.release.infrastructure.di.VersionResolutionContext import pl.allegro.tech.build.axion.release.infrastructure.di.ScmRepositoryFactory +import pl.allegro.tech.build.axion.release.infrastructure.di.VersionResolutionContext import spock.lang.Specification import spock.lang.TempDir @@ -24,32 +25,43 @@ class RepositoryBasedTest extends Specification { String defaultBranch void setup() { + // let's make sure, not to use system wide user settings in tests + setupLocalGitConfiguration() + def rawRepository = Grgit.init(dir: temporaryFolder) defaultBranch = rawRepository.branch.current().name - // let's make sure, not to use system wide user settings in tests - rawRepository.repository.jgit.repository.config.baseConfig.clear() - ScmProperties scmProperties = scmProperties(temporaryFolder).build() ScmRepository scmRepository = ScmRepositoryFactory.create(scmProperties) context = new VersionResolutionContext( - PropertiesBuilder.properties().build(), - scmRepository, - scmProperties, - temporaryFolder, - new LocalOnlyResolver(true) + PropertiesBuilder.properties().build(), + scmRepository, + scmProperties, + temporaryFolder, + new LocalOnlyResolver(true) ) repository = context.repository() repository.commit(['*'], 'initial commit') } + static void setupLocalGitConfiguration() { + File testGitConfig = File.createTempFile("axion-test-git-config", ".tmp") + testGitConfig.with { + append "[user]\n" + append "\tname = Axion Test User\n" + append "\temail = axion-test@no-reply.github.com\n" + deleteOnExit() + } + SystemReader.setInstance(new TestConfigSystemReader(testGitConfig)) + } + protected String currentVersion() { return context.versionService().currentDecoratedVersion( - context.rules().version, - context.rules().tag, - context.rules().nextVersion + context.rules().version, + context.rules().tag, + context.rules().nextVersion ).decoratedVersion } } diff --git a/src/test/groovy/pl/allegro/tech/build/axion/release/TestConfigSystemReader.groovy b/src/test/groovy/pl/allegro/tech/build/axion/release/TestConfigSystemReader.groovy new file mode 100644 index 00000000..486de946 --- /dev/null +++ b/src/test/groovy/pl/allegro/tech/build/axion/release/TestConfigSystemReader.groovy @@ -0,0 +1,65 @@ +package pl.allegro.tech.build.axion.release + +import org.eclipse.jgit.lib.Config +import org.eclipse.jgit.storage.file.FileBasedConfig +import org.eclipse.jgit.util.FS +import org.eclipse.jgit.util.SystemReader + +class TestConfigSystemReader extends SystemReader { + private static final SystemReader proxy = getInstance() + private final File userGitConfig + + TestConfigSystemReader(File userGitConfig) { + super() + this.userGitConfig = userGitConfig + } + + @Override + String getenv(String variable) { + return proxy.getenv(variable) + } + + @Override + String getHostname() { + return proxy.getHostname() + } + + @Override + String getProperty(String key) { + return proxy.getProperty(key) + } + + @Override + long getCurrentTime() { + return proxy.getCurrentTime() + } + + @Override + int getTimezone(long when) { + return proxy.getTimezone(when) + } + + @Override + FileBasedConfig openUserConfig(Config parent, FS fs) { + return new FileBasedConfig(parent, userGitConfig, fs) + } + + @Override + FileBasedConfig openJGitConfig(Config parent, FS fs) { + return proxy.openJGitConfig(parent, fs) + } + + @Override + FileBasedConfig openSystemConfig(Config parent, FS fs) { + return new FileBasedConfig(parent, null, fs) { + @Override + void load() { + } + + @Override + boolean isOutdated() { + return false + } + } + } +} diff --git a/src/test/groovy/pl/allegro/tech/build/axion/release/domain/scm/ScmPropertiesBuilder.groovy b/src/test/groovy/pl/allegro/tech/build/axion/release/domain/scm/ScmPropertiesBuilder.groovy index 50ab51ca..4dd5217c 100644 --- a/src/test/groovy/pl/allegro/tech/build/axion/release/domain/scm/ScmPropertiesBuilder.groovy +++ b/src/test/groovy/pl/allegro/tech/build/axion/release/domain/scm/ScmPropertiesBuilder.groovy @@ -38,7 +38,9 @@ class ScmPropertiesBuilder { overriddenBranchName, overriddenIsClean, ScmIdentity.defaultIdentityWithoutAgents(), - true + true, + ['main', 'master'] as Set, + false ) } diff --git a/src/test/groovy/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepositoryTest.groovy b/src/test/groovy/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepositoryTest.groovy index 2b5e7b59..286ef099 100644 --- a/src/test/groovy/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepositoryTest.groovy +++ b/src/test/groovy/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepositoryTest.groovy @@ -9,6 +9,7 @@ import org.eclipse.jgit.lib.Constants import org.eclipse.jgit.transport.RemoteConfig import org.eclipse.jgit.transport.URIish import org.gradle.testfixtures.ProjectBuilder +import pl.allegro.tech.build.axion.release.RepositoryBasedTest import pl.allegro.tech.build.axion.release.domain.scm.ScmException import pl.allegro.tech.build.axion.release.domain.scm.ScmIdentity import pl.allegro.tech.build.axion.release.domain.scm.ScmPosition @@ -45,6 +46,7 @@ class GitRepositoryTest extends Specification { String defaultBranch; void setup() { + RepositoryBasedTest.setupLocalGitConfiguration() remoteRepositoryDir = File.createTempDir('axion-release', 'tmp') Map remoteRepositories = GitProjectBuilder.gitProject(remoteRepositoryDir).withInitialCommit().build() remoteRawRepository = remoteRepositories[Grgit] From 8b151f0901c3b611029465b6c332448e3c8ca4cf Mon Sep 17 00:00:00 2001 From: Bartosz Galek Date: Sun, 25 Aug 2024 11:47:17 +0200 Subject: [PATCH 2/4] #796 | use actual list in gradle dsl and string in commandline --- docs/configuration/overview.md | 16 ++++++++++---- docs/configuration/version.md | 2 +- .../release/SimpleIntegrationTest.groovy | 8 +++---- .../build/axion/release/ReleaseTask.groovy | 2 +- .../axion/release/domain/BaseExtension.groovy | 6 +++++- .../axion/release/domain/VersionConfig.groovy | 21 ++++++++++--------- .../config/ScmPropertiesFactory.groovy | 2 +- 7 files changed, 35 insertions(+), 22 deletions(-) diff --git a/docs/configuration/overview.md b/docs/configuration/overview.md index 8a47e9fb..0e74261e 100644 --- a/docs/configuration/overview.md +++ b/docs/configuration/overview.md @@ -2,7 +2,6 @@ All `axion-release-plugin` configuration options: - scmVersion { repository { @@ -75,8 +74,9 @@ All `axion-release-plugin` configuration options: aheadOfRemote.set(false) // permanently disable ahead of remote check } - // doc: + // doc: Version / releaseOnlyOnReleaseBranches releaseOnlyOnReleaseBranches = false + releaseBranchNames = ['master', 'main'] } All `axion-release-plugin` configuration flags: @@ -102,11 +102,19 @@ All `axion-release-plugin` configuration flags: - release.overriddenIsClean - default: not set = determine the `isClean`-state - possible values: `true` or `false` - - usually the plugin performs a check if the working directory is clean. With this flag, the result of the check can be overridden. - - If you have a repository with a lot of files and do not use the isClean-feature, you may set this flag for a speed-up. + - usually the plugin performs a check if the working directory is clean. With this flag, the result of the check can + be overridden. + - If you have a repository with a lot of files and do not use the isClean-feature, you may set this flag for a + speed-up. - release.disableSshAgent - default: false - do not use the ssh agent - release.fetchTags - default: false - fetch tags from the remote repository +- release.releaseOnlyOnReleaseBranches + - default: false + - only perform a release on branches that match the `releaseBranchNames` +- release.releaseBranchNames + - default: `['master', 'main']` + - a list of branch names that are considered release branches diff --git a/docs/configuration/version.md b/docs/configuration/version.md index cfabbb30..346d409e 100644 --- a/docs/configuration/version.md +++ b/docs/configuration/version.md @@ -295,7 +295,7 @@ And works well in combination with `releaseBranchNames` option scmVersion { releaseOnlyOnReleaseBranches = true - releaseBranchNames = 'main,release' + releaseBranchNames = ['main', 'master'] } or as command line diff --git a/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy b/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy index 2a52b90f..824d58e6 100644 --- a/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy +++ b/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy @@ -146,7 +146,7 @@ class SimpleIntegrationTest extends BaseIntegrationTest { buildFile(""" scmVersion { releaseOnlyOnReleaseBranches = true - releaseBranchNames = "develop" + releaseBranchNames = ['develop', 'release'] } """) @@ -155,7 +155,7 @@ class SimpleIntegrationTest extends BaseIntegrationTest { then: releaseResult.task(':release').outcome == TaskOutcome.SUCCESS - releaseResult.output.contains('Release step skipped since \'releaseOnlyOnDefaultBranches\' option is set, and \'master\' was not in \'releaseBranchNames\' list [\'develop\']') + releaseResult.output.contains('Release step skipped since \'releaseOnlyOnDefaultBranches\' option is set, and \'master\' was not in \'releaseBranchNames\' list [develop, release]') } def "should skip release when releaseOnlyOnReleaseBranches is set by gradle task property and current branch is not on releaseBranchNames list"() { @@ -163,11 +163,11 @@ class SimpleIntegrationTest extends BaseIntegrationTest { buildFile("") when: - def releaseResult = runGradle('release', '-Prelease.releaseOnlyOnReleaseBranches', '-Prelease.releaseBranchNames=develop', '-Prelease.version=1.0.0', '-Prelease.localOnly', '-Prelease.disableChecks') + def releaseResult = runGradle('release', '-Prelease.releaseOnlyOnReleaseBranches', '-Prelease.releaseBranchNames=develop,release', '-Prelease.version=1.0.0', '-Prelease.localOnly', '-Prelease.disableChecks') then: releaseResult.task(':release').outcome == TaskOutcome.SUCCESS - releaseResult.output.contains('Release step skipped since \'releaseOnlyOnDefaultBranches\' option is set, and \'master\' was not in \'releaseBranchNames\' list [\'develop\']') + releaseResult.output.contains('Release step skipped since \'releaseOnlyOnDefaultBranches\' option is set, and \'master\' was not in \'releaseBranchNames\' list [develop, release]') } def "should not skip release when releaseOnlyOnReleaseBranches is true when on master branch (default releaseBranches list)"() { diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy index 627fbdeb..fe96b0e5 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy @@ -23,7 +23,7 @@ abstract class ReleaseTask extends BaseAxionTask { def releaseBranchNames = scmService.getReleaseBranchNames() def currentBranch = context.repository().currentPosition().getBranch() if (!releaseBranchNames.contains(currentBranch)) { - logger.quiet("Release step skipped since 'releaseOnlyOnDefaultBranches' option is set, and '${currentBranch}' was not in 'releaseBranchNames' list ['${releaseBranchNames.join(', ')}']") + logger.quiet("Release step skipped since 'releaseOnlyOnDefaultBranches' option is set, and '${currentBranch}' was not in 'releaseBranchNames' list [${releaseBranchNames.join(', ')}]") return } } diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/BaseExtension.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/BaseExtension.groovy index 50900c83..a6b4a5cf 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/BaseExtension.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/BaseExtension.groovy @@ -28,11 +28,15 @@ abstract class BaseExtension { GradleVersion.current() } + protected Provider> gradleSetProperty(String name) { + return gradleProperty(name).map({ it.tokenize(',') as Set }) + } + protected Provider gradlePropertyBoolean(String name) { return gradleProperty(name).map(Boolean::valueOf) } protected Provider gradlePropertyPresent(String name) { - return gradleProperty(name).map({true}) + return gradleProperty(name).map({ true }) } } diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy index eadb091e..893588fd 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy @@ -6,6 +6,7 @@ import org.gradle.api.file.Directory import org.gradle.api.provider.MapProperty import org.gradle.api.provider.Property import org.gradle.api.provider.Provider +import org.gradle.api.provider.SetProperty import org.gradle.api.tasks.Input import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Nested @@ -43,7 +44,7 @@ abstract class VersionConfig extends BaseExtension { getIgnoreUncommittedChanges().convention(true) getUseHighestVersion().convention(false) getUnshallowRepoOnCI().convention(false) - getReleaseBranchNames().convention(gradleProperty(RELEASE_BRANCH_NAMES_PROPERTY).orElse('master,main')) + getReleaseBranchNames().convention(gradleSetProperty(RELEASE_BRANCH_NAMES_PROPERTY).orElse(['master', 'main'] as Set)) getReleaseOnlyOnReleaseBranches().convention(gradlePropertyPresent(RELEASE_ONLY_ON_RELEASE_BRANCHES_PROPERTY).orElse(false)) getReleaseBranchPattern().convention(Pattern.compile('^' + defaultPrefix() + '(/.*)?$')) getSanitizeVersion().convention(true) @@ -83,7 +84,7 @@ abstract class VersionConfig extends BaseExtension { abstract Property getIgnoreUncommittedChanges() @Internal - abstract Property getReleaseBranchNames() + abstract SetProperty getReleaseBranchNames() @Internal abstract Property getReleaseOnlyOnReleaseBranches() @@ -142,8 +143,8 @@ abstract class VersionConfig extends BaseExtension { Provider forcedVersion() { gradleProperty(FORCE_VERSION_PROPERTY) .orElse(gradleProperty(DEPRECATED_FORCE_VERSION_PROPERTY)) - .map({it.trim()}) - .map({ it.isBlank() ? null : it}) + .map({ it.trim() }) + .map({ it.isBlank() ? null : it }) } Provider versionIncrementerType() { @@ -226,12 +227,12 @@ abstract class VersionConfig extends BaseExtension { Provider versionProvider() { def cachedVersionSupplier = this.cachedVersionSupplier - providers.provider( { cachedVersionSupplier.resolve(this,layout.projectDirectory)}) + providers.provider({ cachedVersionSupplier.resolve(this, layout.projectDirectory) }) } Provider uncachedVersionProvider() { def versionSupplier = this.versionSupplier - providers.provider( { versionSupplier.resolve(this, layout.projectDirectory)}) + providers.provider({ versionSupplier.resolve(this, layout.projectDirectory) }) } @Nested @@ -241,21 +242,21 @@ abstract class VersionConfig extends BaseExtension { @Input String getVersion() { - return versionProvider().map({ it.decoratedVersion}).get() + return versionProvider().map({ it.decoratedVersion }).get() } @Input String getPreviousVersion() { - return versionProvider().map({ it.previousVersion}).get() + return versionProvider().map({ it.previousVersion }).get() } @Input String getUndecoratedVersion() { - return versionProvider().map({ it.undecoratedVersion}).get() + return versionProvider().map({ it.undecoratedVersion }).get() } @Nested ScmPosition getScmPosition() { - return versionProvider().map({it.position}).get() + return versionProvider().map({ it.position }).get() } } diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy index 145010d7..f47bcb55 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy @@ -18,7 +18,7 @@ class ScmPropertiesFactory { config.repository.overriddenIsClean().getOrNull(), ScmIdentityFactory.create(config.repository, config.repository.disableSshAgent().get()), config.getUnshallowRepoOnCI().get(), - config.getReleaseBranchNames().get().split(",") as Set, + config.getReleaseBranchNames().get(), config.getReleaseOnlyOnReleaseBranches().get() ) } From ef8b6cc185567f9656ee8a0a74fa58ee3cf46274 Mon Sep 17 00:00:00 2001 From: Bartosz Galek Date: Mon, 26 Aug 2024 14:29:39 +0200 Subject: [PATCH 3/4] release skipping logic moved to Releaser class --- .../axion/release/BaseIntegrationTest.groovy | 2 + .../release/SimpleIntegrationTest.groovy | 6 +- .../axion/release/CreateReleaseTask.groovy | 8 +- .../build/axion/release/ReleaseTask.groovy | 15 +--- .../axion/release/domain/BaseExtension.groovy | 4 +- .../release/domain/RepositoryConfig.groovy | 2 +- .../axion/release/domain/VersionConfig.groovy | 6 +- .../config/ScmPropertiesFactory.groovy | 3 +- .../build/axion/release/domain/Releaser.java | 25 ++++++- .../release/domain/scm/ScmProperties.java | 9 ++- .../infrastructure/git/GitRepository.java | 3 +- .../git/SystemReaderWithoutSystemConfig.java | 58 ++++++++------- .../axion/release/RepositoryBasedTest.groovy | 15 ---- .../release/TestConfigSystemReader.groovy | 65 ---------------- .../axion/release/domain/ReleaserTest.groovy | 74 +++++++++++++------ .../domain/scm/ScmPropertiesBuilder.groovy | 3 +- .../git/GitRepositoryTest.groovy | 54 ++++++-------- 17 files changed, 161 insertions(+), 191 deletions(-) delete mode 100644 src/test/groovy/pl/allegro/tech/build/axion/release/TestConfigSystemReader.groovy diff --git a/src/integration/groovy/pl/allegro/tech/build/axion/release/BaseIntegrationTest.groovy b/src/integration/groovy/pl/allegro/tech/build/axion/release/BaseIntegrationTest.groovy index 2cba83ab..771ed37e 100644 --- a/src/integration/groovy/pl/allegro/tech/build/axion/release/BaseIntegrationTest.groovy +++ b/src/integration/groovy/pl/allegro/tech/build/axion/release/BaseIntegrationTest.groovy @@ -25,6 +25,7 @@ class BaseIntegrationTest extends RepositoryBasedTest { """ project.version = scmVersion.version + scmVersion.ignoreGlobalGitConfig = true """) } @@ -48,6 +49,7 @@ class BaseIntegrationTest extends RepositoryBasedTest { try { return gradle().withArguments(args).build() } + finally { def ccDir = new File(temporaryFolder, "build/reports/configuration-cache") if (ccDir.exists() && ccDir.isDirectory()) { diff --git a/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy b/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy index 824d58e6..0a3c89c0 100644 --- a/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy +++ b/src/integration/groovy/pl/allegro/tech/build/axion/release/SimpleIntegrationTest.groovy @@ -13,7 +13,7 @@ import static pl.allegro.tech.build.axion.release.TagPrefixConf.fullPrefix class SimpleIntegrationTest extends BaseIntegrationTest { @Rule - EnvironmentVariables environmentVariablesRule = new EnvironmentVariables(); + EnvironmentVariables environmentVariablesRule = new EnvironmentVariables() def "should return default version on calling currentVersion task on vanilla repo"() { given: @@ -155,7 +155,7 @@ class SimpleIntegrationTest extends BaseIntegrationTest { then: releaseResult.task(':release').outcome == TaskOutcome.SUCCESS - releaseResult.output.contains('Release step skipped since \'releaseOnlyOnDefaultBranches\' option is set, and \'master\' was not in \'releaseBranchNames\' list [develop, release]') + releaseResult.output.contains('Release step skipped since \'releaseOnlyOnDefaultBranches\' option is set, and \'master\' was not in \'releaseBranchNames\' list [develop,release]') } def "should skip release when releaseOnlyOnReleaseBranches is set by gradle task property and current branch is not on releaseBranchNames list"() { @@ -167,7 +167,7 @@ class SimpleIntegrationTest extends BaseIntegrationTest { then: releaseResult.task(':release').outcome == TaskOutcome.SUCCESS - releaseResult.output.contains('Release step skipped since \'releaseOnlyOnDefaultBranches\' option is set, and \'master\' was not in \'releaseBranchNames\' list [develop, release]') + releaseResult.output.contains('Release step skipped since \'releaseOnlyOnDefaultBranches\' option is set, and \'master\' was not in \'releaseBranchNames\' list [develop,release]') } def "should not skip release when releaseOnlyOnReleaseBranches is true when on master branch (default releaseBranches list)"() { diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/CreateReleaseTask.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/CreateReleaseTask.groovy index c8715f2a..f1e2d455 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/CreateReleaseTask.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/CreateReleaseTask.groovy @@ -1,6 +1,5 @@ package pl.allegro.tech.build.axion.release - import org.gradle.api.tasks.TaskAction import pl.allegro.tech.build.axion.release.domain.Releaser import pl.allegro.tech.build.axion.release.infrastructure.di.VersionResolutionContext @@ -11,6 +10,11 @@ abstract class CreateReleaseTask extends BaseAxionTask { void release() { VersionResolutionContext context = resolutionContext() Releaser releaser = context.releaser() - releaser.release(context.rules()) + def scmService = context.scmService() + def repository = context.repository() + def releaseBranchNames = scmService.getReleaseBranchNames() + def currentBranch = repository.currentPosition().getBranch() + def isReleaseOnlyOnDefaultBranches = scmService.isReleaseOnlyOnDefaultBranches() + releaser.release(context.rules(), isReleaseOnlyOnDefaultBranches, currentBranch, releaseBranchNames) } } diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy index b3f099e5..6218dfdc 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy @@ -17,17 +17,10 @@ abstract class ReleaseTask extends BaseAxionTask { VersionResolutionContext context = resolutionContext() Releaser releaser = context.releaser() ScmService scmService = context.scmService() - - if (scmService.isReleaseOnlyOnDefaultBranches()) { - def releaseBranchNames = scmService.getReleaseBranchNames() - def currentBranch = context.repository().currentPosition().getBranch() - if (!releaseBranchNames.contains(currentBranch)) { - logger.quiet("Release step skipped since 'releaseOnlyOnDefaultBranches' option is set, and '${currentBranch}' was not in 'releaseBranchNames' list [${releaseBranchNames.join(', ')}]") - return - } - } - - ScmPushResult result = releaser.releaseAndPush(context.rules()) + def releaseBranchNames = scmService.getReleaseBranchNames() + def currentBranch = context.repository().currentPosition().getBranch() + def isReleaseOnlyOnDefaultBranches = scmService.isReleaseOnlyOnDefaultBranches() + ScmPushResult result = releaser.releaseAndPush(context.rules(), isReleaseOnlyOnDefaultBranches, currentBranch, releaseBranchNames) if (!result.success) { def status = result.failureStatus diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/BaseExtension.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/BaseExtension.groovy index a6b4a5cf..50c72a51 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/BaseExtension.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/BaseExtension.groovy @@ -28,11 +28,11 @@ abstract class BaseExtension { GradleVersion.current() } - protected Provider> gradleSetProperty(String name) { + protected Provider> gradlePropertyAsSet(String name) { return gradleProperty(name).map({ it.tokenize(',') as Set }) } - protected Provider gradlePropertyBoolean(String name) { + protected Provider gradlePropertyAsBoolean(String name) { return gradleProperty(name).map(Boolean::valueOf) } diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/RepositoryConfig.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/RepositoryConfig.groovy index b4cb661a..c19ea8b7 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/RepositoryConfig.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/RepositoryConfig.groovy @@ -89,7 +89,7 @@ abstract class RepositoryConfig extends BaseExtension { } Provider overriddenIsClean() { - gradlePropertyBoolean(OVERRIDDEN_IS_CLEAN) + gradlePropertyAsBoolean(OVERRIDDEN_IS_CLEAN) } Provider disableSshAgent() { diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy index 893588fd..cf1d1282 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/domain/VersionConfig.groovy @@ -44,7 +44,8 @@ abstract class VersionConfig extends BaseExtension { getIgnoreUncommittedChanges().convention(true) getUseHighestVersion().convention(false) getUnshallowRepoOnCI().convention(false) - getReleaseBranchNames().convention(gradleSetProperty(RELEASE_BRANCH_NAMES_PROPERTY).orElse(['master', 'main'] as Set)) + getIgnoreGlobalGitConfig().convention(false) + getReleaseBranchNames().convention(gradlePropertyAsSet(RELEASE_BRANCH_NAMES_PROPERTY).orElse(['master', 'main'] as Set)) getReleaseOnlyOnReleaseBranches().convention(gradlePropertyPresent(RELEASE_ONLY_ON_RELEASE_BRANCHES_PROPERTY).orElse(false)) getReleaseBranchPattern().convention(Pattern.compile('^' + defaultPrefix() + '(/.*)?$')) getSanitizeVersion().convention(true) @@ -89,6 +90,9 @@ abstract class VersionConfig extends BaseExtension { @Internal abstract Property getReleaseOnlyOnReleaseBranches() + @Internal + abstract Property getIgnoreGlobalGitConfig() + @Internal @Incubating abstract Property getUnshallowRepoOnCI(); diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy index f47bcb55..8900f4cb 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/infrastructure/config/ScmPropertiesFactory.groovy @@ -19,7 +19,8 @@ class ScmPropertiesFactory { ScmIdentityFactory.create(config.repository, config.repository.disableSshAgent().get()), config.getUnshallowRepoOnCI().get(), config.getReleaseBranchNames().get(), - config.getReleaseOnlyOnReleaseBranches().get() + config.getReleaseOnlyOnReleaseBranches().get(), + config.getIgnoreGlobalGitConfig().get() ) } } diff --git a/src/main/java/pl/allegro/tech/build/axion/release/domain/Releaser.java b/src/main/java/pl/allegro/tech/build/axion/release/domain/Releaser.java index 5fc78d94..6aa80a43 100644 --- a/src/main/java/pl/allegro/tech/build/axion/release/domain/Releaser.java +++ b/src/main/java/pl/allegro/tech/build/axion/release/domain/Releaser.java @@ -9,6 +9,7 @@ import pl.allegro.tech.build.axion.release.domain.scm.ScmService; import java.util.Optional; +import java.util.Set; public class Releaser { @@ -23,10 +24,20 @@ public Releaser(VersionService versionService, ScmService repository, ReleaseHoo this.hooksRunner = hooksRunner; } - public Optional release(Properties properties) { + public Optional release(Properties properties, + boolean isReleaseOnlyOnDefaultBranches, + String currentBranch, + Set releaseBranchNames) { + if (isReleaseOnlyOnDefaultBranches && !releaseBranchNames.contains(currentBranch)) { + String message = String.format("Release step skipped since 'releaseOnlyOnDefaultBranches' option is set, and '%s' was not in 'releaseBranchNames' list [%s]", currentBranch, String.join(",", releaseBranchNames)); + logger.quiet(message); + return Optional.empty(); + } + VersionContext versionContext = versionService.currentVersion( properties.getVersion(), properties.getTag(), properties.getNextVersion() ); + Version version = versionContext.getVersion(); if (versionContext.isSnapshot()) { @@ -43,11 +54,17 @@ public Optional release(Properties properties) { logger.quiet("Working on released version " + version + ", nothing to release"); return Optional.empty(); } - } - public ScmPushResult releaseAndPush(Properties rules) { - Optional releasedTagName = release(rules); + public ScmPushResult releaseAndPush(Properties rules, + boolean isReleaseOnlyOnDefaultBranches, + String currentBranch, + Set releaseBranchNames) { + Optional releasedTagName = release(rules, isReleaseOnlyOnDefaultBranches, currentBranch, releaseBranchNames); + + if (releasedTagName.isEmpty()) { + return new ScmPushResult(true, Optional.empty(), Optional.empty()); + } ScmPushResult result = pushRelease(); diff --git a/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmProperties.java b/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmProperties.java index 6c1791fd..a264aa65 100644 --- a/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmProperties.java +++ b/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmProperties.java @@ -19,6 +19,7 @@ public class ScmProperties { private final Boolean unshallowRepoOnCI; private final Set releaseBranchNames; private final boolean releaseOnlyOnReleaseBranches; + private final boolean ignoreGlobalGitConfig; public ScmProperties( String type, @@ -33,7 +34,8 @@ public ScmProperties( ScmIdentity identity, Boolean unshallowRepoOnCI, Set releaseBranchNames, - boolean releaseOnlyOnReleaseBranches + boolean releaseOnlyOnReleaseBranches, + boolean ignoreGlobalGitConfig ) { this.type = type; this.directory = directory; @@ -48,6 +50,7 @@ public ScmProperties( this.unshallowRepoOnCI = unshallowRepoOnCI; this.releaseBranchNames = releaseBranchNames; this.releaseOnlyOnReleaseBranches = releaseOnlyOnReleaseBranches; + this.ignoreGlobalGitConfig = ignoreGlobalGitConfig; } public ScmPushOptions pushOptions() { @@ -105,4 +108,8 @@ public Set getReleaseBranchNames() { public boolean isReleaseOnlyOnReleaseBranches() { return releaseOnlyOnReleaseBranches; } + + public boolean isIgnoreGlobalGitConfig() { + return ignoreGlobalGitConfig; + } } diff --git a/src/main/java/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepository.java b/src/main/java/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepository.java index f2029da1..f8d7c7fd 100644 --- a/src/main/java/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepository.java +++ b/src/main/java/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepository.java @@ -38,8 +38,7 @@ public class GitRepository implements ScmRepository { private final ScmProperties properties; public GitRepository(ScmProperties properties) { - SystemReader.setInstance(new SystemReaderWithoutSystemConfig()); - + SystemReader.setInstance(new SystemReaderWithoutSystemConfig(properties.isIgnoreGlobalGitConfig())); try { this.repositoryDir = properties.getDirectory(); this.jgitRepository = Git.open(repositoryDir); diff --git a/src/main/java/pl/allegro/tech/build/axion/release/infrastructure/git/SystemReaderWithoutSystemConfig.java b/src/main/java/pl/allegro/tech/build/axion/release/infrastructure/git/SystemReaderWithoutSystemConfig.java index b0b93f00..640d55e0 100644 --- a/src/main/java/pl/allegro/tech/build/axion/release/infrastructure/git/SystemReaderWithoutSystemConfig.java +++ b/src/main/java/pl/allegro/tech/build/axion/release/infrastructure/git/SystemReaderWithoutSystemConfig.java @@ -5,43 +5,43 @@ import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.SystemReader; -public class SystemReaderWithoutSystemConfig extends SystemReader -{ +public class SystemReaderWithoutSystemConfig extends SystemReader { private static final SystemReader DefaultSystemReader = SystemReader.getInstance(); + private final boolean ignoreUserSettings; + + public SystemReaderWithoutSystemConfig(boolean ignoreUserSettings) { + super(); + this.ignoreUserSettings = ignoreUserSettings; + } @Override - public String getenv(String variable) - { + public String getenv(String variable) { return DefaultSystemReader.getenv(variable); } @Override - public String getHostname() - { + public String getHostname() { return DefaultSystemReader.getHostname(); } @Override - public String getProperty(String key) - { + public String getProperty(String key) { return DefaultSystemReader.getProperty(key); } @Override - public long getCurrentTime() - { + public long getCurrentTime() { return DefaultSystemReader.getCurrentTime(); } @Override - public int getTimezone(long when) - { + public int getTimezone(long when) { return DefaultSystemReader.getTimezone(when); } @Override - public FileBasedConfig openUserConfig(Config parent, FS fs) - { + public FileBasedConfig openUserConfig(Config parent, FS fs) { + if (ignoreUserSettings) return new EmptyFileBasedConfig(parent, fs); return DefaultSystemReader.openUserConfig(parent, fs); } @@ -54,20 +54,22 @@ public FileBasedConfig openJGitConfig(Config parent, FS fs) { // This resolves issues with Gradle being unable to save configuration cache // Based on https://stackoverflow.com/a/59110721 @Override - public FileBasedConfig openSystemConfig(Config parent, FS fs) - { - return new FileBasedConfig(parent, null, fs) - { - @Override - public void load() - { - } + public FileBasedConfig openSystemConfig(Config parent, FS fs) { + return new EmptyFileBasedConfig(parent, fs); + } + + private static class EmptyFileBasedConfig extends FileBasedConfig { + public EmptyFileBasedConfig(Config parent, FS fs) { + super(parent, null, fs); + } + + @Override + public void load() { + } - @Override - public boolean isOutdated() - { - return false; - } - }; + @Override + public boolean isOutdated() { + return false; + } } } diff --git a/src/test/groovy/pl/allegro/tech/build/axion/release/RepositoryBasedTest.groovy b/src/test/groovy/pl/allegro/tech/build/axion/release/RepositoryBasedTest.groovy index 8c213d29..d6d120a6 100644 --- a/src/test/groovy/pl/allegro/tech/build/axion/release/RepositoryBasedTest.groovy +++ b/src/test/groovy/pl/allegro/tech/build/axion/release/RepositoryBasedTest.groovy @@ -1,7 +1,6 @@ package pl.allegro.tech.build.axion.release import org.ajoberstar.grgit.Grgit -import org.eclipse.jgit.util.SystemReader import pl.allegro.tech.build.axion.release.domain.LocalOnlyResolver import pl.allegro.tech.build.axion.release.domain.properties.PropertiesBuilder import pl.allegro.tech.build.axion.release.domain.scm.ScmProperties @@ -25,9 +24,6 @@ class RepositoryBasedTest extends Specification { String defaultBranch void setup() { - // let's make sure, not to use system wide user settings in tests - setupLocalGitConfiguration() - def rawRepository = Grgit.init(dir: temporaryFolder) defaultBranch = rawRepository.branch.current().name @@ -46,17 +42,6 @@ class RepositoryBasedTest extends Specification { repository.commit(['*'], 'initial commit') } - static void setupLocalGitConfiguration() { - File testGitConfig = File.createTempFile("axion-test-git-config", ".tmp") - testGitConfig.with { - append "[user]\n" - append "\tname = Axion Test User\n" - append "\temail = axion-test@no-reply.github.com\n" - deleteOnExit() - } - SystemReader.setInstance(new TestConfigSystemReader(testGitConfig)) - } - protected String currentVersion() { return context.versionService().currentDecoratedVersion( context.rules().version, diff --git a/src/test/groovy/pl/allegro/tech/build/axion/release/TestConfigSystemReader.groovy b/src/test/groovy/pl/allegro/tech/build/axion/release/TestConfigSystemReader.groovy deleted file mode 100644 index 486de946..00000000 --- a/src/test/groovy/pl/allegro/tech/build/axion/release/TestConfigSystemReader.groovy +++ /dev/null @@ -1,65 +0,0 @@ -package pl.allegro.tech.build.axion.release - -import org.eclipse.jgit.lib.Config -import org.eclipse.jgit.storage.file.FileBasedConfig -import org.eclipse.jgit.util.FS -import org.eclipse.jgit.util.SystemReader - -class TestConfigSystemReader extends SystemReader { - private static final SystemReader proxy = getInstance() - private final File userGitConfig - - TestConfigSystemReader(File userGitConfig) { - super() - this.userGitConfig = userGitConfig - } - - @Override - String getenv(String variable) { - return proxy.getenv(variable) - } - - @Override - String getHostname() { - return proxy.getHostname() - } - - @Override - String getProperty(String key) { - return proxy.getProperty(key) - } - - @Override - long getCurrentTime() { - return proxy.getCurrentTime() - } - - @Override - int getTimezone(long when) { - return proxy.getTimezone(when) - } - - @Override - FileBasedConfig openUserConfig(Config parent, FS fs) { - return new FileBasedConfig(parent, userGitConfig, fs) - } - - @Override - FileBasedConfig openJGitConfig(Config parent, FS fs) { - return proxy.openJGitConfig(parent, fs) - } - - @Override - FileBasedConfig openSystemConfig(Config parent, FS fs) { - return new FileBasedConfig(parent, null, fs) { - @Override - void load() { - } - - @Override - boolean isOutdated() { - return false - } - } - } -} diff --git a/src/test/groovy/pl/allegro/tech/build/axion/release/domain/ReleaserTest.groovy b/src/test/groovy/pl/allegro/tech/build/axion/release/domain/ReleaserTest.groovy index 62fefb86..35f3f06e 100644 --- a/src/test/groovy/pl/allegro/tech/build/axion/release/domain/ReleaserTest.groovy +++ b/src/test/groovy/pl/allegro/tech/build/axion/release/domain/ReleaserTest.groovy @@ -1,12 +1,11 @@ package pl.allegro.tech.build.axion.release.domain import pl.allegro.tech.build.axion.release.RepositoryBasedTest -import pl.allegro.tech.build.axion.release.TagPrefixConf import pl.allegro.tech.build.axion.release.domain.hooks.ReleaseHooksRunner import pl.allegro.tech.build.axion.release.domain.properties.Properties import pl.allegro.tech.build.axion.release.domain.scm.ScmService -import static pl.allegro.tech.build.axion.release.TagPrefixConf.* +import static pl.allegro.tech.build.axion.release.TagPrefixConf.fullPrefix import static pl.allegro.tech.build.axion.release.domain.properties.HooksPropertiesBuilder.hooksProperties import static pl.allegro.tech.build.axion.release.domain.properties.PropertiesBuilder.properties import static pl.allegro.tech.build.axion.release.domain.properties.VersionPropertiesBuilder.versionProperties @@ -25,12 +24,12 @@ class ReleaserTest extends RepositoryBasedTest { def "should release new version when not on tag"() { given: Properties rules = properties() - .withVersionRules(versionProperties().forceVersion('2.0.0').build()) - .withHooksRules(hooksProperties().withCommitHook().build()) - .build() + .withVersionRules(versionProperties().forceVersion('2.0.0').build()) + .withHooksRules(hooksProperties().withCommitHook().build()) + .build() when: - releaser.release(rules) + releaser.release(rules, false, 'main', ['main'] as Set) then: currentVersion() == '2.0.0' @@ -41,7 +40,7 @@ class ReleaserTest extends RepositoryBasedTest { repository.tag(fullPrefix() + '1.0.0') when: - releaser.release(context.rules()) + releaser.release(context.rules(), false, 'main', ['main'] as Set) then: currentVersion() == '1.0.0' @@ -50,12 +49,12 @@ class ReleaserTest extends RepositoryBasedTest { def "should release with forced pre-released versions"() { given: Properties rules = properties() - .withVersionRules(versionProperties().forceVersion('3.0.0-rc4').build()) - .withHooksRules(hooksProperties().withCommitHook().build()) - .build() + .withVersionRules(versionProperties().forceVersion('3.0.0-rc4').build()) + .withHooksRules(hooksProperties().withCommitHook().build()) + .build() when: - releaser.release(rules) + releaser.release(rules, false, 'main', ['main'] as Set) then: currentVersion() == '3.0.0-rc4' @@ -66,7 +65,7 @@ class ReleaserTest extends RepositoryBasedTest { repository.tag(fullPrefix() + '3.0.0-rc4') when: - releaser.release(context.rules()) + releaser.release(context.rules(), false, 'main', ['main'] as Set) then: currentVersion() == '3.0.0-rc4' @@ -74,11 +73,11 @@ class ReleaserTest extends RepositoryBasedTest { def "should increment pre-released version correctly"() { given: - repository.tag(fullPrefix() +'3.0.0-rc4') + repository.tag(fullPrefix() + '3.0.0-rc4') repository.commit(['*'], 'make is snapshot') when: - releaser.release(context.rules()) + releaser.release(context.rules(), false, 'main', ['main'] as Set) then: currentVersion() == '3.0.1' @@ -87,12 +86,12 @@ class ReleaserTest extends RepositoryBasedTest { def "should create release commit if configured"() { given: Properties rules = properties() - .withVersionRules(versionProperties().forceVersion('3.0.0').build()) - .withHooksRules(hooksProperties().withCommitHook().build()) - .build() + .withVersionRules(versionProperties().forceVersion('3.0.0').build()) + .withHooksRules(hooksProperties().withCommitHook().build()) + .build() when: - releaser.release(rules) + releaser.release(rules, false, 'main', ['main'] as Set) then: currentVersion() == '3.0.0' @@ -101,17 +100,46 @@ class ReleaserTest extends RepositoryBasedTest { def "should create release commit when on tag but forced"() { given: - repository.tag(fullPrefix() +'3.1.0') + repository.tag(fullPrefix() + '3.1.0') Properties rules = properties() - .withVersionRules(versionProperties().forceVersion('3.2.0').build()) - .withHooksRules(hooksProperties().withCommitHook().build()) - .build() + .withVersionRules(versionProperties().forceVersion('3.2.0').build()) + .withHooksRules(hooksProperties().withCommitHook().build()) + .build() when: - releaser.release(rules) + releaser.release(rules, false, 'main', ['main'] as Set as Set) then: currentVersion() == '3.2.0' repository.lastLogMessages(1) == ['release version: 3.2.0'] } + + def "should do release when isReleaseOnlyOnDefaultBranches option is set and current branch is in releaseBranchNames list"() { + given: + repository.tag(fullPrefix() + '1.0.0') + Properties rules = properties() + .withVersionRules(versionProperties().forceVersion('1.0.1').build()) + .withHooksRules(hooksProperties().withCommitHook().build()) + .build() + + when: + releaser.release(rules, true, 'main', ['main'] as Set) + + then: + currentVersion() == '1.0.1' + } + + def "should skip release when current branch is not in releaseBranchNames list"() { + given: + repository.tag(fullPrefix() + '1.0.0') + Properties rules = properties() + .withHooksRules(hooksProperties().withCommitHook().build()) + .build() + + when: + releaser.release(rules, true, 'feature/branch', ['main'] as Set) + + then: + currentVersion() == '1.0.0' + } } diff --git a/src/test/groovy/pl/allegro/tech/build/axion/release/domain/scm/ScmPropertiesBuilder.groovy b/src/test/groovy/pl/allegro/tech/build/axion/release/domain/scm/ScmPropertiesBuilder.groovy index 4dd5217c..3e496d6b 100644 --- a/src/test/groovy/pl/allegro/tech/build/axion/release/domain/scm/ScmPropertiesBuilder.groovy +++ b/src/test/groovy/pl/allegro/tech/build/axion/release/domain/scm/ScmPropertiesBuilder.groovy @@ -40,7 +40,8 @@ class ScmPropertiesBuilder { ScmIdentity.defaultIdentityWithoutAgents(), true, ['main', 'master'] as Set, - false + false, + true ) } diff --git a/src/test/groovy/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepositoryTest.groovy b/src/test/groovy/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepositoryTest.groovy index 286ef099..4ace9175 100644 --- a/src/test/groovy/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepositoryTest.groovy +++ b/src/test/groovy/pl/allegro/tech/build/axion/release/infrastructure/git/GitRepositoryTest.groovy @@ -9,14 +9,7 @@ import org.eclipse.jgit.lib.Constants import org.eclipse.jgit.transport.RemoteConfig import org.eclipse.jgit.transport.URIish import org.gradle.testfixtures.ProjectBuilder -import pl.allegro.tech.build.axion.release.RepositoryBasedTest -import pl.allegro.tech.build.axion.release.domain.scm.ScmException -import pl.allegro.tech.build.axion.release.domain.scm.ScmIdentity -import pl.allegro.tech.build.axion.release.domain.scm.ScmPosition -import pl.allegro.tech.build.axion.release.domain.scm.ScmProperties -import pl.allegro.tech.build.axion.release.domain.scm.ScmPushOptions -import pl.allegro.tech.build.axion.release.domain.scm.ScmRepositoryUnavailableException -import pl.allegro.tech.build.axion.release.domain.scm.TagsOnCommit +import pl.allegro.tech.build.axion.release.domain.scm.* import pl.allegro.tech.build.axion.release.util.WithEnvironment import spock.lang.Specification @@ -46,7 +39,6 @@ class GitRepositoryTest extends Specification { String defaultBranch; void setup() { - RepositoryBasedTest.setupLocalGitConfiguration() remoteRepositoryDir = File.createTempDir('axion-release', 'tmp') Map remoteRepositories = GitProjectBuilder.gitProject(remoteRepositoryDir).withInitialCommit().build() remoteRawRepository = remoteRepositories[Grgit] @@ -180,7 +172,7 @@ class GitRepositoryTest extends Specification { repository.tag(fullPrefix() + '1') repository.commit(['*'], "commit after " + fullPrefix() + "1") repository.tag(fullPrefix() + '2') - repository.commit(['*'], "commit after " + fullPrefix() +"2") + repository.commit(['*'], "commit after " + fullPrefix() + "2") rawRepository.checkout(branch: fullPrefix() + '1') repository.commit(['*'], "bugfix after " + fullPrefix() + "1") @@ -195,9 +187,9 @@ class GitRepositoryTest extends Specification { def "should return all tagged commits matching the pattern provided"() { given: repository.tag(fullPrefix() + '1') - repository.commit(['*'], "commit after " + fullPrefix() +"1") + repository.commit(['*'], "commit after " + fullPrefix() + "1") repository.tag(fullPrefix() + '2') - repository.commit(['*'], "commit after " + fullPrefix() +"2") + repository.commit(['*'], "commit after " + fullPrefix() + "2") repository.tag('another-tag-1') repository.commit(['*'], "commit after another-tag-1") repository.commit(['*'], "commit after another-tag-1-2") @@ -210,13 +202,13 @@ class GitRepositoryTest extends Specification { List allTaggedCommits = repository.taggedCommits(List.of(compile('^' + defaultPrefix() + '.*'))) then: - allTaggedCommits.collect { c -> c.tags[0] } == [fullPrefix() +'3',fullPrefix() + '4', fullPrefix() + '2', fullPrefix() +'1'] + allTaggedCommits.collect { c -> c.tags[0] } == [fullPrefix() + '3', fullPrefix() + '4', fullPrefix() + '2', fullPrefix() + '1'] } def "should return only tags that match with prefix"() { given: repository.tag(fullPrefix() + '1') - repository.commit(['*'], "commit after " + fullPrefix() +"1") + repository.commit(['*'], "commit after " + fullPrefix() + "1") repository.tag('otherTag') when: @@ -340,12 +332,12 @@ class GitRepositoryTest extends Specification { where: expectedIsClean | overridenIsCleanFlag | dirtyRepository - false | false | false - true | true | false - false | false | true - true | true | true - true | null | false - false | null | true + false | false | false + true | true | false + false | false | true + true | true | true + true | null | false + false | null | true } def "should provide current branch name from overriddenBranchName when in detached state and overriddenBranchName is set"() { @@ -428,7 +420,7 @@ class GitRepositoryTest extends Specification { then: customRemoteRawRepository.log(maxCommits: 1)*.fullMessage == ['commit after ' + fullPrefix() + 'custom'] - customRemoteRawRepository.tag.list()*.fullName == ['refs/tags/' + fullPrefix() +'custom'] + customRemoteRawRepository.tag.list()*.fullName == ['refs/tags/' + fullPrefix() + 'custom'] remoteRawRepository.log(maxCommits: 1)*.fullMessage == ['InitialCommit'] remoteRawRepository.tag.list()*.fullName == [] } @@ -452,11 +444,11 @@ class GitRepositoryTest extends Specification { def "should remove tag"() { given: - repository.tag(fullPrefix() +"1") + repository.tag(fullPrefix() + "1") int intermediateSize = repository.taggedCommits(List.of(~/.*/)).size() when: - repository.dropTag(fullPrefix() +"1") + repository.dropTag(fullPrefix() + "1") then: intermediateSize == 1 @@ -516,7 +508,7 @@ class GitRepositoryTest extends Specification { isLegacyNamed } - def "existing legacy default tagname repo should return false on partially matches"() { + def "existing legacy default tagname repo should return false on partially matches"() { given: repository.tag("release-1") repository.tag("bla1") @@ -682,17 +674,17 @@ class GitRepositoryTest extends Specification { ]) def 'should not unshallow repo locally'() { given: - remoteRepository.tag(fullPrefix() + '1') - 100.times { remoteRepository.commit(['*'], "commit after release") } - File repoDir = File.createTempDir('axion-release', 'tmp') - Map repositories = GitProjectBuilder.gitProject(repoDir, remoteRepositoryDir, 1).build() - GitRepository repository = repositories[GitRepository] + remoteRepository.tag(fullPrefix() + '1') + 100.times { remoteRepository.commit(['*'], "commit after release") } + File repoDir = File.createTempDir('axion-release', 'tmp') + Map repositories = GitProjectBuilder.gitProject(repoDir, remoteRepositoryDir, 1).build() + GitRepository repository = repositories[GitRepository] when: - TagsOnCommit tags = repository.latestTags(List.of(compile('^' + defaultPrefix() + '.*'))) + TagsOnCommit tags = repository.latestTags(List.of(compile('^' + defaultPrefix() + '.*'))) then: - tags.tags.isEmpty() + tags.tags.isEmpty() } private void commitFile(String subDir, String fileName) { From 6590f107d06b77f8d50119386884679c7cc8209a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Ga=C5=82ek?= Date: Tue, 27 Aug 2024 11:02:30 +0200 Subject: [PATCH 4/4] argument class extracted (#799) --- .../axion/release/CreateReleaseTask.groovy | 12 ++++---- .../ReleaseBranchesConfiguration.groovy | 29 +++++++++++++++++++ .../build/axion/release/ReleaseTask.groovy | 12 ++++---- .../build/axion/release/domain/Releaser.java | 22 +++++++------- .../axion/release/domain/scm/ScmService.java | 2 +- .../axion/release/domain/ReleaserTest.groovy | 19 ++++++------ 6 files changed, 62 insertions(+), 34 deletions(-) create mode 100644 src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseBranchesConfiguration.groovy diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/CreateReleaseTask.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/CreateReleaseTask.groovy index f1e2d455..0ba97aa5 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/CreateReleaseTask.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/CreateReleaseTask.groovy @@ -10,11 +10,11 @@ abstract class CreateReleaseTask extends BaseAxionTask { void release() { VersionResolutionContext context = resolutionContext() Releaser releaser = context.releaser() - def scmService = context.scmService() - def repository = context.repository() - def releaseBranchNames = scmService.getReleaseBranchNames() - def currentBranch = repository.currentPosition().getBranch() - def isReleaseOnlyOnDefaultBranches = scmService.isReleaseOnlyOnDefaultBranches() - releaser.release(context.rules(), isReleaseOnlyOnDefaultBranches, currentBranch, releaseBranchNames) + ReleaseBranchesConfiguration releaseBranchesConfiguration = new ReleaseBranchesConfiguration( + context.scmService().isReleaseOnlyOnReleaseBranches(), + context.repository().currentPosition().getBranch(), + context.scmService().getReleaseBranchNames() + ) + releaser.release(context.rules(), releaseBranchesConfiguration) } } diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseBranchesConfiguration.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseBranchesConfiguration.groovy new file mode 100644 index 00000000..d4a8ab7f --- /dev/null +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseBranchesConfiguration.groovy @@ -0,0 +1,29 @@ +package pl.allegro.tech.build.axion.release + +class ReleaseBranchesConfiguration { + private final boolean releaseOnlyOnReleaseBranches + private final String currentBranch + private final Set releaseBranchNames + + ReleaseBranchesConfiguration( + boolean releaseOnlyOnReleaseBranches, + String currentBranch, + Set releaseBranchNames + ) { + this.releaseOnlyOnReleaseBranches = releaseOnlyOnReleaseBranches + this.currentBranch = currentBranch + this.releaseBranchNames = releaseBranchNames + } + + boolean shouldRelease() { + return releaseOnlyOnReleaseBranches && !releaseBranchNames.contains(currentBranch) + } + + String getCurrentBranch() { + return currentBranch + } + + Set getReleaseBranchNames() { + return releaseBranchNames + } +} diff --git a/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy b/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy index 6218dfdc..8ff57718 100644 --- a/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy +++ b/src/main/groovy/pl/allegro/tech/build/axion/release/ReleaseTask.groovy @@ -3,7 +3,6 @@ package pl.allegro.tech.build.axion.release import org.gradle.api.tasks.TaskAction import pl.allegro.tech.build.axion.release.domain.Releaser import pl.allegro.tech.build.axion.release.domain.scm.ScmPushResult -import pl.allegro.tech.build.axion.release.domain.scm.ScmService import pl.allegro.tech.build.axion.release.infrastructure.di.VersionResolutionContext import java.nio.file.Files @@ -16,11 +15,12 @@ abstract class ReleaseTask extends BaseAxionTask { void release() { VersionResolutionContext context = resolutionContext() Releaser releaser = context.releaser() - ScmService scmService = context.scmService() - def releaseBranchNames = scmService.getReleaseBranchNames() - def currentBranch = context.repository().currentPosition().getBranch() - def isReleaseOnlyOnDefaultBranches = scmService.isReleaseOnlyOnDefaultBranches() - ScmPushResult result = releaser.releaseAndPush(context.rules(), isReleaseOnlyOnDefaultBranches, currentBranch, releaseBranchNames) + ReleaseBranchesConfiguration releaseBranchesConfiguration = new ReleaseBranchesConfiguration( + context.scmService().isReleaseOnlyOnReleaseBranches(), + context.repository().currentPosition().getBranch(), + context.scmService().getReleaseBranchNames() + ) + ScmPushResult result = releaser.releaseAndPush(context.rules(), releaseBranchesConfiguration) if (!result.success) { def status = result.failureStatus diff --git a/src/main/java/pl/allegro/tech/build/axion/release/domain/Releaser.java b/src/main/java/pl/allegro/tech/build/axion/release/domain/Releaser.java index 6aa80a43..9bbfb5f3 100644 --- a/src/main/java/pl/allegro/tech/build/axion/release/domain/Releaser.java +++ b/src/main/java/pl/allegro/tech/build/axion/release/domain/Releaser.java @@ -3,13 +3,13 @@ import com.github.zafarkhaja.semver.Version; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; +import pl.allegro.tech.build.axion.release.ReleaseBranchesConfiguration; import pl.allegro.tech.build.axion.release.domain.hooks.ReleaseHooksRunner; import pl.allegro.tech.build.axion.release.domain.properties.Properties; import pl.allegro.tech.build.axion.release.domain.scm.ScmPushResult; import pl.allegro.tech.build.axion.release.domain.scm.ScmService; import java.util.Optional; -import java.util.Set; public class Releaser { @@ -24,12 +24,13 @@ public Releaser(VersionService versionService, ScmService repository, ReleaseHoo this.hooksRunner = hooksRunner; } - public Optional release(Properties properties, - boolean isReleaseOnlyOnDefaultBranches, - String currentBranch, - Set releaseBranchNames) { - if (isReleaseOnlyOnDefaultBranches && !releaseBranchNames.contains(currentBranch)) { - String message = String.format("Release step skipped since 'releaseOnlyOnDefaultBranches' option is set, and '%s' was not in 'releaseBranchNames' list [%s]", currentBranch, String.join(",", releaseBranchNames)); + public Optional release(Properties properties, ReleaseBranchesConfiguration releaseBranchesConfiguration) { + if (releaseBranchesConfiguration.shouldRelease()) { + String message = String.format( + "Release step skipped since 'releaseOnlyOnDefaultBranches' option is set, and '%s' was not in 'releaseBranchNames' list [%s]", + releaseBranchesConfiguration.getCurrentBranch(), + String.join(",", releaseBranchesConfiguration.getReleaseBranchNames()) + ); logger.quiet(message); return Optional.empty(); } @@ -56,11 +57,8 @@ public Optional release(Properties properties, } } - public ScmPushResult releaseAndPush(Properties rules, - boolean isReleaseOnlyOnDefaultBranches, - String currentBranch, - Set releaseBranchNames) { - Optional releasedTagName = release(rules, isReleaseOnlyOnDefaultBranches, currentBranch, releaseBranchNames); + public ScmPushResult releaseAndPush(Properties rules, ReleaseBranchesConfiguration releaseBranchesConfiguration) { + Optional releasedTagName = release(rules, releaseBranchesConfiguration); if (releasedTagName.isEmpty()) { return new ScmPushResult(true, Optional.empty(), Optional.empty()); diff --git a/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmService.java b/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmService.java index 56158c42..6db50e02 100644 --- a/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmService.java +++ b/src/main/java/pl/allegro/tech/build/axion/release/domain/scm/ScmService.java @@ -75,7 +75,7 @@ public Set getReleaseBranchNames() { return scmProperties.getReleaseBranchNames(); } - public boolean isReleaseOnlyOnDefaultBranches(){ + public boolean isReleaseOnlyOnReleaseBranches(){ return scmProperties.isReleaseOnlyOnReleaseBranches(); } } diff --git a/src/test/groovy/pl/allegro/tech/build/axion/release/domain/ReleaserTest.groovy b/src/test/groovy/pl/allegro/tech/build/axion/release/domain/ReleaserTest.groovy index 35f3f06e..a14572e1 100644 --- a/src/test/groovy/pl/allegro/tech/build/axion/release/domain/ReleaserTest.groovy +++ b/src/test/groovy/pl/allegro/tech/build/axion/release/domain/ReleaserTest.groovy @@ -1,5 +1,6 @@ package pl.allegro.tech.build.axion.release.domain +import pl.allegro.tech.build.axion.release.ReleaseBranchesConfiguration import pl.allegro.tech.build.axion.release.RepositoryBasedTest import pl.allegro.tech.build.axion.release.domain.hooks.ReleaseHooksRunner import pl.allegro.tech.build.axion.release.domain.properties.Properties @@ -29,7 +30,7 @@ class ReleaserTest extends RepositoryBasedTest { .build() when: - releaser.release(rules, false, 'main', ['main'] as Set) + releaser.release(rules, new ReleaseBranchesConfiguration(false, 'main', ['main'] as Set)) then: currentVersion() == '2.0.0' @@ -40,7 +41,7 @@ class ReleaserTest extends RepositoryBasedTest { repository.tag(fullPrefix() + '1.0.0') when: - releaser.release(context.rules(), false, 'main', ['main'] as Set) + releaser.release(context.rules(), new ReleaseBranchesConfiguration(false, 'main', ['main'] as Set)) then: currentVersion() == '1.0.0' @@ -54,7 +55,7 @@ class ReleaserTest extends RepositoryBasedTest { .build() when: - releaser.release(rules, false, 'main', ['main'] as Set) + releaser.release(rules, new ReleaseBranchesConfiguration(false, 'main', ['main'] as Set)) then: currentVersion() == '3.0.0-rc4' @@ -65,7 +66,7 @@ class ReleaserTest extends RepositoryBasedTest { repository.tag(fullPrefix() + '3.0.0-rc4') when: - releaser.release(context.rules(), false, 'main', ['main'] as Set) + releaser.release(context.rules(), new ReleaseBranchesConfiguration(false, 'main', ['main'] as Set)) then: currentVersion() == '3.0.0-rc4' @@ -77,7 +78,7 @@ class ReleaserTest extends RepositoryBasedTest { repository.commit(['*'], 'make is snapshot') when: - releaser.release(context.rules(), false, 'main', ['main'] as Set) + releaser.release(context.rules(), new ReleaseBranchesConfiguration(false, 'main', ['main'] as Set)) then: currentVersion() == '3.0.1' @@ -91,7 +92,7 @@ class ReleaserTest extends RepositoryBasedTest { .build() when: - releaser.release(rules, false, 'main', ['main'] as Set) + releaser.release(rules, new ReleaseBranchesConfiguration(false, 'main', ['main'] as Set)) then: currentVersion() == '3.0.0' @@ -107,7 +108,7 @@ class ReleaserTest extends RepositoryBasedTest { .build() when: - releaser.release(rules, false, 'main', ['main'] as Set as Set) + releaser.release(rules, new ReleaseBranchesConfiguration(false, 'main', ['main'] as Set)) then: currentVersion() == '3.2.0' @@ -123,7 +124,7 @@ class ReleaserTest extends RepositoryBasedTest { .build() when: - releaser.release(rules, true, 'main', ['main'] as Set) + releaser.release(rules, new ReleaseBranchesConfiguration(true, 'main', ['main'] as Set)) then: currentVersion() == '1.0.1' @@ -137,7 +138,7 @@ class ReleaserTest extends RepositoryBasedTest { .build() when: - releaser.release(rules, true, 'feature/branch', ['main'] as Set) + releaser.release(rules, new ReleaseBranchesConfiguration(true, 'feature/branch', ['main'] as Set)) then: currentVersion() == '1.0.0'