14 Mart 2022 Pazartesi

Jenkinsfile Declarative Pipeline - Yeni Yöntem

Giriş
Açıklaması şöyle. Stage'ler içinde step'ler olabilir.
Declarative pipelines always begin with the word pipeline.
...
Declarative pipelines break down stages into individual stages that can contain multiple steps.
Groovy kullanmaz.  Açıklaması şöyle
In contrast to the scripted pipeline, the declarative Jenkins pipeline doesn't permit a developer to inject code. A Groovy script or a Java API reference in a declarative pipeline will cause a compilation failure.
Stages -> stage -> steps -> post -> failure
şeklinde bir sıra izlenir

Pipeline Block
Burada agent, stages, options vs belirtiliyor
agent Blok
Örnek - any
Şöyle yaparız
pipeline {
  agent any
  stages {
    stage('Build') {
      steps {
      }
  }
  ...
}
Örnek - none
Şöyle yaparız
pipeline {
    agent none
    stages {
      ...
      stage('build image') {
        agent { label "slave" }
        ...
    }

    stage('deploy to production') {
      agent { label "master" }
      ...
      }
    }
  }
}
Açıklaması şöyle
Let’s start with agent where certain phase will be executed. It can be the entire pipeline or certain stage. At top level agent, we set it to none so we need to set each stage what agent we want to use.
Örnek - master
Şöyle yaparız
pipeline {

  agent {
    node {
      label 'master'
    }
  }

  options {
    buildDiscarder logRotator( 
      daysToKeepStr: '16', 
      numToKeepStr: '10'
    )
  }

  stages {
    ...
  }   
}
Örnek - docker
Şöyle yaparız
agent {
  docker {
    image 'alxibra/forstok-apigateway:0.0.1'
    label 'slave'
  }
}
Açıklaması şöyle
It means we run our stage in docker environment with base image alxibra/forstok-apigateway:0.0.1 . label means which server with certain label you want to execute. we have 2 servers to run Jenkins, we label our server with master and slave .
tools
Tool alanı altında Jenkins'e kurulu bir plugin ismi ve onunla ilgili bir ayar verilir.
Örnek
Şöyle yaparız. Burada Jenkins'e JDK plugin kurulu ve plugine tanıtılmış olan JDK kurulumlarından birisi olan Java17'yi kullanması isteniyor.
pipeline {
  agent any
    
  tools {
    jdk 'Java17'
  }
    
  stages {
    stage('...) {
      steps {
        ...
      }
    }
  }
}
options
Örnek
Şöyle yaparız
pipeline {

  options {
    ansiColor('xterm')
  }
  ...
  stages {
    ...
  }
}
Stage Block
stage block içinde başka stage block olabilir.

