mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-10-26 08:06:09 +01:00
Start Jenkinsfile migration
This commit is contained in:
committed by
René Pfeuffer
parent
964b6c3df5
commit
9e597bb9e0
369
Jenkinsfile
vendored
369
Jenkinsfile
vendored
@@ -1,244 +1,205 @@
|
||||
#!groovy
|
||||
pipeline {
|
||||
|
||||
// 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
|
||||
@Library('github.com/cloudogu/ces-build-lib@7a14da6')
|
||||
import com.cloudogu.ces.cesbuildlib.*
|
||||
|
||||
node('docker') {
|
||||
|
||||
developmentBranch = 'develop'
|
||||
mainBranch = 'master'
|
||||
|
||||
properties([
|
||||
// Keep only the last 10 build to preserve space
|
||||
buildDiscarder(logRotator(numToKeepStr: '10')),
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '10'))
|
||||
disableConcurrentBuilds()
|
||||
])
|
||||
}
|
||||
|
||||
timeout(activity: true, time: 60, unit: 'MINUTES') {
|
||||
agent {
|
||||
docker {
|
||||
image 'scmmanager/java-build:11.0.9_11.1'
|
||||
label 'docker'
|
||||
}
|
||||
}
|
||||
|
||||
Git git = new Git(this)
|
||||
environment {
|
||||
HOME = "${env.WORKSPACE}"
|
||||
SONAR_USER_HOME = "${env.WORKSPACE}/.sonar"
|
||||
}
|
||||
|
||||
catchError {
|
||||
stages {
|
||||
|
||||
Maven mvn = setupMavenBuild()
|
||||
|
||||
stage('Checkout') {
|
||||
checkout scm
|
||||
stage('Set Version') {
|
||||
when {
|
||||
branch pattern: 'release/*', comparator: 'GLOB'
|
||||
}
|
||||
steps {
|
||||
// read version from branch, set it and commit it
|
||||
sh "./gradlew setVersion -PnewVersion ${releaseVersion}"
|
||||
sh "git add gradle.properties lerna.json '**.json'"
|
||||
commit "Release version ${releaseVersion}"
|
||||
|
||||
if (isReleaseBranch()) {
|
||||
stage('Set Version') {
|
||||
String releaseVersion = getReleaseVersion();
|
||||
// set maven versions
|
||||
mvn "versions:set -DgenerateBackupPoms=false -DnewVersion=${releaseVersion}"
|
||||
// set versions for ui packages
|
||||
// we need to run 'yarn install' in order to set version with ui-scripts
|
||||
mvn "-pl :scm-ui buildfrontend:install@install"
|
||||
mvn "-pl :scm-ui buildfrontend:run@set-version"
|
||||
// fetch all remotes from origin
|
||||
sh 'git config --replace-all "remote.origin.fetch" "+refs/heads/*:refs/remotes/origin/*"'
|
||||
sh 'git fetch --all'
|
||||
|
||||
// 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"
|
||||
// checkout, reset and merge
|
||||
sh 'git checkout master'
|
||||
sh 'git reset --hard origin/master'
|
||||
sh "git merge --ff-only ${env.BRANCH_NAME}"
|
||||
|
||||
// commit changes
|
||||
sh "git -c user.name='CES Marvin' -c user.email='cesmarvin@cloudogu.com' commit -m 'release version ${releaseVersion}'"
|
||||
|
||||
// we need to fetch all branches, so we can checkout master and develop later
|
||||
sh "git config 'remote.origin.fetch' '+refs/heads/*:refs/remotes/origin/*'"
|
||||
sh "git fetch --all"
|
||||
|
||||
// merge release branch into main branch
|
||||
sh "git checkout ${mainBranch}"
|
||||
sh "git reset --hard origin/${mainBranch}"
|
||||
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}"
|
||||
}
|
||||
// set tag
|
||||
tag releaseVersion
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
mvn "clean install -DskipTests"
|
||||
stage('Build') {
|
||||
steps {
|
||||
// build without tests
|
||||
sh "./gradlew -xtest build"
|
||||
}
|
||||
}
|
||||
|
||||
parallel(
|
||||
unitTest: {
|
||||
stage('Unit Test') {
|
||||
mvn 'test -DskipFrontendBuild -DskipTypecheck -Pcoverage -pl !scm-it -Dmaven.test.failure.ignore=true'
|
||||
junit allowEmptyResults: true, testResults: '**/target/surefire-reports/TEST-*.xml,**/target/jest-reports/TEST-*.xml'
|
||||
}
|
||||
},
|
||||
integrationTest: {
|
||||
stage('Integration Test') {
|
||||
mvn 'verify -Pit -DskipUnitTests -pl :scm-webapp,:scm-it -Dmaven.test.failure.ignore=true'
|
||||
junit allowEmptyResults: true, testResults: '**/target/failsafe-reports/TEST-*.xml,**/target/cypress-reports/TEST-*.xml'
|
||||
archiveArtifacts allowEmptyArchive: true, artifacts: 'scm-ui/e2e-tests/cypress/videos/*.mp4'
|
||||
archiveArtifacts allowEmptyArchive: true, artifacts: 'scm-ui/e2e-tests/cypress/screenshots/**/*.png'
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
stage('SonarQube') {
|
||||
def sonarQube = new SonarCloud(this, [sonarQubeEnv: 'sonarcloud.io-scm', sonarOrganization: 'scm-manager', integrationBranch: 'develop'])
|
||||
sonarQube.analyzeWith(mvn)
|
||||
stage('Check') {
|
||||
steps {
|
||||
sh "./gradlew check"
|
||||
junit allowEmptyResults: true, testResults: '**/build/test-results/test/TEST-*.xml,**/build/test-results/tests/test/TEST-*.xml,**/build/jest-reports/TEST-*.xml'
|
||||
}
|
||||
}
|
||||
|
||||
if (isBuildSuccessful() && (isDevelopmentBranch() || isReleaseBranch())) {
|
||||
def commitHash = git.getCommitHash()
|
||||
// in parallel with check?
|
||||
stage('Integration Tests') {
|
||||
steps {
|
||||
sh "./gradlew integrationTest"
|
||||
junit allowEmptyResults: true, testResults: 'scm-it/build/test-results/javaIntegrationTests/*.xml,scm-ui/build/reports/e2e/*.xml'
|
||||
archiveArtifacts allowEmptyArchive: true, artifacts: 'scm-ui/e2e-tests/cypress/videos/*.mp4'
|
||||
archiveArtifacts allowEmptyArchive: true, artifacts: 'scm-ui/e2e-tests/cypress/screenshots/**/*.png'
|
||||
}
|
||||
}
|
||||
|
||||
def imageVersion = mvn.getVersion()
|
||||
if (imageVersion.endsWith('-SNAPSHOT')) {
|
||||
imageVersion = imageVersion.replace('-SNAPSHOT', "-${commitHash.substring(0,7)}-${BUILD_NUMBER}")
|
||||
}
|
||||
|
||||
stage('Deployment') {
|
||||
// configuration for docker deployment
|
||||
mvn.useRepositoryCredentials([
|
||||
id: 'docker.io',
|
||||
credentialsId: 'hub.docker.com-cesmarvin'
|
||||
])
|
||||
|
||||
mvn.useRepositoryCredentials([
|
||||
id: 'github.com/scm-manager/website',
|
||||
credentialsId: 'cesmarvin-github'
|
||||
])
|
||||
|
||||
// deploy java artifacts
|
||||
mvn.useDeploymentRepository([
|
||||
id: 'packages.scm-manager.org',
|
||||
url: 'https://packages.scm-manager.org',
|
||||
credentialsId: 'maven.scm-manager.org',
|
||||
snapshotRepository: '/repository/snapshots/',
|
||||
releaseRepository: '/repository/releases/',
|
||||
type: 'Configurable'
|
||||
])
|
||||
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()
|
||||
|
||||
// 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"
|
||||
}
|
||||
}
|
||||
|
||||
// deploy packages
|
||||
withGPGEnvironment {
|
||||
mvn "-Dgpg.scm.keyring='${GPG_KEYRING}' -Dgpg.scm.key='${GPG_KEY_ID}' -Dgpg.scm.passphrase='${GPG_KEY_PASSPHRASE}' -Ppackaging -rf :scm-packaging deploy"
|
||||
}
|
||||
}
|
||||
|
||||
stage('Presentation Environment') {
|
||||
// we don't use developmentBranch, because we only want the lastest version of develop branch on
|
||||
// next-scm. We don't want a support branch or something similar on the presentation environment.
|
||||
if ("develop".equals(env.BRANCH_NAME)) {
|
||||
build job: 'scm-manager/next-scm.cloudogu.com', propagate: false, wait: false, parameters: [
|
||||
string(name: 'changeset', value: commitHash),
|
||||
string(name: 'imageTag', value: imageVersion)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (isReleaseBranch()) {
|
||||
stage('Update Repository') {
|
||||
|
||||
// merge changes into develop
|
||||
sh "git checkout ${developmentBranch}"
|
||||
|
||||
// TODO what if we have a conflict
|
||||
// e.g.: someone has edited the changelog during the release
|
||||
if (!developmentBranch.equals(mainBranch)) {
|
||||
sh "git merge ${mainBranch}"
|
||||
}
|
||||
|
||||
|
||||
// set versions for maven packages
|
||||
mvn "build-helper:parse-version versions:set -DgenerateBackupPoms=false -DnewVersion='\${parsedVersion.majorVersion}.\${parsedVersion.nextMinorVersion}.0-SNAPSHOT'"
|
||||
|
||||
// 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 ${mainBranch} --tags"
|
||||
if (!developmentBranch.equals(mainBranch)) {
|
||||
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}"
|
||||
stage('SonarQube') {
|
||||
steps {
|
||||
sh 'git config --replace-all "remote.origin.fetch" "+refs/heads/*:refs/remotes/origin/*"'
|
||||
sh 'git fetch origin master'
|
||||
sh "./gradlew integrationTest"
|
||||
script {
|
||||
withSonarQubeEnv('sonarcloud.io-scm') {
|
||||
String sonar = "sonarqube -Dsonar.organization=scm-manager -Dsonar.branch.name=${script.env.BRANCH_NAME}"
|
||||
if (script.env.BRANCH_NAME != "master") {
|
||||
sonar += " -Dsonar.branch.target=master"
|
||||
}
|
||||
// disable until we know how todo sonar analysis with subprojects
|
||||
// sh "./gradlew sonarqube"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mailIfStatusChanged(git.commitAuthorEmail)
|
||||
stage('Deployment') {
|
||||
when {
|
||||
branch pattern: 'release/*', comparator: 'GLOB'
|
||||
// TODO or develop
|
||||
expression { return isBuildSuccess() }
|
||||
}
|
||||
steps {
|
||||
withPublishProperies {
|
||||
sh "./gradlew ${PUBLISH_PROPERTIES}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Push Tag') {
|
||||
when {
|
||||
branch pattern: 'release/*', comparator: 'GLOB'
|
||||
expression { return isBuildSuccess() }
|
||||
}
|
||||
steps {
|
||||
// push changes back to remote repository
|
||||
authGit 'cesmarvin-github', 'push origin master --tags'
|
||||
authGit 'cesmarvin-github', 'push origin --tags'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stage('Set Next Version') {
|
||||
when {
|
||||
branch pattern: 'release/*', comparator: 'GLOB'
|
||||
expression { return isBuildSuccess() }
|
||||
}
|
||||
steps {
|
||||
sh returnStatus: true, script: "git branch -D develop"
|
||||
sh "git checkout develop"
|
||||
sh "git merge master"
|
||||
|
||||
sh "./gradlew setVersionToNextSnapshot"
|
||||
|
||||
sh "git add gradle.properties lerna.json '**.json'"
|
||||
commit 'Prepare for next development iteration'
|
||||
authGit 'cesmarvin-github', 'push origin develop'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Delete Release Branch') {
|
||||
when {
|
||||
branch pattern: 'release/*', comparator: 'GLOB'
|
||||
expression { return isBuildSuccess() }
|
||||
}
|
||||
steps {
|
||||
authGit 'cesmarvin-github', "push origin :${env.BRANCH_NAME}"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
String developmentBranch
|
||||
String mainBranch
|
||||
|
||||
Maven setupMavenBuild() {
|
||||
MavenWrapperInDocker mvn = new MavenWrapperInDocker(this, "scmmanager/java-build:11.0.9_11.1")
|
||||
mvn.enableDockerHost = true
|
||||
|
||||
// disable logging durring the build
|
||||
def logConf = "scm-webapp/src/main/resources/logback.ci.xml"
|
||||
mvn.additionalArgs += " -Dlogback.configurationFile=${logConf}"
|
||||
mvn.additionalArgs += " -Dscm-it.logbackConfiguration=${logConf}"
|
||||
mvn.additionalArgs += " -Dsonar.coverage.exclusions=**/*.test.ts,**/*.test.tsx,**/*.stories.tsx"
|
||||
|
||||
if (isDevelopmentBranch() || isReleaseBranch()) {
|
||||
// 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'
|
||||
|
||||
post {
|
||||
failure {
|
||||
mail to: "scm-team@cloudogu.com",
|
||||
subject: "Jenkins Job ${JOB_NAME} - Build #${BUILD_NUMBER} - ${currentBuild.currentResult}!",
|
||||
body: "Check console output at ${BUILD_URL} to view the results."
|
||||
}
|
||||
unstable {
|
||||
mail to: "scm-team@cloudogu.com",
|
||||
subject: "Jenkins Job ${JOB_NAME} - Build #${BUILD_NUMBER} - ${currentBuild.currentResult}!",
|
||||
body: "Check console output at ${BUILD_URL} to view the results."
|
||||
}
|
||||
fixed {
|
||||
mail to: "scm-team@cloudogu.com",
|
||||
subject: "Jenkins Job ${JOB_NAME} - Is back to normal with Build #${BUILD_NUMBER}",
|
||||
body: "Check console output at ${BUILD_URL} to view the results."
|
||||
}
|
||||
}
|
||||
return mvn
|
||||
}
|
||||
|
||||
boolean isReleaseBranch() {
|
||||
return env.BRANCH_NAME.startsWith("release/");
|
||||
}
|
||||
|
||||
String getReleaseVersion() {
|
||||
return env.BRANCH_NAME.substring("release/".length());
|
||||
}
|
||||
|
||||
boolean isDevelopmentBranch() {
|
||||
return developmentBranch.equals(env.BRANCH_NAME)
|
||||
void commit(String message) {
|
||||
sh "git -c user.name='CES Marvin' -c user.email='cesmarvin@cloudogu.com' commit -m '${message}'"
|
||||
}
|
||||
|
||||
void withGPGEnvironment(def closure) {
|
||||
void tag(String version) {
|
||||
String message = "Release version ${version}"
|
||||
sh "git -c user.name='CES Marvin' -c user.email='cesmarvin@cloudogu.com' tag -m '${message}' ${version}"
|
||||
}
|
||||
|
||||
void isBuildSuccess() {
|
||||
return currentBuild.result == null || currentBuild.result == 'SUCCESS'
|
||||
}
|
||||
|
||||
void withPublishProperies(Closure<Void> closure) {
|
||||
withCredentials([
|
||||
usernamePassword(credentialsId: 'maven.scm-manager.org', passwordVariable: 'PACKAGES_PASSWORD', usernameVariable: 'PACKAGES_USERNAME'),
|
||||
usernamePassword(credentialsId: 'hub.docker.com-cesmarvin', passwordVariable: 'DOCKER_PASSWORD', usernameVariable: 'DOCKER_USERNAME'),
|
||||
string(credentialsId: 'cesmarvin_npm_token', variable: 'NPM_TOKEN'),
|
||||
file(credentialsId: 'oss-gpg-secring', variable: 'GPG_KEYRING'),
|
||||
usernamePassword(credentialsId: 'oss-keyid-and-passphrase', usernameVariable: 'GPG_KEY_ID', passwordVariable: 'GPG_KEY_PASSPHRASE')
|
||||
]) {
|
||||
closure.call()
|
||||
String properties = "-PpackagesScmManagerUsername=${PACKAGES_USERNAME} -PpackagesScmManagerPassword=${PACKAGES_PASSWORD}"
|
||||
properties += " -PdockerUsername=${DOCKER_USERNAME} -PdockerPassword=${DOCKER_PASSWORD}"
|
||||
properties += " -PnpmEmail=cesmarvin@cloudogu.com -PnpmToken=${NPM_TOKEN}"
|
||||
properties += " -Psigning.secretKeyRingFile=${GPG_KEYRING} -Psigning.keyId=${GPG_KEY_ID} -Psigning.password=${GPG_KEY_PASSPHRASE}"
|
||||
withEnv(["PUBLISH_PROPERTIES=\"${properties}\""]) {
|
||||
closure.call()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void authGit(String credentials, String command) {
|
||||
withCredentials([
|
||||
usernamePassword(credentialsId: credentials, usernameVariable: 'AUTH_USR', passwordVariable: 'AUTH_PSW')
|
||||
]) {
|
||||
sh "git -c credential.helper=\"!f() { echo username='\$AUTH_USR'; echo password='\$AUTH_PSW'; }; f\" ${command}"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ ffmpeg.setFfmpegPath(ffmpegPath);
|
||||
const options = {
|
||||
reporter: "junit",
|
||||
reporterOptions: {
|
||||
mochaFile: path.join("..", "target", "cypress-reports", "TEST-[hash].xml")
|
||||
mochaFile: path.join("..", "build", "reports", "e2e", "TEST-[hash].xml")
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user