Jenkins集成必會技能——pipeline入門教程


作者:慧哥

一、什么是pipeline

什么是Pipeline?簡單來說,就是一套運行於Jenkins上的工作流框架,將原本獨立運行於單個或者多個節點的任務連接起來,實現單個任務難以完成的復雜發布流程(實用場景:將多個Jenkins構建任務輕松集成)

Pipeline的實現方式是一套Groovy DSL,任何發布流程都可以表述為一段Groovy腳本,並且Jenkins支持從代碼庫直接讀取腳本,從而實現了Pipeline as Code的理念。

使用條件

要使用Jenkins Pipeline,需要: Jenkins 2.x或更高版本、Pipeline插件

使用語言

Pipeline腳本是用Groovy寫的 。

二、pipeline在哪

首先確保Jenkins上已經有pipeline相關插件。如果想在Jenkins上新建一個pipeline Job,按照下列步驟操作:

1、單擊Jenkins主頁上的New Item。

2、輸入Pipeline的名稱,選擇Pipeline,然后單擊確定。

3、最后點擊完成,一個pipeline項目就生成了

三、一個簡單的pipeline腳本

pipeline項目中實際起作用的就是pipeline 腳本部分,這里寫一個HelloWorld,編輯后點擊保存,期望執行打印hello world操作。

由於這個腳本是無參數的,所以直接點擊Build Now就可以了,來查看一下構建結果,

可以看到最后輸出了期望的 Hello world!

這里對語法進行簡單介紹

Example

stages
pipeline {
   agent any
   stages {
       stage('Example') {
           steps {
               echo 'Hello World'
           }
       }
   }
}

agent

在任何可用的agent 上執行Pipeline或stage。例如:agent any

還有其他的agent后面可跟的參數,例如:none,label,node,docker

none

當在pipeline塊的頂層使用none時,將不會為整個Pipeline運行分配全局agent ,每個stage部分將需要包含其自己的agent部分。

label

使用提供的label標簽,在Jenkins環境中可用的代理上執行Pipeline或stage。例如:agent { label 'my-defined-label' }

node

agent { node { label 'labelName' } },等同於 agent { label 'labelName' },但node允許其他選項(如customWorkspace)。

docker

定義此參數時,執行Pipeline或stage時會動態供應一個docker節點去接受Docker-based的Pipelines。docker還可以接受一個args,直接傳遞給docker run調用。例如:agent { docker 'maven:3-alpine' }

stages

包含一個或多個stage的序列,Pipeline的大部分工作在此執行。建議stages至少包含至少一個stage指令,用於連接各個交付過程,如構建,測試和部署等。

steps

steps包含一個或多個在stage塊中執行的step序列。

總結:

1、Pipeline最基本的部分是“step”。基本上,step告訴Jenkins 要做什么,並且作為Declarative Pipeline和Scripted Pipeline語法的基本構建塊。

2、Pipeline支持兩種語法:Declarative Pipeline(在Pipeline 2.5中引入,結構化方式)和Scripted Pipeline,兩者都支持建立連續輸送的Pipeline。

3、所有有效的Declarative Pipeline必須包含在一個pipeline塊內,例如:

pipeline { /* insert Declarative Pipeline here */ }

4、Declarative Pipeline中的基本語句和表達式遵循與Groovy語法相同的規則 ,但有以下例外:

a.Pipeline的頂層必須是塊,具體來說是:pipeline { }

b.沒有分號作為語句分隔符。每個聲明必須在自己的一行

c.塊只能包含Sections, Directives, Steps或賦值語句。

四、pipeline實際實用意義

前文說了Pipeline是將原本獨立運行於單個或者多個節點的任務連接起來

我們來舉兩個例子

1、Git上拉取代碼:

在pipeline中有一個流水線語法,加入想去git上拉代碼,可以這么操作,點擊圖中的流水線語法,選擇git

填寫必要參數后,點擊成成流水線語法

然后將生成的流水線腳本粘貼進入steps里面,就可以完成git代碼的拉取了

jenkins會把代碼拉到Workspace+項目名+projdir的目錄下,當然也可以指定絕對路徑.

2、利用pipeline去執行自動化腳本

