03 流水线基础:Jenkinsfile 语法
本章学会读写 Jenkinsfile。语法点不少,但常用的就那么一小撮,配着例子过一遍就够用了。
1. 声明式 vs 脚本式
Jenkinsfile 有两种写法:
- 声明式(Declarative):
pipeline { ... }开头,结构固定、好读好学,新项目一律用这种 - 脚本式(Scripted):
node { ... }开头,纯 Groovy 代码,灵活但难维护,见到能看懂就行
本教程只写声明式。
2. 最小骨架
Jenkinsfile
pipeline {
agent any // 在哪跑:any = 随便找个可用节点
stages { // 流水线主体:一串阶段
stage('构建') { // 一个阶段
steps { // 阶段里的具体步骤
sh 'echo "hello jenkins"' // 执行 shell 命令
}
}
}
}
三层结构记住就行:pipeline → stages → stage → steps。
3. 常用配置块
3.1 agent:在哪里跑
agent any // 任意节点
agent { label 'linux' } // 指定打了 linux 标签的节点
agent { // 在 Docker 容器里跑(推荐!)
docker {
image 'node:20-alpine' // 用这个镜像当构建环境
args '-v /root/.npm:/root/.npm' // 挂缓存目录加速
}
}
docker agent 是最值得掌握的:构建环境即镜像。要 Node 20 就用 node:20,要 Go 1.22 就用 golang:1.22,宿主机上什么都不用装,也不会出现「这台机器 Node 版本不对」的问题。
3.2 environment:环境变量
environment {
DEPLOY_DIR = '/opt/app' // 普通变量
GIT_CRED = credentials('git-cred') // 从凭据取值(自动脱敏)
}
用 credentials() 取出的值在日志里会显示成 ****,不怕泄露。
3.3 options:流水线选项
options {
timeout(time: 15, unit: 'MINUTES') // 超时强制失败,防止卡死
disableConcurrentBuilds() // 禁止同一任务并行跑
buildDiscarder(logRotator(numToKeepStr: '20')) // 只保留最近 20 次构建记录
timestamps() // 日志带时间戳
}
3.4 triggers:触发器
triggers {
githubPush() // GitHub Webhook 触发(需装 GitHub 插件)
// pollSCM('H/2 * * * *') // 或者:每 2 分钟轮询一次仓库
}
3.5 when:条件执行
stage('部署生产') {
when { branch 'master' } // 只有 master 分支才执行这个阶段
steps { sh './deploy.sh' }
}
3.6 post:收尾动作
post {
success { echo '构建成功' } // 成功时
failure { echo '构建失败,快去看日志' } // 失败时(常用来发通知)
always { cleanWs() } // 无论成败都清理工作目录
}
4. 常用步骤(steps 里能写什么)
| 步骤 | 作用 |
|---|---|
sh '命令' | 执行 shell 命令,最常用 |
checkout scm | 按任务配置拉取代码 |
echo '文本' | 打印日志 |
archiveArtifacts 'dist/**' | 归档构建产物,可在页面下载 |
sshagent(['deploy-server']) { ... } | 块内可用指定 SSH 凭据连服务器 |
withCredentials([...]) { ... } | 块内把凭据注入为环境变量 |
sshagent 是部署的核心,先看个眼熟:
sshagent(['deploy-server']) { // 'deploy-server' 是上一章配的凭据 ID
sh '''
ssh -o StrictHostKeyChecking=no root@1.2.3.4 "mkdir -p /opt/app"
scp dist.tar.gz root@1.2.3.4:/opt/app/
'''
}
-o StrictHostKeyChecking=no是跳过首次连接的指纹确认——CI 里没人能敲 yes。更严谨的做法是提前把服务器指纹放进 Jenkins 容器的~/.ssh/known_hosts。
5. 一个完整例子
把上面的零件拼成一条真实的流水线(不用逐行背,后面三章都是它的变体):
Jenkinsfile
pipeline {
agent {
docker { image 'node:20-alpine' }
}
options {
timeout(time: 15, unit: 'MINUTES')
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '20'))
}
triggers {
githubPush()
}
environment {
SERVER = 'root@1.2.3.4'
}
stages {
stage('拉取代码') {
steps { checkout scm }
}
stage('安装依赖') {
steps { sh 'npm ci' }
}
stage('构建') {
steps { sh 'npm run build' }
}
stage('部署') {
when { branch 'master' }
steps {
sshagent(['deploy-server']) {
sh 'scp -o StrictHostKeyChecking=no -r dist/* $SERVER:/usr/share/nginx/html/'
}
}
}
}
post {
failure { echo '构建失败!' }
always { cleanWs() }
}
}
6. 在 Jenkins 里创建流水线任务
- 首页 →
New Item→ 输入任务名 → 选 Pipeline(单分支)或 Multibranch Pipeline(自动为每个分支建流水线) - 配置里找到 Pipeline 部分,选
Pipeline script from SCM - SCM 选 Git,填仓库地址、凭据(
git-cred)、分支(如*/master) - Script Path 保持默认
Jenkinsfile(就是仓库根目录那个文件) - 保存,点
Build Now手动跑一次验证
以后 Jenkinsfile 改动跟着代码 push 走,Jenkins 页面不用再动。
小结
- 只写声明式:
pipeline → stages → stage → steps四层结构 agent docker用镜像当构建环境,宿主机零安装、版本永远对- 敏感信息走
credentials()/sshagent()/withCredentials(),日志自动脱敏 when { branch 'master' }控制只有主分支才部署post里做失败通知和cleanWs()清理
语法备齐了,开始实战第一战——前端项目:04-部署前端项目