Jenkins Pipeline 实战指南

发布于:2025-07-04 ⋅ 阅读:(13) ⋅ 点赞:(0)

🚀 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核心要点

  1. 🎨 语法选择:新手用Declarative,老手用Scripted
  2. 🏗️ 阶段设计:快速失败,并行优化,增量构建
  3. 🔗 版本控制:深度集成GitHub/GitLab,自动化触发
  4. ⚙️ 参数化:灵活配置,环境变量管理,安全第一

💡 最佳实践清单

实践项 重要性 实施建议
🚀 快速反馈 ⭐⭐⭐⭐⭐ 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成为你的超级助手! 🚀


如果这篇文章对你有帮助,别忘了点赞收藏哦!有问题欢迎在评论区交流讨论! 😊