前置條件:我已經有一個job,用來執行我的回歸腳本,同時我的jmeter+ant+jenkins也已經集成好了,在那個job中,腳本的調用執行是通暢的

pipeline {
    agent any
    stages {
     stage ('Test'){
            steps{
                build job: 'hhh', 
                parameters: [[ $class: 'StringParameterValue', name:'ScriptName', value: 'hhh']]
                }
            }
    }
}

steps里面的第一行是調用的Job 第二行是我那個job下傳輸的參數

來看下執行結果

ps:pipeline可以結合實際情況,在pipeline語法中直接寫打包,部署,執行腳本完成整個流的工作,也可以通過現有的job,去調用job完成持續繼承。使用靈活,按需實操。

最后我們來看一下,如果結合了打包、部署、回歸,它的執行效果,有沒有感覺跟我們這篇文章的封面有異曲同工之處

 

 

出處:https://cloud.tencent.com/developer/article/1653828

=======================================================================================

pipeline的定義

  簡而言之,就是一套工作流框架,將原本獨立運行於單個或者多個節點的任務連接起來,實現單個任務難以完成的復雜流程編排與可視化。
  目前比較流行的pipeline實踐方式如下。

  • gitlabrunner: 是gitlab內置的一套pipeline框架,腳本是yml語言。
  • jenkins: 通過安裝插件的形式實現,腳本語言是jenkinsfile。

由於團隊中的代碼倉庫沒有使用gitlab,因此我這邊選擇了jenkins來實踐pipeline。

什么是jenkinsfile

  jenkinsfile 就是一個腳本文件,放在項目的根目錄下,能夠被jenkins識別並自動觸發pipeline流程,jenkinsfile的編寫可以參考jenkins官網:jenkinsfile語法

pipeline一期目標

  團隊第一期目標是:實現開發pod庫時提交代碼自動觸發單元測試,不同分支能執行不同的策略,執行不同的pipeline任務,能夠自動發布pod。pipeline失敗時能夠發送郵件進行通知,pipeline流成如下:
在這里插入圖片描述
jenkinsfile 腳本如下:

pipeline {
  agent any

  parameters {
     string(name: 'PROJECT_NAME', defaultValue: 'test_rootlib_ios', description:'')
  }

  stages {
    stage('prepare') {
      steps {
          sh './ci_prepare.sh' 
      }
      post {
          failure {
            post_email('prepare','fail')
          }
          aborted {
            post_email('prepare','aborted')
          }
      }
    }

    stage('unit_test') {
      steps {
        sh './ci_unit_test.sh'
      }
      post {
          failure {
            post_email('unit_test','fail')
          }
          aborted {
            post_email('unit_test','aborted')
          }
      }
    }

    stage('lib_lint') {
       when {
          branch 'dev'
       }
       steps {
          sh './lib_lint.sh'
       }
       post {
          failure {
            post_email('lib_lint','fail')
          }
          aborted {
            post_email('lib_lint','aborted')
          }
       }
    }

    stage('publish_pod') {
      when {
          branch 'dev'
       }
       steps {
          sh './repo_tag.sh'
       }
      post {
          failure {
            post_email('publish_pod','fail')
          }
          aborted {
            post_email('publish_pod','aborted')
          }
      }
    }
    stage('pipeline_end') {
      when {
          branch 'dev'
      }
      steps {
          echo 'pipeline_end'
      }
      post {
          success {
            post_email('pipeline_end','success')
          }
          failure {
            post_email('pipeline_end','fail')
          }
          aborted {
            post_email('pipeline_end','aborted')
          }
      }
    }

  }

}

def post_email(String stage, String status) {
  mail to: '12345678@qq.com',
  subject: "【${PROJECT_NAME}】${stage} ${status}",
  body: "build_id: ${env.BUILD_NUMBER}\nbranch: ${env.GIT_BRANCH}\nstage: ${stage}\nbuild_url: ${env.BUILD_URL}"
}

腳本思路:
1,每次提交時都會觸發pipeline,首先執行准備階段的任務主要是清理環境,pod install之類的操作。然后觸發單元測試。測試成功后沒有任何提示,測試失敗時會通過郵件進行通知
2,dev分支是發版分支,當pod准備要發布時,將版本號改好,然后先執行prepare階段的任務,然后執行單元測試,接着執行pod lint的任務,然后執行發版的操作,發版成功后會發送郵件進行通知。ps:后期會執行項目自動集成相關的工作。

