【Jenkins】个人向-Jenkinsfile如何写

发布于:2025-02-28 ⋅ 阅读:(15) ⋅ 点赞:(0)

官方参考:https://www.jenkins.io/doc/book/pipeline/syntax/
Pipeline Utility Steps 插件:https://birdbook.com.cn/ops/ci/jenkins/plugins/pipeline%20utility%20steps.html

常用环境变量

含义 表达式 备注
params,传入参数 传入参数params.都可以用env.来访问
执行Jenkins用户名 env.BUILD_USER_ID 依赖用户名插件:
wrap([$class: ‘BuildUser’]) {
env.BUILD_USER_ID
}
构建序号 env.BUILD_NUMBER
构建节点 env.NODE_NAME
windows默认cpu逻辑核数 env.NUMBER_OF_PROCESSORS linux获取命令 nproc
STAGE名字 env.STAGE_NAME

常用语法

等待

sleep 300

条件

_force_cores = '16'
if (_force_cores.toInteger() < 64 && _force_cores.toInteger() > 0) {
    matlab_cores = _force_cores.toInteger()
} else {
    error "Faulty data in FORCE_MATLAB_CORES: ${_force_cores}"
}

循环

for(i in list_matcher_in.toSet()){
    command = command.replaceAll("@S_IN_VAR@${i}@E_IN_VAR@", global_vars.get(i))
}

def continue_update = true
while (continue_update){
    continue_update=false
}

batch.each { elem ->
    println elem 
}

// 带序号的遍历
batches.eachWithIndex{ elem , index ->
}

临时切换工作目录

dir("xxxx") {
	xxxx
}

常用option

options {
        /* 配置构建超时时间 */
        timeout(time: 600, unit: "MINUTES")
        /* 设置不允许并发构建 */
        disableConcurrentBuilds()
        /* 保留记录 */
        buildDiscarder logRotator(artifactDaysToKeepStr: '30', artifactNumToKeepStr: '30', daysToKeepStr: '30', numToKeepStr: '30')
    }

定义初始参数(可选,可以直接再视图定义,不在jenkinsfile里)

parameters {
    string(defaultValue: "/app/jenkins/xxxx.zip", description: '文件路径', name: 'filePath')
    string(defaultValue: "", description: '部署日期', name: 'date')
    booleanParam defaultValue: true, description: '是否需要验证', name: 'needVerify'
}

任务输入弹窗

// 仅做确认
input ”请确认“
// 输入一个参数
env.URL_REPO_BUILD = input message: '请输入仓库地址', ok: 'Yes', parameters: [string(description: 'ssh://git@10.1.1.111/XX_Build' , name: 'URL_REPO_BUILD', trim: true)]
// 输入多个参数
def inputResp = input message: '请输入子仓库信息', ok: '更新', parameters: [string(defaultValue: 'Application_Code_Files/SWU_XXXX', description: '子仓库相对路径', name: 'SWU_REPO_NAME', trim: false), string(defaultValue: '', description: '子仓库版本号', name: 'SUB_REVISION_ID', trim: false), booleanParam(defaultValue: false, description: '是否继续更新子仓库', name: 'CONTINUE_UPDATE')]
continue_update = inputResp['CONTINUE_UPDATE']
env.SUB_REVISION_ID = inputResp['SUB_REVISION_ID']
env.SWU_REPO_NAME = inputResp['SWU_REPO_NAME']

定义全局可访问的量

/// 全局定义变量
def project_prefix = 'WORK'
def JOB = [
    xxx: "${project_prefix}_Build",
    log_archive: 'log_files.7z',
    repo: [
        base_repo: "${project_prefix}_Build",
        bsw_repo: 'core',
    ],
    path: [
        _7z: 'C:/Program Files/7-Zip/7z.exe'
        var_path: ""
    ],
    lic: [
        XXXX: 'XXXXX',
    ]
]

// 访问方式
JOB.path._7z
// 赋值方式
JOB.path.var_path = 'nihao'

//全局配置文件
/*
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day11
password=root
username=root
maxActive=20
minIdle=3
initialSize=20
*/

// 读取配置文件,原生调用方法
import hudson.FilePath
import hudson.model.ParametersAction
import hudson.model.FileParameterValue
import hudson.model.Executor

def getConfig(){
    File file = new File("static-server.properties")
    def props = new Properties();
    props.load(new BufferedReader(new InputStreamReader(new FileInputStream(file))));
    return props;
}

def config = getConfig();
env.baseDeployDir=config["baseDeployDir"]  //全局可访问
env.deployDir="${baseDeployDir}/${system}"