environment
credentials vs gibi şeyler belirtilir
Örnek - credentials
Şöyle yaparız. "Manage Jenkins > Security > Manage Credentials" ayarlarında tanımlıdır
stage ('QA') {
  parallel {
    stage('test') {
      ...

    environment {
      DATABASE_NAME_TEST = credentials('DATABASE_NAME_TEST')
      DATABASE_USERNAME_TEST = credentials('DATABASE_USERNAME_TEST')
      DATABASE_PASSWORD_TEST = credentials('DATABASE_PASSWORD_TEST')
      DATABASE_PORT_TEST = credentials('DATABASE_PORT_TEST')
      DATABASE_HOST_TEST = credentials('DATABASE_HOST_TEST')
      LAZADA_CLIENT_SECRET = credentials('LAZADA_CLIENT_SECRET')
      DISABLE_RATE_LIMIT = 'true'
    }
    steps {
      ...
    }
  }
}
parallel
Birden fazla stage paralel çalıştırılabilir. 
Örnek
Şöyle yaparız
stage('QA'){
  parallel {
    stage('linter'){
      .......
    }
    stage('test') {
      ........
    }
  }
}
post
Açıklaması şöyle
post section is additional step after certain stage is done or fail. We define 2 conditions the success and failure . They both send notification to our slack the status. 
Örnek
Şöyle yaparız
stage('deploy to production') {
      
  steps {
   ...
  }
  post {
    success {
      slackSend message: "${env.JOB_NAME} is success, info: ${env.BUILD_URL}",
                    color: 'good'
    }
    failure {
      slackSend message: "${env.JOB_NAME} fails, info: ${env.BUILD_URL}",
                    color: 'danger'
    }
  }
}

when Directive
stage içine yazılır. Stage'in çalışıp çalışmamasına karar verir
Örnek
Şöyle yaparız
stage('deploy to production') {
  agent { label "master" }
  when {
    branch 'master'
  }
  ...
}
Örnek - not
Şöyle yaparız
when {
  not {
    branch 'master'
  }
}
Steps Block
Çalıştırılacak komutları içerir
Örnek
Şöyle yaparız
steps('test') {
  sh 'bundle exec rspec'
}
withCredentials
Örnek
Şöyle yaparız
steps {
  withCredentials([file(credentialsId: 'APIGATEWAY_MASTER_KEY', variable: 'master_key')]){
    sh 'sudo cp /$master_key config/master.key'
    sh 'bin/production'
  }
}

Kullanım Örnekleri
git
Örnek
Şöyle yaparız
pipeline {
  agent { label 'node-1' }
  stages {
    stage('Source') {
      steps {
        git 'https://github.com/digitalvarys/jenkins-tutorials.git''
      }
    }
    stage('Compile') {
      tools {
        gradle 'gradle4'
      }
      steps {
        sh 'gradle clean compileJava test'
      }
    }
  }
}
junit
Örnek
Şöyle yaparız. Burada make build sistemi kullanılıyor.
pipeline { 
  agent any 
  options {
    skipStagesAfterUnstable()
  }
  stages {
    stage('Build') { 
      steps { 
        sh 'make' 
      }
    }
    stage('Test'){
      steps {
        sh 'make check'
        junit 'reports/**/*.xml' 
      }
    }
    stage('Deploy') {
      steps {
        sh 'make publish'
      }
    }
  }
}
maven
tools altında maven tanımlanır
Örnek
Şöyle yaparız
CODE_CHANGES = getGitCodeChanges()
pipeline { agent any //Hangi Jenkins üzerine çalışacak tools { maven 'Maven' } parameters { string(name : 'VERSION', defaultValue:'', description:'') choice(name : 'VERSIONS', choices['1.1.0','1.2.0'],description:'') booleamParam(name:'executeTests' defaultValue : true,description:'') } environment { NEW_VERSION = '1.3.0' } stages { stage("build") { //checkout, build , test, deploy, cleanup gibi when { expression { BRANCH_NAME == 'dev'&& CODE_CHANGES == true } } steps { echo "Building version ${NEW_VERSION}" //double quote because of variable sh "mvn install" } } stage("test") { when { expression { params.executeTests } } steps { echo 'Testing...' } }
Şöyle yaparız
pipeline {
  agent any
  tools {
	maven 'mvn'
	//version 3.0.5
  }
  stages {
    stage('unit test') {
      steps {
      echo "Environment selected: ${params.envSelected}"
      sh 'mvn test -Punit-tests'
      }
      post {
        failure {
          mail to: 'vivek.sinless@gmail.com',
          subject: 'Dude your Azuga-RUC Pipeline failed. Check your Unit Tests',
          body: 'Unit Test Cases Failure'
        }
      }
    }
    stage('integration test') {
      steps {
        echo "Environment selected: ${params.envSelected}"
        sh 'mvn test -Pintegration-tests'
      }
      post {
        failure {
          mail to: 'vivek.sinless@gmail.com',
          subject: 'Dude your Azuga-RUC Pipeline failed. Check your integration tests',
          body: 'Integration Test Cases Failure'
        }
      }
    }
    stage('SonarQube Analysis') {
      steps {
        //def mvn = tool 'mvn';
        withSonarQubeEnv('sonar') {
          sh "mvn sonar:sonar"
        }
      }
    }
    stage('Build Jars') {
      steps {
        sh 'mvn clean package'
      }
    }
  } //stages
} //pipeline
Örnek
Şöyle yaparız. Böylece bir mvn komutu çalıştırılır
withMaven() {
  sh 'mvn dockerfile:build dockerfile:push exec:exec'
}
Örnek - maven + docker
Şöyle yaparız
pipeline {
  agent any  
  environment {
    MAVEN_ARGS=" -e clean install"
    registry = ""
    dockerContainerName = 'bookapi'
    dockerImageName = 'bookapi-api'
  }
  stages {
    stage('Build') {
      steps {
         withMaven(maven: 'MAVEN_ENV') {
           sh "mvn ${MAVEN_ARGS}"
        }
      }
    }
     
    stage('clean container') {
      steps {
        sh 'docker ps -f name=${dockerContainerName} -q | xargs --no-run-if-empty docker container stop'
        sh 'docker container ls -a -f name=${dockerContainerName} -q | xargs -r docker container rm'
        sh 'docker images -q --filter=reference=${dockerImageName} | xargs --no-run-if-empty docker rmi -f'
      }
    }
    stage('docker-compose start') {
      steps {
       sh 'docker compose up -d'
      }
    }
  }
}

parameters 
Örnek
Şöyle yaparız
pipeline {
  agent any
  tools {
	maven 'mvn'
	//version 3.0.5
  }
  parameters {
    choice(
	  name: 'envSelected',
	  choices: ['dev', 'test', 'prod'],
	  description: 'Please choose en environment where you want to run?'
    )
  }
  
} //pipeline
Şeklen şöyle
Kullanımı şöyle
stage('Run Spring Boot App') {
  steps {
    script {
      if (env.envSelected == "dev" || env.envSelected == "test") {
        ...
      } else {
        ...
      }
    }
  }
}

sonar
Örnek - gradle
Şöyle yaparız
apipeline {

  agent any

  options {
    timeout(time: 20, unit: 'MINUTES')
    buildDiscarder(logRotator(numToKeepStr: '5'))
  }
  

  environment {
    JAVA_HOME='/home/ajanthan/applications/jdk-11.0.2'

    SOURCE_REPOSITORY_URL = '<GIT_URL>'
    BRANCH = 'develop'
    GIT_CREDINTIALS_ID='<GIT_CRED>'
    
    SONAR_URL='http://localhost:9000'
    SONAR_LOGIN='<SONAR_QUBE_TOKEN>'

  }

  stages {

    stage ('Checkout source') {
      steps {
        echo "Checkout SCM"
        git branch: "${BRANCH}",credentialsId: "${GIT_CREDINTIALS_ID}",url: "${SOURCE_REPOSITORY_URL}"
      }
    }
    
    stage ('Gather facts') {
      steps {
          script {
    
          version = sh (script: "./gradlew properties -q | grep \"version:\" | awk '{print \$2}'",returnStdout: true).trim();
          groupid = sh (script: "./gradlew properties -q | grep \"group:\" | awk '{print \$2}'",returnStdout: true).trim();
          artifactId = sh (script: "./gradlew properties -q | grep \"name:\" | awk '{print \$2}'",returnStdout: true).trim();
    
          }
          echo "Building project in version: $version , groupid: $groupid , artifactId : $artifactId";
        }
    }

    stage ('Build JAR') {
       steps {
        echo "Building version ${version}"
        sh (script: "./gradlew clean build -x test",returnStdout: true)
       }
    }

     stage ('Unit Tests') {
       steps {
         echo "Running Unit Tests"
         sh (script: "./gradlew test",returnStdout: true)
       }
     }
     
     stage ('Code Analysis') {
       steps {
        echo "Running Code Analysis"

        sh (script: "./gradlew sonarqube -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.sources=./src/main -Dsonar.projectKey=$artifactId  -Dsonar.projectVersion=$version",returnStdout: true)

       }
     }
     

    }
}
s

Hiç yorum yok:

Yorum Gönder