/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ /** * Gradle script used to perform DM releases (really similar to Apache ACE build.xml) */ import aQute.bnd.build.Workspace buildscript { repositories { mavenCentral() } dependencies { classpath bnd_plugin } } // Our release number, which has to be monotonically incremented each time we make a new release. ext.dmRelease = "r13" // Our Apache svn Staging repo ext.svnStagingPath = "https://dist.apache.org/repos/dist/dev/felix" // Our Apache svn Release repo ext.svnReleasePath = "https://dist.apache.org/repos/dist/release/felix" apply plugin: 'java' apply from: file("rat.gradle") // Add bnd as a build dependency buildscript { dependencies { classpath files('cnf/gradle/biz.aQute.bnd.gradle.jar') } } // Configure RAT plugin to ignore some files rat { excludes = [ 'rat-report.xml', '**/.git/**', '**/.gradle/**', '**/.project', '**/.settings/**', '**/*.iml', '**/*.iws', '**/*.ipr', '**/.classpath', 'cnf/**', 'gradle/wrapper/**', 'release/**', 'gradlew', 'README', '**/DEPENDENCIES', '**/README', '**/.gitignore', '**/generated/**', 'doc/**', '**/packageinfo', '**/*.txt', 'docs/**', '.metadata/**' ] } // Setup the workspace Workspace workspace workspace = Workspace.getWorkspace(".") task makeStaging { doLast { description = 'Packages the source and binary distributions.' // Package source distributions. logger.lifecycle(" Packaging source distributions.") def topdir="org.apache.felix.dependencymanager-" + dmRelease ant.zip(destfile: "staging/"+topdir+'-src.zip') { zipfileset(dir: '../cnf', prefix: topdir+"-src/cnf", includes: ".project,.classpath,src/**,*.bnd,*.mvn,ext/**") zipfileset(dir: '..', prefix: topdir+"-src", includes: '*.gradle,*.properties') zipfileset(dir: 'resources/src', prefix: topdir+"-src", includes: '*') ant.zipfileset(dir: '..', prefix: topdir+"-src", includes: 'gradlew') ant.zipfileset(dir: '..', prefix: topdir+"-src", includes: 'changelog.txt') ant.zipfileset(dir: '../.gradle-wrapper', prefix: topdir+"-src/.gradle-wrapper", includes: 'gradle-wrapper.properties') new File('.').eachFile { if(new File(it, 'bnd.bnd').exists()) { def bndProject = workspace.getProject(it.name) if (! bndProject.isNoBundles() && ! bndProject.getName().endsWith(".benchmark")) { zipfileset(dir: "../${bndProject.name}", prefix: topdir+"-src/${bndProject.name}", includes: "*.gradle,.project,.classpath,.settings/**,src/**,test/**,*.bnd,*.bndrun,run-*/conf/**,resources/**,README*") } } } } // Package binaries as a simple collection of bundles. We use same license files as for src distrib. logger.lifecycle(" Packaging binary distribution.") // First, get list of latest released bundles available from our Release repository def released = [] def releaseRepo = workspace.getRepository("Release") def bundles=releaseRepo.list(null) bundles.each { def sortedVersions = releaseRepo.versions(it) def latestVersion = sortedVersions.last() def latestBundle = releaseRepo.get(it, latestVersion, null) released << latestBundle } // Before adding all latest released bundles in the binary distribution, check if they contain proper license files. logger.lifecycle(" Checking META-INF mandatory files.") released.each { jarfile -> if (jarfile.isFile()) { new ByteArrayOutputStream().withStream { os -> def result = exec { executable = 'jar' args = ['tf', jarfile, "META-INF"] standardOutput = os } def files = os.toString().split("\n") def mandatory = ["META-INF/LICENSE", "META-INF/NOTICE", "META-INF/DEPENDENCIES", "META-INF/changelog.txt"] mandatory.each { resource -> if (! files.contains(resource)) { throw new GradleException("Missing mandatory license files in " + jarfile) } } } } } // Now, add all the latest released bundles in the binary distribution ant.zip(destfile: "staging/"+topdir+"-bin.zip") { // simply include all released bundle. released.each { file=it ant.mappedresources() { ant.filelist(files: file) ant.chainedmapper() { ant.flattenmapper() ant.globmapper(from: '*', to: topdir+'-bin/*') } } } ant.mappedresources() { ant.fileset(dir: 'resources/bin', includes: '*') ant.chainedmapper() { ant.flattenmapper() ant.globmapper(from: '*', to: topdir+'-bin/*') } } } } } // Sign staging directory (you must use "--no-daemon" gradle option) task signStaging { doLast { ant.input(message: 'Enter PGP password:', addproperty: 'pass') description = 'Signs the local staging distribution.' fileTree("staging").visit { FileVisitDetails details -> logger.lifecycle(" Signing " + details.file.path) ant.exec(executable: 'gpg', dir: 'staging') { ant.arg(line: '--batch') ant.arg(line: '--passphrase') ant.arg(line: ant.properties.pass) ant.arg(line: '--armor') ant.arg(line: '--output') ant.arg(line: details.file.name + ".asc") ant.arg(line: "--detach-sig") ant.arg(line: details.file.name) } ant.exec(executable: 'gpg', dir: 'staging', output: "staging/" + details.file.name + ".sha1") { ant.arg(line: '--print-md') ant.arg(line: 'SHA1') ant.arg(line: details.file.name) } ant.exec(executable: 'gpg', dir: 'staging', output: "staging/" + details.file.name + ".sha512") { ant.arg(line: '--print-md') ant.arg(line: 'SHA512') ant.arg(line: details.file.name) } } } } // Moves the source and binary distributions to staging. task commitToStaging { doLast { description = 'Commits the local staging to the Apache svn staging repository.' getProject().exec { commandLine 'svn', 'import', 'staging', svnStagingPath + "/org.apache.felix.dependencymanager-" + dmRelease + "/", '-m', "Staging Apache Felix Dependency Manager release " + dmRelease + ".", "--force-interactive" } } } // Promotes the staged distributions to release task promoteToRelease { doLast { description = 'Moves the staging repository to the Apache release repository.' // Move all artifacts from the staging repo to the release repo new ByteArrayOutputStream().withStream { os -> def result = exec { executable = 'svn' args = ['list', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease] standardOutput = os } def outputAsString = os.toString() outputAsString.split("\n").each { artifact -> logger.lifecycle(" Moving " + artifact + " to release repository ...") getProject().exec { commandLine 'svn', 'move', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease + "/" + artifact , svnReleasePath, '-m', "Releasing Apache Felix Dependency Manager release " + dmRelease + "." } } } // And remove the toplevel release path from the staging repo logger.lifecycle(" Removing org.apache.felix.dependencymanager-" + dmRelease + " from staging ...") getProject().exec { commandLine 'svn', 'rm', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease, "-m", "Releasing Apache Felix Dependency Manager release " + dmRelease + "." } } } // Removes the staged distributions from staging task deleteFromStaging { doLast { description = 'Cancels the staged distribution from the Apache staging repository.' getProject().exec { commandLine 'svn', 'delete', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease + "/", "-m", "Removing Apache Felix Dependency Manager release " + dmRelease + " from staging." } } } // Clean staging directory clean.doLast { new File("release/staging").deleteDir() new File("rat-report.xml").delete() } // Only clean the staging directory task cleanStaging { doLast { description = 'Clean the local staging directory.' new File("release/staging").deleteDir() new File("release/staging-copy").deleteDir() } }