Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Jenkinsfile 7.84 KiB
  @Library('common-shared') _

  pipeline {
    agent {
      kubernetes {
        label 'buildenv-agent-geoip'
        yaml '''
        apiVersion: v1
        kind: Pod
        spec:
          containers:
          - name: buildcontainer
            image: eclipsefdn/stack-build-agent:h111.3-n18.17-jdk17
            imagePullPolicy: Always
            command:
            - cat
            tty: true
            resources:
              requests:
                cpu: "1"
                memory: "4Gi"
              limits:
                cpu: "2"
                memory: "4Gi"
            env:
            - name: "HOME"
              value: "/home/jenkins"
            - name: "MAVEN_OPTS"
              value: "-Duser.home=/home/jenkins"
            volumeMounts:
            - name: m2-repo
              mountPath: /home/jenkins/.m2/repository
            - name: m2-secret-dir
              mountPath: /home/jenkins/.m2/settings.xml
              subPath: settings.xml
              readOnly: true
            - mountPath: "/home/jenkins/.m2/settings-security.xml"
              name: "m2-secret-dir"
              readOnly: true
              subPath: "settings-security.xml"
            - mountPath: "/home/jenkins/.mavenrc"
              name: "m2-dir"
              readOnly: true
              subPath: ".mavenrc"
            - mountPath: "/home/jenkins/.m2/wrapper"
              name: "m2-wrapper"
              readOnly: false
            - mountPath: "/home/jenkins/.cache"
              name: "yarn-cache"
              readOnly: false
            - mountPath: "/home/jenkins/.sonar"
              name: "sonar-cache"
              readOnly: false
          - name: jnlp
            resources:
              requests:
                memory: "1024Mi"
                cpu: "500m"
              limits:
                memory: "1024Mi"
                cpu: "1000m"
          volumes:
          - name: "m2-dir"
            configMap:
              name: "m2-dir"
          - name: m2-secret-dir
            secret:
              secretName: m2-secret-dir
          - name: m2-repo
            emptyDir: {}
          - name: m2-wrapper
            emptyDir: {}
          - name: yarn-cache
            emptyDir: {}
          - name: sonar-cache
            emptyDir: {}
        '''
      }
    }

    environment {
      APP_NAME = 'geoip-rest-api'
      NAMESPACE = 'foundation-internal-webdev-apps'
      IMAGE_NAME = 'eclipsefdn/geoip-rest-api'
      CONTAINER_NAME = 'app'
      ENVIRONMENT = sh(
        script: """
            printf "${env.BRANCH_NAME}"
        """,
        returnStdout: true
      )
      TAG_NAME = sh(
        script: """
          GIT_COMMIT_SHORT=\$(git rev-parse --short ${env.GIT_COMMIT})
          if [ "${env.ENVIRONMENT}" = "" ]; then
            printf \${GIT_COMMIT_SHORT}-${env.BUILD_NUMBER}
          else
            printf ${env.ENVIRONMENT}-\${GIT_COMMIT_SHORT}-${env.BUILD_NUMBER}
          fi
        """,
        returnStdout: true
      )
      LATEST_TAG_NAME = sh(
        script: """
          if [ "${env.ENVIRONMENT}" = "staging" ]; then
            printf latest-staging
          else
            printf latest
          fi
        """,
        returnStdout: true
      )
    }

    options {
      buildDiscarder(logRotator(numToKeepStr: '10'))
      timeout(time: 30, unit: 'MINUTES') 
    }

    triggers {
      // build once a week to keep up with parents images updates
      cron('H H * * H')
    }

    stages {
      stage('Compile GeoIP resources') {
        steps {
          container('buildcontainer') {
            readTrusted './bin/maxmind.sh'
  
            withCredentials([string(credentialsId: 'maxmind-license-key', variable: 'MAXMIND_LICENSE_KEY')]) {
              sh 'mkdir -p ./maxmind && ./bin/maxmind.sh $PWD/maxmind'
            }
            stash includes: 'maxmind/**/*', name: 'maxmind'
          }
        }
      }

      stage('Build with Sonarcloud scan') {
        when {
          branch 'main'
        }
        steps {
          container('buildcontainer') {
            readTrusted 'pom.xml'
            readTrusted 'Makefile'
            
            unstash 'maxmind'
            sh 'make compile-test-resources'

            withCredentials([string(credentialsId: 'sonarcloud-token-geoip-rest-api', variable: 'SONAR_TOKEN')]) {
              sh 'mvn -B clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \
                -Dsonar.host.url=https://sonarcloud.io \
                -Dsonar.login=${SONAR_TOKEN} \
                -Declipse.maxmind.root=${PWD}/maxmind \
                -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn'
            }
          }
        }
      }
      
      stage('Build without Sonarcloud scan') {
        when {
          not {
           branch 'main'
          }
        }

        steps {
          container('buildcontainer') {
            readTrusted 'pom.xml'
            
            unstash 'maxmind'
            
            sh 'make compile-java'
            
            // only no-scan builds can be deployed as we don't deploy main
            stash includes: 'target/', name: 'target'
          }
        }
      }

      stage('Build docker image') {
        agent {
          label 'docker-build'
        }
        when {
          anyOf {
            environment name: 'ENVIRONMENT', value: 'production'
            environment name: 'ENVIRONMENT', value: 'staging'
          }
        }
        steps {
          readTrusted 'src/main/docker/Dockerfile.jvm'

          unstash 'target'
          unstash 'maxmind'

          sh 'docker build -f src/main/docker/Dockerfile.jvm --no-cache -t ${IMAGE_NAME}:${TAG_NAME} -t ${IMAGE_NAME}:${LATEST_TAG_NAME} .'
        }
      }

      stage('Push docker image') {
        agent {
          label 'docker-build'
        }
        when {
          anyOf {
            environment name: 'ENVIRONMENT', value: 'production'
            environment name: 'ENVIRONMENT', value: 'staging'
          }
        }
        steps {
          withDockerRegistry([credentialsId: '04264967-fea0-40c2-bf60-09af5aeba60f', url: 'https://index.docker.io/v1/']) {
            sh '''
              docker push ${IMAGE_NAME}:${TAG_NAME}
              docker push ${IMAGE_NAME}:${LATEST_TAG_NAME}
            '''
          }
        }
      }

      stage('Deploy to cluster') {
        agent {
          kubernetes {
            label 'kubedeploy-agent'
            yaml '''
              apiVersion: v1
              kind: Pod
              spec:
                containers:
                - name: kubectl
                  image: eclipsefdn/kubectl:okd-c1
                  command:
                  - cat
                  tty: true
                  resources:
                    limits:
                      cpu: 1
                      memory: 1Gi
                  volumeMounts:
                  - mountPath: "/home/default/.kube"
                    name: "dot-kube"
                    readOnly: false
                - name: jnlp
                  resources:
                    limits:
                      cpu: 1
                      memory: 1Gi
                volumes:
                - name: "dot-kube"
                  emptyDir: {}
            '''
          }
        }

        when {
          anyOf {
            environment name: 'ENVIRONMENT', value: 'production'
            environment name: 'ENVIRONMENT', value: 'staging'
          }
        }
        steps {
          container('kubectl') {
            updateContainerImage([
              namespace: "${env.NAMESPACE}",
              selector: "app=${env.APP_NAME},environment=${env.ENVIRONMENT}",
              containerName: "${env.CONTAINER_NAME}",
              newImageRef: "${env.IMAGE_NAME}:${env.TAG_NAME}"
            ])
          }
        }
      }
    }

    post {
      always {
        deleteDir() /* clean up workspace */
        sendNotifications currentBuild
      }
    }
  }