diff --git a/build-plugins/build.gradle b/build-plugins/build.gradle index 51e9374783..39cfc7009e 100644 --- a/build-plugins/build.gradle +++ b/build-plugins/build.gradle @@ -37,6 +37,8 @@ dependencies { implementation libraries.guava implementation libraries.jettyServer implementation libraries.jettyWebapp + + implementation libraries.snakeYml } gradlePlugin { diff --git a/build-plugins/src/main/groovy/com/cloudogu/scm/PackagingPlugin.groovy b/build-plugins/src/main/groovy/com/cloudogu/scm/PackagingPlugin.groovy index d08993a970..10a34f225c 100644 --- a/build-plugins/src/main/groovy/com/cloudogu/scm/PackagingPlugin.groovy +++ b/build-plugins/src/main/groovy/com/cloudogu/scm/PackagingPlugin.groovy @@ -32,6 +32,7 @@ class PackagingPlugin implements Plugin { void apply(Project project) { project.ext.PackageYaml = PackageYamlTask + project.ext.ReleaseYaml = ReleaseYamlTask } } diff --git a/build-plugins/src/main/groovy/com/cloudogu/scm/ReleaseYamlTask.groovy b/build-plugins/src/main/groovy/com/cloudogu/scm/ReleaseYamlTask.groovy new file mode 100644 index 0000000000..9b3deac063 --- /dev/null +++ b/build-plugins/src/main/groovy/com/cloudogu/scm/ReleaseYamlTask.groovy @@ -0,0 +1,115 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the 'Software'), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +package com.cloudogu.scm + +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.Directory +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Classpath +import org.gradle.api.tasks.Nested +import org.gradle.api.tasks.Internal +import org.gradle.api.GradleException + +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import groovy.xml.MarkupBuilder +import java.io.BufferedWriter +import org.gradle.api.artifacts.Configuration +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.Classpath +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile + +import com.google.common.hash.Hashing +import com.google.common.hash.HashCode +import com.google.common.io.Files +import groovy.json.JsonOutput + +import java.text.SimpleDateFormat +import org.yaml.snakeyaml.Yaml + + +class ReleaseYamlTask extends DefaultTask { + + private Configuration configuration + + @Classpath + public Configuration getConfiguration() { + return configuration + } + + public void setConfiguration(Configuration configuration) { + this.configuration = configuration + } + + @OutputFile + public File getOutputFile() { + return new File(project.buildDir, 'libs/release.yml') + } + + @TaskAction + void execute() { + Yaml yaml = new Yaml(); + def release = [:] + release.tag = project.version + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") + sdf.setTimeZone(TimeZone.getTimeZone("UTC")) + release.date = sdf.format(new Date()) + release.packages = [] + + def files = configuration.getResolvedConfiguration().getResolvedArtifacts().collect { artifact -> + File file = artifact.file + if (file.exists() && (file.name.endsWith(".yml")) || file.name.endsWith(".yaml")) { + return file + } + } + + files.forEach { file -> + file.withReader { r -> + def pkg = yaml.load(r) + release.packages.add(pkg) + } + } + + File target = getOutputFile() + File directory = target.getParentFile() + if (!directory.exists() && !directory.mkdirs()) { + throw new GradleException("failed to create directory " + directory); + } + + if (target.exists() && !target.delete()) { + throw new GradleException("failed to delete outdated release.yml " + target); + } + + target << yaml.dump(release) + } + +} diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 63018a1a88..fd7b723413 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -132,6 +132,9 @@ ext { commonsDaemon: 'commons-daemon:commons-daemon:1.2.3', jsvc: 'commons-daemon:commons-daemon-native:1.1.0@tar.gz', + // yaml + snakeYml: 'org.yaml:snakeyaml:1.21', + // jetty jettyServer: "org.eclipse.jetty:jetty-server:${jettyVersion}", jettyWebapp: "org.eclipse.jetty:jetty-webapp:${jettyVersion}", diff --git a/scm-packaging/deb/build.gradle b/scm-packaging/deb/build.gradle index 220bf8bc68..0a62ec2b49 100644 --- a/scm-packaging/deb/build.gradle +++ b/scm-packaging/deb/build.gradle @@ -32,6 +32,9 @@ configurations { server webapp jsvc + packageYaml { + canBeConsumed = true + } } dependencies { @@ -134,11 +137,13 @@ task deb(type: Deb) { link '/opt/scm-server/work', '/var/cache/scm/work' } -task packageYaml(type: PackageYaml) { +task distribution(type: PackageYaml) { type = 'debian' dependsOn deb } -task distribution { - dependsOn packageYaml +artifacts { + packageYaml(file('build/libs/package.yml')) { + builtBy distribution + } } diff --git a/scm-packaging/docker/build.gradle b/scm-packaging/docker/build.gradle index f9cef2fe1e..82649734cf 100644 --- a/scm-packaging/docker/build.gradle +++ b/scm-packaging/docker/build.gradle @@ -34,6 +34,9 @@ import com.bmuschko.gradle.docker.tasks.image.* configurations { server webapp + packageYaml { + canBeConsumed = true + } } dependencies { @@ -89,11 +92,13 @@ def images() { } } -task packageYaml(type: PackageYaml) { +task distribution(type: PackageYaml) { type = 'docker' dependsOn dockerImage } -task distribution { - dependsOn packageYaml +artifacts { + packageYaml(file('build/libs/package.yml')) { + builtBy distribution + } } diff --git a/scm-packaging/helm/build.gradle b/scm-packaging/helm/build.gradle index 7dcb301945..8a3e7cbe25 100644 --- a/scm-packaging/helm/build.gradle +++ b/scm-packaging/helm/build.gradle @@ -27,6 +27,12 @@ plugins { id 'org.scm-manager.packaging' } +configurations { + packageYaml { + canBeConsumed = true + } +} + helm { downloadClient { enabled = true @@ -54,11 +60,13 @@ helmPackageScmServerChart { appVersion = expandedVersion } -task packageYaml(type: PackageYaml) { +task distribution(type: PackageYaml) { type = 'k8s' dependsOn helmPackageScmServerChart } -task distribution { - dependsOn packageYaml +artifacts { + packageYaml(file('build/libs/package.yml')) { + builtBy distribution + } } diff --git a/scm-packaging/release-yaml/build.gradle b/scm-packaging/release-yaml/build.gradle new file mode 100644 index 0000000000..14c8f90258 --- /dev/null +++ b/scm-packaging/release-yaml/build.gradle @@ -0,0 +1,46 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +plugins { + id 'org.scm-manager.packaging' +} + +configurations { + packageYaml { + canBeResolved = true + } +} + +dependencies { + packageYaml project(path: ':scm-packaging:unix', configuration: 'packageYaml') + packageYaml project(path: ':scm-packaging:windows', configuration: 'packageYaml') + packageYaml project(path: ':scm-packaging:deb', configuration: 'packageYaml') + packageYaml project(path: ':scm-packaging:rpm', configuration: 'packageYaml') + packageYaml project(path: ':scm-packaging:docker', configuration: 'packageYaml') + packageYaml project(path: ':scm-packaging:helm', configuration: 'packageYaml') +} + +task distribution(type: ReleaseYaml) { + configuration = configurations.packageYaml +} diff --git a/scm-packaging/rpm/build.gradle b/scm-packaging/rpm/build.gradle index c6f74aba4f..8164c37694 100644 --- a/scm-packaging/rpm/build.gradle +++ b/scm-packaging/rpm/build.gradle @@ -31,6 +31,9 @@ plugins { configurations { server webapp + packageYaml { + canBeConsumed = true + } } dependencies { @@ -131,11 +134,13 @@ task rpm(type: Rpm) { link '/opt/scm-server/work', '/var/cache/scm/work' } -task packageYaml(type: PackageYaml) { +task distribution(type: PackageYaml) { type = 'redhat' dependsOn rpm } -task distribution { - dependsOn packageYaml +artifacts { + packageYaml(file('build/libs/package.yml')) { + builtBy distribution + } } diff --git a/scm-packaging/unix/build.gradle b/scm-packaging/unix/build.gradle index 6e4d078584..4f6a178b0c 100644 --- a/scm-packaging/unix/build.gradle +++ b/scm-packaging/unix/build.gradle @@ -31,6 +31,9 @@ configurations { server webapp jsvc + packageYaml { + canBeConsumed = true + } } dependencies { @@ -83,12 +86,14 @@ task unix(type: Tar) { compression = Compression.GZIP } -task packageYaml(type: PackageYaml) { +task distribution(type: PackageYaml) { type = 'unix' artifact = file("build/libs/unix-${project.version}-app.tar.gz") dependsOn unix } -task distribution { - dependsOn packageYaml +artifacts { + packageYaml(file('build/libs/package.yml')) { + builtBy distribution + } } diff --git a/scm-packaging/windows/build.gradle b/scm-packaging/windows/build.gradle index bb5b5802d5..bdf240878b 100644 --- a/scm-packaging/windows/build.gradle +++ b/scm-packaging/windows/build.gradle @@ -31,6 +31,9 @@ plugins { configurations { server webapp + packageYaml { + canBeConsumed = true + } } dependencies { @@ -87,12 +90,14 @@ task windows(type: Zip) { dependsOn 'verifyWinSW' } -task packageYaml(type: PackageYaml) { +task distribution(type: PackageYaml) { type = 'windows' artifact = file("build/libs/windows-${project.version}-app.zip") dependsOn windows } -task distribution { - dependsOn packageYaml +artifacts { + packageYaml(file('build/libs/package.yml')) { + builtBy distribution + } } diff --git a/settings.gradle b/settings.gradle index 0159231cd1..f24091f24c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -38,12 +38,13 @@ include 'scm-plugins:scm-integration-test-plugin' include 'scm-dao-xml' include 'scm-webapp' include 'scm-server' +include 'scm-it' include 'scm-packaging:unix' include 'scm-packaging:windows' include 'scm-packaging:deb' include 'scm-packaging:rpm' include 'scm-packaging:docker' include 'scm-packaging:helm' -include 'scm-it' +include 'scm-packaging:release-yaml' includeBuild '../gradle-smp-plugin'