blob: fdca4718d6f55158724167e06b6914cd328a09ba [file] [log] [blame]
Pierre De Rop3a00a212015-03-01 09:27:46 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20/**
21 * Gradle script used to perform DM releases (really similar to Apache ACE build.xml)
22 */
23import aQute.bnd.build.Workspace
24
25// Our release number, which has to be monotonically incremented each time we make a new release.
Pierre De Ropdfe72a12016-03-01 19:50:31 +000026ext.dmRelease = "r8"
Pierre De Rop3a00a212015-03-01 09:27:46 +000027
28// Our Apache svn Staging repo
29ext.svnStagingPath = "https://dist.apache.org/repos/dist/dev/felix"
30
31// Our Apache svn Release repo
32ext.svnReleasePath = "https://dist.apache.org/repos/dist/release/felix"
33
34apply plugin: 'java'
35apply from: file("rat.gradle")
36
37// Add bnd as a build dependency
38buildscript {
39 dependencies {
40 classpath files('cnf/gradle/biz.aQute.bnd.gradle.jar')
41 }
42}
43
44// Configure RAT plugin to ignore some files
45rat {
46 excludes = [
47 'rat-report.xml',
48 '**/.git/**',
49 '**/.gradle/**',
50 '**/.project',
51 '**/.settings/**',
52 '**/*.iml',
53 '**/*.iws',
54 '**/*.ipr',
55 '**/.classpath',
56 'cnf/**',
57 'gradle/wrapper/**',
58 'release/**',
59 'gradlew',
60 'README',
61 '**/DEPENDENCIES',
62 '**/README',
63 '**/.gitignore',
64 '**/generated/**',
65 'doc/**',
66 '**/packageinfo',
67 '**/*.txt',
68 'docs/**',
69 '.metadata/**'
70 ]
71}
72
73// Setup the workspace
74Workspace workspace
75workspace = Workspace.getWorkspace(".")
76
77task makeStaging << {
78 description = 'Packages the source and binary distributions.'
79
80 // Package source and source bin dependencies distributions.
81 logger.lifecycle(" Packaging source distributions.")
82 def topdir="org.apache.felix.dependencymanager-" + dmRelease
83 ant.zip(destfile: "staging/"+topdir+'-src.zip') {
84 zipfileset(dir: '../cnf', prefix: topdir+"-src/cnf", includes: ".project,.classpath,src/**,*.bnd,ext/**")
85 zipfileset(dir: '..', prefix: topdir+"-src", includes: '*.gradle,*.properties')
86 zipfileset(dir: 'resources/src', prefix: topdir+"-src", includes: '*')
87 new File('.').eachFile {
88 if(new File(it, 'bnd.bnd').exists()) {
89 def bndProject = workspace.getProject(it.name)
90 if (! bndProject.isNoBundles() && ! bndProject.getName().endsWith(".benchmark")) {
91 zipfileset(dir: "../${bndProject.name}", prefix: topdir+"-src/${bndProject.name}",
92 includes: "*.gradle,.project,.classpath,.settings/**,src/**,test/**,*.bnd,*.bndrun,run-*/conf/**,resources/**,README*")
93 }
94 }
95 }
96 }
97
98 // Package binary dependencies, needed to build the source distributions.
99 logger.lifecycle(" Packaging binary dependencies.")
100 ant.zip(destfile: "staging/"+topdir+"-deps.zip") {
101 ant.zipfileset(dir: '..', prefix: topdir+"-src", includes: 'gradlew')
Pierre De Ropaf331612015-09-18 22:17:09 +0000102 ant.zipfileset(dir: '../gradle', prefix: topdir+"-src/gradle", includes: '**')
Pierre De Rop3a00a212015-03-01 09:27:46 +0000103 ant.zipfileset(dir: 'resources/deps', prefix: topdir+"-src", includes: '*')
104 ant.zipfileset(dir: '../cnf', prefix: topdir+"-src/cnf",
105 includes: 'buildrepo/**,localrepo/**,releaserepo/**,plugins/**,gradle/**')
106 }
107
108 // Package binaries as a simple collection of bundles. We use same license files as for src distrib.
Pierre De Rope8227232015-12-01 20:46:10 +0000109 logger.lifecycle(" Packaging binary distribution.")
110
111 // First, get list of latest released bundles available from our Release repository
112 def released = []
113 def releaseRepo = workspace.getRepository("Release")
Pierre De Rope8227232015-12-01 20:46:10 +0000114 def bundles=releaseRepo.list(null)
115 bundles.each {
116 def sortedVersions = releaseRepo.versions(it)
117 def latestVersion = sortedVersions.last()
118 def latestBundle = releaseRepo.get(it, latestVersion, null)
119 released << latestBundle
120 }
121
Pierre De Rop47cec582016-03-01 20:16:42 +0000122 // Before adding all latest released bundles in the binary distribution, check if they contain proper license files.
Pierre De Ropdfe72a12016-03-01 19:50:31 +0000123 logger.lifecycle(" Checking META-INF mandatory files.")
124 released.each { jarfile ->
125 if (jarfile.isFile()) {
126 new ByteArrayOutputStream().withStream { os ->
127 def result = exec {
128 executable = 'jar'
129 args = ['tf', jarfile, "META-INF"]
130 standardOutput = os
131 }
132 def files = os.toString().split("\n")
133 def mandatory = ["META-INF/LICENSE", "META-INF/NOTICE", "META-INF/DEPENDENCIES", "META-INF/changelog.txt"]
134 mandatory.each { resource ->
135 if (! files.contains(resource)) {
Pierre De Rope07665b2016-03-01 20:17:59 +0000136 throw new GradleException("Missing mandatory license files in " + jarfile)
Pierre De Ropdfe72a12016-03-01 19:50:31 +0000137 }
138 }
139 }
140 }
141 }
142
Pierre De Rope8227232015-12-01 20:46:10 +0000143 // Now, add all the latest released bundles in the binary distribution
Pierre De Rop3a00a212015-03-01 09:27:46 +0000144 ant.zip(destfile: "staging/"+topdir+"-bin.zip") {
Pierre De Rope8227232015-12-01 20:46:10 +0000145 // simply include all released bundle.
146 released.each {
147 file=it
148 ant.mappedresources() {
149 ant.filelist(files: file)
150 ant.chainedmapper() {
151 ant.flattenmapper()
152 ant.globmapper(from: '*', to: topdir+'-bin/*')
153 }
Pierre De Rop3a00a212015-03-01 09:27:46 +0000154 }
155 }
156 ant.mappedresources() {
Pierre De Rope8227232015-12-01 20:46:10 +0000157 ant.fileset(dir: 'resources/bin', includes: '*')
Pierre De Rop3a00a212015-03-01 09:27:46 +0000158 ant.chainedmapper() {
159 ant.flattenmapper()
160 ant.globmapper(from: '*', to: topdir+'-bin/*')
161 }
162 }
163 }
164}
165
166// Sign staging directory
167task signStaging << {
168 description = 'Signs the local staging distribution.'
169 fileTree("staging").visit { FileVisitDetails details ->
170 logger.lifecycle(" Signing " + details.file.path)
171 ant.exec(executable: 'gpg', dir: 'staging') {
172 ant.arg(line: '--armor')
173 ant.arg(line: '--output')
174 ant.arg(line: details.file.name + ".asc")
175 ant.arg(line: "--detach-sig")
176 ant.arg(line: details.file.name)
177 }
178
179 ant.exec(executable: 'gpg', dir: 'staging', output: "staging/" + details.file.name + ".md5") {
180 ant.arg(line: '--print-md')
181 ant.arg(line: 'MD5')
182 ant.arg(line: details.file.name)
183 }
184
185 ant.exec(executable: 'gpg', dir: 'staging', output: "staging/" + details.file.name + ".sha") {
186 ant.arg(line: '--print-md')
187 ant.arg(line: 'SHA512')
188 ant.arg(line: details.file.name)
189 }
190 }
191}
192
193
194// Moves the source and binary distributions to staging.
195task commitToStaging << {
196 description = 'Commits the local staging to the Apache svn staging repository.'
197 getProject().exec {
198 commandLine 'svn',
199 'import', 'staging', svnStagingPath + "/org.apache.felix.dependencymanager-" + dmRelease + "/",
200 '-m', "Staging Apache Felix Dependency Manager release " + dmRelease + "."
201 }
202}
203
204// Promotes the staged distributions to release
205task promoteToRelease << {
206 description = 'Moves the staging repository to the Apache release repository.'
Pierre De Rope91fae52015-03-19 06:19:16 +0000207
Pierre De Ropfdffc272015-03-19 20:57:37 +0000208 // Move all artifacts from the staging repo to the release repo
209 new ByteArrayOutputStream().withStream { os ->
210 def result = exec {
211 executable = 'svn'
212 args = ['list', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease]
213 standardOutput = os
214 }
215 def outputAsString = os.toString()
216
217 outputAsString.split("\n").each { artifact ->
218 logger.lifecycle(" Moving " + artifact + " to release repository ...")
219 getProject().exec {
220 commandLine 'svn',
221 'move', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease + "/" + artifact ,
222 svnReleasePath, '-m', "Releasing Apache Felix Dependency Manager release " + dmRelease + "."
223 }
224 }
Pierre De Rop3a00a212015-03-01 09:27:46 +0000225 }
Pierre De Rope91fae52015-03-19 06:19:16 +0000226
Pierre De Ropfdffc272015-03-19 20:57:37 +0000227 // And remove the toplevel release path from the staging repo
228 logger.lifecycle(" Removing org.apache.felix.dependencymanager-" + dmRelease + " from staging ...")
229 getProject().exec {
Pierre De Rope91fae52015-03-19 06:19:16 +0000230 commandLine 'svn',
231 'rm', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease, "-m",
232 "Releasing Apache Felix Dependency Manager release " + dmRelease + "."
233 }
Pierre De Rop3a00a212015-03-01 09:27:46 +0000234}
235
236// Removes the staged distributions from staging
237task deleteFromStaging << {
238 description = 'Cancels the staged distribution from the Apache staging repository.'
239 getProject().exec {
240 commandLine 'svn',
241 'delete', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease + "/",
242 "-m", "Removing Apache Felix Dependency Manager release " + dmRelease + " from staging."
243 }
244}
245
246// Clean staging directory
247task clean(overwrite: true) << {
248 new File("release/staging").deleteDir()
249 new File("rat-report.xml").delete()
250}
251
252// Only clean the staging directory
253task cleanStaging << {
254 description = 'Clean the local staging directory.'
255 new File("release/staging").deleteDir()
Pierre De Rope91fae52015-03-19 06:19:16 +0000256 new File("release/staging-copy").deleteDir()
Pierre De Rop3a00a212015-03-01 09:27:46 +0000257}