#72 - Migrate to Jenkins.

This commit is contained in:
Greg Turnquist
2019-10-01 11:25:58 -05:00
parent 34f4201633
commit 8ddbb51d43
7 changed files with 524 additions and 2 deletions

275
Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,275 @@
pipeline {
agent none
triggers {
pollSCM 'H/10 * * * *'
}
options {
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '14'))
}
stages {
stage("test: baseline (jdk8)") {
agent {
docker {
image 'adoptopenjdk/openjdk8:latest'
args '-v $HOME/.m2:/tmp/jenkins-home/.m2'
}
}
options { timeout(time: 30, unit: 'MINUTES') }
steps {
sh 'rm -rf ?'
sh 'PROFILE=none ci/test.sh'
}
}
stage("Test other configurations") {
parallel {
stage("test: baseline (jdk11)") {
agent {
docker {
image 'adoptopenjdk/openjdk11:latest'
args '-v $HOME/.m2:/tmp/jenkins-home/.m2'
}
}
options { timeout(time: 30, unit: 'MINUTES') }
steps {
sh 'rm -rf ?'
sh 'PROFILE=none ci/test.sh'
}
}
stage("test: baseline (jdk13)") {
agent {
docker {
image 'adoptopenjdk/openjdk13:latest'
args '-v $HOME/.m2:/tmp/jenkins-home/.m2'
}
}
options { timeout(time: 30, unit: 'MINUTES') }
steps {
sh 'rm -rf ?'
sh 'PROFILE=none ci/test.sh'
}
}
stage("test: spring-next (jdk8)") {
agent {
docker {
image 'adoptopenjdk/openjdk8:latest'
args '-v $HOME/.m2:/tmp/jenkins-home/.m2'
}
}
options { timeout(time: 30, unit: 'MINUTES') }
steps {
sh 'rm -rf ?'
sh 'PROFILE=spring5-next ci/test.sh'
}
}
stage("test: spring-next (jdk11)") {
agent {
docker {
image 'adoptopenjdk/openjdk11:latest'
args '-v $HOME/.m2:/tmp/jenkins-home/.m2'
}
}
options { timeout(time: 30, unit: 'MINUTES') }
steps {
sh 'rm -rf ?'
sh 'PROFILE=spring5-next ci/test.sh'
}
}
stage("test: spring-next (jdk13)") {
agent {
docker {
image 'adoptopenjdk/openjdk13:latest'
args '-v $HOME/.m2:/tmp/jenkins-home/.m2'
}
}
options { timeout(time: 30, unit: 'MINUTES') }
steps {
sh 'rm -rf ?'
sh 'PROFILE=spring5-next ci/test.sh'
}
}
}
}
stage('Deploy to Artifactory') {
agent {
docker {
image 'adoptopenjdk/openjdk8:latest'
args '-v $HOME/.m2:/tmp/jenkins-home/.m2'
}
}
options { timeout(time: 20, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
}
steps {
script {
sh 'rm -rf ?'
// Warm up this plugin quietly before using it.
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -q org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version'
// Extract project's version number
PROJECT_VERSION = sh(
script: 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -o | grep -v INFO',
returnStdout: true
).trim()
RELEASE_TYPE = 'milestone' // .RC? or .M?
if (PROJECT_VERSION.endsWith('SNAPSHOT')) {
RELEASE_TYPE = 'snapshot'
} else if (PROJECT_VERSION.endsWith('RELEASE')) {
RELEASE_TYPE = 'release'
}
// Capture build output...
OUTPUT = sh(
script: "PROFILE=ci,${RELEASE_TYPE} ci/build.sh",
returnStdout: true
).trim()
echo "$OUTPUT"
// ...to extract artifactory build info
build_info_path = OUTPUT.split('\n')
.find { it.contains('Artifactory Build Info Recorder') }
.split('Saving Build Info to ')[1]
.trim()[1..-2]
// Stash the JSON build info to support promotion to bintray
dir(build_info_path + '/..') {
stash name: 'build_info', includes: "*.json"
}
}
}
}
stage('Release documentation') {
when {
anyOf {
branch '2.0.x'
branch 'release-2.0'
}
}
agent {
docker {
image 'adoptopenjdk/openjdk8:latest'
args '-v $HOME/.m2:/tmp/jenkins-home/.m2'
}
}
options { timeout(time: 20, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
}
steps {
script {
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pci,distribute ' +
'-Dartifactory.server=https://repo.spring.io ' +
"-Dartifactory.username=${ARTIFACTORY_USR} " +
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
"-Dartifactory.distribution-repository=temp-private-local " +
'-Dmaven.test.skip=true deploy -B'
}
}
}
stage('Promote to Bintray') {
when {
branch 'release'
}
agent {
docker {
image 'adoptopenjdk/openjdk8:latest'
args '-v $HOME/.m2:/tmp/jenkins-home/.m2'
}
}
options { timeout(time: 20, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
}
steps {
script {
sh 'rm -rf ?'
// Warm up this plugin quietly before using it.
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -q org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version'
PROJECT_VERSION = sh(
script: 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -o | grep -v INFO',
returnStdout: true
).trim()
if (PROJECT_VERSION.endsWith('RELEASE')) {
unstash name: 'build_info'
sh "ci/promote-to-bintray.sh"
} else {
echo "${PROJECT_VERSION} is not a candidate for promotion to Bintray."
}
}
}
}
stage('Sync to Maven Central') {
when {
branch 'release'
}
agent {
docker {
image 'adoptopenjdk/openjdk8:latest'
args '-v $HOME/.m2:/tmp/jenkins-home/.m2'
}
}
options { timeout(time: 20, unit: 'MINUTES') }
environment {
BINTRAY = credentials('Bintray-spring-operator')
SONATYPE = credentials('oss-token')
}
steps {
script {
sh 'rm -rf ?'
// Warm up this plugin quietly before using it.
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -q org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version'
PROJECT_VERSION = sh(
script: 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -o | grep -v INFO',
returnStdout: true
).trim()
if (PROJECT_VERSION.endsWith('RELEASE')) {
unstash name: 'build_info'
sh "ci/sync-to-maven-central.sh"
} else {
echo "${PROJECT_VERSION} is not a candidate for syncing to Maven Central."
}
}
}
}
}
post {
changed {
script {
slackSend(
color: (currentBuild.currentResult == 'SUCCESS') ? 'good' : 'danger',
channel: '#spring-hateoas',
message: "${currentBuild.fullDisplayName} - `${currentBuild.currentResult}`\n${env.BUILD_URL}")
emailext(
subject: "[${currentBuild.fullDisplayName}] ${currentBuild.currentResult}",
mimeType: 'text/html',
recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']],
body: "<a href=\"${env.BUILD_URL}\">${currentBuild.fullDisplayName} is reported as ${currentBuild.currentResult}</a>")
}
}
}
}

5
ci/build.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
set -euo pipefail
MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/spring-plugin-maven-repository" ./mvnw -P${PROFILE} -Dmaven.test.skip=true clean deploy -B

22
ci/create-release.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
set -euo pipefail
ISSUE=$1
RELEASE=$2
SNAPSHOT=$3
# Bump up the version in pom.xml to the desired version and commit the change
./mvnw versions:set -DnewVersion=$RELEASE -DgenerateBackupPoms=false
git add .
git commit --message "#$ISSUE - Releasing Spring Plugin $RELEASE."
# Tag the release
git tag -s $RELEASE -m "$RELEASE"
# Bump up the version in pom.xml to the next snapshot
./mvnw versions:set -DnewVersion=$SNAPSHOT -DgenerateBackupPoms=false
git add .
git commit --message "#$ISSUE - Continue development on $SNAPSHOT."

42
ci/promote-to-bintray.sh Executable file
View File

@@ -0,0 +1,42 @@
#!/bin/bash
set -e -u
buildName=`jq -r '.name' build-info.json`
buildNumber=`jq -r '.number' build-info.json`
groupId=`jq -r '.modules[0].id' build-info.json | sed 's/\(.*\):.*:.*/\1/'`
version=`jq -r '.modules[0].id' build-info.json | sed 's/.*:.*:\(.*\)/\1/'`
echo "Promoting ${buildName}/${buildNumber}/${groupId}/${version} to libs-release-local"
curl \
-s \
--connect-timeout 240 \
--max-time 2700 \
-u ${ARTIFACTORY_USR}:${ARTIFACTORY_PSW} \
-H 'Content-type:application/json' \
-d '{"sourceRepos": ["libs-release-local"], "targetRepo" : "spring-distributions", "async":"true"}' \
-f \
-X \
POST "https://repo.spring.io/api/build/distribute/${buildName}/${buildNumber}" > /dev/null || { echo "Failed to distribute" >&2; exit 1; }
echo "Waiting for artifacts to be published"
ARTIFACTS_PUBLISHED=false
WAIT_TIME=10
COUNTER=0
while [ $ARTIFACTS_PUBLISHED == "false" ] && [ $COUNTER -lt 120 ]; do
result=$( curl -s https://api.bintray.com/packages/spring/jars/"${groupId}" )
versions=$( echo "$result" | jq -r '.versions' )
exists=$( echo "$versions" | grep "$version" -o || true )
if [ "$exists" = "$version" ]; then
ARTIFACTS_PUBLISHED=true
fi
COUNTER=$(( COUNTER + 1 ))
sleep $WAIT_TIME
done

23
ci/sync-to-maven-central.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
set -e -u
buildName=`jq -r '.name' build-info.json`
buildNumber=`jq -r '.number' build-info.json`
groupId=`jq -r '.modules[0].id' build-info.json | sed 's/\(.*\):.*:.*/\1/'`
version=`jq -r '.modules[0].id' build-info.json | sed 's/.*:.*:\(.*\)/\1/'`
echo "Syncing ${buildName}/${buildNumber}/${groupId}/${version} to Maven Central..."
curl \
-s \
--connect-timeout 240 \
--max-time 2700 \
-u ${BINTRAY_USR}:${BINTRAY_PSW} \
-H 'Content-Type: application/json' \
-d "{ \"username\": \"${SONATYPE_USR}\", \"password\": \"${SONATYPE_PSW}\"}" \
-f \
-X \
POST "https://api.bintray.com/maven_central_sync/spring/jars/${groupId}/versions/${version}" > /dev/null || { echo "Failed to sync" >&2; exit 1; }
echo "Sync complete"

5
ci/test.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
set -euo pipefail
MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/spring-plugin-maven-repository" ./mvnw -P${PROFILE} clean dependency:list test -Dsort -B

154
pom.xml
View File

@@ -20,7 +20,7 @@
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
<comments>
Copyright 2010 the original author or authors.
Copyright 2010-2019 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -65,10 +65,11 @@
</developers>
<profiles>
<profile>
<id>spring5-next</id>
<properties>
<spring.version>5.2.0.BUILD-SNAPSHOT</spring.version>
<spring.version>5.2.1.BUILD-SNAPSHOT</spring.version>
</properties>
<repositories>
<repository>
@@ -77,6 +78,155 @@
</repository>
</repositories>
</profile>
<profile>
<!-- Profile to be run on the CI server, JARs JavaDocs -->
<id>ci</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>create-javadoc-jar</id>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>snapshot</id>
<build>
<plugins>
<plugin>
<groupId>org.jfrog.buildinfo</groupId>
<artifactId>artifactory-maven-plugin</artifactId>
<version>2.6.1</version>
<inherited>false</inherited>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>publish</goal>
</goals>
<configuration>
<buildInfo>
<buildUrl>{{BUILD_URL}}</buildUrl>
</buildInfo>
<deployProperties>
<zip.name>spring-plugin</zip.name>
<zip.displayname>spring-plugin</zip.displayname>
<zip.deployed>false</zip.deployed>
<archives>*:*:*:*@zip</archives>
</deployProperties>
<publisher>
<contextUrl>https://repo.spring.io</contextUrl>
<username>{{ARTIFACTORY_USR}}</username>
<password>{{ARTIFACTORY_PSW}}</password>
<repoKey>libs-snapshot-local</repoKey>
<snapshotRepoKey>libs-snapshot-local</snapshotRepoKey>
</publisher>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>milestone</id>
<build>
<plugins>
<plugin>
<groupId>org.jfrog.buildinfo</groupId>
<artifactId>artifactory-maven-plugin</artifactId>
<version>2.6.1</version>
<inherited>false</inherited>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>publish</goal>
</goals>
<configuration>
<buildInfo>
<buildUrl>{{BUILD_URL}}</buildUrl>
</buildInfo>
<deployProperties>
<zip.name>spring-plugin</zip.name>
<zip.displayname>spring-plugin</zip.displayname>
<zip.deployed>false</zip.deployed>
<archives>*:*:*:*@zip</archives>
</deployProperties>
<publisher>
<contextUrl>https://repo.spring.io</contextUrl>
<username>{{ARTIFACTORY_USR}}</username>
<password>{{ARTIFACTORY_PSW}}</password>
<repoKey>libs-milestone-local</repoKey>
<snapshotRepoKey>libs-milestone-local</snapshotRepoKey>
</publisher>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.jfrog.buildinfo</groupId>
<artifactId>artifactory-maven-plugin</artifactId>
<version>2.6.1</version>
<inherited>false</inherited>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>publish</goal>
</goals>
<configuration>
<buildInfo>
<buildUrl>{{BUILD_URL}}</buildUrl>
</buildInfo>
<deployProperties>
<zip.name>spring-plugin</zip.name>
<zip.displayname>spring-plugin</zip.displayname>
<zip.deployed>false</zip.deployed>
<archives>*:*:*:*@zip</archives>
</deployProperties>
<publisher>
<contextUrl>https://repo.spring.io</contextUrl>
<username>{{ARTIFACTORY_USR}}</username>
<password>{{ARTIFACTORY_PSW}}</password>
<repoKey>libs-release-local</repoKey>
<snapshotRepoKey>libs-release-local</snapshotRepoKey>
</publisher>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>