blueOcean

blueOcean 是jenkins提供的可視化的形式編輯jenkinsfile的一個插件,大家可以體驗下,這里就不多說了,感覺剛開始入門的時候可以試試,可視化沒有直接在腳本上編輯流程靈活。
參考網址:blueOcean

遇到的坑點

郵箱

  在最開始的實踐是,本來打算用公司的郵箱進行通知,后來發現公司的郵箱不支持類似配置。我這邊選擇了163郵箱配置在jenkins上進行通知。

bundle exec命令

由於團隊中對組件化進行預編譯,實現了二進制形式的集成,在准備階段執行如下命令的時候一直報錯

bundle config set deployment 'true'
bundle install
bundle exec pod install --repo-update

后來參考網上,在jenkins進行了全局環境變量配置。
在這里插入圖片描述

內存不足

  最開始時候設置了pipeline的配置,當分支刪除時,對應的pipeline構建會被刪除,但是由於電腦配置太差,加上分支較多,出現了內存不足的現象。直接造成jenkins壞掉了,為了解決這個問題,我在jenkinsfile上寫了一個腳本定期去刪除項目中各個分支中的構建。
在這里插入圖片描述

腳本具體如下:

#!/bin/bash
cd ..
cd ..
cd jobs
projects=("項目名字" "項目名字" "項目名字" "項目名字")
for project in ${projects[*]}
do
#進入對應項目目錄
  cd $project
  project_dir=$(pwd)
  echo "project dir is:$project_dir"
  cd branches
  pwd=`pwd`
  filelist=`ls $dir`
  for biranch in $filelist:
  do
  #進入對應項目分支目錄
    cd biranch
    rm -rf builds
    mkdir builds
    cd ..
  done
  
  cd ..

done

更多干貨文章,掃描下方二維碼關注公眾號

 

 

出處:https://blog.csdn.net/hanhailong18/article/details/109861471

=======================================================================================

持續集成:Jenkins pipeline全局變量

在編寫Jenkins Pipeline腳本時,需要使用到一些全局變量,比如環境變量jenkins URL、項目地址,保存在env變量中(字符串類型),可以在Jenkins Pipeline或者其它Jenkinsfile中使用這些變量。本文介紹jenkins 中env、params、currentBuild和manager這幾種全局變量。

 

 

Jenkins 全局變量

Jenkins平台支持的全局變量可通過地址${JENKINS_URL}/pipeline-syntax/globals 訪問。主要包括以下全局變量:

  • env:在groovy代碼和 Jenkins pipeline中以 env.VARNAME 或直接以 VARNAME 的形式訪問環境變量。
  • params:將構建中定義的所有參數公開為具有不同類型值的只讀映射,通過params來訪問。
  • currentBuild:顧名思義,它處理Jenkins管道當前正在運行的構建。
  • managerGroovy Postbuild插件提供的全局變量。
  • docker:這是為了在一個Groovy腳本的Jenkins管道中提供方便的訪問docker相關函數。

下面來舉例說明如何使用。

下面的示例中,groovy腳本在Pipeline 共享庫中編寫,pipeline腳本直接在pipeline工程的pipeline輸入框中編寫。pipeline共享庫的定義可以參考 持續集成:Jenkins Pipeline共享庫定義和使用

env

查看環境變量

可通過多種方式查看jenkins可使用的環境變量:

  1. 訪問:${JENKINS_URL}/pipeline-syntax/globals
  2. 訪問:${JENKINS_URL}/env-vars.html/
  3. 使用windows bat命令:set
  4. 使用Linux/Unix shell命令:printenv

bat和shell命令可以在pipeline中編寫:

pipeline{
    agent {
        label "master"
        }
    stages{
		stage('Parallel Stage') {
		parallel {
		stage('windows') {
			agent {
				label "win_agent"
			}
			steps {
				bat 'set'  
			}
		}
		stage('linux') {
			agent {
				label "linux_agent"
			}
			steps {
				sh 'printenv' 
			}
		}
	}    
   }
   }
}

