[TOC]python
環境變量能夠被看做是pipeline與Jenkins交互的媒介。好比,能夠在pipeline中經過BUILD_NUMBER變量知道構建任務的當前構建次數。環境變量能夠分爲Jenkins內置變量和自定義變量。git
在pipeline執行時,Jenkins經過一個名爲env的全局變量,將Jenkins內置環境變量暴露出來。其使用方法有多種,示例以下:golang
pipeline { agent any stages { stage('Example') { steps { echo "Running ${env.BUILDNUMBER} on ${env.JENKINS_URL}" # 方法1 推薦 echo "Running $env.BUILDNUMBER on $env.JENKINS_URL" # 方法2 echo "Running ${BUILDNUMBER} on ${JENKINS_URL}" # 方法3 不推薦,難排查 } } } }
經過訪問<Jenkins master的地址>/pipeline-syntax/globals#env
來獲取完整列表。在列表中,當一個變量被聲明爲"For a multibranch project"時,表明只有多分支項目纔會有此變量。docker
下面簡單介紹幾個在實際工做中常常用到的變量。安全
BUILD_ NUMBER
:構建號,累加的數字。在打包時,它可做爲製品名稱的一部分,好比server-2.jar
。BRANCH_ NAME
:多分支pipeline項目支持。當須要根據不一樣的分支作不一樣的事情時就會用到,好比經過代碼將release分支發佈到生產環境中、master分支發佈到測試環境中。BUILD_ URL
:當前構建的頁面URL。若是構建失敗,則須要將失敗的構建連接放在郵件通知中,這個連接就能夠是BUILD _URL
。GIT_BRANCH
:經過git拉取的源碼構建的項目纔會有此變量。在使用env
變量時,須要注意不一樣類型的項目,env
變量所包含的屬性及其值是不同的。好比普通pipeline任務中的GIT_BRANCH
變量的值爲origin/master
,而在多分支pipeline任務中GIT_BRANCH
變量的值爲master
。
因此,在pipeline中根據分支進行不一樣行爲的邏輯處理時,須要留意。閉包
當pipeline變得複雜時,咱們就會有定義本身的環境變量的需求。聲明式pipeline提供了environment
指令,方便自定義變量。好比:oracle
pipeline { agent any environment { CC = "clang" } stages { stage("Example") { environment { DEBUG_FLAGS = "-g" } steps { sh "${CC} ${DEBUG_FLAGS}" sh "printenv" } } } }
environment
指令能夠用在pipeline中定義,做用域就是整個pipeline,當定義在stage
階段,只在當前stage
有效。maven
可是這些變量都不是跨pipeline的,好比pipeline a訪問不到pipeline b的變量。在pipeline之間共享變量能夠經過參數化pipeline來實現。ide
環境變量的互相引用:工具
environment { __server_name = 'mail-server' __version = "${BUILD_NUMBER}" __artifact_name = "${__server_name}-${__version}.jar" }
小技巧 :
sh 'printenv'
,將env
變量的屬性值打印出來。這樣能夠幫助咱們避免很多問題。__server_name
,__
就是前綴。定義全局環境變量能夠跨pipeline使用。
進入Jenkins→Manage Jenkins→Confiure System找到Global properties→勾選"Environment variables"複選框,單擊「Add」按鈕,在輸入框中輸入變量名和變量值便可。
自定義全局環境變量會被加入env
屬性列表中,因此使用時能夠直接用${env.g_name}
引用。
構建是指將源碼轉換成一個可以使用的二進制程序的過程。這個過程能夠包括但不限於這幾個環節:下載依賴、編譯、打包。構建過程的輸出——好比一個zip包,咱們稱之爲製品(有些書籍也稱之爲產出物)。而管理製品的倉庫,稱爲製品庫。
對構建工具的選擇,還取決於團隊對工具自己的接受程度。建議是,團隊中同一技術棧的全部項目都使用同一個構建工具。
tools
指令介紹tools
指令能幫助咱們自動下載並安裝所指定的構建工具,並將其加入PATH
變量中。這樣,咱們就能夠在sh
步驟裏直接使用了。但在agent none
的狀況下不會生效。
tools
指令默認支持3種工具:JDK、Maven、Gradle。經過安裝插件,tools
指令還能夠支持更多的工具。接下來,咱們介紹幾種經常使用的構建環境的搭建。
進入Manage Jenkins→Global Tool Configuration→JDK頁,單擊「Add JDK」:
注意
- 這裏須要oracle賬戶驗證。
- Jenkins不會立刻下載JDK,而是當pipeline使用到時纔會直接執行下載操做。
基於安全的考慮,公司的內網機器可能沒法直接訪問因特網,因此使用自動下載會失敗。這時就須要在Jenkins agent上準備JDK,而後在Manage Jenkins→Global Tool Configuration→JDK頁中指定名稱和JAVA_HOME
路徑:
注意
- 使用docker agent或者kubernetes agent時,可以使用agent基礎鏡像內安裝JDK定製成自定義鏡像。
- 能夠腳本自動化,即在使用
tools
安裝JDK前,腳本自動提早準備好這個JAVA_HOME
的JDK。
Jenkins pipeline的tools指令默認就支持Maven。因此,使用Maven只須要兩步。
進入Manage Jenkins→Global Tool Configuration→Maven頁,單擊「Add Maven」:
mvn
命令。Maven默認使用的是其官方倉庫,國內下載速度很慢。因此,咱們一般會使用國內的Maven鏡像倉庫。這時就須要修改 Maven 的配置文件 settings.xml
。settings.xml
文件的默認路徑爲${M2_HOME}/conf/settings.xml
。可是,咱們是不可能登陸上Jenkins的機器,而後手動修改這個文件的。
Config File Provider插件能很好地解決這個問題。只須要在Jenkins的界面上填入settings.xml
的內容,而後在pipeline中指定settings.xml
就能夠了。也就是說,對於不一樣的pipeline,可使用不一樣的settings.xml
。
具體實現方法以下:
單擊「Managed files」進入,在左側菜單欄中選擇「Add a new Config」,就會看到該插件支持不少種配置文件的格式及方式,
settings.xml
的內容粘貼到「Content」字段中,configFileProvider([configFile(fileId: "maven-global-settings", variable: "MAVEN_GLOBAL_ENV")]) { sh "mvn -s $MAVEN_GLOBAL_ENV clean install" }
Jenkins支持Golang的構建,只須要如下幾步。
tools
部分。pipeline { agent none environment { GOPATH = "${env.WORKSPACE}/" } tools { go 'go1.10' } stages { stage('build') { steps { sh "go build" } } } }
此時,在環境變量中會增長一個GOROOT
變量。
GOPATH
。瞭解Go語言開發的讀者都會知道,編譯時須要設置GOPATH
環境變量。直接在environment
指令中添加就能夠了。Python環境很容易產生Python版本衝突、第三方庫衝突等問題。因此,Python開發一般會進行工程級別的環境隔離,也就是每一個Python工程使用一個Python環境。
在Jenkins環境下,咱們使用Pyenv Pipeline插件能夠輕鬆地實現。
首先,準備Python基礎環境。
withPythonEnv
方法。withPythonEnv("/usr/bin/python") { sh "python --version" }
withPythonEnv
方法會根據第一個參數——可執行python路徑——在當前工做空間下建立一個virtualenv環境。withPythonEnv
方法的第二個參數是一個閉包。閉包內的代碼就執行在新建的virtualenv環境下。
不是全部的構建工具都須要安裝相應的Jenkins插件纔可使用。
平時,開發人員在搭建開發環境時作的就是:首先在機器上安裝好構建工具,而後將這個構建工具所在目錄加入PATH環境變量中。
若是想讓Jenkins支持更多的構建工具,也是一樣的作法:在Jenkins agent上安裝構建工具,並記錄下它的可執行命令的目錄,而後在須要使用此命令的Jenkins pipeline的PATH環境變量中加入該可執行命令的目錄。示例以下:
pipeline { agent none environment { PATH = "/usr/local/customtool/bin:$PATH" } stages { stage('build') { steps { sh "customtool build" } } } }
還能夠有另外一種寫法:
pipeline { agent none environment { CUSTOM_TOOL_HOME = "/usr/local/customtool/bin" } stages { stage('build') { steps { sh "${CUSTOM_TOOL_HOME}/customtool build" } } } }
在實際工做中,有時須要對同一份源碼使用多個版本的編譯器進行編譯。tools
指令除了支持pipeline做用域,還支持stage
做用域。因此,咱們能夠在同一個pipeline中實現多版本編譯。代碼以下:
pipeline { agent none stages { stage('build with jdk-10.0.2') { tools { jdk "jdk-10.0.2" } steps { sh "printenv" } } stage('build with jdk-9.0.4') { tools { jdk "jdk-9.0.4" } steps { sh "printenv" } } } }
在打印出來的日誌中,會發現每一個stage下的JAVA_HOME
變量的值都不同。
參考資料:
[1] 《Jenkins 2.x實戰指南》
[2] https://jenkins.io/zh/doc/book/pipeline/syntax/
[3] https://jenkins.io/zh/doc/pipeline/steps/