diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f82bca3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +# Multi-Stage-Build builder +# Extract layers from application to minimize image size +FROM adoptopenjdk/openjdk11:alpine-slim AS builder +WORKDIR application +ARG JAR_FILE=target/*.jar +COPY ${JAR_FILE} application.jar +RUN java -Djarmode=layertools -jar application.jar extract + + +# Build the actual image +FROM adoptopenjdk/openjdk11:alpine-slim +WORKDIR /application +COPY --from=builder application/dependencies/ ./ +COPY --from=builder application/spring-boot-loader/ ./ +COPY --from=builder application/snapshot-dependencies/ ./ +COPY --from=builder application/application/ ./ + +EXPOSE 8080 + +ENV JAVA_OPTIONS="" + +HEALTHCHECK --interval=30s --timeout=30s --retries=3 \ + CMD wget --no-verbose --spider http://localhost:8080/actuator/health || exit 1 + +CMD ["java", "org.springframework.boot.loader.JarLauncher", "-XX:+UseSerialGC", "-XX:MaxRAM=256m", "${JAVA_OPTIONS}" ] \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..ef7b898 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,144 @@ +pipeline { + agent any + + environment { + NEXUS = credentials('jenkins_nexus') + + DOCKER_REGISTRY = "docker.nclazz.de" + DOCKER_GROUP = 'nclazz-service' + DOCKER_IMAGE = 'mail-relay' + DOCKER_TAG = "${ BRANCH_NAME == "master" ? "latest" : "develop" }" + DOCKER_VERSION = "0.0.1-SNAPSHOT" + + DEPLOY_ENV = "${ BRANCH_NAME == "master" ? "production" : "staging" }" + } + + options { + timeout(time: 30, unit: "MINUTES") + } + + parameters { + booleanParam(name: 'RUN_INTEGRATION', defaultValue: false, description: 'Run integration tests.') + booleanParam(name: 'RUN_DEPLOYMENT', defaultValue: false, description: 'Run deployment to staging or production environment.') + } + + stages { + stage('Run Maven') { + agent { + docker 'maven:3.8.3-openjdk-11' + } + stages { + stage('Run Maven Build') { + steps { + sh 'mvn install -DskipTests -B -s settings.xml' + stash includes: '**/target/*.jar', name: 'BUILD_ARTIFACTS' + } + } + stage('Run All Tests') { + steps { + sh 'mvn test -P test -B -s settings.xml' + } + } + } + post { + always { + junit( + allowEmptyResults: true, + testResults: '**/target/surefire-reports/*.xml, **/target/failsafe-reports/*.xml' + ) + jacoco( + changeBuildStatus: true, + exclusionPattern: '**/*Application.class, ' + + '**/*Configuration.class', + minimumInstructionCoverage: env.MIN_INSTRUCTION_COVERAGE, + maximumInstructionCoverage: env.MAX_INSTRUCTION_COVERAGE, + minimumClassCoverage: env.MIN_CLASS_COVERAGE, + maximumClassCoverage: env.MAX_CLASS_COVERAGE + ) + recordIssues( + enabledForFailure: true, + aggregatingResults: true, + tools: [java(), checkStyle(), findBugs(pattern: '**/target/spotbugsXml.xml')] + ) + } + } + } + stage('Run Docker Builds') { + agent { label 'docker' } + when { + anyOf { + branch 'master' + branch 'develop' + } + } + steps { + unstash 'BUILD_ARTIFACTS' + script { + docker.withRegistry("https://$DOCKER_REGISTRY", "jenkins_nexus") { + def apiImage = docker.build("$DOCKER_GROUP/$DOCKER_IMAGE") + apiImage.push("${env.DOCKER_VERSION}") + apiImage.push("${env.DOCKER_TAG}") + } + } + } + } + stage('Run Deployment') { + agent { label 'provision' } + when { + allOf { + anyOf { + branch 'master' + branch 'develop' + expression { return params.RUN_DEPLOYMENT } + } + } + } + steps { + deployToSwarm( + name: 'nclazz-mail-relay', + file: "${env.WORKSPACE}/docker-compose.yml", + forceUpdate: true, + askApproval: !params.RUN_DEPLOYMENT, + slackChannel: 'deployment', + env: [ + PORT: 7006, + VERSION: env.DOCKER_VERSION + ] + ) + exposeService( + name: 'nclazz-email-relay', + fqdn: 'api.nclazz.de', + description: 'nclazz email relay service', + location: '/mail', + backendPort: 7006 + ) + } + } + } + post { + always { + cleanWs() + } + failure { + slackSend( + channel: "notifications", + color: "danger", + message: "There is a *build failure* in ${env.JOB_NAME}.\nBuild: ${env.RUN_DISPLAY_URL} " + ) + } + unstable { + slackSend( + channel: "notifications", + color: "warning", + message: "Some tests have failed in ${env.JOB_NAME}.\nBuild: ${env.RUN_DISPLAY_URL} " + ) + } + fixed { + slackSend( + channel: "notifications", + color: "good", + message: "The build ${env.JOB_NAME} completed successfully and is back to normal.\nBuild: ${env.RUN_DISPLAY_URL} " + ) + } + } +} \ No newline at end of file diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 0000000..1aaafdc --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8f783cf --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3.8' +services: + service: + image: docker.nclazz.de/nclazz-service/mail-relay:$VERSION + stop_grace_period: 60s + deploy: + replicas: 1 + resources: + limits: + memory: 250MB + placement: + max_replicas_per_node: 1 + update_config: + order: start-first + ports: + - "${PORT}:8080" \ No newline at end of file diff --git a/pom.xml b/pom.xml index 630086e..18e1d76 100644 --- a/pom.xml +++ b/pom.xml @@ -25,6 +25,13 @@ UTF-8 3.21.0 + 3.0.0-M5 + 3.0.0-M5 + 3.0.0 + 5.0.0 + 4.2.0 + 0.8.7 + 3.1.2 @@ -119,6 +126,16 @@ + + io.github.git-commit-id + git-commit-id-maven-plugin + 5.0.0 + + + ^git.local.branch.*$ + + + @@ -130,4 +147,151 @@ + + + test + + + + com.github.spotbugs + spotbugs-maven-plugin + ${spotbugs.version} + + true + Medium + Low + false + spotbugs-ignore.xml + + + + compile-findbugs + compile + + check + + + + + + + org.apache.maven.plugins + + maven-checkstyle-plugin + + ${checkstyle.version} + + checkstyle.xml + + src/main/java + + false + true + 0 + + + + checkstyle-check + + check + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + + BUNDLE + + **/*Configuration.class + **/*Application.class + + + + false + + + + prepare-agent + + prepare-agent + + + + report + prepare-package + + report + + + + check + + check + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + ${maven.enforcer.version} + + + + 3.5 + + + 11 + + + + + + + enforce-maven + + enforce + + + + + + + + + + com.github.spotbugs + spotbugs-maven-plugin + ${spotbugs.version} + + true + Medium + Low + + + + org.apache.maven.plugins + + maven-checkstyle-plugin + + ${checkstyle.version} + + ../checkstyle.xml + + src/main/java + + false + false + + + + + + + diff --git a/settings.xml b/settings.xml new file mode 100644 index 0000000..2a4ac94 --- /dev/null +++ b/settings.xml @@ -0,0 +1,24 @@ + + + + + + + + nexus.nclazz.de + https://nexus.nclazz.de/repository/maven-public + * + + + + + nexus.nclazz.de + ${env.NEXUS_USR} + ${env.NEXUS_PSW} + + + + + + \ No newline at end of file diff --git a/spotbugs-ignore.xml b/spotbugs-ignore.xml new file mode 100644 index 0000000..660c773 --- /dev/null +++ b/spotbugs-ignore.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file