diff --git a/README.md b/README.md index f97cc54..31ec2eb 100644 --- a/README.md +++ b/README.md @@ -74,21 +74,21 @@ Tested with Oracle JDK8 | Gradle Version | Works | | :------------- | :---------: | | <= 2.13 | ![no] | -| 2.14 | ![yes] | -| 3.0 | ![yes] | -| 3.1 | ![yes] | -| 3.2 | ![yes] | -| 3.4 | ![yes] | -| 3.4.1 | ![yes] | -| 3.5 | ![yes] | -| 3.5.1 | ![yes] | -| 4.0 | ![yes] | -| 4.1 | ![yes] | -| 4.2 | ![yes] | -| 4.3 | ![yes] | -| 4.4 | ![yes] | -| 4.5 | ![yes] | -| 4.6 | ![yes] | +| 2.14 | ![no] | +| 3.0 | ![no] | +| 3.1 | ![no] | +| 3.2 | ![no] | +| 3.4 | ![no] | +| 3.4.1 | ![no] | +| 3.5 | ![no] | +| 3.5.1 | ![no] | +| 4.0 | ![no] | +| 4.1 | ![no] | +| 4.2 | ![no] | +| 4.3 | ![no] | +| 4.4 | ![no] | +| 4.5 | ![no] | +| 4.6 | ![no] | | 4.7 | ![yes] | | 4.8 | ![yes] | | 4.9 | ![yes] | diff --git a/src/integrationTest/groovy/wooga/gradle/github/GithubPluginExtensionIntegrationSpec.groovy b/src/integrationTest/groovy/wooga/gradle/github/GithubPluginExtensionIntegrationSpec.groovy new file mode 100644 index 0000000..03c77c3 --- /dev/null +++ b/src/integrationTest/groovy/wooga/gradle/github/GithubPluginExtensionIntegrationSpec.groovy @@ -0,0 +1,198 @@ +package wooga.gradle.github + +import spock.lang.Unroll + +class GithubPluginExtensionIntegrationSpec extends IntegrationSpec { + + def setup() { + buildFile << """ + ${applyPlugin(GithubPlugin)} + """.stripIndent() + } + + enum PropertyLocation { + none, script, property, env + + String reason() { + switch (this) { + case script: + return "value is provided in script" + case property: + return "value is provided in props" + case env: + return "value is set in env" + default: + return "no value was configured" + } + } + } + + enum PropertySetType { + setter, setMethod, propertySet + + String reason() { + switch (this) { + case setter: + return "value is provided with setter" + case setMethod: + return "value is with set method" + case propertySet: + return "value is set in property with set" + } + } + } + + String envNameFromProperty(String property) { + "GITHUB_${property.replaceAll(/([A-Z])/, "_\$1").toUpperCase()}" + } + + @Unroll(":#property returns '#testValue' if #reason") + def "extension property :#property returns '#testValue' if #reason"() { + given: + buildFile << """ + task(custom) { + doLast { + def value = "not set" + if(github.${property}.present) { + value = github.${property}.get() + } + + println("github.${property}: " + value) + } + } + """ + + and: "a gradle.properties" + def propertiesFile = createFile("gradle.properties") + + def escapedValue = (value instanceof String) ? escapedPath(value) : value + + switch (location) { + case PropertyLocation.script: + buildFile << "github.${property} = ${escapedValue}" + break + case PropertyLocation.property: + propertiesFile << "github.${property} = ${escapedValue}" + break + case PropertyLocation.env: + environmentVariables.set(envNameFromProperty(property), "${value}") + break + default: + break + } + + when: "" + def result = runTasks("custom") + + then: + result.success + result.standardOutput.contains("github.${property}: ${testValue}") + + where: + property | value | expectedValue | providedValue | location + "repositoryName" | "testUser/testRepo" | _ | "testUser/testRepo" | PropertyLocation.property + "repositoryName" | "'testUser/testRepo'" | 'testUser/testRepo' | "testUser/testRepo" | PropertyLocation.script + "repositoryName" | null | "not set" | null | PropertyLocation.none + + "username" | "testUser" | _ | "testUser" | PropertyLocation.property + "username" | "'testUser'" | 'testUser' | "testUser" | PropertyLocation.script + "username" | null | "not set" | null | PropertyLocation.none + + "password" | "testPass" | _ | "testPass" | PropertyLocation.property + "password" | "'testPass'" | 'testPass' | "testPass" | PropertyLocation.script + "password" | null | "not set" | null | PropertyLocation.none + + "token" | "accessToken" | _ | "accessToken" | PropertyLocation.property + "token" | "'accessToken'" | 'accessToken' | "accessToken" | PropertyLocation.script + "token" | null | "not set" | null | PropertyLocation.none + + "baseUrl" | "https://api.github.com" | 'not set' | "https://api.github.com" | PropertyLocation.property + "baseUrl" | "'https://api.github.com'" | 'https://api.github.com' | "https://api.github.com" | PropertyLocation.script + "baseUrl" | null | "not set" | null | PropertyLocation.none + + testValue = (expectedValue == _) ? value : expectedValue + reason = location.reason() + ((location == PropertyLocation.none) ? "" : " with '$providedValue'") + } + + @Unroll + def "can set #property with #type"() { + given: + buildFile << """ + task(custom) { + doLast { + def value = "not set" + if(github.${property}.present) { + value = github.${property}.get() + } + + println("github.${property}: " + value) + } + } + """ + + def escapedValue = (value instanceof String) ? escapedPath(value) : value + + switch (type) { + case PropertySetType.setter: + buildFile << "github.${property} = ${escapedValue}" + break + case PropertySetType.setMethod: + buildFile << "github.${property} ${escapedValue}" + break + case PropertySetType.propertySet: + buildFile << "github.${property}.set(${escapedValue})" + break + } + + when: "" + def result = runTasks("custom") + + then: + result.success + result.standardOutput.contains("github.${property}: ${testValue}") + + where: + property | value | expectedValue | type + "repositoryName" | "'testUser/testRepo'" | "testUser/testRepo" | PropertySetType.setter + "repositoryName" | "'testUser/testRepo'" | "testUser/testRepo" | PropertySetType.setMethod + "repositoryName" | "'testUser/testRepo'" | "testUser/testRepo" | PropertySetType.propertySet + + "username" | "'testUser'" | "testUser" | PropertySetType.setter + "username" | "'testUser'" | "testUser" | PropertySetType.setMethod + "username" | "'testUser'" | "testUser" | PropertySetType.propertySet + + "password" | "'testPass'" | "testPass" | PropertySetType.setter + "password" | "'testPass'" | "testPass" | PropertySetType.setMethod + "password" | "'testPass'" | "testPass" | PropertySetType.propertySet + + "token" | "'accessToken'" | "accessToken" | PropertySetType.setter + "token" | "'accessToken'" | "accessToken" | PropertySetType.setMethod + "token" | "'accessToken'" | "accessToken" | PropertySetType.propertySet + + "baseUrl" | "'https://api.github.com'" | "https://api.github.com" | PropertySetType.setter + "baseUrl" | "'https://api.github.com'" | "https://api.github.com" | PropertySetType.setMethod + "baseUrl" | "'https://api.github.com'" | "https://api.github.com" | PropertySetType.propertySet + + testValue = (expectedValue == _) ? value : expectedValue + } + + def "validates repoName property before set"() { + given: "" + buildFile << """ + github.repositoryName = "${repositoryName}" + """.stripIndent() + + when: + def result = runTasks("tasks") + + then: + result.success == (expectedError == null) + if(!result.success) { + outputContains(result, expectedError) + } + + where: + repositoryName | expectedError + 'some value' | "Repository value 'some value' is not a valid github repository name. Expecting `owner/repo`" + } +} diff --git a/src/integrationTest/groovy/wooga/gradle/github/GithubPublishPropertySpec.groovy b/src/integrationTest/groovy/wooga/gradle/github/GithubPublishPropertySpec.groovy index 1f966e3..aaab0d7 100644 --- a/src/integrationTest/groovy/wooga/gradle/github/GithubPublishPropertySpec.groovy +++ b/src/integrationTest/groovy/wooga/gradle/github/GithubPublishPropertySpec.groovy @@ -499,74 +499,70 @@ class GithubPublishPropertySpec extends GithubPublishIntegration { } @Unroll - def "fails when setting #methodName with invalid repository name #repoName"() { - given: "files to publish" - createTestAssetsToPublish(1) - - and: "a buildfile with publish task" - buildFile << """ - version "0.1.0" - - task testPublish(type:wooga.gradle.github.publish.tasks.GithubPublish) { - from "releaseAssets" - tagName = "v0.1.0" - $methodName($repoName) - token = "$testUserToken" - } + def "can set publishMethod with #publishMethod #methodValue and #methodName Kotlin"() { + given: "a kotlin buildfile" + def kotlinBuildFile = createFile("build.gradle.kts", projectDir) + buildFile.delete() + kotlinBuildFile << """ + plugins { + id("net.wooga.github") version "1.3.0" + } """.stripIndent() - expect: - def result = runTasksWithFailure("testPublish") - outputContains(result, expectedError) - - where: - repoName | useSetter | expectedError - "'invalid'" | true | "Repository value $repoName is not a valid github repository name" - "'invalid'" | false | "Repository value $repoName is not a valid github repository name" - null | true | "java.lang.IllegalArgumentException: repository" - null | false | "java.lang.IllegalArgumentException: repository" - "''" | false | "java.lang.IllegalArgumentException: repository" - "''" | false | "java.lang.IllegalArgumentException: repository" - "'https://github.com/owner/invalid.git'" | true | "Repository value $repoName is not a valid github repository name" - "'https://github.com/owner/invalid.git'" | false | "Repository value $repoName is not a valid github repository name" - - methodName = useSetter ? "setRepositoryName" : "repositoryName" - } + fork = true - @Unroll - def "fails when setting #methodName with invalid token #token"() { - given: "files to publish" + and: "files to publish" createTestAssetsToPublish(1) + and: "optional release" + if(publishMethod == PublishMethod.update) { + createRelease(tagName) + } + and: "a buildfile with publish task" - buildFile << """ - version "0.1.0" - task testPublish(type:wooga.gradle.github.publish.tasks.GithubPublish) { - from "releaseAssets" - tagName = "v0.1.0" - $methodName($token) - repositoryName = "$testRepositoryName" - - } + kotlinBuildFile << """ + version = "$versionName" + + tasks.register("testPublish") { + draft(false) + tagName("${tagName}") + repositoryName("$testRepositoryName") + token("$testUserToken") + } """.stripIndent() - expect: - def result = runTasksWithFailure("testPublish") - outputContains(result, "java.lang.IllegalArgumentException: token") + when: + def result = runTasks("testPublish") + + then: + hasRelease(tagName) where: - token | useSetter - "''" | true - "''" | false - null | true - null | false + publishMethod | useSetter | isLazy + PublishMethod.create | true | false +// PublishMethod.create | true | true +// PublishMethod.create | false | false +// PublishMethod.create | false | true +// PublishMethod.update | true | false +// PublishMethod.update | true | true +// PublishMethod.update | false | false +// PublishMethod.update | false | true +// PublishMethod.createOrUpdate | true | false +// PublishMethod.createOrUpdate | true | true +// PublishMethod.createOrUpdate | false | false +// PublishMethod.createOrUpdate | false | true - methodName = useSetter ? "setToken" : "token" + methodName = useSetter ? "setPublishMethod" : "publishMethod" + methodValue = isLazy ? "closure" : "value" + preValue = isLazy ? "{" : "" + postValue = isLazy ? "}" : "" + tagName = "v0.3.${Math.abs(new Random().nextInt() % 1000) + 1}-GithubPublishPropertySpec" + versionName = tagName.replaceFirst('v', '') } @Unroll - def "fails when setting #methodName with invalid url #url"() { + def "fails when setting #methodName with invalid repository name #repoName"() { given: "files to publish" createTestAssetsToPublish(1) @@ -577,26 +573,89 @@ class GithubPublishPropertySpec extends GithubPublishIntegration { task testPublish(type:wooga.gradle.github.publish.tasks.GithubPublish) { from "releaseAssets" tagName = "v0.1.0" - $methodName($url) - repositoryName = "$testRepositoryName" - + $methodName($repoName) + token = "$testUserToken" } """.stripIndent() expect: def result = runTasksWithFailure("testPublish") - outputContains(result, "java.lang.IllegalArgumentException: baseUrl") + outputContains(result, expectedError) where: - url | useSetter - "''" | true - "''" | false - null | true - null | false + repoName | useSetter | expectedError + "'invalid'" | true | "Repository value $repoName is not a valid github repository name" + "'invalid'" | false | "Repository value $repoName is not a valid github repository name" + "'https://github.com/owner/invalid.git'" | true | "Repository value $repoName is not a valid github repository name" + "'https://github.com/owner/invalid.git'" | false | "Repository value $repoName is not a valid github repository name" - methodName = useSetter ? "setBaseUrl" : "baseUrl" + methodName = useSetter ? "setRepositoryName" : "repositoryName" } +// @Unroll +// def "fails when setting #methodName with invalid token #token"() { +// given: "files to publish" +// createTestAssetsToPublish(1) +// +// and: "a buildfile with publish task" +// buildFile << """ +// version "0.1.0" +// +// task testPublish(type:wooga.gradle.github.publish.tasks.GithubPublish) { +// from "releaseAssets" +// tagName = "v0.1.0" +// $methodName($token) +// repositoryName = "$testRepositoryName" +// +// } +// """.stripIndent() +// +// expect: +// def result = runTasksWithFailure("testPublish") +// outputContains(result, "java.lang.IllegalArgumentException: token") +// +// where: +// token | useSetter +// //"''" | true +// //"''" | false +// null | true +// //null | false +// +// methodName = useSetter ? "setToken" : "token" +// } + +// @Unroll +// def "fails when setting #methodName with invalid url #url"() { +// given: "files to publish" +// createTestAssetsToPublish(1) +// +// and: "a buildfile with publish task" +// buildFile << """ +// version "0.1.0" +// +// task testPublish(type:wooga.gradle.github.publish.tasks.GithubPublish) { +// from "releaseAssets" +// tagName = "v0.1.0" +// $methodName($url) +// repositoryName = "$testRepositoryName" +// +// } +// """.stripIndent() +// +// expect: +// def result = runTasksWithFailure("testPublish") +// outputContains(result, "java.lang.IllegalArgumentException: baseUrl") +// +// where: +// url | useSetter +// "''" | true +// "''" | false +// null | true +// null | false +// +// methodName = useSetter ? "setBaseUrl" : "baseUrl" +// } + def "fails when release can't be created with generic exception"() { given: "files to publish" createTestAssetsToPublish(1) diff --git a/src/integrationTest/groovy/wooga/gradle/github/IntegrationSpec.groovy b/src/integrationTest/groovy/wooga/gradle/github/IntegrationSpec.groovy index 42f0a86..e23a7fe 100644 --- a/src/integrationTest/groovy/wooga/gradle/github/IntegrationSpec.groovy +++ b/src/integrationTest/groovy/wooga/gradle/github/IntegrationSpec.groovy @@ -17,12 +17,18 @@ package wooga.gradle.github -import org.junit.Rule import nebula.test.functional.ExecutionResult +import org.junit.Rule +import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.contrib.java.lang.system.ProvideSystemProperty +import static groovy.json.StringEscapeUtils.escapeJava + class IntegrationSpec extends nebula.test.IntegrationSpec { + @Rule + public final EnvironmentVariables environmentVariables = new EnvironmentVariables() + @Rule ProvideSystemProperty properties = new ProvideSystemProperty("ignoreDeprecations", "true") @@ -37,4 +43,12 @@ class IntegrationSpec extends nebula.test.IntegrationSpec { Boolean outputContains(ExecutionResult result, String message) { result.standardOutput.contains(message) || result.standardError.contains(message) } + + static String escapedPath(String path) { + String osName = System.getProperty("os.name").toLowerCase() + if (osName.contains("windows")) { + return escapeJava(path) + } + path + } } diff --git a/src/main/groovy/wooga/gradle/github/base/GithubBasePlugin.groovy b/src/main/groovy/wooga/gradle/github/base/GithubBasePlugin.groovy index f90f25f..9c35171 100644 --- a/src/main/groovy/wooga/gradle/github/base/GithubBasePlugin.groovy +++ b/src/main/groovy/wooga/gradle/github/base/GithubBasePlugin.groovy @@ -20,7 +20,6 @@ package wooga.gradle.github.base import org.gradle.api.Action import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.internal.ConventionMapping import wooga.gradle.github.base.internal.DefaultGithubPluginExtension import wooga.gradle.github.base.tasks.internal.AbstractGithubTask @@ -45,15 +44,47 @@ class GithubBasePlugin implements Plugin { @Override void apply(Project project) { GithubPluginExtention extension = project.extensions.create(EXTENSION_NAME, DefaultGithubPluginExtension.class, project) + + extension.username.set(project.provider({ + def value = project.properties.get(GithubBasePluginConsts.GITHUB_USER_NAME_OPTION) + if (value) { + return value.toString() + } + null + })) + + extension.password.set(project.provider({ + def value = project.properties.get(GithubConsts.GITHUB_USER_PASSWORD_OPTION) + if (value) { + return value.toString() + } + null + })) + + extension.token.set(project.provider({ + def value = project.properties.get(GithubBasePluginConsts.GITHUB_TOKEN_OPTION) + if (value) { + return value.toString() + } + null + })) + + extension.repositoryName.set(project.provider({ + def value = project.properties.get(GithubBasePluginConsts.GITHUB_REPOSITORY_NAME_OPTION) + if (value) { + return value.toString() + } + null + })) + project.tasks.withType(AbstractGithubTask, new Action() { @Override void execute(AbstractGithubTask task) { - ConventionMapping taskConventionMapping = task.getConventionMapping() - taskConventionMapping.map("baseUrl", { extension.getBaseUrl() }) - taskConventionMapping.map("repositoryName", { extension.getRepositoryName() }) - taskConventionMapping.map("username", { extension.getUsername() }) - taskConventionMapping.map("password", { extension.getPassword() }) - taskConventionMapping.map("token", { extension.getToken() }) + task.baseUrl.set(extension.baseUrl) + task.repositoryName.set(extension.repositoryName) + task.username.set(extension.username) + task.password.set(extension.password) + task.token.set(extension.token) } }) } diff --git a/src/main/groovy/wooga/gradle/github/base/GithubBasePluginConsts.groovy b/src/main/groovy/wooga/gradle/github/base/GithubBasePluginConsts.groovy index ff0a696..239857f 100644 --- a/src/main/groovy/wooga/gradle/github/base/GithubBasePluginConsts.groovy +++ b/src/main/groovy/wooga/gradle/github/base/GithubBasePluginConsts.groovy @@ -47,5 +47,5 @@ class GithubBasePluginConsts { * @value "github.repository" * @see GithubSpec#repositoryName */ - static final String GITHUB_REPOSITORY_OPTION = "github.repository" + static final String GITHUB_REPOSITORY_NAME_OPTION = "github.repositoryName" } diff --git a/src/main/groovy/wooga/gradle/github/base/GithubConsts.groovy b/src/main/groovy/wooga/gradle/github/base/GithubConsts.groovy new file mode 100644 index 0000000..ce978f4 --- /dev/null +++ b/src/main/groovy/wooga/gradle/github/base/GithubConsts.groovy @@ -0,0 +1,9 @@ +package wooga.gradle.github.base + +class GithubConsts { + + static final String GITHUB_USER_NAME_OPTION = "github.username" + static final String GITHUB_USER_PASSWORD_OPTION = "github.password" + static final String GITHUB_TOKEN_OPTION = "github.token" + static final String GITHUB_REPOSITORY_OPTION = "github.repository" +} diff --git a/src/main/groovy/wooga/gradle/github/base/GithubSpec.groovy b/src/main/groovy/wooga/gradle/github/base/GithubSpec.groovy index af91183..9f4587e 100644 --- a/src/main/groovy/wooga/gradle/github/base/GithubSpec.groovy +++ b/src/main/groovy/wooga/gradle/github/base/GithubSpec.groovy @@ -17,6 +17,8 @@ package wooga.gradle.github.base +import org.gradle.api.provider.Property + /** * Base Task spec definitions for a github tasks/actions. */ @@ -34,7 +36,7 @@ interface GithubSpec { * @return the github username. May be {@code Null} * @see GithubBasePluginConsts#GITHUB_USER_NAME_OPTION */ - String getUsername() + Property getUsername() /** * Sets the github username. @@ -66,7 +68,7 @@ interface GithubSpec { * @return the github username. May be {@code Null} * @see GithubBasePluginConsts#GITHUB_USER_PASSWORD_OPTION */ - String getPassword() + Property getPassword() /** * Sets the github user password. @@ -98,7 +100,7 @@ interface GithubSpec { * @return the github access token. May be {@code Null} * @see GithubBasePluginConsts#GITHUB_TOKEN_OPTION */ - String getToken() + Property getToken() /** * Sets the github access token. @@ -130,9 +132,9 @@ interface GithubSpec { *
  • gradle properties * * @return the github repository name. May be {@code Null} - * @see GithubBasePluginConsts#GITHUB_REPOSITORY_OPTION + * @see GithubBasePluginConsts#GITHUB_REPOSITORY_NAME_OPTION */ - String getRepositoryName() + Property getRepositoryName() /** * Sets the github repository name. @@ -162,7 +164,7 @@ interface GithubSpec { * @return the base url * @default https://api.github.com */ - String getBaseUrl() + Property getBaseUrl() /** * Sets the github api base url. diff --git a/src/main/groovy/wooga/gradle/github/base/internal/DefaultGithubPluginExtension.groovy b/src/main/groovy/wooga/gradle/github/base/internal/DefaultGithubPluginExtension.groovy index 63000b2..27a625a 100644 --- a/src/main/groovy/wooga/gradle/github/base/internal/DefaultGithubPluginExtension.groovy +++ b/src/main/groovy/wooga/gradle/github/base/internal/DefaultGithubPluginExtension.groovy @@ -18,45 +18,34 @@ package wooga.gradle.github.base.internal import org.gradle.api.Project +import org.gradle.api.provider.Property import wooga.gradle.github.base.GithubPluginExtention import wooga.gradle.github.base.GithubSpec class DefaultGithubPluginExtension implements GithubPluginExtention { - static final String GITHUB_USER_NAME_OPTION = "github.username" - static final String GITHUB_USER_PASSWORD_OPTION = "github.password" - static final String GITHUB_TOKEN_OPTION = "github.token" - static final String GITHUB_REPOSITORY_OPTION = "github.repository" + final Property repositoryName + final Property baseUrl - private String repositoryName - private String baseUrl - - private String username - private String password - private String token + final Property username + final Property password + final Property token private final Closure property DefaultGithubPluginExtension(Project project) { this.property = project.&findProperty - } - - DefaultGithubPluginExtension(Map properties) { - this.property = properties.&get - } - @Override - String getUsername() { - this.username ?: property(GITHUB_USER_NAME_OPTION) + repositoryName = project.objects.property(String) + baseUrl = project.objects.property(String) + username = project.objects.property(String) + password = project.objects.property(String) + token = project.objects.property(String) } @Override DefaultGithubPluginExtension setUsername(String username) { - if (username == null || username.isEmpty()) { - throw new IllegalArgumentException("username") - } - - this.username = username + this.username.set(username) this } @@ -65,18 +54,9 @@ class DefaultGithubPluginExtension implements GithubPluginExtention { setUsername(username) } - @Override - String getPassword() { - this.password ?: property(GITHUB_USER_PASSWORD_OPTION) - } - @Override DefaultGithubPluginExtension setPassword(String password) { - if (password == null || password.isEmpty()) { - throw new IllegalArgumentException("password") - } - - this.password = password + this.password.set(password) this } @@ -85,31 +65,13 @@ class DefaultGithubPluginExtension implements GithubPluginExtention { setPassword(password) } - @Override - String getRepositoryName() { - String value = this.repositoryName - if (!this.repositoryName && property(GITHUB_REPOSITORY_OPTION)) { - value = property(GITHUB_REPOSITORY_OPTION) - } - - if (value && !GithubRepositoryValidator.validateRepositoryName(value)) { - throw new IllegalArgumentException("Repository value '$value' is not a valid github repository name. Expecting `owner/repo`.") - } - - value - } - @Override DefaultGithubPluginExtension setRepositoryName(String name) { - if (name == null || name.isEmpty()) { - throw new IllegalArgumentException("repository") - } - if (!GithubRepositoryValidator.validateRepositoryName(name)) { throw new IllegalArgumentException("Repository value '$name' is not a valid github repository name. Expecting `owner/repo`.") } - this.repositoryName = name + this.repositoryName.set(name) this } @@ -118,18 +80,9 @@ class DefaultGithubPluginExtension implements GithubPluginExtention { setRepositoryName(name) } - @Override - String getBaseUrl() { - baseUrl - } - @Override DefaultGithubPluginExtension setBaseUrl(String baseUrl) { - if (baseUrl == null || baseUrl.isEmpty()) { - throw new IllegalArgumentException("baseUrl") - } - - this.baseUrl = baseUrl + this.baseUrl.set(baseUrl) this } @@ -138,17 +91,9 @@ class DefaultGithubPluginExtension implements GithubPluginExtention { setBaseUrl(baseUrl) } - @Override - String getToken() { - this.token ?: property(GITHUB_TOKEN_OPTION) - } - @Override DefaultGithubPluginExtension setToken(String token) { - if (token == null || token.isEmpty()) { - throw new IllegalArgumentException("token") - } - this.token = token + this.token.set(token) this } diff --git a/src/main/groovy/wooga/gradle/github/base/tasks/internal/AbstractGithubTask.groovy b/src/main/groovy/wooga/gradle/github/base/tasks/internal/AbstractGithubTask.groovy index aaf7787..2b24eb7 100644 --- a/src/main/groovy/wooga/gradle/github/base/tasks/internal/AbstractGithubTask.groovy +++ b/src/main/groovy/wooga/gradle/github/base/tasks/internal/AbstractGithubTask.groovy @@ -19,94 +19,101 @@ package wooga.gradle.github.base.tasks.internal import org.gradle.api.GradleException import org.gradle.api.internal.ConventionTask +import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.kohsuke.github.GHRepository import org.kohsuke.github.GitHub import org.kohsuke.github.GitHubBuilder +import org.kohsuke.github.HttpException import wooga.gradle.github.base.internal.GithubRepositoryValidator import wooga.gradle.github.base.GithubSpec +import wooga.gradle.github.base.tasks.Github abstract class AbstractGithubTask extends ConventionTask implements GithubSpec { - private String repositoryName - private String baseUrl - private String username - private String password - private String token + @Input + final Property repositoryName + + @Optional + @Input + final Property baseUrl + + @Optional + @Input + final Property username + + @Optional + @Input + final Property password + + + @Optional + @Input + final Property token - private GitHub client + protected final Property clientProvider private final Class taskType AbstractGithubTask(Class taskType) { this.taskType = taskType - } - protected GitHub getClient() { - if(!this.client) { + repositoryName = project.objects.property(String) + baseUrl = project.objects.property(String) + username = project.objects.property(String) + password = project.objects.property(String) + token = project.objects.property(String) + + clientProvider = project.objects.property(GitHub) + + clientProvider.set(project.provider({ def builder = new GitHubBuilder() - if (getUsername() && getPassword()) { - builder = builder.withPassword(getUsername(), getPassword()) - } else if (getUsername() && getToken()) { - builder = builder.withOAuthToken(getToken(), getUsername()) + if (username.present && password.present) { + builder = builder.withPassword(username.get(), password.get()) + } else if (username.present && token.present) { + builder = builder.withOAuthToken(token.get(), username.get()) - } else if (getToken()) { - builder = builder.withOAuthToken(getToken()) + } else if (token.present) { + builder = builder.withOAuthToken(token.get()) } else { builder = GitHubBuilder.fromCredentials() } - if (getBaseUrl()) { - builder = builder.withEndpoint(getBaseUrl()) + if (baseUrl.present) { + builder = builder.withEndpoint(baseUrl.get()) } - this.client = builder.build() - } - - return client - } - - GHRepository getRepository(GitHub client) { - GHRepository repository - try { - repository = client.getRepository(getRepositoryName()) - } - catch (Exception e) { - throw new GradleException("can't find repository ${getRepositoryName()}") - } - repository + def client = builder.build() + clientProvider.set(client) + return client + })) } GHRepository getRepository() { GHRepository repository try { - repository = getClient().getRepository(getRepositoryName()) + repository = client.getRepository(repositoryName.get()) } - catch (Exception e) { - throw new GradleException("can't find repository ${getRepositoryName()}") + catch (Exception error) { + throw new GradleException("can't find repository ${repositoryName.get()}", error) } repository } - @Override - String getRepositoryName() { - repositoryName + GitHub getClient() { + this.clientProvider.get() } @Override T setRepositoryName(String name) { - if (name == null || name.isEmpty()) { - throw new IllegalArgumentException("repository") - } - if (!GithubRepositoryValidator.validateRepositoryName(name)) { throw new IllegalArgumentException("Repository value '$name' is not a valid github repository name. Expecting `owner/repo`.") } - this.repositoryName = name + this.repositoryName.set(name) taskType.cast(this) } @@ -115,19 +122,9 @@ abstract class AbstractGithubTask extends Conventi taskType.cast(this.setRepositoryName(name)) } - @Optional - @Input - @Override - String getBaseUrl() { - baseUrl - } - @Override T setBaseUrl(String baseUrl) { - if (baseUrl == null || baseUrl.isEmpty()) { - throw new IllegalArgumentException("baseUrl") - } - this.baseUrl = baseUrl + this.baseUrl.set(baseUrl) taskType.cast(this) } @@ -136,19 +133,9 @@ abstract class AbstractGithubTask extends Conventi taskType.cast(this.setBaseUrl(baseUrl)) } - @Optional - @Input - @Override - String getToken() { - this.token - } - @Override T setToken(String token) { - if (token == null || token.isEmpty()) { - throw new IllegalArgumentException("token") - } - this.token = token + this.token.set(token) taskType.cast(this) } @@ -157,16 +144,9 @@ abstract class AbstractGithubTask extends Conventi taskType.cast(this.setToken(token)) } - @Optional - @Input - @Override - String getUsername() { - this.username - } - @Override T setUsername(String userName) { - this.username = userName + this.username.set(userName) taskType.cast(this) } @@ -176,16 +156,9 @@ abstract class AbstractGithubTask extends Conventi taskType.cast(this) } - @Optional - @Input - @Override - String getPassword() { - this.password - } - @Override T setPassword(String password) { - this.password = password + this.password.set(password) taskType.cast(this) } diff --git a/src/main/groovy/wooga/gradle/github/publish/GithubPublishPlugin.groovy b/src/main/groovy/wooga/gradle/github/publish/GithubPublishPlugin.groovy index f826116..05bb26b 100644 --- a/src/main/groovy/wooga/gradle/github/publish/GithubPublishPlugin.groovy +++ b/src/main/groovy/wooga/gradle/github/publish/GithubPublishPlugin.groovy @@ -87,18 +87,20 @@ class GithubPublishPlugin implements Plugin { project.tasks.withType(GithubPublish, new Action() { @Override void execute(GithubPublish task) { - ConventionMapping taskConventionMapping = task.getConventionMapping() + task.targetCommitish.set("master") + task.prerelease.set(false) + task.draft.set(false) + task.publishMethod.set(PublishMethod.create) - taskConventionMapping.map("targetCommitish", { "master" }) - taskConventionMapping.map("prerelease", { false }) - taskConventionMapping.map("draft", { false }) - taskConventionMapping.map("tagName", { project.version.toString() }) - taskConventionMapping.map("releaseName", { project.version.toString() }) + def projectProvider = project.provider({project.version.toString()}) + + task.tagName.set(projectProvider) + task.releaseName.set(projectProvider) task.onlyIf(new Spec() { @Override boolean isSatisfiedBy(GithubPublish publishTask) { - publishTask.repositoryName != null + publishTask.repositoryName.present } }) } diff --git a/src/main/groovy/wooga/gradle/github/publish/GithubPublishSpec.groovy b/src/main/groovy/wooga/gradle/github/publish/GithubPublishSpec.groovy index 2f6b9f2..f6ff345 100644 --- a/src/main/groovy/wooga/gradle/github/publish/GithubPublishSpec.groovy +++ b/src/main/groovy/wooga/gradle/github/publish/GithubPublishSpec.groovy @@ -18,6 +18,7 @@ package wooga.gradle.github.publish import org.gradle.api.file.CopySourceSpec +import org.gradle.api.provider.Property import org.gradle.api.tasks.util.PatternFilterable import wooga.gradle.github.base.GithubSpec @@ -39,16 +40,10 @@ import wooga.gradle.github.base.GithubSpec * *
      * {@code
    - *     String getReleaseName() {
    - *         if(this.releaseName == null) {
    - *             return null
    - *         }
    - *         if (this.releaseName instanceof Callable) {
    - *             return ((Callable) this.releaseName).call().toString()
    - *         }
    - *         this.releaseName.toString()
    - *     }
    - * }
    + *     String getReleaseName() {*         if(this.releaseName == null) {*             return null
    + *}*         if (this.releaseName instanceof Callable) {*             return ((Callable) this.releaseName).call().toString()
    + *}*         this.releaseName.toString()
    + *}*}
      */
     interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterable {
     
    @@ -57,12 +52,12 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
          *
          * @return the Git tag name
          */
    -    String getTagName()
    +    Property getTagName()
     
         /**
          * Sets the tag name for the release.
          *
    -     * @param  the {@code String} tagName value
    +     * @param the {@code String} tagName value
          * @return this
          */
         GithubPublishSpec setTagName(String tagName)
    @@ -70,7 +65,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
         /**
          * Sets the tag name for the release.
          *
    -     * @param  the {@code Object} tagName value.
    +     * @param the {@code Object} tagName value.
          * @return this
          */
         GithubPublishSpec setTagName(Object tagName)
    @@ -78,7 +73,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
         /**
          * Sets the tag name for the release.
          *
    -     * @param  the {@code String} tagName value
    +     * @param the {@code String} tagName value
          * @return this
          */
         GithubPublishSpec tagName(String tagName)
    @@ -86,7 +81,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
         /**
          * Sets the tag name for the release.
          *
    -     * @param  the {@code Object} tagName value.
    +     * @param the {@code Object} tagName value.
          * @return this
          */
         GithubPublishSpec tagName(Object tagName)
    @@ -97,14 +92,14 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
          * Can be any branch or commit SHA. Unused if the Git tag already exists.
          *
          * @default the repository's default branch (usually master).
    -     * @return  this
    +     * @return this
          */
    -    String getTargetCommitish()
    +    Property getTargetCommitish()
     
         /**
          * Sets the commitish value.
          *
    -     * @param  targetCommitish the commitish value, can be any branch or commit SHA
    +     * @param targetCommitish the commitish value, can be any branch or commit SHA
          * @return this
          */
         GithubPublishSpec setTargetCommitish(String targetCommitish)
    @@ -112,7 +107,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
         /**
          * Sets the commitish value.
          *
    -     * @param  targetCommitish the commitish value, can be any branch or commit SHA
    +     * @param targetCommitish the commitish value, can be any branch or commit SHA
          * @return this
          */
         GithubPublishSpec setTargetCommitish(Object targetCommitish)
    @@ -120,7 +115,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
         /**
          * Sets the commitish value.
          *
    -     * @param  targetCommitish the commitish value, can be any branch or commit SHA
    +     * @param targetCommitish the commitish value, can be any branch or commit SHA
          * @return this
          */
         GithubPublishSpec targetCommitish(String targetCommitish)
    @@ -128,7 +123,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
         /**
          * Sets the commitish value.
          *
    -     * @param  targetCommitish the commitish value, can be any branch or commit SHA
    +     * @param targetCommitish the commitish value, can be any branch or commit SHA
          * @return this
          */
         GithubPublishSpec targetCommitish(Object targetCommitish)
    @@ -138,12 +133,12 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
          *
          * @return the name of the release
          */
    -    String getReleaseName()
    +    Property getReleaseName()
     
         /**
          * Sets the name of the release.
          *
    -     * @param  name the name to use for the release
    +     * @param name the name to use for the release
          * @return this
          */
         GithubPublishSpec setReleaseName(String name)
    @@ -151,7 +146,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
         /**
          * Sets the name of the release.
          *
    -     * @param  name the name to use for the release
    +     * @param name the name to use for the release
          * @return this
          */
         GithubPublishSpec setReleaseName(Object name)
    @@ -159,7 +154,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
         /**
          * Sets the name of the release.
          *
    -     * @param  name the name to use for the release
    +     * @param name the name to use for the release
          * @return this
          */
         GithubPublishSpec releaseName(String name)
    @@ -167,7 +162,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
         /**
          * Sets the name of the release.
          *
    -     * @param  name the name to use for the release
    +     * @param name the name to use for the release
          * @return this
          */
         GithubPublishSpec releaseName(Object name)
    @@ -177,12 +172,12 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
          *
          * @return the release description
          */
    -    String getBody()
    +    Property getBody()
     
         /**
          * Sets the description text for the release.
          *
    -     * @param  body the release description
    +     * @param body the release description
          * @return this
          */
         GithubPublishSpec setBody(String body)
    @@ -194,7 +189,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
          * If the value is a {@code Callable}, the result after calling the object
          * and executing {@code toString} on the return value will be used.
          *
    -     * @param  body the release description
    +     * @param body the release description
          * @return this
          */
         GithubPublishSpec setBody(Object body)
    @@ -205,7 +200,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
          * The closure will be called with a {@link org.kohsuke.github.GHRepository} repository object.
          * The repository object can be used to query the Git commit log or pull requests etc.
          *
    -     * @param  closure a configuration closure which returns the release description
    +     * @param closure a configuration closure which returns the release description
          * @return this
          */
         GithubPublishSpec setBody(Closure closure)
    @@ -213,19 +208,18 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl
         /**
          * Sets the description text for the release.
          * 

    - * The body strategies {@code getBody()} method will be called with a {@link org.kohsuke.github.GHRepository} repository object. + * The body strategies {@code getBody( )} method will be called with a {@link org.kohsuke.github.GHRepository} repository object. * The repository object can be used to query the Git commit log or pull requests etc. * - * @param bodyStrategy an object of type {@link PublishBodyStrategy} which returns the release description - * @return this - * @see PublishBodyStrategy#getBody(org.kohsuke.github.GHRepository) + * @param bodyStrategy an object of type {@link PublishBodyStrategy} which returns the release description + * @return this* @see PublishBodyStrategy#getBody(org.kohsuke.github.GHRepository) */ GithubPublishSpec setBody(PublishBodyStrategy bodyStrategy) /** * Sets the description text for the release. * - * @param body the release description + * @param body the release description * @return this */ GithubPublishSpec body(String body) @@ -233,7 +227,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl /** * Sets the description text for the release. * - * @param body the release description + * @param body the release description * @return this */ GithubPublishSpec body(Object body) @@ -244,7 +238,7 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl * The closure will be called with a {@link org.kohsuke.github.GHRepository} repository object. * The repository object can be used to query the Git commit log or pull requests etc. * - * @param closure a configuration closure which returns the release description + * @param closure a configuration closure which returns the release description * @return this */ GithubPublishSpec body(Closure bodyStrategy) @@ -252,35 +246,34 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl /** * Sets the description text for the release. *

    - * The body strategies {@code getBody()} method will be called with a {@link org.kohsuke.github.GHRepository} repository object. + * The body strategies {@code getBody( )} method will be called with a {@link org.kohsuke.github.GHRepository} repository object. * The repository object can be used to query the Git commit log or pull requests etc. * - * @param bodyStrategy an object of type {@link PublishBodyStrategy} which returns the release description - * @return this - * @see PublishBodyStrategy#getBody(org.kohsuke.github.GHRepository) + * @param bodyStrategy an object of type {@link PublishBodyStrategy} which returns the release description + * @return this* @see PublishBodyStrategy#getBody(org.kohsuke.github.GHRepository) */ GithubPublishSpec body(PublishBodyStrategy bodyStrategy) /** * Returns a {@code boolean} value indicating if the release as a prerelease. * - * @return {@code true} to identify the release as a prerelease. {@code false} to identify the release as a full release. + * @return {@code true} to identify the release as a prerelease. {@code false} to identify the release as a full release. * @default {@code false} */ - boolean isPrerelease() + Property isPrerelease() /** * Sets the prerelease status of the release. * - * @param prerelease the prerelease status. Set {@code true} to identify the release as a prerelease. + * @param prerelease the prerelease status. Set {@code true} to identify the release as a prerelease. * @return this */ - GithubPublishSpec setPrerelease(boolean prerelease) + GithubPublishSpec setPrerelease(Boolean prerelease) /** * Sets the prerelease status of the release. * - * @param prerelease the prerelease status. Set {@code true} to identify the release as a prerelease. + * @param prerelease the prerelease status. Set {@code true} to identify the release as a prerelease. * @return this */ GithubPublishSpec setPrerelease(Object prerelease) @@ -288,15 +281,15 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl /** * Sets the prerelease status of the release. * - * @param prerelease the prerelease status. Set {@code true} to identify the release as a prerelease. + * @param prerelease the prerelease status. Set {@code true} to identify the release as a prerelease. * @return this */ - GithubPublishSpec prerelease(boolean prerelease) + GithubPublishSpec prerelease(Boolean prerelease) /** * Sets the prerelease status of the release. * - * @param prerelease the prerelease status. Set {@code true} to identify the release as a prerelease. + * @param prerelease the prerelease status. Set {@code true} to identify the release as a prerelease. * @return this */ GithubPublishSpec prerelease(Object prerelease) @@ -304,23 +297,23 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl /** * Returns a {@code boolean} value indicating if the release will be automatically published. * - * @return {@code true} to create a draft (unpublished) release, {@code false} to create a published one. + * @return {@code true} to create a draft (unpublished) release, {@code false} to create a published one. * @default {@code false} */ - boolean isDraft() + Property isDraft() /** * Sets the publication status for the release. * - * @param draft the status. Set to {@code true} to create a draft (unpublished) release. + * @param draft the status. Set to {@code true} to create a draft (unpublished) release. * @return this */ - GithubPublishSpec setDraft(boolean draft) + GithubPublishSpec setDraft(Boolean draft) /** * Sets the publication status for the release. * - * @param draft the status. Set to {@code true} to create a draft (unpublished) release. + * @param draft the status. Set to {@code true} to create a draft (unpublished) release. * @return this */ GithubPublishSpec setDraft(Object draft) @@ -328,15 +321,15 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl /** * Sets the publication status for the release. * - * @param draft the status. Set to {@code true} to create a draft (unpublished) release. + * @param draft the status. Set to {@code true} to create a draft (unpublished) release. * @return this */ - GithubPublishSpec draft(boolean draft) + GithubPublishSpec draft(Boolean draft) /** * Sets the publication status for the release. * - * @param draft the status. Set to {@code true} to create a draft (unpublished) release. + * @param draft the status. Set to {@code true} to create a draft (unpublished) release. * @return this */ GithubPublishSpec draft(Object draft) @@ -355,19 +348,17 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl * When set to {@code update}, the {@code GithubPublish} task will fail if a release doesn't exists. * When set to {@code createOrUpdate}, the {@code GithubPublish} task will create a release if missing. * - * @return {@code PublishMethod} indicating if a release should be created or updated. + * @return {@code PublishMethod} indicating if a release should be created or updated. * @default {@code PublishMethod.create} - * @see wooga.gradle.github.publish.tasks.GithubPublish - * @see wooga.gradle.github.publish.PublishMethod + * @see wooga.gradle.github.publish.tasks.GithubPublish* @see wooga.gradle.github.publish.PublishMethod */ - PublishMethod getPublishMethod() + Property getPublishMethod() /** * Sets the publish method. * - * @param {@code PublishMethod} indicating if a release should be created or updated. - * @return this - * + * @param {@code PublishMethod} indicating if a release should be created or updated. + * @return this* * @see #getPublishMethod() */ GithubPublishSpec setPublishMethod(PublishMethod method) @@ -375,9 +366,8 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl /** * Sets the publish method. * - * @param {@code Object} which can be converted to a {@code PublishMethod} - * @return this - * + * @param {@code Object} which can be converted to a {@code PublishMethod} + * @return this* * @see #getPublishMethod() */ GithubPublishSpec setPublishMethod(Object method) @@ -385,9 +375,8 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl /** * Sets the publish method. * - * @param {@code PublishMethod} indicating if a release should be created or updated. - * @return this - * + * @param {@code PublishMethod} indicating if a release should be created or updated. + * @return this* * @see #getPublishMethod() */ GithubPublishSpec publishMethod(PublishMethod method) @@ -395,9 +384,8 @@ interface GithubPublishSpec extends GithubSpec, CopySourceSpec, PatternFilterabl /** * Sets the publish method. * - * @param {@code Object} which can be converted to a {@code PublishMethod} - * @return this - * + * @param {@code Object} which can be converted to a {@code PublishMethod} + * @return this* * @see #getPublishMethod() */ GithubPublishSpec publishMethod(Object method) diff --git a/src/main/groovy/wooga/gradle/github/publish/tasks/GithubPublish.groovy b/src/main/groovy/wooga/gradle/github/publish/tasks/GithubPublish.groovy index d53ae4d..da8a5b7 100644 --- a/src/main/groovy/wooga/gradle/github/publish/tasks/GithubPublish.groovy +++ b/src/main/groovy/wooga/gradle/github/publish/tasks/GithubPublish.groovy @@ -26,6 +26,7 @@ import org.gradle.api.file.CopySpec import org.gradle.api.file.FileTreeElement import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging +import org.gradle.api.provider.Property import org.gradle.api.specs.Spec import org.gradle.api.specs.Specs import org.gradle.api.tasks.Input @@ -39,14 +40,7 @@ import wooga.gradle.github.base.tasks.internal.AbstractGithubTask import wooga.gradle.github.publish.GithubPublishSpec import wooga.gradle.github.publish.PublishBodyStrategy import wooga.gradle.github.publish.PublishMethod -import wooga.gradle.github.publish.internal.GithubPublishRollbackHandler -import wooga.gradle.github.publish.internal.GithubReleasePropertySetter -import wooga.gradle.github.publish.internal.GithubReleaseCreateException -import wooga.gradle.github.publish.internal.GithubReleasePublishException -import wooga.gradle.github.publish.internal.GithubReleaseUpdateException -import wooga.gradle.github.publish.internal.GithubReleaseUploadAssetException -import wooga.gradle.github.publish.internal.GithubReleaseUploadAssetsException -import wooga.gradle.github.publish.internal.ReleaseAssetUpload +import wooga.gradle.github.publish.internal.* import java.util.concurrent.Callable @@ -59,8 +53,7 @@ import java.util.concurrent.Callable * Example: *

      * {@code
    - *     githubPublish {
    - *         targetCommitish = "master"
    + *     githubPublish {*         targetCommitish = "master"
      *         tagName = project.version
      *         releaseName = project.version
      *         body = "Release XYZ"
    @@ -68,8 +61,7 @@ import java.util.concurrent.Callable
      *         draft = false
      *         publishMethod = "create"
      *         from(file('build/output'))
    - *     }
    - *}
    + *}*}
      */
     class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
     
    @@ -81,12 +73,53 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
         private Boolean processAssets
         private Boolean isNewlyCreatedRelease = false
     
    +    @Input
    +    final Property tagName
    +
    +    @Input
    +    @Optional
    +    final Property targetCommitish
    +
    +    @Input
    +    final Property releaseName
    +
    +    @Input
    +    @Optional
    +    final Property body
    +
    +    @Input
    +    final Property prerelease
    +
    +    @Input
    +    final Property draft
    +
    +    final Property publishMethod
    +
    +    @Override
    +    Property isPrerelease() {
    +        return prerelease
    +    }
    +
    +    @Override
    +    Property isDraft() {
    +        return draft
    +    }
    +
         GithubPublish() {
             super(GithubPublish.class)
             assetsCopySpec = project.copySpec()
     
             assetCollectDirectory = project.file("${temporaryDir}/collect")
             assetUploadDirectory = project.file("${temporaryDir}/prepare")
    +
    +        tagName = project.objects.property(String)
    +        targetCommitish = project.objects.property(String)
    +        releaseName = project.objects.property(String)
    +        body = project.objects.property(String)
    +
    +        prerelease = project.objects.property(Boolean)
    +        draft = project.objects.property(Boolean)
    +        publishMethod = project.objects.property(PublishMethod)
         }
     
         File getDestinationDir() {
    @@ -99,7 +132,7 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
         @TaskAction
         protected void publish() {
             try {
    -            GHRelease release = createOrUpdateGithubRelease(this.processAssets || isDraft())
    +            GHRelease release = createOrUpdateGithubRelease(this.processAssets || draft.get())
                 if (this.processAssets) {
                     processReleaseAssets(release)
                 }
    @@ -109,7 +142,7 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
             setDidWork(true)
         }
     
    -    protected void processReleaseAssets(GHRelease release) throws GithubReleaseUploadAssetsException, GithubReleaseUpdateException{
    +    protected void processReleaseAssets(GHRelease release) throws GithubReleaseUploadAssetsException, GithubReleaseUpdateException {
             getDestinationDir().mkdirs()
             WorkResult assetCopyResult = project.sync(new Action()
             {
    @@ -130,8 +163,8 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
                 }
     
                 try {
    -                if (release.draft != isDraft()) {
    -                    release.update().draft(isDraft()).tag(getTagName()).update()
    +                if (release.draft != draft.get()) {
    +                    release.update().draft(draft.get()).tag(tagName.get()).update()
                     }
                 } catch (Exception error) {
                     throw new GithubReleaseUpdateException(release, "error while publishing draft", error)
    @@ -180,21 +213,21 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
             List publishedAssets = []
             List updatedAssets = []
     
    -        assetUploadDirectory.listFiles().findAll {it.isFile()}.sort().each { File assetFile ->
    +        assetUploadDirectory.listFiles().findAll { it.isFile() }.sort().each { File assetFile ->
                 try {
                     publishedAssets << ReleaseAssetUpload.uploadAsset(release, assetFile)
                 } catch (HttpException httpError) {
    -                if( isDuplicateAssetError(httpError)) {
    +                if (isDuplicateAssetError(httpError)) {
                         logger.info("asset ${assetFile.name} already published")
                         logger.info("attempt override")
    -                    def duplicateAsset = release.assets.find {it.name == assetFile.name}
    -                    if(duplicateAsset) {
    +                    def duplicateAsset = release.assets.find { it.name == assetFile.name }
    +                    if (duplicateAsset) {
                             try {
                                 UpdatedAsset updatedAsset = UpdatedAsset.fromAsset(duplicateAsset)
                                 duplicateAsset.delete()
                                 updatedAssets << updatedAsset
                                 publishedAssets << ReleaseAssetUpload.uploadAsset(release, assetFile)
    -                        } catch(Exception e) {
    +                        } catch (Exception e) {
                                 logger.error("failure during update of duplicate asset ${assetFile.name}")
                                 logger.error(e.message)
                                 logger.info("fail with original error")
    @@ -242,19 +275,18 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
         }
     
         protected GHRelease createOrUpdateGithubRelease(Boolean createDraft) throws GithubReleaseUpdateException, GithubReleaseCreateException {
    -        GitHub client = getClient()
    -        GHRepository repository = getRepository(client)
    -
    -        GHRelease release = repository.listReleases().find({ it.tagName == getTagName() }) as GHRelease
    +        GHRepository repository = getRepository()
    +        String tagName = tagName.get()
    +        GHRelease release = repository.listReleases().find({ it.tagName == tagName }) as GHRelease
             GithubReleasePropertySetter releasePropertySet
             GHRelease result
             if (release) {
    -            if (this.getPublishMethod() == PublishMethod.create) {
    -                throw new GithubReleaseCreateException("github release with tag ${getTagName()} already exist")
    +            if (this.publishMethod.get() == PublishMethod.create) {
    +                throw new GithubReleaseCreateException("github release with tag ${tagName} already exist")
                 }
     
                 releasePropertySet = new GithubReleasePropertySetter(release.update())
    -            releasePropertySet.draft(isDraft())
    +            releasePropertySet.draft(draft.get())
     
                 try {
                     result = setReleasePropertiesAndCommit(releasePropertySet)
    @@ -262,36 +294,36 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
                     throw new GithubReleaseUpdateException("failed to update release ${release.tagName}", error)
                 }
             } else {
    -            if (this.getPublishMethod() == PublishMethod.update) {
    -                throw new GithubReleaseUpdateException("github release with tag ${getTagName()} for update not found")
    +            if (this.publishMethod.get() == PublishMethod.update) {
    +                throw new GithubReleaseUpdateException("github release with tag ${tagName} for update not found")
                 }
     
                 isNewlyCreatedRelease = true
    -            releasePropertySet = new GithubReleasePropertySetter(repository.createRelease(getTagName()))
    +            releasePropertySet = new GithubReleasePropertySetter(repository.createRelease(tagName))
                 releasePropertySet.draft(createDraft as boolean)
     
                 try {
                     result = setReleasePropertiesAndCommit(releasePropertySet)
                 } catch (Exception error) {
    -                throw new GithubReleaseCreateException("failed to create release ${release.tagName}", error)
    +                throw new GithubReleaseCreateException("failed to create release ${tagName}", error)
                 }
             }
             result
         }
     
         protected GHRelease setReleasePropertiesAndCommit(GithubReleasePropertySetter releasePropertySet) {
    -        releasePropertySet.prerelease(isPrerelease())
    +        releasePropertySet.prerelease(prerelease.get())
     
    -        if (getTargetCommitish()) {
    -            releasePropertySet.commitish(getTargetCommitish())
    +        if (targetCommitish.present) {
    +            releasePropertySet.commitish(targetCommitish.get())
             }
     
    -        if (getBody()) {
    -            releasePropertySet.body(getBody())
    +        if (body.present) {
    +            releasePropertySet.body(body.get())
             }
     
    -        if (getReleaseName()) {
    -            releasePropertySet.name(getReleaseName())
    +        if (releaseName.present) {
    +            releasePropertySet.name(releaseName.get())
             }
     
             releasePropertySet.commit()
    @@ -513,38 +545,12 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
             this.exclude(Specs. convertClosureToSpec(excludeSpec))
         }
     
    -    private Object tagName
    -    private Object targetCommitish
    -    private Object releaseName
    -    private Object body
    -
    -    private Object prerelease
    -    private Object draft
    -    private Object publishMethod = PublishMethod.create
    -
    -    /**
    -     * See: {@link GithubPublishSpec#getTagName()}
    -     */
    -    @Input
    -    @Override
    -    String getTagName() {
    -        if (this.tagName == null) {
    -            return null
    -        }
    -
    -        if (this.tagName instanceof Callable) {
    -            return ((Callable) this.tagName).call().toString()
    -        }
    -
    -        this.tagName.toString()
    -    }
    -
         /**
          * See: {@link GithubPublishSpec#setTagName(String)}
          */
         @Override
         GithubPublish setTagName(String tagName) {
    -        this.tagName = tagName
    +        this.tagName.set(tagName)
             this
         }
     
    @@ -553,7 +559,13 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
          */
         @Override
         GithubPublish setTagName(Object tagName) {
    -        this.tagName = tagName
    +        this.tagName.set(project.provider({
    +            if (tagName instanceof Callable) {
    +                return ((Callable) tagName).call().toString()
    +            }
    +
    +            tagName.toString()
    +        }))
             this
         }
     
    @@ -573,30 +585,12 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
             this.setTagName(tagName)
         }
     
    -    /**
    -     * See: {@link GithubPublishSpec#getTargetCommitish()}
    -     */
    -    @Input
    -    @Optional
    -    @Override
    -    String getTargetCommitish() {
    -        if (this.targetCommitish == null) {
    -            return null
    -        }
    -
    -        if (this.targetCommitish instanceof Callable) {
    -            return ((Callable) this.targetCommitish).call().toString()
    -        }
    -
    -        this.targetCommitish.toString()
    -    }
    -
         /**
          * See: {@link GithubPublishSpec#setTargetCommitish(String)}
          */
         @Override
         GithubPublish setTargetCommitish(String targetCommitish) {
    -        this.targetCommitish = targetCommitish
    +        this.targetCommitish.set(targetCommitish)
             this
         }
     
    @@ -605,7 +599,13 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
          */
         @Override
         GithubPublish setTargetCommitish(Object targetCommitish) {
    -        this.targetCommitish = targetCommitish
    +        this.targetCommitish.set(project.provider({
    +            if (targetCommitish instanceof Callable) {
    +                return ((Callable) targetCommitish).call().toString()
    +            }
    +
    +            targetCommitish.toString()
    +        }))
             this
         }
     
    @@ -625,29 +625,12 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
             this.setTargetCommitish(targetCommitish)
         }
     
    -    /**
    -     * See: {@link GithubPublishSpec#getReleaseName()}
    -     */
    -    @Optional
    -    @Input
    -    String getReleaseName() {
    -        if (this.releaseName == null) {
    -            return null
    -        }
    -
    -        if (this.releaseName instanceof Callable) {
    -            return ((Callable) this.releaseName).call().toString()
    -        }
    -
    -        this.releaseName.toString()
    -    }
    -
         /**
          * See: {@link GithubPublishSpec#setReleaseName(String)}
          */
         @Override
         GithubPublish setReleaseName(String name) {
    -        this.releaseName = name
    +        this.releaseName.set(name)
             this
         }
     
    @@ -656,7 +639,13 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
          */
         @Override
         GithubPublish setReleaseName(Object name) {
    -        this.releaseName = name
    +        this.releaseName.set(project.provider({
    +            if (name instanceof Callable) {
    +                return ((Callable) name).call().toString()
    +            }
    +
    +            name.toString()
    +        }))
             this
         }
     
    @@ -676,38 +665,38 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
             this.setReleaseName(name)
         }
     
    -    /**
    -     * See: {@link GithubPublishSpec#getBody()}
    -     */
    -    @Optional
    -    @Input
    -    @Override
    -    String getBody() {
    -        if (this.body == null) {
    -            return null
    -        }
    -
    -        if (this.body instanceof Closure) {
    -            return ((Closure) this.body).call(getRepository(getClient())).toString()
    -        }
    -
    -        if (this.body instanceof PublishBodyStrategy) {
    -            return ((PublishBodyStrategy) this.body).getBody(getRepository(getClient()))
    -        }
    -
    -        if (this.body instanceof Callable) {
    -            return ((Callable) this.body).call().toString()
    -        }
    -
    -        this.body.toString()
    -    }
    +//    /**
    +//     * See: {@link GithubPublishSpec#getBody()}
    +//     */
    +//    @Optional
    +//    @Input
    +//    @Override
    +//    String getBody() {
    +//        if (this.body == null) {
    +//            return null
    +//        }
    +//
    +//        if (this.body instanceof Closure) {
    +//            return ((Closure) this.body).call(getRepository(getClient())).toString()
    +//        }
    +//
    +//        if (this.body instanceof PublishBodyStrategy) {
    +//            return ((PublishBodyStrategy) this.body).getBody(getRepository(getClient()))
    +//        }
    +//
    +//        if (this.body instanceof Callable) {
    +//            return ((Callable) this.body).call().toString()
    +//        }
    +//
    +//        this.body.toString()
    +//    }
     
         /**
          * See: {@link GithubPublishSpec#setBody(String)}
          */
         @Override
         GithubPublish setBody(String body) {
    -        this.body = body
    +        this.body.set(body)
             this
         }
     
    @@ -716,7 +705,13 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
          */
         @Override
         GithubPublish setBody(Object body) {
    -        this.body = body
    +        this.body.set(project.provider({
    +            if (body instanceof Callable) {
    +                return ((Callable) body).call().toString()
    +            }
    +
    +            body.toString()
    +        }))
             this
         }
     
    @@ -729,7 +724,9 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
                 throw new GradleException("Too many parameters for body clojure")
             }
     
    -        this.body = closure
    +        this.body.set(project.provider({
    +            closure.call(getRepository()).toString()
    +        }))
             this
         }
     
    @@ -737,7 +734,9 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
          * See: {@link GithubPublishSpec#setBody(PublishBodyStrategy)}
          */
         GithubPublish setBody(PublishBodyStrategy bodyStrategy) {
    -        this.body = bodyStrategy
    +        this.body.set(project.provider({
    +            bodyStrategy.getBody(getRepository())
    +        }))
             this
         }
     
    @@ -773,25 +772,12 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
             this.setBody(bodyStrategy)
         }
     
    -    /**
    -     * See: {@link GithubPublishSpec#isPrerelease()}
    -     */
    -    @Input
    -    @Override
    -    boolean isPrerelease() {
    -        if (this.prerelease instanceof Callable) {
    -            return ((Callable) this.prerelease).call().asBoolean()
    -        }
    -
    -        this.prerelease.asBoolean()
    -    }
    -
         /**
          * See: {@link GithubPublishSpec#setPrerelease(boolean)}
          */
         @Override
    -    GithubPublish setPrerelease(boolean prerelease) {
    -        this.prerelease = prerelease
    +    GithubPublish setPrerelease(Boolean prerelease) {
    +        this.prerelease.set(prerelease)
             this
         }
     
    @@ -800,7 +786,14 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
          */
         @Override
         GithubPublish setPrerelease(Object prerelease) {
    -        this.prerelease = prerelease
    +
    +        this.prerelease.set(project.provider({
    +            if (prerelease instanceof Callable) {
    +                return Boolean.parseBoolean(((Callable) prerelease).call().toString())
    +            }
    +
    +            Boolean.parseBoolean(prerelease.toString())
    +        }))
             this
         }
     
    @@ -808,7 +801,7 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
          * See: {@link GithubPublishSpec#prerelease(boolean)}
          */
         @Override
    -    GithubPublish prerelease(boolean prerelease) {
    +    GithubPublish prerelease(Boolean prerelease) {
             this.setPrerelease(prerelease)
         }
     
    @@ -820,25 +813,12 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
             this.setPrerelease(prerelease)
         }
     
    -    /**
    -     * See: {@link GithubPublishSpec#isDraft()}
    -     */
    -    @Input
    -    @Override
    -    boolean isDraft() {
    -        if (this.draft instanceof Callable) {
    -            return ((Callable) this.draft).call().asBoolean()
    -        }
    -
    -        this.draft.asBoolean()
    -    }
    -
         /**
          * See: {@link GithubPublishSpec#setDraft(boolean)}
          */
         @Override
    -    GithubPublish setDraft(boolean draft) {
    -        this.draft = draft
    +    GithubPublish setDraft(Boolean draft) {
    +        this.draft.set(draft)
             this
         }
     
    @@ -847,7 +827,13 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
          */
         @Override
         GithubPublish setDraft(Object draft) {
    -        this.draft = draft
    +        this.draft.set(project.provider({
    +            if (draft instanceof Callable) {
    +                return Boolean.parseBoolean(((Callable) draft).call().toString())
    +            }
    +
    +            Boolean.parseBoolean(draft.toString())
    +        }))
             this
         }
     
    @@ -855,7 +841,7 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
          * See: {@link GithubPublishSpec#draft(boolean)}
          */
         @Override
    -    GithubPublish draft(boolean draft) {
    +    GithubPublish draft(Boolean draft) {
             this.setDraft(draft)
         }
     
    @@ -867,24 +853,12 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
             this.setDraft(draft)
         }
     
    -    /**
    -     * See: {@link GithubPublishSpec#getPublishMethod()}
    -     */
    -    @Override
    -    PublishMethod getPublishMethod() {
    -        if (this.publishMethod instanceof Callable) {
    -            return ((Callable) this.publishMethod).call() as PublishMethod
    -        }
    -
    -        this.publishMethod as PublishMethod
    -    }
    -
         /**
          * See: {@link GithubPublishSpec#setPublishMethod(PublishMethod)}
          */
         @Override
         GithubPublishSpec setPublishMethod(PublishMethod method) {
    -        this.publishMethod = method
    +        this.publishMethod.set(method)
             this
         }
     
    @@ -893,7 +867,13 @@ class GithubPublish extends AbstractGithubTask implements GithubPublishSpec {
          */
         @Override
         GithubPublishSpec setPublishMethod(Object method) {
    -        this.publishMethod = method
    +        this.publishMethod.set(project.provider({
    +            if (method instanceof Callable) {
    +                return ((Callable) method).call() as PublishMethod
    +            }
    +
    +            method as PublishMethod
    +        }))
             this
         }
     
    diff --git a/src/test/groovy/wooga/gradle/github/base/internal/DefaultGithubPluginExtensionSpec.groovy b/src/test/groovy/wooga/gradle/github/base/internal/DefaultGithubPluginExtensionSpec.groovy
    deleted file mode 100644
    index c0d44df..0000000
    --- a/src/test/groovy/wooga/gradle/github/base/internal/DefaultGithubPluginExtensionSpec.groovy
    +++ /dev/null
    @@ -1,273 +0,0 @@
    -/*
    - * Copyright 2018 Wooga GmbH
    - *
    - * Licensed under the Apache License, Version 2.0 (the "License");
    - * you may not use this file except in compliance with the License.
    - * You may obtain a copy of the License at
    - *
    - *       http://www.apache.org/licenses/LICENSE-2.0
    - *
    - * Unless required by applicable law or agreed to in writing, software
    - * distributed under the License is distributed on an "AS IS" BASIS,
    - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    - * See the License for the specific language governing permissions and
    - * limitations under the License.
    - *
    - */
    -
    -package wooga.gradle.github.base.internal
    -
    -import spock.lang.Specification
    -import spock.lang.Subject
    -import spock.lang.Unroll
    -
    -@Subject(DefaultGithubPluginExtension)
    -class DefaultGithubPluginExtensionSpec extends Specification {
    -
    -    Map properties = [:]
    -
    -    def extension = new DefaultGithubPluginExtension(properties)
    -
    -    @Unroll
    -    def "retrieve default values from properties when set #userNameValue:#passwordValue:#tokenValue:#repositoryValue"() {
    -        given: "project properties with values"
    -
    -        if (userNameValue) {
    -            properties[DefaultGithubPluginExtension.GITHUB_USER_NAME_OPTION] = userNameValue
    -        }
    -
    -        if (passwordValue) {
    -            properties[DefaultGithubPluginExtension.GITHUB_USER_PASSWORD_OPTION] = passwordValue
    -        }
    -
    -        if (tokenValue) {
    -            properties[DefaultGithubPluginExtension.GITHUB_TOKEN_OPTION] = tokenValue
    -        }
    -
    -        if (repositoryValue) {
    -            properties[DefaultGithubPluginExtension.GITHUB_REPOSITORY_OPTION] = repositoryValue
    -        }
    -
    -        expect:
    -        with(extension) {
    -            username == userNameValue
    -            getUsername() == userNameValue
    -
    -            password == passwordValue
    -            getPassword() == passwordValue
    -
    -            token == tokenValue
    -            getToken() == tokenValue
    -
    -            repositoryName == repositoryValue
    -            getRepositoryName() == repositoryValue
    -        }
    -
    -        where:
    -        userNameValue | passwordValue  | tokenValue  | repositoryValue
    -        "testUser"    | "testPassword" | "testToken" | "test/repo"
    -        null          | null           | null        | "test/repo"
    -    }
    -
    -    @Unroll
    -    def "retrieve default values from properties when set repository:#propertyValue"() {
    -        given: "project properties with values"
    -        if (propertyValue) {
    -            properties[propertyKey] = propertyValue
    -        }
    -
    -        when:
    -        extension.repositoryName
    -
    -        then:
    -        IllegalArgumentException e = thrown()
    -        e.message.contains("Repository value '$propertyValue' is not a valid github repository name")
    -
    -        where:
    -        valueToTest      | propertyKey                                           | propertyValue
    -        "repositoryName" | DefaultGithubPluginExtension.GITHUB_REPOSITORY_OPTION | "invalid-repo-name"
    -        "repositoryName" | DefaultGithubPluginExtension.GITHUB_REPOSITORY_OPTION | "https://github.com/some/repo"
    -    }
    -
    -    @Unroll("#methodName throws IllegalArgumentException when value is #propertyMessage")
    -    def "token throws IllegalArgumentException"() {
    -        when:
    -        if (useSetter) {
    -            extension.setToken(propertyValue)
    -        } else {
    -            extension.token(propertyValue)
    -        }
    -
    -        then:
    -        IllegalArgumentException e = thrown()
    -        e.message == "token"
    -
    -        where:
    -        propertyValue | useSetter
    -        null          | true
    -        null          | false
    -        ""            | true
    -        ""            | false
    -
    -        propertyMessage = propertyValue == null ? propertyValue : "empty"
    -        methodName = useSetter ? "setToken" : "token"
    -    }
    -
    -    @Unroll("#methodName throws IllegalArgumentException when value is #propertyMessage")
    -    def "repositoryName setter throws IllegalArgumentException"() {
    -        when:
    -        if (useSetter) {
    -            extension.setRepositoryName(propertyValue)
    -        } else {
    -            extension.repositoryName(propertyValue)
    -        }
    -
    -        then:
    -        IllegalArgumentException e = thrown()
    -        e.message == "repository"
    -
    -        where:
    -        propertyValue | useSetter
    -        null          | true
    -        null          | false
    -        ""            | true
    -        ""            | false
    -
    -        propertyMessage = propertyValue == null ? propertyValue : "empty"
    -        methodName = useSetter ? "setRepository" : "repository"
    -    }
    -
    -    @Unroll("#methodName throws IllegalArgumentException when value is #propertyMessage")
    -    def "repositoryName setter throws IllegalArgumentException when passing invalid repo"() {
    -        when:
    -        if (useSetter) {
    -            extension.setRepositoryName(propertyValue)
    -        } else {
    -            extension.repositoryName(propertyValue)
    -        }
    -
    -        then:
    -        IllegalArgumentException e = thrown()
    -        e.message.contains("Repository value '$propertyValue' is not a valid github repository")
    -
    -        where:
    -        propertyValue                              | useSetter
    -        "invalid-repo"                             | true
    -        "invalid-repo"                             | false
    -        "https://github.com/user/invalid-repo.git" | true
    -        "https://github.com/user/invalid-repo.git" | false
    -
    -        propertyMessage = propertyValue
    -        methodName = useSetter ? "setRepository" : "repository"
    -    }
    -
    -    @Unroll("#methodName throws IllegalArgumentException when value is #propertyMessage")
    -    def "userName setter throws IllegalArgumentException"() {
    -        when:
    -        if (useSetter) {
    -            extension.setUsername(propertyValue)
    -        } else {
    -            extension.username(propertyValue)
    -        }
    -
    -        then:
    -        IllegalArgumentException e = thrown()
    -        e.message == "username"
    -
    -        where:
    -        propertyValue | useSetter
    -        null          | true
    -        null          | false
    -        ""            | true
    -        ""            | false
    -
    -        propertyMessage = propertyValue == null ? propertyValue : "empty"
    -        methodName = useSetter ? "setUsername" : "username"
    -    }
    -
    -    @Unroll("#methodName throws IllegalArgumentException when value is #propertyMessage")
    -    def "password setter throws IllegalArgumentException"() {
    -        when:
    -        if (useSetter) {
    -            extension.setPassword(propertyValue)
    -        } else {
    -            extension.password(propertyValue)
    -        }
    -
    -        then:
    -        IllegalArgumentException e = thrown()
    -        e.message == "password"
    -
    -        where:
    -        propertyValue | useSetter
    -        null          | true
    -        null          | false
    -        ""            | true
    -        ""            | false
    -
    -        propertyMessage = propertyValue == null ? propertyValue : "empty"
    -        methodName = useSetter ? "setPassword" : "password"
    -    }
    -
    -    @Unroll("#methodName throws IllegalArgumentException when value is #propertyMessage")
    -    def "baseUrl setter throws IllegalArgumentException"() {
    -        when:
    -        if (useSetter) {
    -            extension.setBaseUrl(propertyValue)
    -        } else {
    -            extension.baseUrl(propertyValue)
    -        }
    -
    -        then:
    -        IllegalArgumentException e = thrown()
    -        e.message == "baseUrl"
    -
    -        where:
    -        propertyValue | useSetter
    -        null          | true
    -        null          | false
    -        ""            | true
    -        ""            | false
    -
    -        propertyMessage = propertyValue == null ? propertyValue : "empty"
    -        methodName = useSetter ? "setBaseUrl" : "baseUrl"
    -    }
    -
    -    @Unroll("can set values via #methodName")
    -    def "can set values with setter and set method"() {
    -        when:
    -        if (useSetter) {
    -            with(extension) {
    -                setBaseUrl("baseURL")
    -                setUsername("username")
    -                setPassword("password")
    -                setToken("token")
    -                setRepositoryName("test/repository")
    -            }
    -
    -        } else {
    -            with(extension) {
    -                baseUrl("baseURL")
    -                username("username")
    -                password("password")
    -                token("token")
    -                repositoryName("test/repository")
    -            }
    -        }
    -
    -        then:
    -        with(extension) {
    -            baseUrl == "baseURL"
    -            username == "username"
    -            password == "password"
    -            token == "token"
    -            repositoryName == "test/repository"
    -        }
    -
    -
    -        where:
    -        useSetter << [true, false]
    -        methodName = useSetter ? "setter" : "set short method"
    -    }
    -
    -}