bingoogolapple.github.io
bingoogolapple.github.io copied to clipboard
Pipeline 备忘
- 查看内置的环境变量,域名/pipeline-syntax/globals#env
- 用 echo 输出日志,用 error 使当前的 stage 返回失败
stage('test') {
// echo "用 echo 输出日志"
// error "用 error 使当前的 stage 返回失败"
test()
}
def test() {
echo "用 echo 输出日志"
error "用 error 使当前的 stage 返回失败"
}
wrap([$class: 'BuildUser']) {
echo "BUILD_USER 为 ${BUILD_USER}"
echo "BUILD_USER_ID 为 ${BUILD_USER_ID}"
echo "BUILD_USER_EMAIL 为 ${BUILD_USER_EMAIL}"
}
- 参数化构建时,参数会放入 params 中,params 中不会包含 BUILD_NUMBER,params 实际上就是 map
echo "参数 ${params}"
参数 [isSdf:true, branch:develop]
- 当前 job 的构建版本号可以通过 ${BUILD_NUMBER} 或 ${BUILD_ID} 来获取
- 当前 job 的工作目录可通过 ${WORKSPACE} 来获取
- 可以直接通过 ${isSdf} 来取值,但是建议都通过 params.isSdf 来取值,如果直接 isSdf,if 判断会有问题
if (isSdf) { // 不管 isSdf 是否为 true,都为真
echo "直接取值,需要"
} else {
echo "直接取值,不需要"
}
if (params.isSdf) { // 只有 isSdf 为 true 是才为真
echo "需要"
} else {
echo "不需要"
}
- 变量名不能以减号 - 分隔
- 不管是在外部、stage 内、方法内,定义变量时加了 def 就是局部变量,不加 def 就是全局变量
- 如果想在 sh 中使用 groovy 中定义的变量,可以在 groovy 中通过 env.xxxx 来定义变量
stage('test') {
env.CUSTOM_PARAM = "自定义参数"
def cmd = '''echo ${CUSTOM_PARAM}
echo ${CUSTOM_PARAM}
echo ${CUSTOM_PARAM}
'''
sh cmd
}
- 创建目录和判断文件是否存在
def currentDirectory = pwd()
echo "当前目录 ${currentDirectory}"
sh "ls"
def testDir = currentDirectory + "/testDir"
if (!fileExists(testDir)) {
sh "mkdir ${testDir}"
}
sh "ls"
- 日志中不输出 sh 命令
def shWhithoutLog(cmd) {
sh('#!/bin/sh -e\n' + cmd)
}
- 获取 shell 的输出和状态
stage('test') {
env.CUSTOM_PARAM = "自定义参数"
def cmd = '''echo ${CUSTOM_PARAM}
echo ${CUSTOM_PARAM}
'''
output = sh (
script: cmd,
returnStdout: true
).trim()
echo "输出为:${output}"
result = sh (
script: cmd,
returnStatus: true
)
echo "结果为:${result}"
}
- 触发其他 job
build job: 'other_job_name', parameters: [string(name: 'channels', value: 'a,b,c'), string(name: 'apk_url', value: 'xxxxx'), string(name: 'app_name', value: 'xxx')]
- 获取版本号
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep package
// awk '{print $4}' 空格 split,从1开始,取第4个
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep package | awk '{print $4}'
// sed s/versionName=//g 将 versionName= 替换成功空串,如果要将 versionName= 替换成 BGA,则写成 sed s/versionName=/BGA/g
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep package | awk '{print $4}' | sed s/versionName=//g
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep package | awk '{print $4}' | sed s/versionName=//g | sed s/\'//g
env.DUMP_BADGING_CMD = "${ANDROID_HOME}/build-tools/27.0.1/aapt dump badging ${ORIGIN_APK_FILE}"
// APK_VERSION_NAME=`${DUMP_BADGING_CMD} | grep package | awk '{print $4}' | sed s/versionName=//g | sed s/\'//g`
def getApkVersionNameCmd = '''
APK_VERSION_NAME=`${DUMP_BADGING_CMD} | grep package | awk '{print $4}' | sed s/versionName=//g | sed s/\\'//g`
echo "${APK_VERSION_NAME}"
'''
env.APK_VERSION_NAME = sh (
script: getApkVersionNameCmd,
returnStdout: true
).trim()
echo "版本号为 ${APK_VERSION_NAME}"
- 获取中文名称
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep application-label-zh-CN
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep application-label-zh-CN: | sed s/application-label-zh-CN://g
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep application-label-zh-CN: | sed s/application-label-zh-CN://g | sed s/\'//g
// APP_CHINESE_NAME=`${DUMP_BADGING_CMD} | grep application-label-zh-CN: | sed s/application-label-zh-CN://g | sed s/\'//g`
def getAppChineseNameCmd = '''
APP_CHINESE_NAME=`${DUMP_BADGING_CMD} | grep application-label-zh-CN: | sed s/application-label-zh-CN://g | sed s/\\'//g`
echo "${APP_CHINESE_NAME}"
'''
env.APP_CHINESE_NAME = sh (
script: getAppChineseNameCmd,
returnStdout: true
).trim()
echo "中文名称为 ${APP_CHINESE_NAME}"
- 获取英文名称
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep package
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep package | awk '{print $2}'
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep package | awk '{print $2}' | sed s/name=//g | sed s/\'//g
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep package | awk '{print $2}' | sed s/name=//g | sed s/\'//g | sed s/\\./\ /g
// awk '{print $NF}' 空格 split,从1开始,取第最后
/Applications/develop/AndroidSDK/build-tools/27.0.1/aapt dump badging /Users/wanghao/Desktop/sdf.apk | grep package | awk '{print $2}' | sed s/name=//g | sed s/\'//g | sed s/\\./\ /g | awk '{print $NF}'
// APP_NAME=`${DUMP_BADGING_CMD} | grep package | awk '{print $2}' | sed s/name=//g | sed s/\'//g | sed s/\\./\ /g | awk '{print $NF}'`
def getPackageNameCmd = '''
PACKAGENAME=`${DUMP_BADGING_CMD} | grep package | awk '{print $2}' | sed s/name=//g | sed s/\\'//g`
echo "${PACKAGENAME}"
'''
def packageName = sh (
script: getPackageNameCmd,
returnStdout: true
).trim()
echo "包名为 ${packageName}"
env.APP_NAME = "${packageName.substring(packageName.lastIndexOf('.') + 1)}"
echo "英文名称为 ${APP_NAME}"
#!/usr/bin/env groovy
node('xxxx') {
try {
def language = "Java,Kotlin"
def testArr = language.split(",")
def testMap = ["key1": "value1", "key2": "value2"]
stage('测试字符串') {
echo "添加前数组的值为 ${testArr}"
language += ",Python"
testArr = language.split(",")
echo "添加后数组的值为 ${testArr}"
echo "tokenize 的结果为 ${language.tokenize(',')}"
echo "split 的结果为 ${language.split(',')}"
echo "最后一个元素为 ${language.substring(language.lastIndexOf(',') + 1)}"
echo "转换为大写 ${language.toUpperCase()} 转换为小写 ${language.toLowerCase()}"
echo "是否包含 ${language.contains('Java')} ${language.contains('java')}"
}
stage('测试map') {
echo "${testMap.key1}"
echo "${testMap['key2']}"
echo "${testMap.keySet()}"
echo "${testMap.values()}"
}
stage('测试 for 循环') {
// 可以
for (def test : testArr) {
echo "测试 ${test}"
}
// 可以
for (def i = 0; i < 3; i++) {
echo "测试 ${i}"
}
}
// 可以
for (def i = 0; i < testArr.length; i++) {
stage("${testArr[i]}") {
echo "${testArr[i]}"
}
}
currentBuild.result = 'SUCCESS'
} catch (e) {
currentBuild.result = 'FAILURE'
def errorMsg = "========================================= 错误信息 START =========================================\n"
errorMsg += "${e.toString()}|${e.message}\n"
errorMsg += "========================================= 错误信息 END ========================================="
echo "${errorMsg}"
sh 'exit 1'
} finally {
// 清空工作空间,notFailBuild: true 设置失败时也清除工作空间
cleanWs notFailBuild: true
}
}
多选
node('xxx_agent') {
try {
stage('build') {
echo "job参数为 ${params.flavors}"
def flavorArr = params.flavors.split(",")
for(def flavor : flavorArr) {
echo "flavor is ${flavor}"
}
}
currentBuild.result = 'SUCCESS'
} catch (e) {
currentBuild.result = 'FAILURE'
// 打印错误信息
def errorMsg = "========================================= 错误信息 START =========================================\n"
errorMsg += "${e.toString()}\n"
errorMsg += "========================================= 错误信息 END ========================================="
echo "${errorMsg}"
sh 'exit 1'
} finally {
if (currentBuild.result == null || currentBuild.result == 'SUCCESS') {
echo '构建成功'
} else {
echo '构建失败'
}
// 清空工作空间,notFailBuild: true 设置失败时也清除工作空间
cleanWs notFailBuild: true
}
}
隐藏域
闭包,MissingPropertyException、并发
#!/usr/bin/env groovy
def ignoreError(def closure) {
try {
closure.call("Hello", 3333)
} catch(e) {
echo "${e.toString()}\n"
}
}
def testClosureParams(def closure) {
closure.call('bingoogolapple', 27, '男')
}
node('xxx_agent') {
try {
stage('测试闭包1') {
testClosureParams { name, age, gender ->
echo "name is $name, age is $age, gender is $gender"
}
ignoreError { p1, p2 ->
echo "参数21 is $p1, 参数22 is $p2"
if (Boolean.valueOf("${IS_XXX}")) {
echo "启用"
} else {
echo "不启用"
}
}
ignoreError { p1, p2 ->
echo "参数11 is $p1, 参数12 is $p2"
// 要加上 params. 前缀,不然会报 groovy.lang.MissingPropertyException: No such property: IS_XXX for class: groovy.lang.Binding
if (Boolean.valueOf("${params.IS_XXX}")) {
echo "启用"
} else {
echo "不启用"
}
}
}
stage('测试闭包2') {
def aClosure = { innerIt ->
echo "aClosure:param1 is ${innerIt[0]}, param2 is ${innerIt[1]}"
}
aClosure.call(["hello", 100])
def bClosure = {
echo "bClosure:param1 is ${it[0]}, param2 is ${it[1]}"
}
bClosure.call(["hello", 100])
def cClosure = { p1, p2 ->
echo "cClosure:param1 is $p1, param2 is $p2"
}
cClosure.call("hello", 100)
}
stage('测试并发1') {
def jobs=["init":{echo "init"}]
def languageStr = "Java,Kotlin,C,Swift"
def languageArr = languageStr.split(",")
for(def i = 0; i < languageArr.length; i++){
def language = "${languageArr[i]}"
jobs["$language"] = {
echo "执行 $language"
}
}
parallel(jobs)
}
stage('测试并发2') {
parallel(['check one': {
echo "start one"
sleep 1
echo "finish one"
}, 'check two': {
echo "start two"
sleep 2
echo "finish two"
}, 'check three': {
echo "start three"
sleep 3
echo "finish three"
}])
}
stage('测试并发3') {
parallel 'check one': {
echo "start one"
sleep 1
echo "finish one"
}, 'check two': {
echo "start two"
sleep 2
echo "finish two"
}, 'check three': {
echo "start three"
sleep 3
echo "finish three"
}
}
stage('测试JSON解析') {
echo "job参数为 ${params}"
def jsonStr = '{ "key1": "value1", "key2": 999999}'
def jsonSlurper = new groovy.json.JsonSlurper()
def jsonObject = jsonSlurper.parseText(jsonStr)
echo "key1 is ${jsonObject.key1}, key2 is ${jsonObject.key2}"
jsonObject = readJSON text: "${jsonStr}"
echo "key1 is ${jsonObject.key1}, key2 is ${jsonObject.key2}"
}
currentBuild.result = 'SUCCESS'
} catch (e) {
currentBuild.result = 'FAILURE'
// 打印错误信息
def errorMsg = "========================================= 错误信息 START =========================================\n"
errorMsg += "${e.toString()}\n"
errorMsg += "========================================= 错误信息 END ========================================="
echo "${errorMsg}"
sh 'exit 1'
} finally {
if (currentBuild.result == null || currentBuild.result == 'SUCCESS') {
echo '构建成功'
} else {
echo '构建失败'
}
// 清空工作空间,notFailBuild: true 设置失败时也清除工作空间
cleanWs notFailBuild: true
}
}
- 获取 git 仓库名称
git remote -v | grep push | grep origin | awk '{print $2}' | sed 's/.*\///g' | sed 's/.git//g'