Jenkins Pipeline 基础:从安装到参数化触发回归

搭建 CI 环境,说白了就是让机器替你跑测试。而 Jenkins 是其中最常用的工具之一。Pipeline 是它的大脑——你要告诉它「什么时候做、做什么、怎么做」。这章我带你过一遍基础的安装配置、两种 Pipeline 写法的区别,以及怎么用参数化构建把回归用例串起来。

3.1 Jenkins 安装与初始配置

我一般用 Docker 装 Jenkins,省去环境依赖的坑。跑下面这行命令就行:

docker run -d -p 8080:8080 -p 50000:50000 \
  --name jenkins \
  -v jenkins_home:/var/jenkins_home \
  jenkins/jenkins:lts

启动后访问 http://localhost:8080,终端会打印初始密码。复制粘贴,装推荐插件就好。这里有个坑:

注意: 我曾经图省事把 docker 卷映射到本地目录,但权限没设对,导致 Jenkins 写不了 workspace。后来用 chown 1000:1000 才搞定。建议直接用匿名卷 jenkins_home。

装完插件进系统设置,JDK、Git、Maven 这些工具路径最好配成「自动安装」——其实 Jenkins 会自动去下载,省心。我个人习惯把 Agent 也加好,如果之后要跑分布式回归测试,提前把节点注册好能省很多事。

小技巧: 初始装插件时只选「推荐插件」,别一上来就装几百个。我遇到过插件冲突导致 Jenkins 页面加载慢,后来忍痛清理了一波。后期根据项目需求再按需装。

3.2 Pipeline 语法:Declarative vs Scripted

Pipeline 有两种写法——声明式(Declarative)和脚本式(Scripted)。你想想看,它们本质上都是 Groovy 脚本,但风格截然不同。

声明式 结构清晰,像填表一样:pipeline { agent { any }; stages { stage('Build') { steps { ... } } } }。我建议初学者先学这个,因为更容易维护。

脚本式 更灵活,就是纯 Groovy 代码,节点用 node { } 包裹。适合复杂逻辑,比如动态生成 stage、循环执行。我之前在项目中用脚本式写过一个「根据测试标签自动分配机器」的 Pipeline,声明式做起来反而费劲。

下面这个表,我直接对比一下核心差异:

对比项 Declarative Scripted
结构 固定块状:pipeline → agent → stages → stage → steps 自由 Groovy:node → stage → 任意代码
错误重启 内置自动退出、post 块处理 需手动 try/catch
代码复用 通过 shared library 的 function 直接定义方法或闭包
适用场景 标准 CICD 流程、回归测试触发 动态环境、参数化测试矩阵
我自己的经验: 回归触发 90% 的情况用声明式就够了。但如果需要根据 Git commit 信息动态决定跑不跑某个用例集,脚本式更直接。话说回来,别为了炫技强行用脚本式——让团队能看懂才重要。

举个声明式例子,一个简单的回归 Pipeline:

pipeline {
    agent any
    parameters {
        string(name: 'TEST_SUITE', defaultValue: 'smoke', description: '测试套件名')
    }
    stages {
        stage('Checkout') {
            steps { checkout scm }
        }
        stage('Run Regression') {
            steps {
                sh "mvn test -Dsuite=${params.TEST_SUITE}"
            }
        }
    }
    post {
        always { junit 'target/surefire-reports/*.xml' }
        failure { emailext to: 'team@example.com', subject: '回归失败' }
    }
}

3.3 参数化构建触发回归

回归测试不能每次全量跑,太慢。所以我们用「参数化构建」来控制:跑哪个模块?哪个测试套件?并行数多少?Jenkins 里打开 Pipeline 项目的「This project is parameterized」,添加参数类型(String、Choice、Boolean 等)。

我推荐以下参数组合:

  • TEST_SUITE(Choice):可选 smoke、regression_full、module_a
  • PARALLEL_COUNT(String):默认 4,控制并发线程数
  • RUN_ON_PUSH(Boolean):是否在提交时自动触发(配合 webhook)

在 Pipeline 脚本里通过 params.TEST_SUITE 取值。自动触发时,我们可以由 Git webhook 带一个默认参数,手动触发时再覆盖。避坑提醒:

注意: 我曾经把参数默认值设错了,结果 webhook 触发时也用了那个错误的值,导致回归跑了整整两个小时——全量测试,而我想跑的是冒烟。后来我在 Pipeline 里加了 when { expression { params.RUN_ON_PUSH == false } } 来区分触发来源,才彻底解决问题。

参数化搭配构建触发器更强大。比如用 Generic Webhook Trigger 插件,从 GitLab 的 push 事件 JSON 里提取分支名、commit 作者,动态设置参数。下面是一个简化版 webhook 配置:

# Jenkins 的 Pipeline 中定义
trigger {
    genericWebhookTrigger(
        genericVariables: [
            [key: 'BRANCH', value: '$.ref'],
            [key: 'COMMIT_MSG', value: '$.commits[0].message']
        ],
        : 'my-secret-'
    )
}

这样每次 push 都会自动识别分支,你可以在 stage 里判断:如果是 master 分支就跑全量回归,否则只跑 smoke。嗯,这里要提一句:别把 写在脚本里,用 Jenkins 的 credential 管理。

个人习惯: 我通常会在项目根目录放一个 .ci-params.yaml 文件,里面定义每个模块对应的测试套件名。Pipeline 解析这个文件,动态生成参数选项。这样改测试配置不用动 Jenkins 作业,团队其他成员也能参与。
Jenkins Pipeline 参数化触发回归流程 Git Push / Webhook 参数化构建 TEST_SUITE Generic Webhook 解析分支 / commit Pipeline 脚本 Declarative / Scripted 阶段:Checkout 拉取代码 阶段:Run Regression mvn test -Dsuite=... Post 处理 junit 报告 / 邮件通知 注:参数可手动覆盖 或从触发JSON提取

整体来看,这套机制让回归触发变得灵活可控——你既能通过 webhook 全自动跑,也能在 Jenkins 页面上点「Build with Parameters」手动选套件。我个人建议把参数化构建和分支策略结合起来,比如 master 推送自动触发全量回归,功能分支只触发冒烟。能做到这样,CI 就已经解决掉 80% 的重复劳动了。