diff --git a/README.md b/README.md index 1111e5b..599f31e 100644 --- a/README.md +++ b/README.md @@ -141,8 +141,12 @@ task sourcesJar(type: Jar) { from sourceSets.main.allSource } semanticRelease { - changeLog { - releaseAssets(jar, sourcesJar) + repo { + releaseAsset jar + // optionally set name, label and/or contentType + releaseAsset sourcesJar, name: "the-sources.jar", label: 'the sources jar', contentType: 'application/zip' + // or + // releaseAsset sourcesJar name "the-sources.jar" label "the sources jar" contentType "application/zip" } } ``` diff --git a/build.gradle b/build.gradle index 488fb97..16d9b65 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,7 @@ sourceSets { group = 'de.gliderpilot.gradle.semantic-release' semanticRelease { - changeLog.ghToken = project.ext.ghToken + repo.ghToken = project.ext.ghToken } task integTest { diff --git a/src/main/groovy/de/gliderpilot/gradle/semanticrelease/GitRepo.groovy b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/GitRepo.groovy new file mode 100644 index 0000000..664310a --- /dev/null +++ b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/GitRepo.groovy @@ -0,0 +1,77 @@ +/* + * Copyright 2015 the original author or authors. + * + * 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 de.gliderpilot.gradle.semanticrelease + +import groovy.transform.PackageScope +import org.gradle.api.Task +import org.gradle.api.tasks.bundling.AbstractArchiveTask + +abstract class GitRepo { + + private Map releaseAssets = [:].withDefault { file -> new Asset(file) } + + @PackageScope + Collection getReleaseAssets() { + return releaseAssets.values() + } + + + Asset releaseAsset(Map params = [:], AbstractArchiveTask task) { + params.builtBy = task + releaseAsset(params, task.outputs.files.singleFile) + } + + Asset releaseAsset(Map params = [:], File file) { + Asset asset = releaseAssets[file] + params.each { key, value -> + asset."$key" = value + } + asset + } + + abstract String diffUrl(String previousTag, String currentTag) + + abstract String commitUrl(String abbreviatedId) +} + +class Asset { + final File file + Task builtBy + String name + String label + String contentType + + Asset(File file) { + this.file = file + name = file.name + contentType = URLConnection.guessContentTypeFromName(name) ?: "application/octet-stream" + } + + Asset name(String name) { + this.name = name + this + } + + Asset label(String label) { + this.label = label + this + } + + Asset contentType(String contentType) { + this.contentType = contentType + this + } +} diff --git a/src/main/groovy/de/gliderpilot/gradle/semanticrelease/GithubRepo.groovy b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/GithubRepo.groovy new file mode 100644 index 0000000..2983cef --- /dev/null +++ b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/GithubRepo.groovy @@ -0,0 +1,74 @@ +/* + * Copyright 2015 the original author or authors. + * + * 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 de.gliderpilot.gradle.semanticrelease + +import com.jcabi.github.Github +import com.jcabi.github.RtGithub +import groovy.transform.Memoized +import groovy.transform.PackageScope +import org.ajoberstar.grgit.Grgit + +import java.util.regex.Matcher + +class GithubRepo extends GitRepo { + + private final Grgit grgit + + private Github github + + @PackageScope + Github getGithub() { + github + } + + GithubRepo(Grgit grgit) { + this.grgit = grgit + } + + void setGhToken(String token) { + if (token) + github = new RtGithub(token) + } + + @PackageScope + @Memoized + String getMnemo() { + String repositoryUrl = grgit.remote.list().find { it.name == 'origin' }.url + Matcher matcher = repositoryUrl =~ /.*github.com[\/:]((?:.+?)\/(?:.+?))(?:\.git)/ + if (!matcher) + return null + return matcher.group(1) + } + + private String repositoryUrl(String suffix) { + if (!mnemo) + return null + return "https://github.com/${mnemo}/$suffix" + } + + String diffUrl(String previousTag, String currentTag) { + if (!(previousTag && currentTag)) + return null + repositoryUrl("compare/${previousTag}...${currentTag}") + } + + String commitUrl(String abbreviatedId) { + if (!abbreviatedId) + return null + repositoryUrl("commit/${abbreviatedId}") + } + +} \ No newline at end of file diff --git a/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseChangeLogService.groovy b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseChangeLogService.groovy index 7bc3a3b..c41ca38 100644 --- a/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseChangeLogService.groovy +++ b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseChangeLogService.groovy @@ -16,7 +16,7 @@ package de.gliderpilot.gradle.semanticrelease import com.github.zafarkhaja.semver.Version -import com.jcabi.github.* +import com.jcabi.github.Github import groovy.text.SimpleTemplateEngine import groovy.text.Template import groovy.transform.Memoized @@ -29,8 +29,6 @@ import org.ajoberstar.grgit.Grgit import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging -import java.util.regex.Matcher - /** * Created by tobias on 7/26/15. */ @@ -40,34 +38,31 @@ class SemanticReleaseChangeLogService { private final TagStrategy tagStrategy private final Grgit grgit + private final GitRepo repo - @PackageScope - Github github - private Closure> files - private Iterable releaseAssets - - SemanticReleaseChangeLogService(Grgit grgit, TagStrategy tagStrategy, Closure> files) { + SemanticReleaseChangeLogService(Grgit grgit, GitRepo repo, TagStrategy tagStrategy) { this.grgit = grgit + this.repo = repo this.tagStrategy = tagStrategy - this.files = files - releaseAssets = files() } + @Deprecated void setGhToken(String token) { - if (token) - github = new RtGithub(token) + logger.warn("semanticRelease.changeLog.ghToken is deprecated and will be removed in v2.0.0") + logger.warn("use semanticRelease.gitRepo.ghToken instead") + repo.ghToken = token } @Deprecated Github getGithub() { logger.warn("semanticRelease.changeLog.github is deprecated and will be removed in v2.0.0") - github + repo.github } @Deprecated void setGithub(Github github) { logger.warn("semanticRelease.changeLog.github is deprecated and will be removed in v2.0.0") - this.github = github + repo.github = github } /** @@ -107,7 +102,7 @@ class SemanticReleaseChangeLogService { Template template = new SimpleTemplateEngine().createTemplate(getClass().getResource('/CHANGELOG.md')) template.make([ title : null, - versionUrl: versionUrl(previousTag, currentTag), + versionUrl: repo.diffUrl(previousTag, currentTag), service : this, version : version.version, fix : byTypeGroupByComponent(commits, 'fix'), @@ -175,7 +170,7 @@ class SemanticReleaseChangeLogService { @PackageScope def commitish = { Commit commit -> - String url = repositoryUrl("commit/${commit.abbreviatedId}") + String url = repo.commitUrl(commit.abbreviatedId) url ? "[${commit.abbreviatedId}]($url)" : "${commit.abbreviatedId}" } @@ -186,35 +181,6 @@ class SemanticReleaseChangeLogService { }.groupBy(component).sort { a, b -> a.key <=> b.key } } - @PackageScope - @Memoized - String mnemo() { - String repositoryUrl = grgit.remote.list().find { it.name == 'origin' }.url - Matcher matcher = repositoryUrl =~ /.*github.com[\/:]((?:.+?)\/(?:.+?))(?:\.git)/ - if (!matcher) - return null - return matcher.group(1) - } - - @PackageScope - Closure repositoryUrl = { String suffix -> - String mnemo = mnemo() - if (!mnemo) - return null - return "https://github.com/${mnemo}/$suffix" - } - - @PackageScope - Closure versionUrl = { String previousTag, String currentTag -> - if (!(previousTag && currentTag)) - return null - repositoryUrl("compare/${previousTag}...${currentTag}") - } - - void releaseAssets(Object... assets) { - releaseAssets += files(assets) - } - @PackageScope @Memoized List commits(Version previousVersion) { @@ -228,36 +194,4 @@ class SemanticReleaseChangeLogService { } } - @PackageScope - void createGitHubVersion(ReleaseVersion version) { - String mnemo = mnemo() - if (!mnemo) - return - if (!github) - return - String tag = tagStrategy.toTagString(version.version) - - Repo repo = github.repos().get(new Coordinates.Simple(mnemo)) - - // check for the existance of the tag using the api -> #3 - long start = System.currentTimeMillis() - while (!tagExists(repo, tag) && System.currentTimeMillis() - start < 60000) { - } - - Release release = repo.releases().create(tag) - new Release.Smart(release).body(changeLog(commits(Version.valueOf(version.previousVersion)), version).toString()) - releaseAssets.each { - release.assets().upload(it.bytes, URLConnection.guessContentTypeFromName(it.name) ?: "application/octet-stream", it.name) - } - } - - private boolean tagExists(Repo repo, String tag) { - try { - repo.git().references().get("refs/tags/$tag").json() - return true - } catch (Throwable t) { - return false - } - } - } diff --git a/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePlugin.groovy b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePlugin.groovy index 22f24f4..36a3cb3 100644 --- a/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePlugin.groovy +++ b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePlugin.groovy @@ -31,11 +31,8 @@ class SemanticReleasePlugin implements Plugin { SemanticReleasePluginExtension semanticReleaseExtension = extensions.create("semanticRelease", SemanticReleasePluginExtension, project) ReleasePluginExtension releaseExtension = extensions.findByType(ReleasePluginExtension) def releaseTask = tasks.release - releaseTask.doLast { - if (project.version.inferredVersion.createTag) { - semanticReleaseExtension.changeLog.createGitHubVersion(project.version.inferredVersion) - } - } + tasks.create("updateGithubRelease", UpdateGithubRelease) + releaseTask.finalizedBy project.tasks.updateGithubRelease releaseExtension.with { versionStrategy semanticReleaseExtension.releaseStrategy defaultVersionStrategy = semanticReleaseExtension.snapshotStrategy diff --git a/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePluginExtension.groovy b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePluginExtension.groovy index cc8f0fa..dd0b690 100644 --- a/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePluginExtension.groovy +++ b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePluginExtension.groovy @@ -29,6 +29,7 @@ import javax.inject.Inject class SemanticReleasePluginExtension { final Project project + final GitRepo repo final SemanticReleaseChangeLogService changeLog final SemanticReleaseCheckBranch releaseBranches final SemanticReleaseAppendBranchNameStrategy branchNames @@ -39,12 +40,8 @@ class SemanticReleasePluginExtension { @Inject SemanticReleasePluginExtension(Project project) { this.project = project - def files = { Object[] args -> - if (args) - project.tasks.release.dependsOn args - project.files(args) - } - changeLog = new SemanticReleaseChangeLogService(project.grgit, project.release.tagStrategy, files) + this.repo = new GithubRepo(project.grgit) + changeLog = new SemanticReleaseChangeLogService(project.grgit, repo, project.release.tagStrategy) releaseBranches = new SemanticReleaseCheckBranch() branchNames = new SemanticReleaseAppendBranchNameStrategy(releaseBranches) semanticStrategy = new SemanticReleaseNormalStrategy(project.grgit, changeLog) @@ -70,6 +67,10 @@ class SemanticReleasePluginExtension { ConfigureUtil.configure(closure, changeLog) } + def repo(Closure closure) { + ConfigureUtil.configure(closure, repo) + } + def releaseBranches(Closure closure) { ConfigureUtil.configure(closure, releaseBranches) } diff --git a/src/main/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubRelease.groovy b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubRelease.groovy new file mode 100644 index 0000000..a65ca4b --- /dev/null +++ b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubRelease.groovy @@ -0,0 +1,62 @@ +/* + * Copyright 2015 the original author or authors. + * + * 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 de.gliderpilot.gradle.semanticrelease + +import org.ajoberstar.gradle.git.release.base.ReleaseVersion +import org.gradle.api.DefaultTask +import org.gradle.api.logging.Logger +import org.gradle.api.logging.Logging +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.TaskAction + +class UpdateGithubRelease extends DefaultTask { + + private final Logger logger = Logging.getLogger(getClass()) + + UpdateGithubRelease() { + onlyIf { repo.mnemo } + onlyIf { repo.github } + onlyIf { version?.createTag } + dependsOn { repo.releaseAssets*.builtBy.findAll { it != null } } + } + + @Input + protected ReleaseVersion getVersion() { + project.version.inferredVersion + } + + protected String getTagName() { + project.release.tagStrategy.toTagString(version.version) + } + + @Input + Collection getReleaseAssets() { + return repo.releaseAssets + } + + GithubRepo getRepo() { + project.semanticRelease.repo + } + + SemanticReleaseChangeLogService getChangeLog() { + project.semanticRelease.changeLog + } + + @TaskAction + void updateGithubRelease() { + new UpdateGithubReleaseService().updateGithubRelease(changeLog, repo, version, tagName) + } +} diff --git a/src/main/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubReleaseService.groovy b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubReleaseService.groovy new file mode 100644 index 0000000..702226b --- /dev/null +++ b/src/main/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubReleaseService.groovy @@ -0,0 +1,62 @@ +/* + * Copyright 2015 the original author or authors. + * + * 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 de.gliderpilot.gradle.semanticrelease + +import com.github.zafarkhaja.semver.Version +import com.jcabi.github.Coordinates +import com.jcabi.github.Release +import com.jcabi.github.ReleaseAsset +import com.jcabi.github.Repo +import groovy.transform.PackageScope +import org.ajoberstar.gradle.git.release.base.ReleaseVersion +import org.gradle.api.logging.Logger +import org.gradle.api.logging.Logging + +@PackageScope +class UpdateGithubReleaseService { + + private final Logger logger = Logging.getLogger(getClass()) + + void updateGithubRelease(SemanticReleaseChangeLogService changeLog, + GithubRepo githubRepo, + ReleaseVersion version, + String tagName) { + Repo repo = githubRepo.github.repos().get(new Coordinates.Simple(githubRepo.mnemo)) + + // check for the existance of the tag using the api -> #3 + long start = System.currentTimeMillis() + while (!tagExists(repo, tagName) && System.currentTimeMillis() - start < 60000) { + } + + Release release = repo.releases().create(tagName) + def commits = changeLog.commits(Version.valueOf(version.previousVersion)) + new Release.Smart(release).body(changeLog.changeLog(commits, version).toString()) + githubRepo.releaseAssets.each { asset -> + ReleaseAsset releaseAsset = release.assets().upload(asset.file.bytes, asset.contentType, asset.name) + if (asset.label) + new ReleaseAsset.Smart(releaseAsset).label(asset.label) + } + } + + private boolean tagExists(Repo repo, String tag) { + try { + repo.git().references().get("refs/tags/$tag").json() + return true + } catch (Throwable t) { + return false + } + } +} diff --git a/src/test/groovy/de/gliderpilot/gradle/semanticrelease/GithubRepoSpec.groovy b/src/test/groovy/de/gliderpilot/gradle/semanticrelease/GithubRepoSpec.groovy new file mode 100644 index 0000000..dae405e --- /dev/null +++ b/src/test/groovy/de/gliderpilot/gradle/semanticrelease/GithubRepoSpec.groovy @@ -0,0 +1,71 @@ +/* + * Copyright 2015 the original author or authors. + * + * 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 de.gliderpilot.gradle.semanticrelease + +import com.jcabi.github.RtGithub +import org.ajoberstar.grgit.Grgit +import spock.lang.Shared +import spock.lang.Specification +import spock.lang.Subject +import spock.lang.Unroll + +class GithubRepoSpec extends Specification { + + @Shared + Grgit grgit = Grgit.open() + + @Shared + @Subject + GithubRepo repo = new GithubRepo(grgit) + + def "creates github service upon setting ghToken"() { + when: + repo.ghToken = '12345' + + then: + repo.github instanceof RtGithub + } + + @Unroll + def "diffUrl for #tag1 and #tag2 is #expectedUrl"() { + when: + String diffUrl = repo.diffUrl(tag1, tag2) + + then: + diffUrl == expectedUrl + + where: + tag1 | tag2 | expectedUrl + "v1.0.0" | "v1.1.0" | "https://github.com/${repo.mnemo}/compare/v1.0.0...v1.1.0" + "v1.0.0" | null | null + null | "v1.1.0" | null + + } + + def "generates commitUrl"() { + when: + String commitUrl = repo.commitUrl("affe") + + then: + commitUrl == "https://github.com/${repo.mnemo}/commit/affe" + } + + def "commitUrl for null is null"() { + expect: + repo.commitUrl(null) == null + } + +} diff --git a/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseChangeLogServiceSpec.groovy b/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseChangeLogServiceSpec.groovy index 87eb8a2..8af8dea 100644 --- a/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseChangeLogServiceSpec.groovy +++ b/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseChangeLogServiceSpec.groovy @@ -15,18 +15,12 @@ */ package de.gliderpilot.gradle.semanticrelease -import com.jcabi.github.Coordinates -import com.jcabi.github.Release -import com.jcabi.github.Repos -import com.jcabi.github.RtGithub -import com.jcabi.github.mock.MkGithub import org.ajoberstar.gradle.git.release.base.ReleaseVersion import org.ajoberstar.gradle.git.release.base.TagStrategy import org.ajoberstar.grgit.Commit import org.ajoberstar.grgit.Grgit import spock.lang.Specification import spock.lang.Subject -import spock.lang.Timeout import spock.lang.Unroll import static org.ajoberstar.gradle.git.release.semver.ChangeScope.* @@ -39,10 +33,10 @@ class SemanticReleaseChangeLogServiceSpec extends Specification { Grgit grgit = Mock() TagStrategy tagStrategy = new TagStrategy() - Closure> files = { it instanceof Object[] ? it as List : [] } + GitRepo repo = new GithubRepo(grgit) @Subject - SemanticReleaseChangeLogService changeLogService = new SemanticReleaseChangeLogService(grgit, tagStrategy, files) + SemanticReleaseChangeLogService changeLogService = new SemanticReleaseChangeLogService(grgit, repo, tagStrategy) def "does not throw an exception if no ticket is referenced"() { given: @@ -58,14 +52,6 @@ class SemanticReleaseChangeLogServiceSpec extends Specification { '\n' | _ } - def "creates github service upon setting ghToken"() { - when: - changeLogService.ghToken = '12345' - - then: - changeLogService.github instanceof RtGithub - } - def "finds referenced tickets one on each line"() { given: Commit commit = new Commit(fullMessage: '''\ @@ -181,8 +167,9 @@ class SemanticReleaseChangeLogServiceSpec extends Specification { def "changeLog is generated"() { given: grgit = Grgit.open() - changeLogService = new SemanticReleaseChangeLogService(grgit, tagStrategy, files) - String mnemo = changeLogService.mnemo() + repo = new GithubRepo(grgit) + changeLogService = new SemanticReleaseChangeLogService(grgit, repo, tagStrategy) + String mnemo = repo.mnemo when: def commits = [ @@ -218,48 +205,6 @@ class SemanticReleaseChangeLogServiceSpec extends Specification { changeLogService.changeLog(commits.collect(asCommit), new ReleaseVersion(previousVersion: '1.0.0', version: '2.0.0', createTag: true)).toString() == expected } - @Timeout(10) - def "change log is uploaded to GitHub"() { - given: - grgit = Grgit.open() - changeLogService = new SemanticReleaseChangeLogService(grgit, tagStrategy, files) - File asset = new File('settings.gradle') - changeLogService.releaseAssets(asset) - String mnemo = changeLogService.mnemo() - String user = mnemo.substring(0, mnemo.indexOf("/")) - String repo = mnemo.substring(mnemo.indexOf("/") + 1) - changeLogService.github = new MkGithub(user) - changeLogService.github.repos().create(new Repos.RepoCreate(repo, false)) - def coordinates = new Coordinates.Simple("$mnemo") - changeLogService.github.repos().get(coordinates).git().references().create("refs/tags/v1.0.0", "affe") - changeLogService.changeLog = { List commits, ReleaseVersion version -> - "${'changelog'}" - } - - when: - changeLogService.createGitHubVersion(new ReleaseVersion(previousVersion: '0.0.0', version: '1.0.0')) - def releases = changeLogService.github.repos().get(coordinates).releases() - def release = releases.iterate().collect { new Release.Smart(it) }.find { - it.tag() == 'v1.0.0' - } - - then: - release?.body() == 'changelog' - release?.assets().iterate().any { it.json().getString("name") == asset.name } - } - - def "change log is not uploaded to GitHub when no gh token is set"() { - given: - grgit = Grgit.open() - changeLogService = new SemanticReleaseChangeLogService(grgit, tagStrategy, files) - - when: - changeLogService.createGitHubVersion(new ReleaseVersion(previousVersion: '1.0.0', version: '1.0.1')) - - then: - noExceptionThrown() - } - static asCommit = { new Commit(fullMessage: it, shortMessage: it.readLines().first(), id: '123456789abc') } } diff --git a/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseNormalStrategySpec.groovy b/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseNormalStrategySpec.groovy index 444d77f..794bdf7 100644 --- a/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseNormalStrategySpec.groovy +++ b/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleaseNormalStrategySpec.groovy @@ -29,7 +29,8 @@ class SemanticReleaseNormalStrategySpec extends Specification { Grgit grgit = Mock() TagStrategy tagStrategy = new TagStrategy() - SemanticReleaseChangeLogService changeLogService = new SemanticReleaseChangeLogService(grgit, tagStrategy, { [] }) + GitRepo repo = new GithubRepo(grgit) + SemanticReleaseChangeLogService changeLogService = new SemanticReleaseChangeLogService(grgit, repo, tagStrategy) @Subject SemanticReleaseNormalStrategy strategy = new SemanticReleaseNormalStrategy(grgit, diff --git a/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePluginSpec.groovy b/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePluginSpec.groovy index 4792952..6e5d13d 100644 --- a/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePluginSpec.groovy +++ b/src/test/groovy/de/gliderpilot/gradle/semanticrelease/SemanticReleasePluginSpec.groovy @@ -181,14 +181,20 @@ class SemanticReleasePluginSpec extends ProjectSpec { from javadoc } semanticRelease { - changeLog { - releaseAssets jar, sourcesJar, javadocJar + repo { + releaseAsset jar, name: "thejar.jar" + releaseAsset sourcesJar, label: 'thelabel' + releaseAsset javadocJar, contentType: 'thecontenttype' } } } when: - List releaseAssets = project.semanticRelease.changeLog.releaseAssets.toList() + Collection releaseAssets = project.semanticRelease.repo.releaseAssets.collect { it.file } + def finalizedBy = project.tasks.release.finalizedBy.getDependencies(project.tasks.release) + def dependsOn = project.tasks.updateGithubRelease.dependsOn.collect { + it instanceof Closure ? it() : it + }.flatten() then: releaseAssets.containsAll(project.jar.outputs.files.files) @@ -196,8 +202,10 @@ class SemanticReleasePluginSpec extends ProjectSpec { releaseAssets.containsAll(project.javadocJar.outputs.files.files) and: "task dependencies are automatically added" - project.tasks.release.dependsOn.contains(project.jar) - project.tasks.release.dependsOn.contains(project.sourcesJar) - project.tasks.release.dependsOn.contains(project.javadocJar) + finalizedBy.contains(project.tasks.updateGithubRelease) + + dependsOn.contains(project.jar) + dependsOn.contains(project.sourcesJar) + dependsOn.contains(project.javadocJar) } } diff --git a/src/test/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubReleaseServiceSpec.groovy b/src/test/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubReleaseServiceSpec.groovy new file mode 100644 index 0000000..da79f42 --- /dev/null +++ b/src/test/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubReleaseServiceSpec.groovy @@ -0,0 +1,74 @@ +/* + * Copyright 2015 the original author or authors. + * + * 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 de.gliderpilot.gradle.semanticrelease + +import com.jcabi.github.Coordinates +import com.jcabi.github.Release +import com.jcabi.github.Repos +import com.jcabi.github.mock.MkGithub +import org.ajoberstar.gradle.git.release.base.ReleaseVersion +import org.ajoberstar.gradle.git.release.base.TagStrategy +import org.ajoberstar.grgit.Commit +import org.ajoberstar.grgit.Grgit +import spock.lang.Specification +import spock.lang.Subject +import spock.lang.Timeout + +class UpdateGithubReleaseServiceSpec extends Specification { + + Grgit grgit = Grgit.open() + + GithubRepo repo = new GithubRepo(grgit) + + TagStrategy tagStrategy = new TagStrategy() + SemanticReleaseChangeLogService changeLogService = new SemanticReleaseChangeLogService(grgit, repo, tagStrategy) + + @Subject + UpdateGithubReleaseService service = new UpdateGithubReleaseService() + + @Timeout(10) + def "change log is uploaded to GitHub"() { + given: + File asset = new File('settings.gradle') + repo.releaseAsset(asset) + String mnemo = repo.mnemo + String user = mnemo.substring(0, mnemo.indexOf("/")) + String repoName = mnemo.substring(mnemo.indexOf("/") + 1) + repo.github = new MkGithub(user) + repo.github.repos().create(new Repos.RepoCreate(repoName, false)) + def coordinates = new Coordinates.Simple("$mnemo") + repo.github.repos().get(coordinates).git().references().create("refs/tags/v1.1.0", "affe") + changeLogService.changeLog = { List commits, ReleaseVersion version -> + "${'changelog'}" + } + + when: + service.updateGithubRelease(changeLogService, + repo, + new ReleaseVersion(version: "1.1.0", previousVersion: "1.0.0", createTag: true), + "v1.1.0" + ) + def releases = repo.github.repos().get(coordinates).releases() + def release = releases.iterate().collect { new Release.Smart(it) }.find { + it.tag() == 'v1.1.0' + } + + then: + release?.body() == 'changelog' + release?.assets().iterate().any { it.json().getString("name") == asset.name } + } + +}