SEC-1995: Use Gradle Artifactory integration for releases
This commit is contained in:
parent
25248c7536
commit
8ad0e0e8e8
10
build.gradle
10
build.gradle
|
@ -44,7 +44,8 @@ configure (aspectjProjects) {
|
||||||
// Task for creating the distro zip
|
// Task for creating the distro zip
|
||||||
|
|
||||||
task dist(type: Zip) {
|
task dist(type: Zip) {
|
||||||
dependsOn subprojects*.tasks*.matching { task -> task.name == 'assemble' }
|
dependsOn subprojects*.tasks*.matching { task -> task.name == 'assemble' || task.name.endsWith('Zip') }
|
||||||
|
classifier = 'dist'
|
||||||
|
|
||||||
evaluationDependsOn(':docs')
|
evaluationDependsOn(':docs')
|
||||||
|
|
||||||
|
@ -65,9 +66,10 @@ task dist(type: Zip) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task uploadDist(type: S3DistroUpload) {
|
artifacts {
|
||||||
archiveFile = dist.archivePath
|
archives dist
|
||||||
projectKey = 'SEC'
|
archives project(':docs').docsZip
|
||||||
|
archives project(':docs').schemaZip
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/gradle/ide-integration.gradle"
|
apply from: "$rootDir/gradle/ide-integration.gradle"
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
|
|
||||||
import org.gradle.api.DefaultTask
|
|
||||||
import org.gradle.api.tasks.InputFile
|
|
||||||
import org.gradle.api.tasks.Input
|
|
||||||
import org.gradle.api.tasks.TaskAction
|
|
||||||
import org.jets3t.service.security.AWSCredentials
|
|
||||||
import org.jets3t.service.impl.rest.httpclient.RestS3Service
|
|
||||||
import org.jets3t.service.S3Service
|
|
||||||
import org.jets3t.service.model.S3Bucket
|
|
||||||
import org.jets3t.service.model.S3Object
|
|
||||||
import org.jets3t.service.acl.AccessControlList
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Luke Taylor
|
|
||||||
*/
|
|
||||||
class S3DistroUpload extends DefaultTask {
|
|
||||||
@InputFile
|
|
||||||
File archiveFile
|
|
||||||
|
|
||||||
@Input
|
|
||||||
String bucketName = 'dist.springframework.org'
|
|
||||||
|
|
||||||
// 'Spring Security'
|
|
||||||
@Input
|
|
||||||
String projectName = project.description
|
|
||||||
|
|
||||||
// e.g 'SEC'
|
|
||||||
@Input
|
|
||||||
String projectKey
|
|
||||||
|
|
||||||
@TaskAction
|
|
||||||
def upload() {
|
|
||||||
def accessKey = project.s3AccessKey
|
|
||||||
def secretKey = project.s3SecretAccessKey
|
|
||||||
def version = project.version.toString()
|
|
||||||
|
|
||||||
assert version.length() > 0
|
|
||||||
assert accessKey.length() > 0
|
|
||||||
assert secretKey.length() > 0
|
|
||||||
assert projectName.length() > 0
|
|
||||||
|
|
||||||
assert archiveFile.exists()
|
|
||||||
|
|
||||||
String archiveName = archiveFile.getName()
|
|
||||||
|
|
||||||
logger.info("Creating SHA checksum file...")
|
|
||||||
project.ant.checksum(file: archiveFile, algorithm: 'SHA1', fileext: '.sha1', forceoverwrite: 'true')
|
|
||||||
File shaFile = "${archiveFile}.sha1" as File
|
|
||||||
|
|
||||||
assert shaFile.exists()
|
|
||||||
|
|
||||||
AWSCredentials creds = new AWSCredentials(accessKey, secretKey);
|
|
||||||
S3Service s3 = new RestS3Service(creds)
|
|
||||||
S3Bucket bucket = new S3Bucket(bucketName)
|
|
||||||
|
|
||||||
String releaseType = releaseType(version)
|
|
||||||
|
|
||||||
String key = releaseType + '/' + projectKey + '/' + archiveName
|
|
||||||
|
|
||||||
S3Object archiveDest = new S3Object(bucket, key)
|
|
||||||
archiveDest.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ)
|
|
||||||
archiveDest.setDataInputFile(archiveFile)
|
|
||||||
archiveDest.setContentLength(archiveFile.length())
|
|
||||||
archiveDest.addMetadata('project.name', projectName)
|
|
||||||
archiveDest.addMetadata('bundle.version', version)
|
|
||||||
archiveDest.addMetadata('release.type', releaseType)
|
|
||||||
archiveDest.addMetadata('package.file.name', archiveName)
|
|
||||||
|
|
||||||
logger.info("Uploading archive " + archiveFile.getName() + " to " + archiveDest + "...")
|
|
||||||
s3.putObject(bucket, archiveDest)
|
|
||||||
logger.info("Done")
|
|
||||||
|
|
||||||
S3Object shaDest = new S3Object(bucket, key + '.sha1')
|
|
||||||
shaDest.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ)
|
|
||||||
shaDest.setDataInputFile(shaFile)
|
|
||||||
shaDest.setContentLength(shaFile.length())
|
|
||||||
|
|
||||||
logger.info("Uploading SHA checksum " + shaFile.getName() + " to " + key + '.sha1' + "...")
|
|
||||||
s3.putObject(bucket, shaDest);
|
|
||||||
logger.info("Done")
|
|
||||||
}
|
|
||||||
|
|
||||||
def releaseType(String version) {
|
|
||||||
if (version.endsWith('RELEASE')) {
|
|
||||||
'release'
|
|
||||||
} else if (version.endsWith('SNAPSHOT')) {
|
|
||||||
'snapshot'
|
|
||||||
} else {
|
|
||||||
'milestone'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
import org.gradle.api.DefaultTask;
|
|
||||||
import org.gradle.api.tasks.*;
|
|
||||||
import org.gradle.api.tasks.bundling.Tar;
|
|
||||||
import org.gradle.api.tasks.bundling.Compression;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extends the Tar task, uploading the created archive to a remote directory, unpacking and deleting it.
|
|
||||||
* Requires Ant ssh (jsch) support.
|
|
||||||
*/
|
|
||||||
class TarUpload extends Tar {
|
|
||||||
@Input
|
|
||||||
String remoteDir
|
|
||||||
Login login
|
|
||||||
@Input
|
|
||||||
String host
|
|
||||||
|
|
||||||
TarUpload() {
|
|
||||||
compression = Compression.BZIP2
|
|
||||||
if (project.configurations.findByName('antjsch') == null) {
|
|
||||||
project.configurations.add('antjsch')
|
|
||||||
project.dependencies {
|
|
||||||
antjsch 'org.apache.ant:ant-jsch:1.8.1'
|
|
||||||
}
|
|
||||||
def classpath = project.configurations.antjsch.asPath
|
|
||||||
project.ant {
|
|
||||||
taskdef(name: 'scp', classname: 'org.apache.tools.ant.taskdefs.optional.ssh.Scp', classpath: classpath)
|
|
||||||
taskdef(name: 'sshexec', classname: 'org.apache.tools.ant.taskdefs.optional.ssh.SSHExec', classpath: classpath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TaskAction
|
|
||||||
void copy() {
|
|
||||||
super.copy();
|
|
||||||
upload();
|
|
||||||
}
|
|
||||||
|
|
||||||
def upload() {
|
|
||||||
String username = login.username
|
|
||||||
String password = login.password
|
|
||||||
String host = login.host
|
|
||||||
project.ant {
|
|
||||||
scp(file: archivePath, todir: "$username@$host:$remoteDir", password: password)
|
|
||||||
sshexec(host: host, username: username, password: password, command: "cd $remoteDir && tar -xjf $archiveName")
|
|
||||||
sshexec(host: host, username: username, password: password, command: "rm $remoteDir/$archiveName")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setLogin(Login login) {
|
|
||||||
dependsOn(login)
|
|
||||||
this.login = login
|
|
||||||
this.host = login.host
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores login information for a remote host.
|
|
||||||
*/
|
|
||||||
class Login extends DefaultTask {
|
|
||||||
@Input
|
|
||||||
String host
|
|
||||||
String username
|
|
||||||
String password
|
|
||||||
|
|
||||||
@TaskAction
|
|
||||||
login() {
|
|
||||||
def console = System.console()
|
|
||||||
if (console) {
|
|
||||||
username = console.readLine("\nPlease enter the ssh username for host '$host': ")
|
|
||||||
password = new String(console.readPassword("Please enter the ssh password for '$host': "))
|
|
||||||
} else {
|
|
||||||
logger.error "Unable to access System.console()."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -92,7 +92,7 @@ public class Docbook extends DefaultTask {
|
||||||
factory.setXIncludeAware(XIncludeAware);
|
factory.setXIncludeAware(XIncludeAware);
|
||||||
docsDir.mkdirs();
|
docsDir.mkdirs();
|
||||||
|
|
||||||
File srcFile = new File(sourceDirectory, sourceFileName);
|
File srcFile = new File(filterDocbookSources(sourceDirectory), sourceFileName);
|
||||||
String outputFilename = srcFile.getName().substring(0, srcFile.getName().length() - 4) + suffix + '.' + extension;
|
String outputFilename = srcFile.getName().substring(0, srcFile.getName().length() - 4) + suffix + '.' + extension;
|
||||||
|
|
||||||
File outputFile = new File(getDocsDir(), outputFilename);
|
File outputFile = new File(getDocsDir(), outputFilename);
|
||||||
|
@ -135,6 +135,32 @@ public class Docbook extends DefaultTask {
|
||||||
postTransform(outputFile);
|
postTransform(outputFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sourceDir directory of unfiltered sources
|
||||||
|
* @return directory of filtered sources
|
||||||
|
* @author Chris Beams
|
||||||
|
*/
|
||||||
|
private File filterDocbookSources(File sourceDir) {
|
||||||
|
def docbookWorkDir = new File("${project.buildDir}/reference-work")
|
||||||
|
|
||||||
|
docbookWorkDir.mkdirs()
|
||||||
|
|
||||||
|
// copy everything but springsecurity.xml
|
||||||
|
project.copy {
|
||||||
|
into(docbookWorkDir)
|
||||||
|
from(sourceDir) { exclude '**/springsecurity.xml' }
|
||||||
|
}
|
||||||
|
// copy index.xml and expand ${...} variables along the way
|
||||||
|
// e.g.: ${version} needs to be replaced in the header
|
||||||
|
project.copy {
|
||||||
|
into(docbookWorkDir)
|
||||||
|
from(sourceDir) { include '**/springsecurity.xml' }
|
||||||
|
expand(version: "${project.version}")
|
||||||
|
}
|
||||||
|
|
||||||
|
return docbookWorkDir
|
||||||
|
}
|
||||||
|
|
||||||
private void extractHighlightFiles(File toDir) {
|
private void extractHighlightFiles(File toDir) {
|
||||||
URLClassLoader cl = (URLClassLoader) getClass().getClassLoader();
|
URLClassLoader cl = (URLClassLoader) getClass().getClassLoader();
|
||||||
URL[] urls = cl.getURLs();
|
URL[] urls = cl.getURLs();
|
||||||
|
|
|
@ -99,49 +99,45 @@ ext.apiSpec = copySpec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task docSiteLogin(type: Login) {
|
|
||||||
if (project.hasProperty('sshHost')) {
|
|
||||||
host = project.property('sshHost')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define remoteSiteDir and sshHost in gradle.properties
|
|
||||||
def remoteDocsDir = null
|
|
||||||
|
|
||||||
if (hasProperty('remoteSiteDir')) {
|
|
||||||
remoteDocsDir="$remoteSiteDir/docs/3.1.x"
|
|
||||||
}
|
|
||||||
|
|
||||||
task uploadApidocs(type: TarUpload) {
|
|
||||||
dependsOn apidocs
|
|
||||||
baseName = "${rootProject.name}"
|
|
||||||
appendix = 'apidocs'
|
|
||||||
remoteDir = remoteDocsDir
|
|
||||||
login = docSiteLogin
|
|
||||||
|
|
||||||
with(apiSpec)
|
|
||||||
}
|
|
||||||
|
|
||||||
task uploadManual(type: TarUpload) {
|
|
||||||
dependsOn 'manual:docbook'
|
|
||||||
baseName = "${rootProject.name}"
|
|
||||||
appendix = 'doc'
|
|
||||||
remoteDir = remoteDocsDir
|
|
||||||
login = docSiteLogin
|
|
||||||
|
|
||||||
with(project('manual').spec)
|
|
||||||
}
|
|
||||||
|
|
||||||
task uploadFaq(type: TarUpload) {
|
|
||||||
dependsOn 'faq:docbookHtmlSingle'
|
|
||||||
baseName = "${rootProject.name}"
|
|
||||||
appendix = 'faq'
|
|
||||||
if (project.hasProperty('remoteSiteDir')) {
|
|
||||||
remoteDir = project.property('remoteSiteDir')
|
|
||||||
}
|
|
||||||
login = docSiteLogin
|
|
||||||
|
|
||||||
with(project('faq').spec)
|
|
||||||
}
|
|
||||||
|
|
||||||
assemble.dependsOn = [apidocs, 'manual:docbook']
|
assemble.dependsOn = [apidocs, 'manual:docbook']
|
||||||
|
|
||||||
|
task docsZip(type: Zip) {
|
||||||
|
dependsOn docs
|
||||||
|
group = 'Distribution'
|
||||||
|
baseName = rootProject.name
|
||||||
|
classifier = 'docs'
|
||||||
|
description = "Builds -${classifier} archive containing api and reference " +
|
||||||
|
"for deployment at static.springframework.org/spring-security/site/docs."
|
||||||
|
|
||||||
|
with(project(':docs').apiSpec)
|
||||||
|
with(project(':docs:manual').spec)
|
||||||
|
with(project(':docs:faq').spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
task schemaZip(type: Zip) {
|
||||||
|
group = 'Distribution'
|
||||||
|
baseName = rootProject.name
|
||||||
|
classifier = 'schema'
|
||||||
|
description = "Builds -${classifier} archive containing all " +
|
||||||
|
"XSDs for deployment at static.springframework.org/schema."
|
||||||
|
|
||||||
|
coreModuleProjects.each { module ->
|
||||||
|
def Properties schemas = new Properties();
|
||||||
|
|
||||||
|
module.sourceSets.main.resources.find {
|
||||||
|
it.path.endsWith('META-INF/spring.schemas')
|
||||||
|
}?.withInputStream { schemas.load(it) }
|
||||||
|
|
||||||
|
for (def key : schemas.keySet()) {
|
||||||
|
def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
|
||||||
|
assert shortName != key
|
||||||
|
File xsdFile = module.sourceSets.main.resources.find {
|
||||||
|
it.path.endsWith(schemas.get(key))
|
||||||
|
}
|
||||||
|
assert xsdFile != null
|
||||||
|
into (shortName) {
|
||||||
|
from xsdFile.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</author>
|
</author>
|
||||||
</authorgroup>
|
</authorgroup>
|
||||||
<productname>Spring Security</productname>
|
<productname>Spring Security</productname>
|
||||||
<releaseinfo>3.1.2.CI-SNAPSHOT</releaseinfo>
|
<releaseinfo>${version}</releaseinfo>
|
||||||
</info>
|
</info>
|
||||||
<toc/>
|
<toc/>
|
||||||
<preface xml:id="preface">
|
<preface xml:id="preface">
|
||||||
|
|
|
@ -25,37 +25,6 @@ configurations.default.extendsFrom = [configurations.runtime] as Set
|
||||||
// Add the main jar into the default configuration
|
// Add the main jar into the default configuration
|
||||||
artifacts { 'default' jar }
|
artifacts { 'default' jar }
|
||||||
|
|
||||||
gradle.taskGraph.whenReady {graph ->
|
|
||||||
if (graph.hasTask(uploadArchives)) {
|
|
||||||
// check properties defined and fail early
|
|
||||||
s3AccessKey
|
|
||||||
s3SecretAccessKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadArchives {
|
|
||||||
// "mavenSyncRepoDir" should be set in properties
|
|
||||||
def releaseRepositoryUrl = "file://${project.properties.mavenSyncRepoDir}"
|
|
||||||
def milestoneRepositoryUrl = 's3://maven.springframework.org/milestone'
|
|
||||||
def snapshotRepositoryUrl = 's3://maven.springframework.org/snapshot'
|
|
||||||
|
|
||||||
repositories.mavenDeployer { deployer ->
|
|
||||||
configuration = configurations.deployerJars
|
|
||||||
if (releaseBuild) {
|
|
||||||
repository(url: releaseRepositoryUrl)
|
|
||||||
} else {
|
|
||||||
def s3credentials = [userName: project.properties.s3AccessKey, passphrase: project.properties.s3SecretAccessKey]
|
|
||||||
repository(url: milestoneRepositoryUrl) {
|
|
||||||
authentication(s3credentials)
|
|
||||||
}
|
|
||||||
snapshotRepository(url: snapshotRepositoryUrl) {
|
|
||||||
authentication(s3credentials)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customizePom(deployer.pom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
install {
|
install {
|
||||||
customizePom(repositories.mavenInstaller.pom)
|
customizePom(repositories.mavenInstaller.pom)
|
||||||
}
|
}
|
||||||
|
@ -105,4 +74,4 @@ def customizePom(pom) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -63,6 +63,8 @@ include 'docs', 'docs:faq', 'docs:manual'
|
||||||
def docs = findProject(':docs')
|
def docs = findProject(':docs')
|
||||||
docs.buildFileName = 'docs.gradle'
|
docs.buildFileName = 'docs.gradle'
|
||||||
|
|
||||||
|
rootProject.name = 'spring-security'
|
||||||
|
|
||||||
rootProject.children.each {project ->
|
rootProject.children.each {project ->
|
||||||
assert project.projectDir.isDirectory()
|
assert project.projectDir.isDirectory()
|
||||||
assert project.buildFile.isFile()
|
assert project.buildFile.isFile()
|
||||||
|
|
Loading…
Reference in New Issue