From 8b5995e23cb9c574ab4151d426ecbe592918560c Mon Sep 17 00:00:00 2001 From: Tobias Schulte Date: Sat, 13 Aug 2016 10:16:27 +0200 Subject: [PATCH] feat: allow specifying name, label and contentType of releaseAssets refactor on the way. Add new repo closure to semanticRelease extension. Here both ghToken and all releaseAssets must be given. Mark old changeLog.ghToken as deprecated Add new UpdateGithubRelease task. The release is now updated using this task instead of release.doLast --- README.md | 8 +- build.gradle | 2 +- .../gradle/semanticrelease/GitRepo.groovy | 77 ++++++++++++++++ .../gradle/semanticrelease/GithubRepo.groovy | 74 +++++++++++++++ .../SemanticReleaseChangeLogService.groovy | 90 +++---------------- .../SemanticReleasePlugin.groovy | 7 +- .../SemanticReleasePluginExtension.groovy | 13 +-- .../UpdateGithubRelease.groovy | 62 +++++++++++++ .../UpdateGithubReleaseService.groovy | 62 +++++++++++++ .../semanticrelease/GithubRepoSpec.groovy | 71 +++++++++++++++ ...SemanticReleaseChangeLogServiceSpec.groovy | 65 ++------------ .../SemanticReleaseNormalStrategySpec.groovy | 3 +- .../SemanticReleasePluginSpec.groovy | 20 +++-- .../UpdateGithubReleaseServiceSpec.groovy | 74 +++++++++++++++ 14 files changed, 469 insertions(+), 159 deletions(-) create mode 100644 src/main/groovy/de/gliderpilot/gradle/semanticrelease/GitRepo.groovy create mode 100644 src/main/groovy/de/gliderpilot/gradle/semanticrelease/GithubRepo.groovy create mode 100644 src/main/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubRelease.groovy create mode 100644 src/main/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubReleaseService.groovy create mode 100644 src/test/groovy/de/gliderpilot/gradle/semanticrelease/GithubRepoSpec.groovy create mode 100644 src/test/groovy/de/gliderpilot/gradle/semanticrelease/UpdateGithubReleaseServiceSpec.groovy 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 } + } + +}