From 4c0418a02a6e2072d106d811b012b86cd1999c64 Mon Sep 17 00:00:00 2001 From: Philipp Markiewka Date: Mon, 26 Oct 2020 15:11:32 +0100 Subject: [PATCH] Init for gitops flow --- Jenkinsfile | 67 ++++++++++++++++--- pom.xml | 5 ++ .../owner/OwnerControllerITCase.java | 24 +++---- 3 files changed, 73 insertions(+), 23 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 29f8660e2..15a7a43a5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,19 +1,38 @@ #!groovy -@Library('github.com/cloudogu/ces-build-lib@1.35.1') -import com.cloudogu.ces.cesbuildlib.* + +// "Constants" +String getCesBuildLibVersion() { '1.44.3' } +String getCesBuildLibRepo() { 'https://github.com/cloudogu/ces-build-lib/' } +String getAppDockerRegistry() { 'eu.gcr.io/cloudogu-backend' } +String getCloudoguDockerRegistry() { 'ecosystem.cloudogu.com' } +String getRegistryCredentials() { 'jenkins' } +String getScmManagerCredentials() { 'jenkins' } +String getKubectlImage() { 'lachlanevenson/k8s-kubectl:v1.18.2' } +String getJdkImage() { 'bellsoft/liberica-openjdk-alpine' } +String getHelmImage() { "${cloudoguDockerRegistry}/build-images/helm-kubeval:gcl308.0.0-alpine-helmv3.3.1" } +String getKubevalImage() { 'garethr/kubeval:0.15.0' } +String getGitVersion() { '2.24.3' } +String getConfigRepositoryUrl() { "https://ecosystem.cloudogu.com/scm/repo/backend/k8s-gitops" } +String getConfigRepositoryPRUrl() { 'ecosystem.cloudogu.com/scm/api/v2/pull-requests/backend/k8s-gitops' } +String getDockerRegistryBaseUrl() { "https://console.cloud.google.com/gcr/images/cloudogu-backend/eu/${application}.cloudogu.com" } +String getHelmReleaseChartSourceUrl() { "ssh://k8s-git-ops@ecosystem.cloudogu.com:2222/repo/backend/myCloudogu-helm-chart" } +// Redundant definition of helm repo, because Flux connects via SSH and Jenkins via HTTPS. Best would be to use SSH on Jenkins -> No redundancy +String getHelmChartRepoSourceUrl() { "https://ecosystem.cloudogu.com/scm/repo/backend/myCloudogu-helm-chart" } +String getHelmChartTag() { "1.0.4" } properties([ // Don't run concurrent builds, because the ITs use the same port causing random failures on concurrent builds. disableConcurrentBuilds() ]) +cesBuilbLib = library(identifier: "ces-build-lib@${cesBuildLibVersion}", + retriever: modernSCM([$class: 'GitSCMSource', remote: cesBuildLibRepo]) +).com.cloudogu.ces.cesbuildlib +def git = cesBuilbLib.Git.new(this, scmManagerCredentials) + node { - String cesFqdn = findHostName() - String cesUrl = "https://${cesFqdn}" - String credentialsId = 'scmCredentials' - - Maven mvn = new MavenWrapper(this) + mvn = cesBuilbLib.MavenWrapper.new(this) catchError { @@ -41,18 +60,44 @@ node { stage('Static Code Analysis') { - def sonarQube = new SonarQube(this, [usernamePassword: credentialsId, sonarHostUrl: "${cesUrl}/sonar"]) - sonarQube.analyzeWith(mvn) + } + + stage('Docker') { + if (isBuildSuccessful()) { + def docker = cesBuilbLib.Docker.new(this) + + String imageTag = createImageTag() + imageName = "docker-registry:9092/petclinic-plain:${imageTag}" + def dockerImage = docker.build(imageName) + dockerImage.push() + } else { + echo 'Skipping docker push, because build not successful or neither on develop branch nor "forceDeployStaging" param set' + } } stage('Deploy') { - mvn.useDeploymentRepository([id: cesFqdn, url: "${cesUrl}/nexus", credentialsId: credentialsId, type: 'Nexus3']) - mvn.deployToNexusRepository('-Dmaven.javadoc.failOnError=false') } } // Archive Unit and integration test results, if any junit allowEmptyResults: true, testResults: '**/target/failsafe-reports/TEST-*.xml,**/target/surefire-reports/TEST-*.xml' } + + +/** + * Reflect build parameters version name. + * This is meant to support GitOps PR reviewers to avoid releasing versions not meant for production. + */ +String createImageTag() { + def git = cesBuilbLib.Git.new(this) + String branch = git.simpleBranchName + String branchSuffix = "" + + if (!"develop".equals(branch)) { + branchSuffix = "-${branch}" + } + + return "${new Date().format('yyyyMMddHHmm')}-${git.commitHashShort}${branchSuffix}" +} diff --git a/pom.xml b/pom.xml index e4e74747a..8def0edf4 100644 --- a/pom.xml +++ b/pom.xml @@ -131,6 +131,11 @@ spring-boot-devtools true + + junit + junit + test + diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerITCase.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerITCase.java index 3ffd69ce0..7ea5bd845 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerITCase.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerITCase.java @@ -1,6 +1,5 @@ package org.springframework.samples.petclinic.owner; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -14,16 +13,17 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class OwnerControllerITCase { - @Autowired - private TestRestTemplate restTemplate; + @Autowired + private TestRestTemplate restTemplate; + + /** + * Note: This test exists only for the purpose of serving as an example! Please write + * tests more sensible than this for your own applications. + */ + @Test + public void assertsUser1IsGeorgeFranklin() { + String body = this.restTemplate.getForObject("/owners/1", String.class); + assertThat(body).contains("George Franklin"); + } - /** - * Note: This test exists only for the purpose of serving as an example! Please write tests more sensible - * than this for your own applications. - */ - @Test - public void assertsUser1IsGeorgeFranklin() { - String body = this.restTemplate.getForObject("/owners/1", String.class); - assertThat(body).contains("George Franklin"); - } }