blob: db781b03901759b1371aea74df02a96c1c860551 [file] [log] [blame]
/*
* 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 = "r17"
// 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*,changelog.txt")
}
}
}
}
// 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") {
// include workspace changelog
zipfileset(dir: '..', prefix: topdir+"-bin/", includes: "changelog.txt")
// 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.'
ant.input(message: 'Enter SVN user:', addproperty: 'user')
ant.input(message: 'Enter SVN password:', addproperty: 'password')
def user = ant.properties.user
def password = ant.properties.password
getProject().exec {
commandLine 'svn',
'import', 'staging', svnStagingPath + "/org.apache.felix.dependencymanager-" + dmRelease + "/",
'-m', "Staging Apache Felix Dependency Manager release " + dmRelease + ".", "--username", user, "--password", password
}
}
}
// Promotes the staged distributions to release
task promoteToRelease {
doLast {
description = 'Moves the staging repository to the Apache release repository.'
ant.input(message: 'Enter SVN user:', addproperty: 'user')
ant.input(message: 'Enter SVN password:', addproperty: 'password')
def user = ant.properties.user
def password = ant.properties.password
// 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 + ".",
"--username", user, "--password", password
}
}
}
// 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 + ".",
"--username", user, "--password", password
}
}
}
// Removes the staged distributions from staging
task deleteFromStaging {
doLast {
description = 'Cancels the staged distribution from the Apache staging repository.'
ant.input(message: 'Enter SVN user:', addproperty: 'user')
ant.input(message: 'Enter SVN password:', addproperty: 'password')
def user = ant.properties.user
def password = ant.properties.password
getProject().exec {
commandLine 'svn',
'delete', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease + "/",
"-m", "Removing Apache Felix Dependency Manager release " + dmRelease + " from staging.",
"--username", user, "--password", password
}
}
}
// 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()
}
}