// Pipeline Utility Steps
pipeline {
    agent any
    stages {
        stage('Read Properties') {
            steps {
                script {
                    // 读取 properties 文件
                    def props = readProperties file: 'config.properties'
                    // 输出 properties 文件中的值
                    echo "DB_URL: ${props['db.url']}"
                    echo "DB_USER: ${props['db.user']}"
                    echo "DB_PASSWORD: ${props['db.password']}"
                    // 或者遍历所有的属性
                    props.each { key, value ->
                        echo "${key}: ${value}"
                    }
                }
            }
        }
    }
}


// 不推荐(中途定义全局变量)
定义变量的时候不加def,默认定义全局变量


// 用environment初始定义环境变量
pipeline {
    agent any
    environment {
        A = '100' // 环境变量,在所有 stage 中有效
    }
    stages {
        stage('Stage 1') {
            steps {
                echo "A in Stage 1: ${env.A}"
            }
        }
        stage('Stage 2') {
            steps {
                echo "A in Stage 2: ${env.A}"
            }
        }
    }
}

// 用env定义环境变量
env.system_type="linux"
pipeline {
    agent any
    stages {
        stage('Stage 1') {
            steps {
                script{
                    env.system="system"
                }
            }
        }
        stage('Stage 2') {
            steps {
                echo env.system
                println env.system_type
            }
        }
    }
}

执行条件

// 环境变量当条件
when{
	environment name: 'deployMgmt', value: 'true'
}
// 多个条件
when{
    allOf{
      environment name: 'deploy1', value: 'true'
      anyOf{
        environment name: 'deploy2', value: 'true'
        environment name: 'deploy3', value: 'true'
      }
    }
}

字符串操作

// 拼接
"${aa}${bb}"
aa+bb
//替换
command = command.replaceAll('aa', 'bb')
// 切分
text.split(/[ ,!]+/)  // 正则表达式切分
text.split('split')   // 按单词切分 如果分割单词出现2次,返回的字符串数组中会有一个null
text.tokenize('ab')  // 按字符a和b去切分,连续出现分割字符,自动合并连续的分隔符,保证没有null
// 判断包含
filepath.contains('xxx.pdf')

有用的内置函数

fileExists('/app/a.txt') //判断是否有文件
fileExists('/app/dir/'') //判断是否有目录,多个/
isUnix() //判断系统类型,依赖插件Pipeline Utility Steps
// 正则表达式 /[0-9a-f]{12}/
def matcher = (inPath =~ /\/([^_]+)_Autosar\.mdl/)
if (matcher) {
    match = matcher[0][1]
}
// 列表拼接
def swuList = []
swuList.add(name)
swus = '\n'.join(swuList)

调用其他作业

jobB =build job: "xxxx-deploy", propagate: false, wait: true, parameters: [
  string(name: 'dir', value: "${env.dir}")
]
String result = jobB.getResult();
Name = jobB.getProjectName()
println result;

函数功能抽象,以微信通知为例

def notice(result){
  return script {
        String author=config["receiver"]
        String msg = "${envDesc}发布${result}"
        jobB = build job: "notice", propagate: false, wait: false, parameters: [
                string(name: 'msg', value: "${msg}"),
                string(name: 'authors', value: "${author}"),
                string(name: "msgType", value: "wechat")
        ]
    }
}

post处理

post {
    /* post节点定义在阶段运行结束的操作,支持一些后置条件
    * always 总是运行
    * changed 当前状态与上一次构建状态不同时运行
    * failure 当前失败时运行
    * success 当前成功时运行
    * unstable 不稳定状态时运行
    * aborted 被终止时运行
    * */
  failure {
    script{
    }
}

多台机器执行的时候,共享文件

// 保留文件或者文件夹
stash includes: "${JOB.output_folder_name}/**", allowEmpty: true, name: 'output_folder_stash'
// 切换节点后,释放
unstash 'output_folder_stash'

归档文件

// 可多次执行
archiveArtifacts artifacts: "${JOB.log_archive}"

主动报错

error 'Invalid format'

环境变量局部生效

//代码块生效
withEnv (['TMP=E:\\TMP']) {
}

//stage级别生效
stage('STAGE') {
    agent {label "MATLAB"}
    environment {
        TOOLS_PATH = "${JOB.path.build_tools_common}"
    }
    stages {

动态stage,可以动态生成stage

batches.eachWithIndex { batch, index ->
	stage("Batch ${index+1}/${batches.size()}") {
		echo running
	}