由於打印內容較多,這里就不展示結果了。這兩個命令除了返回jenkins平台的環境變量外,還會打印對應代理節點的環境變量。

使用環境變量

可以以 env.VARNAME 或直接以 VARNAME 的形式訪問環境變量。

pipeline腳本:

// @Library('pipelinelibs2@main') // Github庫 
@Library('pipelinelibs@1.0') _   // SVN庫

import com.hiyongz.MyLib

def mylib = new MyLib();

mylib.getJenkinsHome();

println "${JENKINS_HOME}";
println "${env.JENKINS_HOME}";

MyLib.groovy:

def getJenkinsHome(){
	println "${JENKINS_HOME}";
	println "${env.JENKINS_HOME}";
}

構建結果日志:

[Pipeline] echo
/var/jenkins_home
[Pipeline] echo
/var/jenkins_home
[Pipeline] echo
/var/jenkins_home
[Pipeline] echo
/var/jenkins_home
[Pipeline] End of Pipeline
Finished: SUCCESS

創建環境變量

除了讀取環境變量外,也可以對環境變量進行賦值或者創建新的環境變量。聲明環境變量可以使用以下3種方式:

  1. withEnv(["VARIABLE_NAME=value"]) {} , 腳本式流水線語法,可以覆蓋任何環境變量。
  2. env.VARIABLE_NAME :只能覆蓋以env.VARIABLE_NAME的方式創建的環境變量。
  3. environment { } ,聲明式流水線語法,不能以env.VARIABLE_NAME的方式覆蓋。

pipeline腳本:

// @Library('pipelinelibs2@main') // Github庫 
@Library('pipelinelibs@1.0') _   // SVN庫

import com.hiyongz.MyLib

def mylib = new MyLib();

env.MY_VERSION = '1.0'
mylib.myEnv();
println "MY_VERSION = ${MY_VERSION}";
println "MY_VERSION = ${env.MY_VERSION}";

pipeline{
    agent {
        label "master"
    }
	environment {
        ENV1 = "env1"
    }
    stages{	
	stage("Env Test") {
		environment {
			ENV1 = "env1_1" // 覆蓋environment{}塊創建的環境變量
			BUILD_NUMBER = "666" // 可以覆蓋以`env.VARIABLE_NAME`方式賦值的環境變量。
			
		}
		steps {
			println "ENV1 = ${env.ENV1}";
			println "BUILD_NUMBER = ${env.BUILD_NUMBER}";
			
			script {
				env.MY_VERSION = "2.0" // env.MY_VERSION會被覆蓋
				env.ENV1 = "env1_2"		// env.ENV1不會被覆蓋
			}
			
			println "ENV1 = ${env.ENV1}";
			println "MY_VERSION = ${env.MY_VERSION}";

			withEnv(["ENV1=env1_3"]) { // env.ENV1會被覆蓋
				echo "ENV1 = ${env.ENV1}"
			}
		}
	}
	}
}

MyLib.groovy:

def myEnv(){
	println "MY_VERSION = ${env.MY_VERSION}";
	println "MY_VERSION = ${MY_VERSION}";
}

構建結果日志:

MY_VERSION = 1.0
MY_VERSION = 1.0
MY_VERSION = 1.0
MY_VERSION = 1.0
ENV1 = env1_1
BUILD_NUMBER = 666
ENV1 = env1_1
MY_VERSION = 2.0
ENV1 = env1_3

新創建的環境變量在groovy也可以通過如下方式獲取:

def myEnv(){
	def jobVariables = currentBuild.getBuildVariables();
	println "${jobVariables.MY_VERSION}";
}

在pipeline script中創建的環境變量只能在當前pipeline工程中生效,如果想要設置全局環境變量,可以在jenkins系統配置中進行配置。

進入【Manage Jenkins】-> 【Configure System】-> 【Global properties】,新增環境變量,這里設置的環境變量是全局生效的。

params

對於參數的讀取可以使用params來訪問,groovy腳本中可以使用params.get()env.getProperty()方法來獲取:

def ParamDemo(){
	def deploy_env = params.get("DEPLOY_ENV") // or: params."${paramName}"
	println "DEPLOY_ENV = ${deploy_env}";
	
	def debug_build = env.getProperty("DEBUG_BUILD")
	println "DEBUG_BUILD = ${debug_build}";
}

