Introduce Jenkins.

This commit is contained in:
Greg Turnquist
2019-06-08 07:43:47 -05:00
parent 5ebe61a784
commit c80d1ff6f1
11 changed files with 348 additions and 134 deletions

186
Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,186 @@
pipeline {
agent none
triggers {
pollSCM 'H/10 * * * *'
}
options {
disableConcurrentBuilds()
}
stages {
stage("test: baseline (jdk8)") {
agent {
docker {
image 'adoptopenjdk/openjdk8:latest'
args '-v $HOME/.m2:/root/.m2'
}
}
steps {
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:/root/.m2'
}
}
steps {
sh "PROFILE=none ci/test.sh"
}
}
stage("test: baseline (jdk12)") {
agent {
docker {
image 'adoptopenjdk/openjdk12:latest'
args '-v $HOME/.m2:/root/.m2'
}
}
steps {
sh "PROFILE=none ci/test.sh"
}
}
}
}
stage('Deploy to Artifactory') {
agent {
docker {
image 'springci/spring-hateoas-openjdk8-with-graphviz-and-jq:latest'
args '-v $HOME/.m2:/root/.m2'
}
}
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
}
steps {
script {
// Warm up this plugin quietly before using it.
sh "./mvnw -q org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version"
PROJECT_VERSION = sh(
script: "./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('BUILD-SNAPSHOT')) {
RELEASE_TYPE = 'snapshot'
} else if (PROJECT_VERSION.endsWith('RELEASE')) {
RELEASE_TYPE = 'release'
}
OUTPUT = sh(
script: "PROFILE=ci,${RELEASE_TYPE} ci/build.sh",
returnStdout: true
).trim()
echo "$OUTPUT"
build_info_path = OUTPUT.split('\n')
.find { it.contains('Artifactory Build Info Recorder') }
.split('Saving Build Info to ')[1]
.trim()[1..-2]
dir(build_info_path + '/..') {
stash name: 'build_info', includes: "*.json"
}
}
}
}
stage('Promote to Bintray') {
when {
branch 'release'
}
agent {
docker {
image 'springci/spring-hateoas-openjdk8-with-graphviz-and-jq:latest'
args '-v $HOME/.m2:/root/.m2'
}
}
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
}
steps {
script {
// Warm up this plugin quietly before using it.
sh "./mvnw -q org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version"
PROJECT_VERSION = sh(
script: "./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 'springci/spring-hateoas-openjdk8-with-graphviz-and-jq:latest'
args '-v $HOME/.m2:/root/.m2'
}
}
environment {
BINTRAY = credentials('Bintray-spring-operator')
SONATYPE = credentials('oss-token')
}
steps {
script {
// Warm up this plugin quietly before using it.
sh "./mvnw -q org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version"
PROJECT_VERSION = sh(
script: "./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>")
}
}
}
}

View File

@@ -15,16 +15,6 @@
*/
package org.springframework.hateoas.examples;
import static org.hamcrest.CoreMatchers.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.util.Arrays;
import java.util.Optional;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -36,6 +26,18 @@ import org.springframework.http.HttpHeaders;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Arrays;
import java.util.Optional;
import static org.hamcrest.CoreMatchers.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Greg Turnquist
*/
@@ -58,7 +60,7 @@ public class EmployeeControllerTests {
mvc.perform(get("/employees").accept(MediaTypes.HAL_FORMS_JSON_VALUE)) //
.andDo(print()) //
.andExpect(status().isOk()) //
.andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaTypes.HAL_FORMS_JSON_VALUE + ";charset=UTF-8"))
.andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaTypes.HAL_FORMS_JSON_VALUE))
.andExpect(jsonPath("$._embedded.employees[0].id", is(1)))
.andExpect(jsonPath("$._embedded.employees[0].firstName", is("Frodo")))
@@ -113,7 +115,7 @@ public class EmployeeControllerTests {
mvc.perform(get("/employees/1").accept(MediaTypes.HAL_FORMS_JSON_VALUE)) //
.andDo(print()) //
.andExpect(status().isOk()) //
.andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaTypes.HAL_FORMS_JSON_VALUE + ";charset=UTF-8"))
.andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaTypes.HAL_FORMS_JSON_VALUE))
.andExpect(jsonPath("$.id", is(1))) //
.andExpect(jsonPath("$.firstName", is("Frodo"))) //

View File

@@ -2,13 +2,4 @@
set -euo pipefail
[[ -d $PWD/maven && ! -d $HOME/.m2 ]] && ln -s $PWD/maven $HOME/.m2
spring_hateoas_examples_artifactory=$(pwd)/spring-hateoas-examples-artifactory
rm -rf $HOME/.m2/repository/org/springframework/hateoas 2> /dev/null || :
cd spring-hateoas-examples-github
./mvnw -Pdistribute -Dmaven.test.skip=true clean deploy \
-DaltDeploymentRepository=distribution::default::file://${spring_hateoas_examples_artifactory}
./mvnw -P${PROFILE} -Dmaven.test.skip=true clean deploy -B

View File

@@ -1,20 +0,0 @@
---
platform: linux
image_resource:
type: docker-image
source:
repository: openjdk
tag: 8-jdk
inputs:
- name: spring-hateoas-examples-github
outputs:
- name: spring-hateoas-examples-artifactory
caches:
- path: maven
run:
path: spring-hateoas-examples-github/ci/build.sh

View File

@@ -2,24 +2,20 @@
set -e -u
apt-get update
apt-get install -y jq
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/'`
buildName=$( cat spring-hateoas-examples-artifactory/build-info.json | jq -r '.buildInfo.name' )
buildNumber=$( cat spring-hateoas-examples-artifactory/build-info.json | jq -r '.buildInfo.number' )
groupId=$( cat spring-hateoas-examples-artifactory/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/\(.*\):.*:.*/\1/' )
version=$( cat spring-hateoas-examples-artifactory/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
targetRepo="libs-release-local"
echo "Promoting ${buildName}/${buildNumber} to ${targetRepo}"
echo "Promoting ${buildName}/${buildNumber}/${groupId}/${version} to libs-release-local"
curl \
-s \
--connect-timeout 240 \
--max-time 2700 \
-u ${ARTIFACTORY_USERNAME}:${ARTIFACTORY_PASSWORD} \
-H "Content-type:application/json" \
-d "{\"sourceRepos\": [\"libs-release-local\"], \"targetRepo\" : \"spring-distributions\", \"async\":\"true\"}" \
-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; }

View File

@@ -1,19 +0,0 @@
---
platform: linux
image_resource:
type: docker-image
source:
repository: openjdk
tag: 8-jdk
inputs:
- name: spring-hateoas-examples-artifactory
- name: spring-hateoas-examples-github
run:
path: spring-hateoas-examples-github/ci/promote-to-bintray.sh
params:
ARTIFACTORY_USERNAME:
ARTIFACTORY_PASSWORD:

View File

@@ -2,23 +2,22 @@
set -e -u
apt-get update
apt-get install -y jq
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/'`
buildName=$( cat spring-hateoas-examples-artifactory/build-info.json | jq -r '.buildInfo.name' )
buildNumber=$( cat spring-hateoas-examples-artifactory/build-info.json | jq -r '.buildInfo.number' )
groupId=$( cat spring-hateoas-examples-artifactory/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/\(.*\):.*:.*/\1/' )
version=$( cat spring-hateoas-examples-artifactory/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
echo "Syncing ${buildName}/${buildNumber}/${groupId}/${version} to Maven Central..."
echo "Syncing ${buildName}/${buildNumber} to Maven Central"
curl \
-s \
--connect-timeout 240 \
--max-time 2700 \
-u ${BINTRAY_USERNAME}:${BINTRAY_API_KEY} \
-H "Content-Type: application/json" -d "{ \"username\": \"${SONATYPE_USER_TOKEN}\", \"password\": \"${SONATYPE_PASSWORD_TOKEN}\"}" \
-f \
-X \
POST "https://api.bintray.com/maven_central_sync/spring/jars/${groupId}/versions/${version}" > /dev/null || { echo "Failed to sync" >&2; exit 1; }
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"

View File

@@ -1,21 +0,0 @@
---
platform: linux
image_resource:
type: docker-image
source:
repository: openjdk
tag: 8-jdk
inputs:
- name: spring-hateoas-examples-artifactory
- name: spring-hateoas-examples-github
run:
path: spring-hateoas-examples-github/ci/sync-to-maven-central.sh
params:
BINTRAY_USERNAME:
BINTRAY_API_KEY:
SONATYPE_USER_TOKEN:
SONATYPE_PASSWORD_TOKEN:

View File

@@ -2,10 +2,4 @@
set -euo pipefail
[[ -d $PWD/maven && ! -d $HOME/.m2 ]] && ln -s $PWD/maven $HOME/.m2
rm -rf $HOME/.m2/repository/org/springframework/hateoas 2> /dev/null || :
cd spring-hateoas-examples-github
./mvnw clean dependency:list test -P${PROFILE} -Dsort
./mvnw -P${PROFILE} clean dependency:list test -Dsort -B

View File

@@ -1,17 +0,0 @@
---
platform: linux
image_resource:
type: docker-image
source:
repository: openjdk
tag: 8-jdk
inputs:
- name: spring-hateoas-examples-github
caches:
- path: maven
run:
path: spring-hateoas-examples-github/ci/test.sh

123
pom.xml
View File

@@ -91,6 +91,129 @@
</repositories>
</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-hateoas</zip.name>
<zip.displayname>spring-hateoas</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-hateoas</zip.name>
<zip.displayname>spring-hateoas</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-hateoas</zip.name>
<zip.displayname>spring-hateoas</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>
<developers>