2018-05-31 12:34:34 +02:00
|
|
|
#!groovy
|
2018-07-12 11:06:54 +02:00
|
|
|
|
2020-03-11 15:36:59 +01:00
|
|
|
// switch back to a stable tag, after pr 22 is mreged an the next version is released
|
|
|
|
|
// see https://github.com/cloudogu/ces-build-lib/pull/22
|
2020-05-17 10:23:29 +02:00
|
|
|
@Library('github.com/cloudogu/ces-build-lib@c079662')
|
2018-05-31 12:34:34 +02:00
|
|
|
import com.cloudogu.ces.cesbuildlib.*
|
|
|
|
|
|
2018-09-24 13:04:03 +02:00
|
|
|
node('docker') {
|
2018-05-31 12:34:34 +02:00
|
|
|
|
2020-03-06 12:02:34 +01:00
|
|
|
mainBranch = 'develop'
|
2018-07-12 11:46:50 +02:00
|
|
|
|
2018-07-11 18:07:26 +02:00
|
|
|
properties([
|
|
|
|
|
// Keep only the last 10 build to preserve space
|
2018-09-21 09:07:12 +02:00
|
|
|
buildDiscarder(logRotator(numToKeepStr: '10')),
|
2020-03-11 11:05:54 +01:00
|
|
|
disableConcurrentBuilds()
|
2018-07-11 18:07:26 +02:00
|
|
|
])
|
2018-05-31 12:34:34 +02:00
|
|
|
|
2020-03-11 11:05:54 +01:00
|
|
|
timeout(activity: true, time: 60, unit: 'MINUTES') {
|
2018-05-31 12:34:34 +02:00
|
|
|
|
2020-03-06 12:02:34 +01:00
|
|
|
Git git = new Git(this)
|
2018-05-31 12:34:34 +02:00
|
|
|
|
2018-09-12 18:01:00 +02:00
|
|
|
catchError {
|
2018-05-31 12:34:34 +02:00
|
|
|
|
2018-09-12 18:01:00 +02:00
|
|
|
Maven mvn = setupMavenBuild()
|
2018-05-31 12:34:34 +02:00
|
|
|
|
2018-09-12 18:01:00 +02:00
|
|
|
stage('Checkout') {
|
|
|
|
|
checkout scm
|
|
|
|
|
}
|
2018-05-31 12:34:34 +02:00
|
|
|
|
2020-03-11 11:05:54 +01:00
|
|
|
if (isReleaseBranch()) {
|
|
|
|
|
stage('Set Version') {
|
|
|
|
|
String releaseVersion = getReleaseVersion();
|
|
|
|
|
// set maven versions
|
|
|
|
|
mvn "versions:set -DgenerateBackupPoms=false -DnewVersion=${releaseVersion}"
|
|
|
|
|
// set versions for ui packages
|
2020-03-12 10:36:13 +01:00
|
|
|
// we need to run 'yarn install' in order to set version with ui-scripts
|
2020-03-11 11:05:54 +01:00
|
|
|
mvn "-pl :scm-ui buildfrontend:install@install"
|
|
|
|
|
mvn "-pl :scm-ui buildfrontend:run@set-version"
|
|
|
|
|
|
|
|
|
|
// stage pom changes
|
|
|
|
|
sh "git status --porcelain | sed s/^...// | grep pom.xml | xargs git add"
|
|
|
|
|
// stage package.json changes
|
|
|
|
|
sh "git status --porcelain | sed s/^...// | grep package.json | xargs git add"
|
|
|
|
|
// stage lerna.json changes
|
|
|
|
|
sh "git add lerna.json"
|
|
|
|
|
|
|
|
|
|
// commit changes
|
|
|
|
|
sh "git -c user.name='CES Marvin' -c user.email='cesmarvin@cloudogu.com' commit -m 'release version ${releaseVersion}'"
|
|
|
|
|
|
2020-03-13 07:51:07 +01:00
|
|
|
// we need to fetch all branches, so we can checkout master and develop later
|
2020-03-26 18:43:00 +01:00
|
|
|
sh "git config 'remote.origin.fetch' '+refs/heads/*:refs/remotes/origin/*'"
|
2020-03-13 07:51:07 +01:00
|
|
|
sh "git fetch --all"
|
|
|
|
|
|
2020-03-11 11:05:54 +01:00
|
|
|
// merge release branch into master
|
|
|
|
|
sh "git checkout master"
|
2020-04-09 21:07:54 +02:00
|
|
|
sh "git reset --hard origin/master"
|
2020-03-11 11:05:54 +01:00
|
|
|
sh "git merge --ff-only ${env.BRANCH_NAME}"
|
|
|
|
|
|
|
|
|
|
// set tag
|
|
|
|
|
sh "git -c user.name='CES Marvin' -c user.email='cesmarvin@cloudogu.com' tag -m 'release version ${releaseVersion}' ${releaseVersion}"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-12 18:01:00 +02:00
|
|
|
stage('Build') {
|
2020-02-25 11:12:04 +01:00
|
|
|
mvn 'clean install -DskipTests'
|
2018-09-12 18:01:00 +02:00
|
|
|
}
|
2018-05-31 12:34:34 +02:00
|
|
|
|
2020-03-04 10:14:59 +01:00
|
|
|
parallel(
|
|
|
|
|
unitTest: {
|
|
|
|
|
stage('Unit Test') {
|
|
|
|
|
mvn 'test -DskipFrontendBuild -DskipTypecheck -Pcoverage -pl !scm-it -Dmaven.test.failure.ignore=true'
|
2020-03-13 08:06:34 +01:00
|
|
|
junit allowEmptyResults: true, testResults: '**/target/surefire-reports/TEST-*.xml,**/target/jest-reports/TEST-*.xml'
|
2020-03-04 10:14:59 +01:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
integrationTest: {
|
|
|
|
|
stage('Integration Test') {
|
|
|
|
|
mvn 'verify -Pit -DskipUnitTests -pl :scm-webapp,:scm-it -Dmaven.test.failure.ignore=true'
|
2020-03-13 08:06:34 +01:00
|
|
|
junit allowEmptyResults: true, testResults: '**/target/failsafe-reports/TEST-*.xml'
|
2020-03-04 10:14:59 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
2018-08-06 16:37:22 +02:00
|
|
|
|
2018-09-12 18:01:00 +02:00
|
|
|
stage('SonarQube') {
|
2018-07-11 18:07:26 +02:00
|
|
|
|
2018-09-12 18:01:00 +02:00
|
|
|
analyzeWith(mvn)
|
2018-07-11 18:23:49 +02:00
|
|
|
|
2018-09-12 18:01:00 +02:00
|
|
|
if (!waitForQualityGateWebhookToBeCalled()) {
|
|
|
|
|
currentBuild.result = 'UNSTABLE'
|
|
|
|
|
}
|
2018-07-11 18:07:26 +02:00
|
|
|
}
|
2018-09-24 13:03:02 +02:00
|
|
|
|
2020-03-11 11:05:54 +01:00
|
|
|
if (isMainBranch() || isReleaseBranch()) {
|
2019-01-30 11:25:01 +01:00
|
|
|
|
2019-07-31 13:26:58 +02:00
|
|
|
stage('Lifecycle') {
|
2019-12-19 11:01:12 +01:00
|
|
|
try {
|
|
|
|
|
// failBuildOnNetworkError -> so we can catch the exception and neither fail nor make our build unstable
|
|
|
|
|
nexusPolicyEvaluation iqApplication: selectedApplication('scm'), iqScanPatterns: [[scanPattern: 'scm-server/target/scm-server-app.zip']], iqStage: 'build', failBuildOnNetworkError: true
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
echo "ERROR: iQ Server policy eval failed. Not marking build unstable for now."
|
|
|
|
|
echo "ERROR: iQ Server Exception: ${e.getMessage()}"
|
|
|
|
|
}
|
2019-07-31 13:26:58 +02:00
|
|
|
}
|
2019-01-30 11:25:01 +01:00
|
|
|
|
2020-03-11 11:05:54 +01:00
|
|
|
if (isBuildSuccessful()) {
|
2019-01-16 14:40:34 +01:00
|
|
|
|
2020-03-11 11:05:54 +01:00
|
|
|
def commitHash = git.getCommitHash()
|
2019-01-16 14:40:34 +01:00
|
|
|
|
2020-03-11 11:05:54 +01:00
|
|
|
def imageVersion = mvn.getVersion()
|
|
|
|
|
if (imageVersion.endsWith('-SNAPSHOT')) {
|
2020-03-11 15:30:24 +01:00
|
|
|
imageVersion = imageVersion.replace('-SNAPSHOT', "-${commitHash.substring(0,7)}-${BUILD_NUMBER}")
|
2020-03-11 11:05:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stage('Maven Deployment') {
|
2020-05-17 12:43:56 +02:00
|
|
|
// configuration for docker deployment
|
|
|
|
|
mvn.useRepositoryCredentials([
|
|
|
|
|
id: 'docker.io',
|
|
|
|
|
credentialsId: 'hub.docker.com-cesmarvin'
|
|
|
|
|
])
|
2020-03-11 11:05:54 +01:00
|
|
|
|
2020-05-17 12:43:56 +02:00
|
|
|
// configuration for maven deployment
|
2020-05-17 10:23:29 +02:00
|
|
|
mvn.useDeploymentRepository([
|
2020-05-23 15:02:15 +02:00
|
|
|
id: 'packages.scm-manager.org',
|
|
|
|
|
url: 'https://packages.scm-manager.org',
|
|
|
|
|
credentialsId: 'packages.scm-manager.org',
|
2020-05-17 10:23:29 +02:00
|
|
|
type: 'Configurable',
|
|
|
|
|
snapshotRepository: '/repository/snapshots',
|
|
|
|
|
releaseRepository: '/repository/releases'
|
|
|
|
|
])
|
2020-03-11 11:05:54 +01:00
|
|
|
mvn.deployToNexusRepository()
|
|
|
|
|
|
|
|
|
|
// deploy frontend bits
|
|
|
|
|
withCredentials([string(credentialsId: 'cesmarvin_npm_token', variable: 'NPM_TOKEN')]) {
|
|
|
|
|
writeFile encoding: 'UTF-8', file: '.npmrc', text: "//registry.npmjs.org/:_authToken='${NPM_TOKEN}'"
|
|
|
|
|
writeFile encoding: 'UTF-8', file: '.yarnrc', text: '''
|
|
|
|
|
registry "https://registry.npmjs.org/"
|
|
|
|
|
always-auth true
|
|
|
|
|
email cesmarvin@cloudogu.com
|
|
|
|
|
'''.trim()
|
2020-03-11 14:31:21 +01:00
|
|
|
|
|
|
|
|
// we are tricking lerna by pretending that we are not a git repository
|
|
|
|
|
sh "mv .git .git.disabled"
|
|
|
|
|
try {
|
|
|
|
|
mvn "-pl :scm-ui buildfrontend:run@deploy"
|
|
|
|
|
} finally {
|
|
|
|
|
sh "mv .git.disabled .git"
|
|
|
|
|
}
|
2020-03-11 11:05:54 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stage('Presentation Environment') {
|
2020-05-17 12:43:56 +02:00
|
|
|
/**
|
|
|
|
|
* TODO does not match docker version (scm-packaging/docker)
|
|
|
|
|
* build job: 'scm-manager/next-scm.cloudogu.com', propagate: false, wait: false, parameters: [
|
|
|
|
|
* string(name: 'changeset', value: commitHash),
|
|
|
|
|
* string(name: 'imageTag', value: imageVersion)
|
|
|
|
|
* ]
|
|
|
|
|
*/
|
2020-03-11 11:05:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isReleaseBranch()) {
|
|
|
|
|
stage('Update Repository') {
|
|
|
|
|
|
|
|
|
|
// merge changes into develop
|
|
|
|
|
sh "git checkout develop"
|
2020-03-12 10:36:13 +01:00
|
|
|
// TODO what if we have a conflict
|
|
|
|
|
// e.g.: someone has edited the changelog during the release
|
2020-03-11 11:05:54 +01:00
|
|
|
sh "git merge master"
|
|
|
|
|
|
|
|
|
|
// set versions for maven packages
|
|
|
|
|
mvn "build-helper:parse-version versions:set -DgenerateBackupPoms=false -DnewVersion='\${parsedVersion.majorVersion}.\${parsedVersion.nextMinorVersion}.0-SNAPSHOT'"
|
2020-03-12 10:36:13 +01:00
|
|
|
|
2020-03-11 11:05:54 +01:00
|
|
|
// set versions for ui packages
|
|
|
|
|
mvn "-pl :scm-ui buildfrontend:run@set-version"
|
|
|
|
|
|
|
|
|
|
// stage pom changes
|
|
|
|
|
sh "git status --porcelain | sed s/^...// | grep pom.xml | xargs git add"
|
|
|
|
|
// stage package.json changes
|
|
|
|
|
sh "git status --porcelain | sed s/^...// | grep package.json | xargs git add"
|
|
|
|
|
// stage lerna.json changes
|
|
|
|
|
sh "git add lerna.json"
|
|
|
|
|
|
|
|
|
|
// commit changes
|
|
|
|
|
sh "git -c user.name='CES Marvin' -c user.email='cesmarvin@cloudogu.com' commit -m 'prepare for next development iteration'"
|
|
|
|
|
|
|
|
|
|
// push changes back to remote repository
|
|
|
|
|
withCredentials([usernamePassword(credentialsId: 'cesmarvin-github', usernameVariable: 'GIT_AUTH_USR', passwordVariable: 'GIT_AUTH_PSW')]) {
|
|
|
|
|
sh "git -c credential.helper=\"!f() { echo username='\$GIT_AUTH_USR'; echo password='\$GIT_AUTH_PSW'; }; f\" push origin master --tags"
|
|
|
|
|
sh "git -c credential.helper=\"!f() { echo username='\$GIT_AUTH_USR'; echo password='\$GIT_AUTH_PSW'; }; f\" push origin develop --tags"
|
|
|
|
|
sh "git -c credential.helper=\"!f() { echo username='\$GIT_AUTH_USR'; echo password='\$GIT_AUTH_PSW'; }; f\" push origin :${env.BRANCH_NAME}"
|
|
|
|
|
}
|
2019-08-06 11:32:05 +02:00
|
|
|
}
|
2018-09-25 09:22:25 +02:00
|
|
|
}
|
2018-09-24 17:13:47 +02:00
|
|
|
|
2018-09-25 09:22:25 +02:00
|
|
|
}
|
2018-09-24 17:13:47 +02:00
|
|
|
}
|
2018-05-31 12:34:34 +02:00
|
|
|
}
|
|
|
|
|
|
2020-03-06 12:02:34 +01:00
|
|
|
mailIfStatusChanged(git.commitAuthorEmail)
|
2018-09-12 18:01:00 +02:00
|
|
|
}
|
2018-05-31 12:34:34 +02:00
|
|
|
}
|
2018-07-11 18:23:49 +02:00
|
|
|
|
2018-07-12 11:46:50 +02:00
|
|
|
String mainBranch
|
2018-07-12 10:55:03 +02:00
|
|
|
|
2018-07-12 11:15:24 +02:00
|
|
|
Maven setupMavenBuild() {
|
2020-05-10 21:18:51 +02:00
|
|
|
MavenWrapperInDocker mvn = new MavenWrapperInDocker(this, "scmmanager/java-build:11.0.7_10")
|
|
|
|
|
mvn.enableDockerHost = true
|
|
|
|
|
|
2020-03-04 12:12:57 +01:00
|
|
|
// disable logging durring the build
|
2020-03-04 12:56:38 +01:00
|
|
|
def logConf = "scm-webapp/src/main/resources/logback.ci.xml"
|
|
|
|
|
mvn.additionalArgs += " -Dlogback.configurationFile=${logConf}"
|
|
|
|
|
mvn.additionalArgs += " -Dscm-it.logbackConfiguration=${logConf}"
|
2018-07-12 11:15:24 +02:00
|
|
|
|
2020-03-11 11:05:54 +01:00
|
|
|
if (isMainBranch() || isReleaseBranch()) {
|
2018-07-12 11:15:24 +02:00
|
|
|
// Release starts javadoc, which takes very long, so do only for certain branches
|
|
|
|
|
mvn.additionalArgs += ' -DperformRelease'
|
|
|
|
|
// JDK8 is more strict, we should fix this before the next release. Right now, this is just not the focus, yet.
|
|
|
|
|
mvn.additionalArgs += ' -Dmaven.javadoc.failOnError=false'
|
|
|
|
|
}
|
|
|
|
|
return mvn
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-11 18:23:49 +02:00
|
|
|
void analyzeWith(Maven mvn) {
|
|
|
|
|
|
2018-09-07 10:29:58 +02:00
|
|
|
withSonarQubeEnv('sonarcloud.io-scm') {
|
2018-07-11 18:23:49 +02:00
|
|
|
|
|
|
|
|
String mvnArgs = "${env.SONAR_MAVEN_GOAL} " +
|
|
|
|
|
"-Dsonar.host.url=${env.SONAR_HOST_URL} " +
|
|
|
|
|
"-Dsonar.login=${env.SONAR_AUTH_TOKEN} "
|
|
|
|
|
|
|
|
|
|
if (isPullRequest()) {
|
|
|
|
|
echo "Analysing SQ in PR mode"
|
|
|
|
|
mvnArgs += "-Dsonar.pullrequest.base=${env.CHANGE_TARGET} " +
|
|
|
|
|
"-Dsonar.pullrequest.branch=${env.CHANGE_BRANCH} " +
|
|
|
|
|
"-Dsonar.pullrequest.key=${env.CHANGE_ID} " +
|
|
|
|
|
"-Dsonar.pullrequest.provider=bitbucketcloud " +
|
|
|
|
|
"-Dsonar.pullrequest.bitbucketcloud.owner=sdorra " +
|
2018-12-04 15:52:02 +01:00
|
|
|
"-Dsonar.pullrequest.bitbucketcloud.repository=scm-manager " +
|
|
|
|
|
"-Dsonar.cpd.exclusions=**/*StoreFactory.java,**/*UserPassword.js "
|
2018-07-11 18:23:49 +02:00
|
|
|
} else {
|
|
|
|
|
mvnArgs += " -Dsonar.branch.name=${env.BRANCH_NAME} "
|
2018-09-25 09:22:25 +02:00
|
|
|
if (!isMainBranch()) {
|
2018-07-12 10:55:03 +02:00
|
|
|
// Avoid exception "The main branch must not have a target" on main branch
|
|
|
|
|
mvnArgs += " -Dsonar.branch.target=${mainBranch} "
|
2018-07-11 18:23:49 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mvn "${mvnArgs}"
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-12 10:32:24 +02:00
|
|
|
|
2020-03-11 11:05:54 +01:00
|
|
|
boolean isReleaseBranch() {
|
|
|
|
|
return env.BRANCH_NAME.startsWith("release/");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String getReleaseVersion() {
|
|
|
|
|
return env.BRANCH_NAME.substring("release/".length());
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-25 09:22:25 +02:00
|
|
|
boolean isMainBranch() {
|
|
|
|
|
return mainBranch.equals(env.BRANCH_NAME)
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-16 11:38:04 +02:00
|
|
|
boolean waitForQualityGateWebhookToBeCalled() {
|
2018-07-16 11:54:35 +02:00
|
|
|
boolean isQualityGateSucceeded = true
|
2018-10-09 11:17:06 +02:00
|
|
|
timeout(time: 5, unit: 'MINUTES') { // Needed when there is no webhook for example
|
2018-07-16 11:38:04 +02:00
|
|
|
def qGate = waitForQualityGate()
|
|
|
|
|
echo "SonarQube Quality Gate status: ${qGate.status}"
|
|
|
|
|
if (qGate.status != 'OK') {
|
2018-07-16 11:54:35 +02:00
|
|
|
isQualityGateSucceeded = false
|
2018-07-16 11:38:04 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-07-16 11:54:35 +02:00
|
|
|
return isQualityGateSucceeded
|
2018-07-16 11:38:04 +02:00
|
|
|
}
|
|
|
|
|
|