pipeline腳本如下:

// @Library('pipelinelibs2@main') // Github庫 
@Library('pipelinelibs@1.0') _   // SVN庫

import com.hiyongz.MyLib
def mylib = new MyLib();

pipeline{
    agent {
        label "master"
    }
    parameters {
        string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') 
        text(name: 'DEPLOY_TEXT', defaultValue: 'One\nTwo\nThree\n', description: '') 
        booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '')
        choice(name: 'CHOICES', choices: ['one', 'two', 'three'], description: '')
        password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'A secret password')
    }
    stages{	
	stage("Param Test") {
		steps {
		    script {
			println "DEPLOY_ENV = ${params.DEPLOY_ENV}";
            mylib.ParamDemo();
		    }			
		}
	}
	}
}

構建結果:

DEPLOY_ENV = staging
[Pipeline] echo
DEPLOY_ENV = staging
[Pipeline] echo
DEBUG_BUILD = true

currentBuild

currentBuild變量可以用來獲取當前構建的一些屬性,比如absoluteUrl、projectName、result等,更多支持的屬性方法可以訪問:${JENKINS_URL}/pipeline-syntax/globals

pipeline{
    agent {
        label "master"
    }
    stages{	
	stage("Param Test") {
		steps {
		    script {
			    println "build number: ${currentBuild.number}";
			    println "current result: ${currentBuild.currentResult}";
			    println "build URL: ${currentBuild.absoluteUrl}";
		    }			
		}
	}
	}
}

manager

manager是Groovy Postbuild插件提供的全局變量,用於構建后操作,它是在jenkins JVM 中執行groovy腳本。可用來更改構建結果,顯示構建摘要信息等,下面來舉幾個例子。

1、addShortText方法

語法:addShortText(text, color, background, border, borderColor)

pipeline {
    agent {
        label 'master'
    } 
    stages {
        stage('manager usage') {
            steps {
                script {
                    manager.addShortText("hello world",'black','lightgreen','5px','yellow')
                    currentBuild.description = "Foreground: black\n"
                    currentBuild.description += "Background: lightgreen\n"
                    currentBuild.description += "Border size: 5px\n"
                    currentBuild.description += "Border color: yellow" 
                }
            }
        }
    }
}

效果如下圖:

2、添加徽章圖標

添加刪除圖標相關方法:

  • addBadge(icon, text)
  • addBadge(icon, text, link)
  • addWarningBadge(text)
  • addErrorBadge(text)
  • addHtmlBadge(html)
  • removeBadges()
  • removeBadge(index)

還可以設置構建結果:

  • buildUnstable() - 設置構建結果為 UNSTABLE.
  • buildFailure() -設置構建結果為 FAILURE.
  • buildSuccess() - 設置構建結果為 SUCCESS.

pipeline腳本舉例:

pipeline {
    agent {
        label 'master'
    } 
    stages {
        stage('manager usage') {
            steps {
                script {
                    echo "buildFailure test"
                }
            }
        }
    }
    post {
        always {
            script {
                if(manager.logContains(".*buildFailure.*")) {
                    manager.addWarningBadge("build Failure.")
                    manager.buildFailure()
                }                
                if(manager.build.result.isBetterOrEqualTo(hudson.model.Result.UNSTABLE)) {
                    manager.addBadge("success.gif", "success")
                } else {
                    manager.addBadge("error.gif", "failed")
                }
                manager.addBadge("text.gif", "console output","${currentBuild.absoluteUrl}/console")
            }
        }
            
    }
}

構建效果圖:

注意Groovy Postbuild 在2.0版本以后引入了 Script Security Plugi,對一些非白名單方法(比如上述腳本使用到的logContains、build方法)需要管理員同意,可以進入【Manage Jenkins】 > 【In-process Script Approval】同意相關方法:

參考資料:

  1. https://plugins.jenkins.io/groovy-postbuild/
  2. https://javadoc.jenkins-ci.org/index-core.html
--THE END--

欲忘忘未得,欲去去無由。——唐·白居易 《寄遠》

 

出處:https://blog.csdn.net/u010698107/article/details/123307911

=======================================================================================

 

出處:https://blog.csdn.net/u010698107/category_10842276.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM