Jenkins實踐指南-09-pipeline 擴展

5. pipeline 擴展

    [作者:Surpassme]如果在大量使用pipelin後,會發現Jenkins內置的功能並不能滿足我們的需求,這時就需要pipeline 擴展。

5.1 pipeline中使用函數

    [作者:Surpassme]pipeline本質上就是一個Groovy腳本。因此,也可以在pipeline中定義函數,這樣就可以使用Groovy的特性了。示例如下所示:

// 定義一個函數
def hello(name="Kevin"){
    return "Hello,${name}"
}

pipeline{
    agent any
    options{
        timestamps()
    }
    stages{
        stage("pipeline extend demo"){
            steps{
                // 調用函數
                echo "${hello('Surpass')}"
            }
        }
    }
}

    [作者:Surpassme]另外也可以將變量定義在environment中,如下所示:

// 定義一個函數
def hello(name="Kevin"){
    return "Hello,${name}"
}

pipeline{
    agent any
    options{
        timestamps()
    }
    environment{
        // 調用函數
        HELLO=hello("Surpass")
    }
    stages{
        stage("pipeline extend demo"){
            steps{
                echo "${env.HELLO}"
            }
        }
    }
}

    運行結果如下所示:

5.2 使用共享庫

    [作者:Surpassme]如果在pipeline中定義的函數具有通用性,那很可能另外一個pipeline也會使用,這個時候該怎麼辦呢?針對這一問題,Jenkins提供了共享庫(Shared Library)功能,從而可以將重複代碼定義一個獨立的代碼倉庫中,其他的pipeline通過摘取加載使用,達到共享功能

5.2.1 目錄結構

    共享庫存儲庫的目錄結構如下:

|--src
|    └──org
|        └──foo
|            └──Bar.groovy # org.foo.Bar 類
|--vars
|    └──foo.groovy  # 全局變量 foo
|    └──foo.txt     # 全局變更 foo 幫助文檔
|--resources
|    └──org
|        └──foo
|            └──bar.json #

    以上各目錄詳細解釋如下所示:

  • src: 該目錄是一個標準的Java源碼結構。目錄中的類稱這爲庫類,在執行pipeline時,將被添加到classpath路徑中,文件格式爲.groovy

在pipeline中使用時@Library("surpass-shared-library") _,其中-代表一次性靜態加載src目錄下所有代碼到classpath中

  • vars:該目錄用於存放pipeline可以直接使用的全局變量

    [作者:Surpassme]假設現在有一個文件名var/log.groovy,其文件內容如下所示:

// vars/logger.groovy

def info(message){
    println "message is ${message}"
}

    在pipeline中,我們可以這樣進行調用

  logger.info "Hello,Surpass"

    其注意事項如下所示:

  • 1.每個groovy文件應該是一個Groovy標識符,遵循camelCased命名規範

  • 2.存在相應的使用幫助文檔,可以HTML、Markdown等,但卻需要以.txt做爲擴展名

  • resources:該目錄允許從外部庫中使用該步驟libraryResource來加載相關聯的非groovy文件。目前暫內部庫不支持該功能

以上參考來自於:https://www.jenkins.io/doc/book/pipeline/shared-libraries/

5.2.2 創建共享庫

    [作者:Surpassme]按共享庫目錄分別創建文件,如下所示:

// src/org/surpass/SharedLibrarySample.groovy

package org.surpass

class SharedLibrarySample{
   String name
   String location

   SharedLibrarySample(String name,String location){
        this.name=name
	    this.location=location
   }

   def greet(){
      return "Hello ${this.name},welcome to ${this.location}"
   }
}

// var/logger.groovy
def info(message){
    println "[INFO] ${message}"
}

def error(message){
    println "[ERROR] ${message}"
}

def warning(message){
    println "[WARNNING] ${message}"
}

    [作者:Surpassme]將以上代碼推送至代碼倉庫中,在Jenkins中按以下進行配置:

Manage Jenkins -> Configure System -> Global Pipeline Libraries

    [作者:Surpassme]主要配置說明如下所示:

  • Name:共享庫的唯一標識,在pipeline中會使用到
  • Default version:默認版本,可以是branchname、tag等
  • Load implicitly:隱式加載。若勾選,將自動加載全局共享庫,在pipeline中不需要顯式引用,就可以直接使用。
  • Allow default version to be overridden:若勾選,則表示允許默認被 pipeline中的配置覆蓋
  • Include @Library changes in job recent changes:若勾選,則共享庫的最近變更信息將會打印在構建日誌中
  • Cache fetched versions on controller for quick retrieval:若勾選,則表示允許從當前節點緩存中加載共享庫
  • Retrieval method:獲取共享庫代碼的方法

5.2.3 使用共享庫

    [作者:Surpassme]使用共享庫全局變量的示例如下所示:

@Library("surpass-shared-library") _
pipeline{
    agent any
    options{
        timestamps()
    }
    stages{
        stage("use shared library demo"){
            steps{
                script{
                    logger.error "use shared library demo"
                }
            }
        }
    }
}

    運行結果如下所示:

    [作者:Surpassme]使用共享庫中類庫的示例如下所示:

@Library("surpass-shared-library@master") _
pipeline{
    agent any
    options{
        timestamps()
    }
    stages{
        stage("use shared library demo"){
            steps{
                script{
                    def sharedLibraySample=new org.surpass.SharedLibrarySample("Surpass","Shanghai")
                    def ret=sharedLibraySample.greet()
                    println "result is ${ret}"
                }
            }
        }
    }
}

    運行結果如下所示:

    [作者:Surpassme]若要使用共享庫,需要在pipeline的最上方,使用@Library指定共享庫,以上示例中surpass-shared-library爲Jenkins中配置的共享庫唯一標識符。在引入共享庫後,就可以在pipeline中直接使用vars目錄中的logger中的函數了。

    [作者:Surpassme]通過以上步驟,我們可以總結出,使用共享庫的基本步驟爲:

  • 按照共享給定的源碼目錄結構,創建實現自身邏輯的代碼
  • 將共享庫代碼上傳至代碼倉庫中用以託管
  • 在Jenkins中配置共享庫信息,用於獲取共享庫代碼
  • 在pipeline中使用@Library引用共享庫

    使用@Library註解可以指定共享庫在代碼倉庫中的版本,示例如下所求:

@Library("surpass-shared-library@<version>") _

    [作者:Surpassme]其中version可以是以下任意一種

  • branch:分支,如@Library("surpass-shared-library@master") _
  • tag:標籤,如@Library("[email protected]") _
  • commit id: 提交的commit id,如@Library("surpass-shared-library@908d5d889bfaa0b5221b66c260a7c004114f0750") _

    [作者:Surpassme]在一個共享庫無法滿足要求進,Jenkins也支持添加多個共享庫,使用方法如下所求:

@Library(["surpass-shared-library-a","surpass-shared-library-2","surpass-shared-library-3"]) _

若多個共享庫存在相同的函數時,則優先使用先定義的共享庫函數

5.2.4 使用共享庫實現pipeline 模板

    [作者:Surpassme] 在pipeline 1.2 版本後,可以在共享庫定義pipeline。通過該特性,我們可以定義pipeline的模板。示例如下所求:

// vars/pipelineTemplate.groovy

def call(String opType){
   if (opType == "build"){
      pipeline{
	    agent any
		options{
		  timestamps()
		}
		parameters{
		   string(name:"build",
		          defaultValue:"generate pipelin template by build",
				  description:"build demo"
				)
		}
		stages{
		  stage("build demo"){
		    steps{
			  echo "generatePipelineTemplate demo to build"
			  echo "params is ${params.build}"
			}
		  }
		}
	  }
   } else if (opType == "test"){
      pipeline{
	    agent any
		options{
		  timestamps()
		}
		parameters{
		   string(name:"test",
		          defaultValue:"generate pipelin template by test",
				  description:"test demo"
				 )
		}
		stages{
		  stage("test demo"){
		    steps{
			  echo "generatePipelineTemplate demo to test"
			  echo "params is ${params.test}"
			}
		  }
		}
	  }
	} else if (opType == "deploy"){
      pipeline{
	    agent any
		options{
		  timestamps()
		}
		parameters{
		   string(name:"deploy",
		          defaultValue:"generate pipelin template by deploy",
				  description:"deploy demo"
				 )
		}
		stages{
		  stage("deploy demo"){
		    steps{
			  echo "generatePipelineTemplate demo to deploy"
			  echo "params is ${params.deploy}"
			}
		  }
		}
	  }
	}
}

    [作者:Surpassme]在使用Jenkins時,Jenkinsfile僅有兩行,是不是特別簡潔,如下所示:

@Library("surpass-shared-library@master") _
pipelineTemplate("test")

    最終運行日誌如下所示:

    [作者:Surpassme]生成的pipeline項目示意圖如下所示:

當項目結構都是非常標準化的時候 ,利用pipeline模板可以批量生成統一的模板,同時也降低了維護pipeline的的成本。

原文地址:https://www.jianshu.com/p/13d32877b2d1

本文同步在微信訂閱號上發佈,如各位小夥伴們喜歡我的文章,也可以關注我的微信訂閱號:woaitest,或掃描下面的二維碼添加關注:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章