🚀 Jenkins Pipeline 实战指南
从代码到部署,一条流水线搞定所有!让CI/CD像搭积木一样简单
🎯 快速导航
📝 Pipeline基础:两种语法大PK
🤔 选择困难症?先了解两兄弟
Jenkins Pipeline有两种写法,就像写作文有记叙文和议论文一样,各有千秋:
特性 | Scripted Pipeline | Declarative Pipeline |
---|---|---|
🎯 学习难度 | 较难(需要Groovy基础) | 简单(结构化语法) |
🔧 灵活性 | 极高(编程式) | 中等(声明式) |
📖 可读性 | 一般 | 优秀 |
🛠️ 维护性 | 较难 | 容易 |
🎨 适用场景 | 复杂逻辑、高度定制 | 标准流程、团队协作 |
🔥 Scripted Pipeline:老司机的选择
基础语法结构
// Jenkinsfile (Scripted)
node {
// 这里是你的构建逻辑
stage('准备阶段') {
echo '开始构建...'
}
stage('代码检出') {
checkout scm
}
stage('构建') {
sh 'mvn clean package'
}
stage('测试') {
sh 'mvn test'
}
stage('部署') {
sh 'docker build -t myapp .'
sh 'docker run -d -p 8080:8080 myapp'
}
}
高级特性示例
// 复杂的Scripted Pipeline
node {
def buildNumber = env.BUILD_NUMBER
def gitCommit
try {
stage('环境准备') {
// 清理工作空间
deleteDir()
// 设置构建描述
currentBuild.description = "构建 #${buildNumber}"
}
stage('代码检出') {
// 检出代码并获取commit信息
def scmVars = checkout scm
gitCommit = scmVars.GIT_COMMIT
echo "当前提交: ${gitCommit}"
}
stage('条件构建') {
// 根据分支执行不同逻辑
if (env.BRANCH_NAME == 'master') {
echo '主分支构建,执行完整流程'
sh 'mvn clean package -P production'
} else if (env.BRANCH_NAME.startsWith('feature/')) {
echo '功能分支构建,快速验证'
sh 'mvn clean compile test'
} else {
echo '其他分支,跳过构建'
return
}
}
stage('并行测试') {
parallel (
'单元测试': {
sh 'mvn test'
},
'集成测试': {
sh 'mvn integration-test'
},
'代码质量检查': {
sh 'sonar-scanner'
}
)
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
throw e
} finally {
// 清理资源
sh 'docker system prune -f'
}
}
🎨 Declarative Pipeline:新手友好型
基础语法结构
// Jenkinsfile (Declarative)
pipeline {
agent any
stages {
stage('代码检出') {
steps {
checkout scm
}
}
stage('构建') {
steps {
sh 'mvn clean package'
}
}
stage('测试') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
stage('部署') {
when {
branch 'master'
}
steps {
sh 'docker build -t myapp .'
sh 'docker run -d -p 8080:8080 myapp'
}
}
}
post {
success {
echo '构建成功!🎉'
}
failure {
echo '构建失败!😭'
}
always {
cleanWs()
}
}
}
完整功能示例
// 生产级Declarative Pipeline
pipeline {
agent {
docker {
image 'maven:3.8.1-openjdk-11'
args '-v /root/.m2:/root/.m2'
}
}
environment {
DOCKER_REGISTRY = 'registry.company.com'
APP_NAME = 'my-awesome-app'
SONAR_TOKEN = credentials('sonar-token')
}
parameters {
choice(
name: 'DEPLOY_ENV',
choices: ['dev', 'test', 'prod'],
description: '选择部署环境'
)
booleanParam(
name: 'SKIP_TESTS',
defaultValue: false,
description: '是否跳过测试'
)
}
triggers {
pollSCM('H/5 * * * *') // 每5分钟检查一次代码变更
}
stages {
stage('环境信息') {
steps {
script {
echo "构建环境: ${params.DEPLOY_ENV}"
echo "跳过测试: ${params.SKIP_TESTS}"
echo "分支: ${env.BRANCH_NAME}"
echo "构建号: ${env.BUILD_NUMBER}"
}
}
}
stage('代码检出') {
steps {
checkout scm
script {
env.GIT_COMMIT_SHORT = sh(
script: 'git rev-parse --short HEAD',
returnStdout: true
).trim()
}
}
}
stage('构建') {
steps {
sh 'mvn clean compile'
}
}
stage('测试') {
when {
not { params.SKIP_TESTS }
}
parallel {
stage('单元测试') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'target/site/jacoco',
reportFiles: 'index.html',
reportName: '代码覆盖率报告'
])
}
}
}
stage('代码质量') {
steps {
withSonarQubeEnv('SonarQube') {
sh '''
mvn sonar:sonar \
-Dsonar.projectKey=${APP_NAME} \
-Dsonar.host.url=${SONAR_HOST_URL} \
-Dsonar.login=${SONAR_TOKEN}
'''
}
}
}
}
}
stage('质量门禁') {
when {
not { params.SKIP_TESTS }
}
steps {
timeout(time: 5, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
stage('打包') {
steps {
sh 'mvn package -DskipTests'
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
}
}
stage('Docker构建') {
steps {
script {
def imageTag = "${env.BUILD_NUMBER}-${env.GIT_COMMIT_SHORT}"
def imageName = "${DOCKER_REGISTRY}/${APP_NAME}:${imageTag}"
sh "docker build -t ${imageName} ."
sh "docker push ${imageName}"
env.DOCKER_IMAGE = imageName
}
}
}
stage('部署') {
when {
anyOf {
branch 'master'
branch 'develop'
}
}
steps {
script {
def deployScript = """
kubectl set image deployment/${APP_NAME} \
${APP_NAME}=${env.DOCKER_IMAGE} \
-n ${params.DEPLOY_ENV}
kubectl rollout status deployment/${APP_NAME} -n ${params.DEPLOY_ENV}
"""
sh deployScript
}
}
}
}
post {
success {
script {
def message = """
✅ 构建成功!
📋 构建信息:
• 项目: ${APP_NAME}
• 分支: ${env.BRANCH_NAME}
• 构建号: ${env.BUILD_NUMBER}
• 提交: ${env.GIT_COMMIT_SHORT}
• 环境: ${params.DEPLOY_ENV}
🔗 查看详情: ${env.BUILD_URL}
"""
// 发送钉钉通知
dingtalk(
robot: 'jenkins-bot',
type: 'MARKDOWN',
title: '构建成功通知',
text: message
)
}
}
failure {
script {
def message = """
❌ 构建失败!
📋 构建信息:
• 项目: ${APP_NAME}
• 分支: ${env.BRANCH_NAME}
• 构建号: ${env.BUILD_NUMBER}
• 失败阶段: ${env.STAGE_NAME}
🔗 查看日志: ${env.BUILD_URL}console
"""
dingtalk(
robot: 'jenkins-bot',
type: 'MARKDOWN',
title: '构建失败通知',
text: message
)
}
}
always {
cleanWs()
}
}
}
🏗️ 流水线设计:多阶段构建的艺术
🎯 阶段设计原则
1. 快速失败原则
pipeline {
agent any
stages {
// 第一阶段:快速检查(1-2分钟)
stage('快速验证') {
parallel {
stage('语法检查') {
steps {
sh 'mvn validate'
}
}
stage('代码规范') {
steps {
sh 'checkstyle:check'
}
}
stage('安全扫描') {
steps {
sh 'dependency-check.sh'
}
}
}
}
// 第二阶段:编译构建(3-5分钟)
stage('编译构建') {
steps {
sh 'mvn clean compile'
}
}
// 第三阶段:测试验证(5-10分钟)
stage('测试验证') {
parallel {
stage('单元测试') {
steps {
sh 'mvn test'
}
}
stage('集成测试') {
steps {
sh 'mvn integration-test'
}
}
}
}
// 第四阶段:打包部署(2-3分钟)
stage('打包部署') {
when {
branch 'master'
}
steps {
sh 'mvn package'
sh 'docker build -t myapp .'
}
}
}
}
2. 并行任务编排
// 复杂并行任务示例
stage('并行处理') {
parallel {
stage('前端构建') {
agent {
docker { image 'node:16' }
}
steps {
dir('frontend') {
sh 'npm install'
sh 'npm run build'
sh 'npm run test'
}
}
post {
always {
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'frontend/coverage',
reportFiles: 'index.html',
reportName: '前端测试报告'
])
}
}
}
stage('后端构建') {
agent {
docker { image 'maven:3.8.1-openjdk-11' }
}
steps {
dir('backend') {
sh 'mvn clean package'
sh 'mvn test'
}
}
post {
always {
junit 'backend/target/surefire-reports/*.xml'
}
}
}
stage('数据库迁移') {
agent {
docker { image 'flyway/flyway' }
}
steps {
sh 'flyway migrate'
}
}
stage('文档生成') {
agent {
docker { image 'python:3.9' }
}
steps {
sh 'pip install mkdocs'
sh 'mkdocs build'
}
post {
always {
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'site',
reportFiles: 'index.html',
reportName: 'API文档'
])
}
}
}
}
}
3. 矩阵构建(多环境测试)
pipeline {
agent none
stages {
stage('多环境测试') {
matrix {
axes {
axis {
name 'JAVA_VERSION'
values '8', '11', '17'
}
axis {
name 'OS'
values 'linux', 'windows'
}
}
excludes {
exclude {
axis {
name 'JAVA_VERSION'
values '8'
}
axis {
name 'OS'
values 'windows'
}
}
}
stages {
stage('测试') {
agent {
docker {
image "openjdk:${JAVA_VERSION}"
}
}
steps {
echo "在 ${OS} 系统上使用 Java ${JAVA_VERSION} 进行测试"
sh 'mvn test'
}
}
}
}
}
}
}
🔄 流水线优化策略
1. 缓存优化
pipeline {
agent any
stages {
stage('依赖缓存') {
steps {
script {
// Maven依赖缓存
def cacheKey = "maven-${hashFiles('**/pom.xml')}"
cache(maxCacheSize: 250, caches: [
arbitraryFileCache(
path: '.m2/repository',
fingerprinting: true
)
]) {
sh 'mvn dependency:go-offline'
}
}
}
}
stage('Node模块缓存') {
steps {
script {
// Node.js依赖缓存
def cacheKey = "node-${hashFiles('**/package-lock.json')}"
cache(maxCacheSize: 250, caches: [
arbitraryFileCache(
path: 'node_modules',
fingerprinting: true
)
]) {
sh 'npm ci'
}
}
}
}
}
}
2. 增量构建
stage('增量构建') {
steps {
script {
// 检查文件变更
def changedFiles = sh(
script: 'git diff --name-only HEAD~1',
returnStdout: true
).trim().split('\n')
def frontendChanged = changedFiles.any { it.startsWith('frontend/') }
def backendChanged = changedFiles.any { it.startsWith('backend/') }
if (frontendChanged) {
echo '前端代码有变更,执行前端构建'
sh 'cd frontend && npm run build'
}
if (backendChanged) {
echo '后端代码有变更,执行后端构建'
sh 'cd backend && mvn package'
}
if (!frontendChanged && !backendChanged) {
echo '没有代码变更,跳过构建'
}
}
}
}
🔗 版本控制集成:Git家族全搞定
🐙 GitHub集成
1. GitHub Webhook配置
// Jenkinsfile for GitHub
pipeline {
agent any
triggers {
// GitHub webhook触发
githubPush()
}
stages {
stage('GitHub集成') {
steps {
script {
// 获取GitHub信息
def prNumber = env.CHANGE_ID
def prTitle = env.CHANGE_TITLE
def prAuthor = env.CHANGE_AUTHOR
if (prNumber) {
echo "处理PR #${prNumber}: ${prTitle} by ${prAuthor}"
// 设置GitHub状态
githubNotify(
status: 'PENDING',
description: '构建进行中...',
context: 'jenkins/build'
)
}
}
}
}
stage('代码检出') {
steps {
checkout([
$class: 'GitSCM',
branches: [[name: '*/master']],
userRemoteConfigs: [[
url: 'https://github.com/company/project.git',
credentialsId: 'github-token'
]]
])
}
}
stage('PR检查') {
when {
changeRequest()
}
steps {
script {
// PR特定检查
sh 'mvn checkstyle:check'
sh 'mvn test'
// 发布PR评论
pullRequest.comment('✅ 自动化检查通过!')
}
}
}
}
post {
success {
script {
if (env.CHANGE_ID) {
githubNotify(
status: 'SUCCESS',
description: '构建成功!',
context: 'jenkins/build'
)
}
}
}
failure {
script {
if (env.CHANGE_ID) {
githubNotify(
status: 'FAILURE',
description: '构建失败!',
context: 'jenkins/build'
)
pullRequest.comment('❌ 构建失败,请检查代码!')
}
}
}
}
}
2. GitHub Actions集成
# .github/workflows/jenkins-trigger.yml
name: Trigger Jenkins Build
on:
push:
branches: [ master, develop ]
pull_request:
branches: [ master ]
jobs:
trigger-jenkins:
runs-on: ubuntu-latest
steps:
- name: Trigger Jenkins Job
run: |
curl -X POST \
-H "Authorization: Bearer ${{ secrets.JENKINS_TOKEN }}" \
"${{ secrets.JENKINS_URL }}/job/my-project/build"
🦊 GitLab集成
1. GitLab CI与Jenkins联动
# .gitlab-ci.yml
stages:
- trigger
- wait
- report
trigger-jenkins:
stage: trigger
script:
- |
JENKINS_JOB_URL="${JENKINS_URL}/job/${CI_PROJECT_NAME}/buildWithParameters"
curl -X POST \
-H "Authorization: Bearer ${JENKINS_TOKEN}" \
-d "GITLAB_BRANCH=${CI_COMMIT_REF_NAME}" \
-d "GITLAB_COMMIT=${CI_COMMIT_SHA}" \
-d "GITLAB_MR_ID=${CI_MERGE_REQUEST_IID}" \
"${JENKINS_JOB_URL}"
only:
- merge_requests
- master
- develop
wait-jenkins:
stage: wait
script:
- |
# 等待Jenkins构建完成
while true; do
STATUS=$(curl -s "${JENKINS_URL}/job/${CI_PROJECT_NAME}/lastBuild/api/json" | jq -r '.result')
if [ "$STATUS" = "SUCCESS" ]; then
echo "Jenkins构建成功"
break
elif [ "$STATUS" = "FAILURE" ]; then
echo "Jenkins构建失败"
exit 1
fi
sleep 30
done
2. Jenkins中的GitLab集成
// Jenkinsfile for GitLab
pipeline {
agent any
triggers {
gitlab(
triggerOnPush: true,
triggerOnMergeRequest: true,
branchFilterType: 'All'
)
}
stages {
stage('GitLab集成') {
steps {
script {
// 更新GitLab提交状态
updateGitlabCommitStatus(
name: 'jenkins-build',
state: 'running'
)
// 获取GitLab信息
def mrId = env.gitlabMergeRequestId
def mrTitle = env.gitlabMergeRequestTitle
def sourceBranch = env.gitlabSourceBranch
def targetBranch = env.gitlabTargetBranch
if (mrId) {
echo "处理MR !${mrId}: ${mrTitle}"
echo "${sourceBranch} -> ${targetBranch}"
}
}
}
}
stage('代码检出') {
steps {
checkout([
$class: 'GitSCM',
branches: [[name: "origin/${env.gitlabSourceBranch}"]],
userRemoteConfigs: [[
url: env.gitlabSourceRepoHttpUrl,
credentialsId: 'gitlab-token'
]]
])
}
}
stage('MR检查') {
when {
expression { env.gitlabMergeRequestId != null }
}
steps {
sh 'mvn checkstyle:check'
sh 'mvn test'
script {
// 添加MR评论
addGitLabMRComment(
comment: '✅ Jenkins自动化检查通过!'
)
}
}
}
}
post {
success {
updateGitlabCommitStatus(
name: 'jenkins-build',
state: 'success'
)
}
failure {
updateGitlabCommitStatus(
name: 'jenkins-build',
state: 'failed'
)
script {
if (env.gitlabMergeRequestId) {
addGitLabMRComment(
comment: '❌ Jenkins构建失败,请检查代码!'
)
}
}
}
}
}
🔀 多仓库协同
// 多仓库构建Pipeline
pipeline {
agent any
stages {
stage('多仓库检出') {
parallel {
stage('主项目') {
steps {
dir('main-project') {
git(
url: 'https://github.com/company/main-project.git',
branch: 'master',
credentialsId: 'github-token'
)
}
}
}
stage('共享库') {
steps {
dir('shared-lib') {
git(
url: 'https://github.com/company/shared-lib.git',
branch: 'master',
credentialsId: 'github-token'
)
}
}
}
stage('配置仓库') {
steps {
dir('config') {
git(
url: 'https://github.com/company/config.git',
branch: env.DEPLOY_ENV ?: 'dev',
credentialsId: 'github-token'
)
}
}
}
}
}
stage('依赖构建') {
steps {
script {
// 先构建共享库
dir('shared-lib') {
sh 'mvn clean install'
}
// 再构建主项目
dir('main-project') {
sh 'mvn clean package'
}
}
}
}
stage('配置合并') {
steps {
script {
// 合并配置文件
sh '''
cp config/application-${DEPLOY_ENV}.yml main-project/src/main/resources/
cp config/docker/Dockerfile-${DEPLOY_ENV} main-project/Dockerfile
'''
}
}
}
}
}
⚙️ 参数化构建:让Pipeline更智能
🎛️ 参数类型大全
1. 基础参数类型
pipeline {
agent any
parameters {
// 字符串参数
string(
name: 'APP_VERSION',
defaultValue: '1.0.0',
description: '应用版本号'
)
// 文本参数(多行)
text(
name: 'RELEASE_NOTES',
defaultValue: '',
description: '发布说明(支持多行)'
)
// 布尔参数
booleanParam(
name: 'SKIP_TESTS',
defaultValue: false,
description: '是否跳过测试'
)
// 选择参数
choice(
name: 'DEPLOY_ENV',
choices: ['dev', 'test', 'staging', 'prod'],
description: '部署环境'
)
// 密码参数
password(
name: 'DB_PASSWORD',
defaultValue: '',
description: '数据库密码'
)
// 文件参数
file(
name: 'CONFIG_FILE',
description: '上传配置文件'
)
}
stages {
stage('参数展示') {
steps {
script {
echo "应用版本: ${params.APP_VERSION}"
echo "部署环境: ${params.DEPLOY_ENV}"
echo "跳过测试: ${params.SKIP_TESTS}"
echo "发布说明: ${params.RELEASE_NOTES}"
}
}
}
}
}
2. 高级参数配置
// 动态参数Pipeline
pipeline {
agent any
parameters {
// 级联选择参数
activeChoice(
choiceType: 'PT_SINGLE_SELECT',
description: '选择项目',
name: 'PROJECT',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: 'return ["项目A", "项目B", "项目C"]'
],
script: [
classpath: [],
sandbox: false,
script: '''
def projects = []
def url = "http://api.company.com/projects"
def response = new URL(url).text
def json = new groovy.json.JsonSlurper().parseText(response)
json.each { project ->
projects.add(project.name)
}
return projects
'''
]
]
)
// 依赖选择参数
reactiveChoice(
choiceType: 'PT_SINGLE_SELECT',
description: '选择分支',
name: 'BRANCH',
referencedParameters: 'PROJECT',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: 'return ["master", "develop"]'
],
script: [
classpath: [],
sandbox: false,
script: '''
def branches = []
def project = PROJECT
if (project) {
def url = "http://api.company.com/projects/${project}/branches"
def response = new URL(url).text
def json = new groovy.json.JsonSlurper().parseText(response)
json.each { branch ->
branches.add(branch.name)
}
}
return branches
'''
]
]
)
}
stages {
stage('动态参数处理') {
steps {
script {
echo "选择的项目: ${params.PROJECT}"
echo "选择的分支: ${params.BRANCH}"
// 根据参数动态检出代码
def repoUrl = "https://github.com/company/${params.PROJECT}.git"
checkout([
$class: 'GitSCM',
branches: [[name: "*/${params.BRANCH}"]],
userRemoteConfigs: [[
url: repoUrl,
credentialsId: 'github-token'
]]
])
}
}
}
}
}
🌍 环境变量管理
1. 内置环境变量
stage('环境变量展示') {
steps {
script {
echo "构建信息:"
echo " 构建号: ${env.BUILD_NUMBER}"
echo " 构建ID: ${env.BUILD_ID}"
echo " 构建URL: ${env.BUILD_URL}"
echo " 任务名称: ${env.JOB_NAME}"
echo " 任务URL: ${env.JOB_URL}"
echo " 工作空间: ${env.WORKSPACE}"
echo "Git信息:"
echo " 分支: ${env.BRANCH_NAME}"
echo " 提交: ${env.GIT_COMMIT}"
echo " 提交者: ${env.GIT_COMMITTER_NAME}"
echo " 提交邮箱: ${env.GIT_COMMITTER_EMAIL}"
echo "Jenkins信息:"
echo " Jenkins URL: ${env.JENKINS_URL}"
echo " 节点名称: ${env.NODE_NAME}"
echo " 执行器号: ${env.EXECUTOR_NUMBER}"
}
}
}
2. 自定义环境变量
pipeline {
agent any
environment {
// 全局环境变量
APP_NAME = 'my-awesome-app'
DOCKER_REGISTRY = 'registry.company.com'
MAVEN_OPTS = '-Xmx1024m -XX:MaxPermSize=256m'
// 从凭据获取
DOCKER_CREDENTIALS = credentials('docker-registry')
SONAR_TOKEN = credentials('sonar-token')
// 动态生成
BUILD_TIMESTAMP = sh(
script: 'date +"%Y%m%d-%H%M%S"',
returnStdout: true
).trim()
// 条件环境变量
DEPLOY_ENV = "${env.BRANCH_NAME == 'master' ? 'prod' : 'dev'}"
}
stages {
stage('阶段级环境变量') {
environment {
// 仅在此阶段有效
STAGE_SPECIFIC_VAR = 'stage-value'
DATABASE_URL = "jdbc:mysql://db-${DEPLOY_ENV}.company.com:3306/myapp"
}
steps {
script {
echo "应用名称: ${env.APP_NAME}"
echo "构建时间戳: ${env.BUILD_TIMESTAMP}"
echo "部署环境: ${env.DEPLOY_ENV}"
echo "数据库URL: ${env.DATABASE_URL}"
// 运行时设置环境变量
env.DYNAMIC_VAR = "runtime-${env.BUILD_NUMBER}"
echo "动态变量: ${env.DYNAMIC_VAR}"
}
}
}
stage('环境变量文件') {
steps {
script {
// 生成环境变量文件
def envFile = """
APP_NAME=${env.APP_NAME}
APP_VERSION=${params.APP_VERSION ?: '1.0.0'}
BUILD_NUMBER=${env.BUILD_NUMBER}
BUILD_TIMESTAMP=${env.BUILD_TIMESTAMP}
DEPLOY_ENV=${env.DEPLOY_ENV}
GIT_COMMIT=${env.GIT_COMMIT}
"""
writeFile file: '.env', text: envFile
// 在Docker中使用
sh 'docker run --env-file .env my-app:latest'
}
}
}
}
}
3. 环境变量最佳实践
// 环境变量管理最佳实践
pipeline {
agent any
environment {
// 使用凭据管理敏感信息
DB_CREDENTIALS = credentials('database-credentials')
API_KEY = credentials('api-key')
// 环境特定配置
CONFIG_FILE = "config-${env.BRANCH_NAME}.yml"
// 版本信息
VERSION = sh(
script: 'git describe --tags --always',
returnStdout: true
).trim()
}
stages {
stage('环境验证') {
steps {
script {
// 验证必需的环境变量
def requiredVars = [
'APP_NAME',
'DEPLOY_ENV',
'DB_CREDENTIALS',
'API_KEY'
]
requiredVars.each { varName ->
if (!env[varName]) {
error "缺少必需的环境变量: ${varName}"
}
}
echo "✅ 环境变量验证通过"
}
}
}
stage('配置文件生成') {
steps {
script {
// 使用模板生成配置文件
def configTemplate = libraryResource 'config-template.yml'
def config = configTemplate
.replace('{{APP_NAME}}', env.APP_NAME)
.replace('{{VERSION}}', env.VERSION)
.replace('{{DB_HOST}}', env.DB_CREDENTIALS_USR)
.replace('{{DB_PASSWORD}}', env.DB_CREDENTIALS_PSW)
.replace('{{API_KEY}}', env.API_KEY)
writeFile file: 'application.yml', text: config
}
}
}
stage('安全处理') {
steps {
script {
// 敏感信息脱敏
def maskedApiKey = env.API_KEY.replaceAll(/.{4}$/, '****')
echo "使用API Key: ${maskedApiKey}"
// 临时环境变量
withEnv([
"TEMP_TOKEN=${UUID.randomUUID().toString()}",
"SESSION_ID=session-${env.BUILD_NUMBER}"
]) {
sh 'echo "临时Token: $TEMP_TOKEN"'
sh 'echo "会话ID: $SESSION_ID"'
}
}
}
}
}
post {
always {
script {
// 清理敏感信息
sh 'rm -f .env application.yml'
}
}
}
}
🎯 总结
🔑 Pipeline核心要点
- 🎨 语法选择:新手用Declarative,老手用Scripted
- 🏗️ 阶段设计:快速失败,并行优化,增量构建
- 🔗 版本控制:深度集成GitHub/GitLab,自动化触发
- ⚙️ 参数化:灵活配置,环境变量管理,安全第一
💡 最佳实践清单
实践项 | 重要性 | 实施建议 |
---|---|---|
🚀 快速反馈 | ⭐⭐⭐⭐⭐ | 5分钟内给出初步结果 |
🔄 并行执行 | ⭐⭐⭐⭐ | 充分利用多核资源 |
📦 缓存优化 | ⭐⭐⭐⭐ | 依赖缓存,构建缓存 |
🔒 安全管理 | ⭐⭐⭐⭐⭐ | 凭据管理,权限控制 |
📊 监控告警 | ⭐⭐⭐ | 构建状态,性能指标 |
🆘 常见问题速查
// Pipeline调试技巧
stage('调试信息') {
steps {
script {
// 打印所有环境变量
sh 'printenv | sort'
// 打印构建参数
params.each { key, value ->
echo "参数 ${key}: ${value}"
}
// 检查文件系统
sh 'ls -la'
sh 'pwd'
sh 'df -h'
}
}
}
// 错误处理
try {
sh 'mvn test'
} catch (Exception e) {
echo "测试失败: ${e.getMessage()}"
currentBuild.result = 'UNSTABLE'
} finally {
// 清理资源
sh 'docker system prune -f'
}
🎉 恭喜你! 现在你已经掌握了Jenkins Pipeline的核心技能。记住,Pipeline不只是工具,更是一种思维方式。从代码提交到生产部署,让每一步都自动化、可视化、可追溯!
下一步: 开始设计你的第一条生产级Pipeline吧!让CI/CD成为你的超级助手! 🚀
如果这篇文章对你有帮助,别忘了点赞收藏哦!有问题欢迎在评论区交流讨论! 😊