Jenkins pipeline中優(yōu)雅的執(zhí)行shell/python/groovy腳本

背景

單純的聲明或者腳本式的流水線語法,能力非常有限,只能搭建起整體運行框架。具體每個step的實現(xiàn)細(xì)節(jié),多是使用腳本進(jìn)行的。

鑒于groovy 與 pipeline語法的不穩(wěn)定性,我的原則是,python/shell 腳本能解決的,不在pipeline中用groovy多做邏輯

如何在pipeline 更好的使用腳本,這里寫了幾個實踐。

groovy腳本使用

這里給一個普通的完整聲明式流水線的demo,執(zhí)行腳本,我們可以直接在steps中執(zhí)行g(shù)roovy腳本,也可以用script關(guān)鍵字,形成整體的groovy腳本代碼塊兒,以便于整體運用,抽象復(fù)用等。
這里要注意的是,使用groovy,有一些細(xì)節(jié)語法問題。
官方groovy語法請參考,使用時閱讀,可避免不必要的問題
http://docs.groovy-lang.org/latest/html/documentation/core-operators.html#_conditional_operators

pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                // groovy 腳本
                sh 'echo hello'
                echo 'Hello World'
                script {
                    // groovy 腳本
                    def browsers = ['chrome', 'firefox']
                    for (int i = 0; i < browsers.size(); ++i) {
                        echo "Testing the ${browsers[i]} browser"
                    }
                }
            }
        }
    }
}

在groovy腳本中使用shell

shell腳本是依托在steps中的groovy腳本而被調(diào)用。

無輸出shell腳本運行

在pipeline中,我們通常用 sh 來執(zhí)行shell,具體語法見 https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script
無輸出的shell 語法如下

// 單引號需要拼接 容易出錯 不推薦使用
sh 'mkdir -p ' + VARIABLE
// 三引號支持變量等內(nèi)容,引號嵌套等 推薦使用
sh """cp ${VARIABLE}/ 'abc' "123" ${VARIABLE_1}/${VARIABLE_2}"""

有輸出的shell腳本

獲取執(zhí)行狀態(tài)
// 執(zhí)行腳本,并獲取腳本的exit狀態(tài),針對不同狀態(tài),做邏輯
def run_status = sh (
    script: """cd ${ROOT_BIN_PATH} &&  \
           ./run.sh  ${env.var1} '${str_param_1}' """,
        returnStatus:true
)
print run_status
// 失敗強制退出
if (run_status != 0) {
    print '腳本執(zhí)行失敗,強制退出'
    sh 'exit 1'
}
獲取標(biāo)準(zhǔn)輸出
// 這里以判斷空文件舉例,獲取行數(shù)
def is_empty_file = sh (
    script: """cat ${PROJECT_ROOT_PATH}/${record_filename}.txt | wc -l""", 
    returnStdout: true
).trim()
print 'is_empty_file: ' + is_empty_file
if ( is_empty_file == '0') {
    print '此次錄制生成數(shù)據(jù)文件為空文件,不能上傳生成或者更新case!可在reporter 里面查看原先的請求數(shù)據(jù)文件。'
    sh 'exit 1'
}

使用python 腳本

從遠(yuǎn)端git拉取并執(zhí)行python腳本

如果我們把腳本維護(hù)在常用倉庫里面,這樣可以作為依賴包用于pipeline中,這要比維護(hù)在機器上有兩個特點

  1. 遷移性更好
  2. 維護(hù),調(diào)試都更方便,支持參數(shù)式指定腳本分支,更靈活
script {
    // 對照版本的分支,如果傳入的是master 默認(rèn)替換成最新上線的commit
    if (express) {
        dir ('./script') {
            // 利用git 獲取python工具腳本
            git branch: 'master', credentialsId: 'your_git_credential', url: 'git@repository.git'
            script {
                env.result = sh(script: """echo `python ./path/act.py ${param}` | awk '{print \$NF}' """, returnStdout: true, returnStatus: false).trim()
                print '結(jié)果: ' + env.result
            }
        }
    }                    
}

groovy解析json,更豐富的與python腳本交互

如果python腳本產(chǎn)生的數(shù)據(jù)比較復(fù)雜,這里建議在python腳本中序列化成json,保存在文件中,后者這機print到標(biāo)準(zhǔn)輸出,以供groovy使用
這里給下解析的串聯(lián)

python文本 舉例

#!/usr/bin/python
import json
a = {}
a['name'] = 'John Doe'
# 方式1 輸出到標(biāo)準(zhǔn)輸出
print(json.dumps(a))

# 方式2 輸出到文件
format_json_str = json.dumps(a, default=lambda o: o.__dict__, indent=2).decode('unicode-escape')
with open(./python_result.json, 'a+') as f:
    f.write(format_json_str)

groovy文本

// 引用在文件最上面,不放在script中
import groovy.json.JsonSlurper

def json_output = sh(script: """python ./act.py""", returnStdout: true).trim()


def result_json = new JsonSlurper()
// 方法1
def result_map = jsonSlurper.parseText(json_output)
// 方法2
def result_map = readJSON file:'./python_result.json'

print result_map.name

參考

  1. 《Jenkins2 權(quán)威指南》
  2. groovy http://docs.groovy-lang.org/latest/html/documentation/core-operators.html#_conditional_operators
  3. https://jenkins.io/doc/
  4. https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容