From d6390a8c0ecff53493b1bfd1b9056eb5215d0866 Mon Sep 17 00:00:00 2001 From: "jordan.eales" Date: Thu, 7 Dec 2023 16:28:46 +0000 Subject: [PATCH] Issue 1741 - Add to main branch option to match what is possible in the Pact Flow UI --- .../pact/core/pactbroker/PactBrokerClient.kt | 8 +++- .../pactbroker/PactBrokerClientSpec.groovy | 48 +++++++++++++------ .../provider/gradle/PactCanIDeployTask.groovy | 11 ++++- .../pact/provider/gradle/PactPlugin.groovy | 1 + .../gradle/PactCanIDeployTaskSpec.groovy | 26 +++++++++- .../pact/provider/maven/PactCanIDeployMojo.kt | 5 +- .../maven/PactCanIDeployMojoSpec.groovy | 15 ++++++ 7 files changed, 94 insertions(+), 20 deletions(-) diff --git a/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt b/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt index 5a49d5114..b8ec5b7ec 100644 --- a/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt +++ b/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt @@ -101,7 +101,7 @@ sealed class Latest { /** * Specifies the target for the can-i-deploy check (tag or environment) */ -data class To @JvmOverloads constructor(val tag: String? = null, val environment: String? = null) +data class To @JvmOverloads constructor(val tag: String? = null, val environment: String? = null, val mainBranch: Boolean? = null) /** * Model for a CanIDeploy result @@ -1151,7 +1151,11 @@ open class PactBrokerClient( if (to.tag.isNotEmpty()) { params.add("latest" to "true") params.add("tag" to escaper.escape(to.tag)) - } else if (to.environment.isNullOrEmpty()) { + } + + if (to.mainBranch == true) { + params.add("mainBranch" to "true") + } else if (to.environment.isNullOrEmpty() && to.tag.isNullOrEmpty()) { params.add("latest" to "true") } } else { diff --git a/core/pactbroker/src/test/groovy/au/com/dius/pact/core/pactbroker/PactBrokerClientSpec.groovy b/core/pactbroker/src/test/groovy/au/com/dius/pact/core/pactbroker/PactBrokerClientSpec.groovy index ba6e6dc94..3af60bb67 100644 --- a/core/pactbroker/src/test/groovy/au/com/dius/pact/core/pactbroker/PactBrokerClientSpec.groovy +++ b/core/pactbroker/src/test/groovy/au/com/dius/pact/core/pactbroker/PactBrokerClientSpec.groovy @@ -677,21 +677,39 @@ class PactBrokerClientSpec extends Specification { where: - pacticipant | pacticipantVersion | latest | to | ignore || result - 'Test' | '' | new Latest.UseLatest(true) | null | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true' - 'Test' | '100' | new Latest.UseLatest(false) | null | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][version]=100&latest=true' - 'Test' | '' | new Latest.UseLatestTag('tst') | null | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][tag]=tst&latest=true' - 'Test' | '' | new Latest.UseLatest(true) | new To('tst') | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true&tag=tst' - 'Test 1 2 3' | '' | new Latest.UseLatest(true) | null | [] || 'q[][pacticipant]=Test+1+2+3&latestby=cvp&q[][latest]=true&latest=true' - 'Test' | '1 0 0' | new Latest.UseLatest(false) | null | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][version]=1+0+0&latest=true' - 'Test' | '' | new Latest.UseLatestTag('tst 3/4') | null | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][tag]=tst+3%2F4&latest=true' - 'Test' | '' | new Latest.UseLatest(true) | new To('tst 3/4') | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true&tag=tst+3%2F4' - 'Test' | '' | new Latest.UseLatest(true) | null | [new IgnoreSelector('bob', null)] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true&ignore[][pacticipant]=bob' - 'Test' | '' | new Latest.UseLatest(true) | null | [new IgnoreSelector('bob', '100')] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true&ignore[][pacticipant]=bob&ignore[][version]=100' - 'Test' | '' | new Latest.UseLatest(true) | null | [new IgnoreSelector('bob', null), new IgnoreSelector('fred', null)] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true&ignore[][pacticipant]=bob&ignore[][pacticipant]=fred' - 'Test' | '' | new Latest.UseLatest(true) | new To(null, 'env1') | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env1' - 'Test' | '' | new Latest.UseLatest(true) | new To('tag1', 'env1') | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env1&latest=true&tag=tag1' - 'Test' | '' | new Latest.UseLatest(true) | new To(null, 'env 1') | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env+1' + pacticipant | pacticipantVersion | latest | to | ignore || result + 'Test' | '' | new Latest.UseLatest(true) | null | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true' + 'Test' | '100' | new Latest.UseLatest(false) | null | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][version]=100&latest=true' + 'Test' | '' | new Latest.UseLatestTag('tst') | null | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][tag]=tst&latest=true' + 'Test' | '' | new Latest.UseLatest(true) | new To('tst') | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true&tag=tst' + 'Test 1 2 3' | '' | new Latest.UseLatest(true) | null | [] || 'q[][pacticipant]=Test+1+2+3&latestby=cvp&q[][latest]=true&latest=true' + 'Test' | '1 0 0' | new Latest.UseLatest(false) | null | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][version]=1+0+0&latest=true' + 'Test' | '' | new Latest.UseLatestTag('tst 3/4') | null | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][tag]=tst+3%2F4&latest=true' + 'Test' | '' | new Latest.UseLatest(true) | new To('tst 3/4') | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true&tag=tst+3%2F4' + 'Test' | '' | new Latest.UseLatest(true) | null | [new IgnoreSelector('bob', null)] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true&ignore[][pacticipant]=bob' + 'Test' | '' | new Latest.UseLatest(true) | null | [new IgnoreSelector('bob', '100')] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true&ignore[][pacticipant]=bob&ignore[][version]=100' + 'Test' | '' | new Latest.UseLatest(true) | null | [new IgnoreSelector('bob', null), new IgnoreSelector('fred', null)] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&latest=true&ignore[][pacticipant]=bob&ignore[][pacticipant]=fred' + 'Test' | '' | new Latest.UseLatest(true) | new To(null, 'env1', null) | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env1' + 'Test' | '' | new Latest.UseLatest(true) | new To('tag1', 'env1', null) | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env1&latest=true&tag=tag1' + 'Test' | '' | new Latest.UseLatest(true) | new To(null, 'env 1', null) | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env+1' + } + + @Unroll + @SuppressWarnings('UnnecessaryBooleanExpression') + // Had to move to different test as codenarc wouldn't allow too many rows of complexity + def 'can-i-deploy to main branch - matrix query'() { + expect: + PactBrokerClient.internalBuildMatrixQuery(pacticipant, pacticipantVersion, (Latest) latest, to, ignore) == result + + where: + + pacticipant | pacticipantVersion | latest | to | ignore || result + 'Test' | '' | new Latest.UseLatest(true) | new To(null, 'env1', false) | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env1' + 'Test' | '' | new Latest.UseLatest(true) | new To('tag1', 'env1', false) | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env1&latest=true&tag=tag1' + 'Test' | '' | new Latest.UseLatest(true) | new To(null, 'env 1', false) | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env+1' + 'Test' | '' | new Latest.UseLatest(true) | new To(null, 'env1', true) | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env1&mainBranch=true' + 'Test' | '' | new Latest.UseLatest(true) | new To('tag1', 'env1', true) | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env1&latest=true&tag=tag1&mainBranch=true' + 'Test' | '' | new Latest.UseLatest(true) | new To(null, 'env 1', true) | [] || 'q[][pacticipant]=Test&latestby=cvp&q[][latest]=true&environment=env+1&mainBranch=true' } @Issue('#1511') diff --git a/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTask.groovy b/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTask.groovy index 0d63b2689..d3795548f 100644 --- a/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTask.groovy +++ b/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTask.groovy @@ -21,6 +21,7 @@ abstract class PactCanIDeployTask extends PactCanIDeployBaseTask { static final String PACTICIPANT_VERSION = 'pacticipantVersion' static final String TO = 'toTag' static final String TO_ENVIRONMENT = 'toEnvironment' + static final String TO_MAIN_BRANCH = 'toMainBranch' static final String LATEST = 'latest' @Internal @@ -46,6 +47,10 @@ abstract class PactCanIDeployTask extends PactCanIDeployBaseTask { @Optional abstract Property getToEnvironment() + @Input + @Optional + abstract Property getToMainBranch() + @Input @Optional abstract Property getLatestProp() @@ -79,7 +84,11 @@ abstract class PactCanIDeployTask extends PactCanIDeployBaseTask { if (toEnvironment.present) { environment = toEnvironment.get() } - def to = new To(toTag, environment) + Boolean mainBranch = null + if (toMainBranch.present) { + mainBranch = toMainBranch.get() + } + def to = new To(toTag, environment, mainBranch) def t = new TermColors() logger.debug( "Calling canIDeploy(pacticipant=$pacticipant, pacticipantVersion=$pacticipantVersion, latest=$latest, to=$to)" diff --git a/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactPlugin.groovy b/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactPlugin.groovy index 981778d04..9f1842f50 100644 --- a/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactPlugin.groovy +++ b/provider/gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactPlugin.groovy @@ -40,6 +40,7 @@ class PactPlugin extends PactPluginBase { toProp.set(project.hasProperty(TO) ? project.property(TO) : null) latestProp.set(project.hasProperty(LATEST) ? project.property(LATEST) : null) toEnvironment.set(project.hasProperty(TO_ENVIRONMENT) ? project.property(TO_ENVIRONMENT) : null) + toMainBranch.set(project.hasProperty(TO_MAIN_BRANCH) ? project.property(TO_MAIN_BRANCH) : null) } project.afterEvaluate { diff --git a/provider/gradle/src/test/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTaskSpec.groovy b/provider/gradle/src/test/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTaskSpec.groovy index ea9eaff19..1bcea14e3 100644 --- a/provider/gradle/src/test/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTaskSpec.groovy +++ b/provider/gradle/src/test/groovy/au/com/dius/pact/provider/gradle/PactCanIDeployTaskSpec.groovy @@ -129,7 +129,7 @@ class PactCanIDeployTaskSpec extends Specification { then: notThrown(GradleScriptException) 1 * project.tasks.canIDeploy.brokerClient.canIDeploy('pacticipant', '1.0.0', - new Latest.UseLatest(true), new To('prod'), _) >> new CanIDeployResult(true, '', '', null, 'verificationResultUrl') + new Latest.UseLatest(true), new To('prod', null), _) >> new CanIDeployResult(true, '', '', null, 'verificationResultUrl') } def 'passes optional parameters to the pact broker client'() { @@ -180,6 +180,30 @@ class PactCanIDeployTaskSpec extends Specification { new Latest.UseLatest(true), new To(null, 'prod'), _) >> new CanIDeployResult(true, '', '', null, null) } + def 'passes toMainBranch parameter to the pact broker client'() { + given: + project.pact { + broker { + pactBrokerUrl = 'pactBrokerUrl' + } + } + project.ext.pacticipant = 'pacticipant' + project.ext.pacticipantVersion = '1.0.0' + project.ext.latest = 'true' + project.ext.toMainBranch = true + project.evaluate() + + project.tasks.canIDeploy.brokerClient = Mock(PactBrokerClient) + + when: + project.tasks.canIDeploy.canIDeploy() + + then: + notThrown(GradleScriptException) + 1 * project.tasks.canIDeploy.brokerClient.canIDeploy('pacticipant', '1.0.0', + new Latest.UseLatest(true), new To(null, null, true), _) >> new CanIDeployResult(true, '', '', null, null) + } + def 'throws an exception if the pact broker client says no'() { given: project.pact { diff --git a/provider/maven/src/main/kotlin/au/com/dius/pact/provider/maven/PactCanIDeployMojo.kt b/provider/maven/src/main/kotlin/au/com/dius/pact/provider/maven/PactCanIDeployMojo.kt index 675a5f049..4b03a792f 100644 --- a/provider/maven/src/main/kotlin/au/com/dius/pact/provider/maven/PactCanIDeployMojo.kt +++ b/provider/maven/src/main/kotlin/au/com/dius/pact/provider/maven/PactCanIDeployMojo.kt @@ -33,6 +33,9 @@ open class PactCanIDeployMojo : PactBaseMojo() { @Parameter(property = "toEnvironment", defaultValue = "") private var toEnvironment: String? = "" + @Parameter(property = "toMainBranch") + private var toMainBranch: Boolean? = null + @Parameter(property = "ignore") private var ignore: Array = emptyArray() @@ -56,7 +59,7 @@ open class PactCanIDeployMojo : PactBaseMojo() { throw MojoExecutionException("The can-i-deploy task requires -DpacticipantVersion=... or -Dlatest=true", null) } - val to = To(toTag, toEnvironment) + val to = To(toTag, toEnvironment, toMainBranch) val result = brokerClient!!.canIDeploy(pacticipant!!, pacticipantVersion.orEmpty(), latest, to, ignore.asList()) if (result.ok) { println("Computer says yes \\o/ ${result.message}\n\n${t.green(result.reason)}") diff --git a/provider/maven/src/test/groovy/au/com/dius/pact/provider/maven/PactCanIDeployMojoSpec.groovy b/provider/maven/src/test/groovy/au/com/dius/pact/provider/maven/PactCanIDeployMojoSpec.groovy index d3611fb18..487c9e27c 100644 --- a/provider/maven/src/test/groovy/au/com/dius/pact/provider/maven/PactCanIDeployMojoSpec.groovy +++ b/provider/maven/src/test/groovy/au/com/dius/pact/provider/maven/PactCanIDeployMojoSpec.groovy @@ -113,6 +113,21 @@ class PactCanIDeployMojoSpec extends Specification { new Latest.UseLatest(true), new To('', 'prod'), _) >> new CanIDeployResult(true, '', '', null, null) } + def 'passes toMainBranch parameter to the pact broker client'() { + given: + mojo.latest = 'true' + mojo.toMainBranch = true + mojo.brokerClient = Mock(PactBrokerClient) + + when: + mojo.execute() + + then: + notThrown(MojoExecutionException) + 1 * mojo.brokerClient.canIDeploy('test', '1234', + new Latest.UseLatest(true), new To('', '', true), _) >> new CanIDeployResult(true, '', '', null, null) + } + def 'passes ignore parameters to the pact broker client'() { given: IgnoreSelector[] selectors = [new IgnoreSelector('bob')] as IgnoreSelector[]