From ee4a0ed46c1c94e2ae6f1b55de64ce077ce46fa2 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 7 Mar 2023 15:21:29 +0100 Subject: [PATCH] Add Jenkins config See gh-719. --- Jenkinsfile | 128 +++++++++++++++++++++++++++++++++++ ci/deploy-milestone.sh | 19 ++++++ ci/deploy-release.sh | 22 ++++++ ci/deploy-snapshot.sh | 12 ++++ ci/openjdk8-vault/Dockerfile | 24 +++++++ ci/pipeline.properties | 21 ++++++ ci/version.sh | 13 ++++ settings.xml | 34 ++++++++++ 8 files changed, 273 insertions(+) create mode 100644 Jenkinsfile create mode 100644 ci/deploy-milestone.sh create mode 100644 ci/deploy-release.sh create mode 100644 ci/deploy-snapshot.sh create mode 100644 ci/openjdk8-vault/Dockerfile create mode 100644 ci/pipeline.properties create mode 100644 ci/version.sh create mode 100644 settings.xml diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..3dda1381 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,128 @@ +def p = [:] +node { + checkout scm + p = readProperties interpolate: true, file: 'ci/pipeline.properties' +} + +pipeline { + agent none + + triggers { + pollSCM 'H/10 * * * *' + } + + options { + disableConcurrentBuilds() + buildDiscarder(logRotator(numToKeepStr: '14')) + } + + stages { + stage("Docker images") { + parallel { + stage('Publish JDK 8 + Vault Docker image') { + when { + anyOf { + changeset "ci/openjdk8-vault/Dockerfile" + changeset "src/test/bash/install_vault.sh" + changeset "ci/pipeline.properties" + } + } + agent { label 'data' } + options { timeout(time: 20, unit: 'MINUTES') } + + steps { + script { + def image = docker.build("${p['docker.build.image.name']}", "--build-arg BASE=${p['docker.java.main.image']} --build-arg VAULT=${p['docker.vault.version']} -f ci/openjdk8-vault/Dockerfile .") + docker.withRegistry(p['docker.registry'], p['docker.credentials']) { + image.push() + } + } + } + } + } + } + + stage("test: baseline (Java 8)") { + when { + beforeAgent(true) + anyOf { + branch(pattern: "main|(\\d\\.\\d\\.x)", comparator: "REGEXP") + not { triggeredBy 'UpstreamCause' } + } + } + agent { + label 'data' + } + options { timeout(time: 30, unit: 'MINUTES') } + environment { + ARTIFACTORY = credentials("${p['artifactory.credentials']}") + } + steps { + script { + docker.image("${p['docker.image']}").inside(p['docker.java.inside.basic']) { + sh 'src/test/bash/create_certificates.sh' + sh '/opt/vault/vault server -config=$(pwd)/src/test/bash/vault.conf &' + sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list verify -Dsort -U -B' + } + } + } + } + + stage('Deploy') { + when { + beforeAgent(true) + anyOf { + branch(pattern: "main|(\\d\\.\\d\\.x)|v(\\d\\.\\d\\.d)|", comparator: "REGEXP") + not { triggeredBy 'UpstreamCause' } + } + } + agent { + docker { + image "${p['docker.image']}" + args "${p['docker.java.inside.basic']}" + } + } + options { timeout(time: 20, unit: 'MINUTES') } + + environment { + ARTIFACTORY = credentials("${p['artifactory.credentials']}") + SONATYPE = credentials('oss-login') + KEYRING = credentials('spring-signing-secring.gpg') + PASSPHRASE = credentials('spring-gpg-passphrase') + } + + steps { + script { + PROJECT_VERSION = sh( + script: "ci/version.sh", + returnStdout: true + ).trim() + + RELEASE_TYPE = 'snapshot' + + if (PROJECT_VERSION.matches(/.*-RC[0-9]+$/) || PROJECT_VERSION.matches(/.*-M[0-9]+$/)) { + RELEASE_TYPE = "milestone" + } else if (PROJECT_VERSION.endsWith('SNAPSHOT')) { + RELEASE_TYPE = 'snapshot' + } else if (PROJECT_VERSION.matches(/.*\.[0-9]+$/)) { + RELEASE_TYPE = 'release' + } + + sh "ci/deploy-${RELEASE_TYPE}.sh" + } + } + } + } + + post { + changed { + script { + emailext( + subject: "[${currentBuild.fullDisplayName}] ${currentBuild.currentResult}", + mimeType: 'text/html', + recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']], + body: "${currentBuild.fullDisplayName} is reported as ${currentBuild.currentResult}") + } + } + } +} diff --git a/ci/deploy-milestone.sh b/ci/deploy-milestone.sh new file mode 100644 index 00000000..bd9da866 --- /dev/null +++ b/ci/deploy-milestone.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -euo pipefail + +MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,milestone,artifactory,release \ + -Dartifactory.server=https://repo.spring.io \ + -Dartifactory.username=${ARTIFACTORY_USR} \ + -Dartifactory.password=${ARTIFACTORY_PSW} \ + -Dartifactory.staging-repository=libs-milestone-local \ + -Dartifactory.build-name=spring-vault \ + -Dartifactory.build-number=${BUILD_NUMBER} \ + clean deploy -U -B + +MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pdistribute \ + -Dartifactory.server=https://repo.spring.io \ + -Dartifactory.username=${ARTIFACTORY_USR} \ + -Dartifactory.password=${ARTIFACTORY_PSW} \ + -Dartifactory.staging-repository=temp-private-local \ + clean deploy -U -B diff --git a/ci/deploy-release.sh b/ci/deploy-release.sh new file mode 100644 index 00000000..dc07ef70 --- /dev/null +++ b/ci/deploy-release.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -euo pipefail + +GNUPGHOME=/tmp/gpghome +export GNUPGHOME + +mkdir $GNUPGHOME +cp $KEYRING $GNUPGHOME + +MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,central,release \ + -Dgpg.passphrase=${PASSPHRASE} \ + -Dgpg.secretKeyring=${GNUPGHOME}/secring.gpg \ + -DstagingDescription="Releasing Spring Vault" \ + clean deploy -U -B + +MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pdistribute \ + -Dartifactory.server=https://repo.spring.io \ + -Dartifactory.username=${ARTIFACTORY_USR} \ + -Dartifactory.password=${ARTIFACTORY_PSW} \ + -Dartifactory.staging-repository=temp-private-local \ + clean deploy -U -B diff --git a/ci/deploy-snapshot.sh b/ci/deploy-snapshot.sh new file mode 100644 index 00000000..5820fb94 --- /dev/null +++ b/ci/deploy-snapshot.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euo pipefail +MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,snapshot,artifactory \ + -Dartifactory.server=https://repo.spring.io \ + -Dartifactory.username=${ARTIFACTORY_USR} \ + -Dartifactory.password=${ARTIFACTORY_PSW} \ + -Dartifactory.staging-repository=libs-snapshot-local \ + -Dartifactory.build-name=spring-vault \ + -Dartifactory.build-number=${BUILD_NUMBER} \ + -Dmaven.test.skip=true \ + clean deploy -U -B diff --git a/ci/openjdk8-vault/Dockerfile b/ci/openjdk8-vault/Dockerfile new file mode 100644 index 00000000..9b6cfaa8 --- /dev/null +++ b/ci/openjdk8-vault/Dockerfile @@ -0,0 +1,24 @@ +ARG BASE +FROM ${BASE} +# Any ARG statements before FROM are cleared. + +ENV TZ=Etc/UTC +ENV DEBIAN_FRONTEND=noninteractive + +# Copy Vault's install file into the container + +COPY ./src/test/bash/install_vault.sh /opt + +ARG VAULT + +RUN set -eux && \ + sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \ + sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \ + sed -i -e 's/http/https/g' /etc/apt/sources.list && \ + apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 wget unzip && \ + echo ${TZ} > /etc/timezone && \ + rm -rf /var/lib/apt/lists/* + +RUN set -eux && \ + cd /opt && \ + /opt/install_vault.sh -v ${VAULT} diff --git a/ci/pipeline.properties b/ci/pipeline.properties new file mode 100644 index 00000000..c8d23768 --- /dev/null +++ b/ci/pipeline.properties @@ -0,0 +1,21 @@ +# Java versions +java.main.tag=8u362-b09-jdk + +# Docker container images - standard +docker.java.main.image=eclipse-temurin:${java.main.tag} + +# Main docker image name using during the CI build +docker.build.image.name=springci/spring-vault-openjdk8-vault:${java.main.tag}-${docker.vault.version} +docker.image=harbor-repo.vmware.com/dockerhub-proxy-cache/${docker.build.image.name} + +# Supported versions of Vault +docker.vault.version=1.6.1 + +# Docker environment settings +docker.java.inside.basic=-v $HOME:/tmp/jenkins-home +docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v $HOME:/tmp/jenkins-home + +# Credentials +docker.registry= +docker.credentials=hub.docker.com-springbuildmaster +artifactory.credentials=02bd1690-b54f-4c9f-819d-a77cb7a9822c diff --git a/ci/version.sh b/ci/version.sh new file mode 100644 index 00000000..71b2f024 --- /dev/null +++ b/ci/version.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -euo pipefail + +RAW_VERSION=`MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw \ + org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate \ + -Dexpression=project.version -q -DforceStdout` + +# Split things up +VERSION_PARTS=($RAW_VERSION) + +# Grab the last part, which is the actual version number. +echo ${VERSION_PARTS[${#VERSION_PARTS[@]}-1]} diff --git a/settings.xml b/settings.xml new file mode 100644 index 00000000..2700e663 --- /dev/null +++ b/settings.xml @@ -0,0 +1,34 @@ + + + + + spring-plugins-release + ${env.ARTIFACTORY_USR} + ${env.ARTIFACTORY_PSW} + + + spring-libs-snapshot + ${env.ARTIFACTORY_USR} + ${env.ARTIFACTORY_PSW} + + + spring-libs-milestone + ${env.ARTIFACTORY_USR} + ${env.ARTIFACTORY_PSW} + + + spring-libs-release + ${env.ARTIFACTORY_USR} + ${env.ARTIFACTORY_PSW} + + + sonatype-nexus-staging + ${env.SONATYPE_USR} + ${env.SONATYPE_PSW} + + + +