《Jenkins 2.x實踐指南》讀書筆記-環境變量與構建工具

[TOC]python

1. 環境變量

環境變量能夠被看做是pipeline與Jenkins交互的媒介。好比,能夠在pipeline中經過BUILD_NUMBER變量知道構建任務的當前構建次數。環境變量能夠分爲Jenkins內置變量和自定義變量。git

1.1 內置變量

在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中根據分支進行不一樣行爲的邏輯處理時,須要留意。閉包

1.2 自定義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"
}

小技巧 :

  1. 在調試pipeline時,能夠在pipeline的開始階段加一句:sh 'printenv',將env變量的屬性值打印出來。這樣能夠幫助咱們避免很多問題。
  2. 自定義變量時,爲避免命名衝突,可根據項目或公司加上統一前綴,如__server_name__就是前綴。

1.3 自定義全局環境變量

定義全局環境變量能夠跨pipeline使用。
進入Jenkins→Manage Jenkins→Confiure System找到Global properties→勾選"Environment variables"複選框,單擊「Add」按鈕,在輸入框中輸入變量名和變量值便可。

添加自定義全局變量

自定義全局環境變量會被加入env屬性列表中,因此使用時能夠直接用${env.g_name}引用。

2. 構建工具

構建是指將源碼轉換成一個可以使用的二進制程序的過程。這個過程能夠包括但不限於這幾個環節:下載依賴、編譯、打包。構建過程的輸出——好比一個zip包,咱們稱之爲製品(有些書籍也稱之爲產出物)。而管理製品的倉庫,稱爲製品庫。

2.1 構建工具的選擇

對構建工具的選擇,還取決於團隊對工具自己的接受程度。建議是,團隊中同一技術棧的全部項目都使用同一個構建工具。

2.2 tools指令介紹

tools指令能幫助咱們自動下載並安裝所指定的構建工具,並將其加入PATH變量中。這樣,咱們就能夠在sh步驟裏直接使用了。但在agent none的狀況下不會生效。

tools指令默認支持3種工具:JDK、Maven、Gradle。經過安裝插件,tools指令還能夠支持更多的工具。接下來,咱們介紹幾種經常使用的構建環境的搭建。

2.3 JDK環境搭建

2.3.1 自動安裝JDK

進入Manage Jenkins→Global Tool Configuration→JDK頁,單擊「Add JDK」:

添加jdk

注意

  1. 這裏須要oracle賬戶驗證。
  2. Jenkins不會立刻下載JDK,而是當pipeline使用到時纔會直接執行下載操做。

2.3.2 自定義JDK路徑

基於安全的考慮,公司的內網機器可能沒法直接訪問因特網,因此使用自動下載會失敗。這時就須要在Jenkins agent上準備JDK,而後在Manage Jenkins→Global Tool Configuration→JDK頁中指定名稱和JAVA_HOME路徑:

指定JDK路徑

注意

  1. 使用docker agent或者kubernetes agent時,可以使用agent基礎鏡像內安裝JDK定製成自定義鏡像。
  2. 能夠腳本自動化,即在使用tools安裝JDK前,腳本自動提早準備好這個JAVA_HOME的JDK。

2.4 Maven

2.4.1 使用Maven進行構建

Jenkins pipeline的tools指令默認就支持Maven。因此,使用Maven只須要兩步。

  1. 進入Manage Jenkins→Global Tool Configuration→Maven頁,單擊「Add Maven」:
    添加maven-3.5.4

  2. 在Jenkinsfile中指定Maven版本,並使用mvn命令。

2.4.2 使用Managed files設置Maven

Maven默認使用的是其官方倉庫,國內下載速度很慢。因此,咱們一般會使用國內的Maven鏡像倉庫。這時就須要修改 Maven 的配置文件 settings.xmlsettings.xml 文件的默認路徑爲${M2_HOME}/conf/settings.xml。可是,咱們是不可能登陸上Jenkins的機器,而後手動修改這個文件的。
Config File Provider插件能很好地解決這個問題。只須要在Jenkins的界面上填入settings.xml的內容,而後在pipeline中指定settings.xml就能夠了。也就是說,對於不一樣的pipeline,可使用不一樣的settings.xml
具體實現方法以下:

  1. 安裝Config File Provider插件。
  2. 進入Manage Jenkins頁面,就能夠看到多出一個「Managed files」菜單。
  3. 單擊「Managed files」進入,在左側菜單欄中選擇「Add a new Config」,就會看到該插件支持不少種配置文件的格式及方式,
    Config Files

  4. 選擇「Global Maven settings.xml」選項。由於咱們的設置是全局的。填寫「ID」字段,Jenkins pipeline會引用此變量名。假如使用的ID爲maven-global-settings。
  5. 在編輯頁將自定義的Maven settings.xml的內容粘貼到「Content」字段中,

Edit Configuration File

  1. 在Jenkins pipeline中使用的方法以下:
configFileProvider([configFile(fileId: "maven-global-settings", variable: "MAVEN_GLOBAL_ENV")]) {
    sh "mvn -s $MAVEN_GLOBAL_ENV clean install"
}

2.5 Go語言環境搭建

Jenkins支持Golang的構建,只須要如下幾步。

  1. 安裝Go插件
  2. 進入Manage Jenkins→Global Tool Configuration→Go頁

添加go

  1. 在pipeline中加入tools部分。
pipeline {
    agent none
    environment {
        GOPATH = "${env.WORKSPACE}/"
    }
    tools {
        go 'go1.10'
    }    
    stages {
        stage('build') {
            steps {
                sh "go build"
            }
        }
    }
}

此時,在環境變量中會增長一個GOROOT變量。

  1. 設置GOPATH。瞭解Go語言開發的讀者都會知道,編譯時須要設置GOPATH環境變量。直接在environment指令中添加就能夠了。

2.6 Python環境搭建

Python環境很容易產生Python版本衝突、第三方庫衝突等問題。因此,Python開發一般會進行工程級別的環境隔離,也就是每一個Python工程使用一個Python環境。

在Jenkins環境下,咱們使用Pyenv Pipeline插件能夠輕鬆地實現。
首先,準備Python基礎環境。

  1. 在Jenkins機器上安裝python、pip、virtualenv。
    • pip:Python的包管理工具。
    • virtualenv:Python中的虛擬環境管理工具。
  2. 安裝Pyenv Pipeline插件。
    而後,在pipeline中使用Pyenv Pipeline插件提供的withPythonEnv方法。
withPythonEnv("/usr/bin/python") {
    sh "python --version"
}

withPythonEnv方法會根據第一個參數——可執行python路徑——在當前工做空間下建立一個virtualenv環境。
withPythonEnv方法的第二個參數是一個閉包。閉包內的代碼就執行在新建的virtualenv環境下。

3. 利用環境變量支持更多的構建工具

不是全部的構建工具都須要安裝相應的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"
            }
        }
    }
}

4. 利用tools做用域實現多版本編譯

在實際工做中,有時須要對同一份源碼使用多個版本的編譯器進行編譯。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/

相關文章
相關標籤/搜索