Jenkins详细教程 - 从入门到精通

发布于:2025-07-09 ⋅ 阅读:(19) ⋅ 点赞:(0)

目录

1. 什么是Jenkins

1.1 简单理解

1.2 技术定义

1.3 核心特点

2. 为什么需要Jenkins

2.1 传统开发的痛点

手工发布的问题

真实场景举例

2.2 Jenkins的解决方案

自动化CI/CD流程

3. 核心概念解析

3.1 Job(任务)

Job示例

3.2 Build(构建)

3.3 Pipeline(流水线)

3.4 Node(节点)

节点配置示例

3.5 Workspace(工作空间)

4. 安装和初始配置

4.1 Docker安装(推荐)

4.2 Linux系统安装

4.3 初始配置向导

4.4 基础配置

系统配置

5. 第一个Jenkins任务

5.1 创建自由风格项目

基础配置

构建步骤

5.2 第一个Pipeline项目

Pipeline脚本

6. Pipeline详解

6.1 声明式Pipeline vs 脚本式Pipeline

声明式Pipeline(推荐)

脚本式Pipeline(灵活)

6.2 Pipeline高级特性

并行执行

条件执行

矩阵构建

6.3 共享库

共享库结构

共享库代码

使用共享库

7. 插件系统

7.1 必备插件推荐

基础功能插件

质量管理插件

7.2 插件安装和配置

通过Web界面安装

通过命令行安装

通过插件配置文件批量安装

7.3 常用插件配置示例

Blue Ocean配置

SonarQube集成

Docker插件使用

8. 分布式构建

8.1 Master-Slave架构

8.2 添加Slave节点

通过SSH添加Linux节点

通过JNLP添加Windows节点

Docker动态节点

8.3 Kubernetes集成

Kubernetes插件配置

Kubernetes Pipeline示例

8.4 节点管理最佳实践

节点标签管理

节点监控脚本

9. 实际应用场景

9.1 微服务CI/CD流程

多服务构建Pipeline

9.2 前端项目CI/CD

React/Vue项目Pipeline

9.3 数据库变更管理

Flyway数据库迁移Pipeline

10. 安全管理

10.1 用户和权限管理

基于角色的访问控制

LDAP集成

10.2 凭据管理

安全存储敏感信息

10.3 构建安全

安全扫描Pipeline

11. 性能优化

11.1 Jenkins性能调优

JVM参数优化

磁盘性能优化

11.2 构建性能优化

并行构建优化

缓存策略

11.3 监控和告警

性能监控Dashboard

12. 最佳实践

12.1 Pipeline设计原则

12.1.1 可复用和模块化

12.1.2 环境隔离

12.2 代码管理最佳实践

12.2.1 Git分支策略集成

12.3 监控和告警

12.3.1 构建健康度监控

12.3.2 实时告警系统

13. 问题排查和调试

13.1 常见问题诊断

13.1.1 构建失败排查

13.2 性能问题诊断

13.2.1 构建性能分析

13.3 调试工具和技巧

13.3.1 Pipeline调试模式

总结

🎯 核心收获

📋 关键要点回顾

核心概念

最佳实践

性能优化

🚀 进阶方向

💡 实施建议

🔧 实施检查清单

基础设施

流程设计

质量保证

运维监控


1. 什么是Jenkins

1.1 简单理解

想象一下你经营一家汽车工厂

传统方式(手工生产)

  • 工人手工制造每个零件
  • 手工组装汽车
  • 手工检查质量
  • 手工包装发货
  • 效率低下,容易出错

使用Jenkins(自动化工厂)

  • 自动化生产线制造零件
  • 自动化组装流程
  • 自动化质量检测
  • 自动化包装发货
  • 高效准确,24小时不间断

1.2 技术定义

Jenkins是一个开源的自动化服务器,用于实现持续集成(CI)和持续部署(CD)。它可以自动化软件开发过程中的构建、测试、部署等环节。

1.3 核心特点

Jenkins的能力:
  构建自动化: 自动编译代码、运行测试
  部署自动化: 自动发布到不同环境
  流程编排: 串联复杂的发布流程
  监控告警: 实时监控构建状态
  插件生态: 丰富的插件扩展功能

主要优势

  • 🚀 提高效率:自动化重复性工作
  • 🛡️ 降低风险:标准化的发布流程
  • 🔧 快速反馈:及时发现和修复问题
  • 🎯 持续交付:快速响应业务需求

2. 为什么需要Jenkins

2.1 传统开发的痛点

手工发布的问题
# 传统手工发布流程
开发人员完成代码 → 手工打包 → 手工测试 → 手工部署 → 手工验证
    ↓              ↓        ↓        ↓        ↓
容易忘记步骤    格式不统一  测试不充分  环境不一致  验证不完整

具体痛点

  1. 效率低下:每次发布需要几小时甚至几天
  2. 容易出错:手工操作容易遗漏步骤
  3. 环境不一致:开发、测试、生产环境差异
  4. 难以回滚:出问题时难以快速回滚
  5. 协作困难:多人协作时容易冲突
真实场景举例
场景:电商网站双11大促前发布

传统方式:
周五晚上11点 → 开发提交代码
周五晚上11:30 → 测试人员手工测试
周六凌晨1点 → 运维手工部署
周六凌晨2点 → 发现Bug,紧急回滚
周六凌晨3点 → 修复Bug,重新部署
周六凌晨4点 → 终于发布成功
结果:团队通宵达旦,身心俱疲

2.2 Jenkins的解决方案

自动化CI/CD流程
graph LR
    A[代码提交] --> B[自动构建]
    B --> C[自动测试]
    C --> D[自动部署到测试环境]
    D --> E[自动化测试]
    E --> F{测试通过?}
    F -->|是| G[自动部署到生产环境]
    F -->|否| H[通知开发人员]
    G --> I[自动监控]

Jenkins后的效果

相同场景:电商网站双11大促前发布

Jenkins方式:
周五下午5点 → 开发提交代码到Git
周五下午5:05 → Jenkins自动触发构建
周五下午5:10 → 自动编译、测试通过
周五下午5:15 → 自动部署到测试环境
周五下午5:20 → 自动化测试通过
周五下午5:25 → 自动部署到生产环境
周五下午5:30 → 发布完成,监控一切正常
结果:开发人员准点下班,轻松愉快

3. 核心概念解析

3.1 Job(任务)

生活比喻:Job就像工厂里的一条生产线,专门生产某种产品。

Job的类型:
  自由风格项目: 最灵活的任务类型,可以执行任何脚本
  Pipeline项目: 使用代码定义的复杂工作流
  多配置项目: 在多个环境中同时执行的任务
  Maven项目: 专门用于Java Maven项目的任务
Job示例
// 一个简单的Job配置
job('my-first-job') {
    description('我的第一个Jenkins任务')
    
    // 源码管理
    scm {
        git('https://github.com/username/project.git')
    }
    
    // 构建触发器
    triggers {
        scm('H/5 * * * *')  // 每5分钟检查一次代码变更
    }
    
    // 构建步骤
    steps {
        shell('echo "开始构建..."')
        shell('mvn clean package')  // Maven打包
        shell('echo "构建完成!"')
    }
    
    // 构建后操作
    publishers {
        archiveArtifacts('target/*.jar')  // 归档构建产物
        emailext {
            subject('构建完成: ${JOB_NAME} - ${BUILD_NUMBER}')
            body('构建已完成,请查看详情。')
            to('developer@company.com')
        }
    }
}

3.2 Build(构建)

生活比喻:Build就像一次生产过程,把原材料(代码)加工成产品(可部署的软件)。

# 构建过程示例
Build #1: 
  开始时间: 2024-01-15 10:00:00
  状态: 成功 ✅
  耗时: 3分钟
  
Build #2:
  开始时间: 2024-01-15 14:30:00
  状态: 失败 ❌
  耗时: 1分钟
  失败原因: 单元测试失败
  
Build #3:
  开始时间: 2024-01-15 15:00:00
  状态: 成功 ✅
  耗时: 3分钟

3.3 Pipeline(流水线)

生活比喻:Pipeline就像汽车组装流水线,每个工位(Stage)完成特定工作。

pipeline {
    agent any
    
    stages {
        stage('准备工作') {
            steps {
                echo '获取代码...'
                git 'https://github.com/username/project.git'
            }
        }
        
        stage('编译构建') {
            steps {
                echo '开始编译...'
                sh 'mvn clean compile'
            }
        }
        
        stage('运行测试') {
            steps {
                echo '运行单元测试...'
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }
        
        stage('打包应用') {
            steps {
                echo '打包应用...'
                sh 'mvn package'
                archiveArtifacts artifacts: 'target/*.jar'
            }
        }
        
        stage('部署应用') {
            steps {
                echo '部署到测试环境...'
                sh './deploy.sh test'
            }
        }
    }
    
    post {
        success {
            echo '🎉 构建成功!'
            emailext (
                subject: "构建成功: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
                body: "恭喜!构建成功完成。",
                to: "team@company.com"
            )
        }
        failure {
            echo '😞 构建失败!'
            emailext (
                subject: "构建失败: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
                body: "构建失败,请及时处理。",
                to: "team@company.com"
            )
        }
    }
}

3.4 Node(节点)

生活比喻:Node就像工厂里的车间,每个车间都可以执行生产任务。

节点类型:
  Master节点: 
    - Jenkins的大脑,负责调度和管理
    - 运行Jenkins Web界面
    - 分配任务给Slave节点
    
  Slave节点:
    - 执行具体的构建任务
    - 可以是物理机、虚拟机、Docker容器
    - 可以根据需要动态创建和销毁
节点配置示例
// Docker节点配置
node('docker') {
    stage('在Docker中构建') {
        docker.image('maven:3.8.1-jdk-11').inside {
            sh 'mvn --version'
            sh 'mvn clean package'
        }
    }
}

// Windows节点配置
node('windows') {
    stage('在Windows中构建') {
        bat 'echo %PATH%'
        bat 'dotnet build'
    }
}

// Linux节点配置
node('linux') {
    stage('在Linux中构建') {
        sh 'uname -a'
        sh 'make build'
    }
}

3.5 Workspace(工作空间)

生活比喻:Workspace就像工人的工作台,存放当前正在处理的材料和工具。

# 工作空间目录结构
/var/jenkins_home/workspace/my-project/
├── src/                    # 源代码
├── target/                 # 编译输出
├── Jenkinsfile            # Pipeline定义文件
├── pom.xml                # Maven配置文件
└── README.md              # 项目说明

4. 安装和初始配置

4.1 Docker安装(推荐)

最简单快捷的安装方式:

# 1. 拉取Jenkins镜像
docker pull jenkins/jenkins:lts

# 2. 创建数据目录
mkdir -p /var/jenkins_home
sudo chown 1000:1000 /var/jenkins_home

# 3. 启动Jenkins容器
docker run -d \
  --name jenkins \
  -p 8080:8080 \
  -p 50000:50000 \
  -v /var/jenkins_home:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  jenkins/jenkins:lts

# 4. 查看初始管理员密码
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

4.2 Linux系统安装

# CentOS/RHEL安装
sudo wget -O /etc/yum.repos.d/jenkins.repo \
    https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
sudo yum upgrade
sudo yum install jenkins java-11-openjdk

# Ubuntu/Debian安装
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > \
    /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

# 启动Jenkins
sudo systemctl start jenkins
sudo systemctl enable jenkins

4.3 初始配置向导

1. 首次访问设置:
   打开浏览器访问: http://localhost:8080
   
2. 解锁Jenkins:
   输入初始管理员密码(从日志中获取)
   
3. 安装插件:
   选择"安装推荐插件"(适合新手)
   或者"选择要安装的插件"(高级用户)
   
4. 创建管理员用户:
   用户名: admin
   密码: ********
   全名: Jenkins Administrator
   邮箱: admin@company.com
   
5. 实例配置:
   Jenkins URL: http://localhost:8080/
   
6. 开始使用Jenkins!

4.4 基础配置

系统配置
// 在 Manage Jenkins → Configure System 中配置

// 全局工具配置
configure {
    // JDK配置
    jdk {
        name('JDK-11')
        home('/usr/lib/jvm/java-11-openjdk')
    }
    
    // Maven配置
    maven {
        name('Maven-3.8')
        home('/usr/share/maven')
    }
    
    // Git配置
    git {
        name('Default')
        path('/usr/bin/git')
    }
}

// 邮件配置
emailext {
    smtpServer('smtp.company.com')
    smtpPort(587)
    useSsl(true)
    charset('UTF-8')
    defaultSubject('Jenkins构建通知: ${JOB_NAME} - ${BUILD_NUMBER}')
    defaultBody('''
        构建状态: ${BUILD_STATUS}
        项目名称: ${JOB_NAME}
        构建编号: ${BUILD_NUMBER}
        构建URL: ${BUILD_URL}
        构建日志: ${BUILD_LOG}
    ''')
}

5. 第一个Jenkins任务

5.1 创建自由风格项目

让我们创建一个简单的"Hello World"项目:

1. 点击"新建任务"
2. 输入任务名称: hello-world
3. 选择"构建一个自由风格的软件项目"
4. 点击"确定"
基础配置
任务配置:
  描述: 我的第一个Jenkins任务,用于学习基础操作
  
  源码管理:
    Git仓库: https://github.com/username/hello-world.git
    分支: main
    
  构建触发器:
    GitHub hook trigger: ✓
    定时构建: H/15 * * * * (每15分钟检查一次)
    
  构建环境:
    删除工作空间: ✓
    超时时间: 10分钟
构建步骤
# 添加构建步骤 → 执行shell
#!/bin/bash

echo "========================================="
echo "🚀 开始执行Jenkins构建任务"
echo "========================================="

# 显示环境信息
echo "📅 构建时间: $(date)"
echo "🏷️  构建编号: ${BUILD_NUMBER}"
echo "📁 工作目录: ${WORKSPACE}"
echo "🌳 Git分支: ${GIT_BRANCH}"
echo "📋 任务名称: ${JOB_NAME}"

# 检查代码
echo "📦 检查项目文件:"
ls -la

# 如果是Java项目
if [ -f "pom.xml" ]; then
    echo "☕ 检测到Maven项目,开始构建..."
    mvn clean compile
    mvn test
    mvn package
    echo "✅ Maven构建完成"
fi

# 如果是Node.js项目
if [ -f "package.json" ]; then
    echo "🟢 检测到Node.js项目,开始构建..."
    npm install
    npm test
    npm run build
    echo "✅ Node.js构建完成"
fi

# 如果是Python项目
if [ -f "requirements.txt" ]; then
    echo "🐍 检测到Python项目,开始构建..."
    pip install -r requirements.txt
    python -m pytest
    echo "✅ Python测试完成"
fi

echo "========================================="
echo "🎉 Jenkins构建任务完成!"
echo "========================================="

5.2 第一个Pipeline项目

创建一个更现代的Pipeline项目:

1. 新建任务 → Pipeline
2. 任务名称: my-first-pipeline
3. 在Pipeline配置中选择"Pipeline script"
Pipeline脚本
pipeline {
    agent any
    
    // 环境变量
    environment {
        APP_NAME = 'my-awesome-app'
        VERSION = '1.0.0'
        ENVIRONMENT = 'development'
    }
    
    // 参数化构建
    parameters {
        choice(
            name: 'DEPLOY_ENV',
            choices: ['dev', 'test', 'prod'],
            description: '选择部署环境'
        )
        string(
            name: 'BUILD_VERSION',
            defaultValue: '1.0.0',
            description: '构建版本号'
        )
        booleanParam(
            name: 'SKIP_TESTS',
            defaultValue: false,
            description: '是否跳过测试'
        )
    }
    
    stages {
        stage('📋 准备阶段') {
            steps {
                script {
                    echo "🚀 开始构建 ${APP_NAME} v${BUILD_VERSION}"
                    echo "🎯 目标环境: ${params.DEPLOY_ENV}"
                    echo "⏰ 构建时间: ${new Date().format('yyyy-MM-dd HH:mm:ss')}"
                    
                    // 清理工作空间
                    cleanWs()
                }
            }
        }
        
        stage('📥 代码检出') {
            steps {
                echo '正在检出代码...'
                git branch: 'main', url: 'https://github.com/username/project.git'
                
                script {
                    // 获取Git信息
                    env.GIT_COMMIT_SHORT = sh(
                        script: 'git rev-parse --short HEAD',
                        returnStdout: true
                    ).trim()
                    
                    echo "📝 当前提交: ${env.GIT_COMMIT_SHORT}"
                }
            }
        }
        
        stage('🔍 代码质量检查') {
            parallel {
                stage('语法检查') {
                    steps {
                        echo '正在进行语法检查...'
                        sh 'echo "语法检查通过 ✅"'
                    }
                }
                stage('安全扫描') {
                    steps {
                        echo '正在进行安全扫描...'
                        sh 'echo "安全扫描通过 🔒"'
                    }
                }
            }
        }
        
        stage('🔨 编译构建') {
            steps {
                echo '开始编译项目...'
                script {
                    if (fileExists('pom.xml')) {
                        sh 'mvn clean compile'
                    } else if (fileExists('package.json')) {
                        sh 'npm install'
                        sh 'npm run build'
                    } else {
                        echo '未找到构建配置文件,跳过编译步骤'
                    }
                }
            }
        }
        
        stage('🧪 运行测试') {
            when {
                not { params.SKIP_TESTS }
            }
            steps {
                echo '开始运行测试...'
                script {
                    try {
                        if (fileExists('pom.xml')) {
                            sh 'mvn test'
                        } else if (fileExists('package.json')) {
                            sh 'npm test'
                        }
                        echo '✅ 所有测试通过!'
                    } catch (Exception e) {
                        echo '❌ 测试失败!'
                        currentBuild.result = 'FAILURE'
                        error("测试阶段失败: ${e.getMessage()}")
                    }
                }
            }
            post {
                always {
                    // 发布测试报告
                    script {
                        if (fileExists('target/surefire-reports/*.xml')) {
                            junit 'target/surefire-reports/*.xml'
                        }
                    }
                }
            }
        }
        
        stage('📦 打包应用') {
            steps {
                echo '开始打包应用...'
                script {
                    if (fileExists('pom.xml')) {
                        sh 'mvn package -DskipTests'
                        archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
                    } else if (fileExists('package.json')) {
                        sh 'npm run package'
                        archiveArtifacts artifacts: 'dist/**/*', fingerprint: true
                    }
                }
                echo '📦 应用打包完成!'
            }
        }
        
        stage('🚀 部署应用') {
            steps {
                script {
                    echo "正在部署到 ${params.DEPLOY_ENV} 环境..."
                    
                    switch(params.DEPLOY_ENV) {
                        case 'dev':
                            sh './deploy.sh dev'
                            env.APP_URL = 'http://dev.myapp.com'
                            break
                        case 'test':
                            sh './deploy.sh test'
                            env.APP_URL = 'http://test.myapp.com'
                            break
                        case 'prod':
                            // 生产环境需要额外确认
                            input message: '确认部署到生产环境?', ok: '确认部署'
                            sh './deploy.sh prod'
                            env.APP_URL = 'http://www.myapp.com'
                            break
                    }
                    
                    echo "🎉 部署完成!访问地址: ${env.APP_URL}"
                }
            }
        }
        
        stage('✅ 验证部署') {
            steps {
                echo '正在验证部署结果...'
                script {
                    // 健康检查
                    sh """
                        echo "等待应用启动..."
                        sleep 30
                        
                        echo "检查应用健康状态..."
                        curl -f ${env.APP_URL}/health || exit 1
                        
                        echo "应用部署验证成功!✅"
                    """
                }
            }
        }
    }
    
    post {
        always {
            echo '📊 构建后清理工作...'
            script {
                // 计算构建时长
                def duration = currentBuild.duration
                def durationString = "${Math.round(duration/1000)}秒"
                echo "⏱️ 总构建时长: ${durationString}"
            }
        }
        
        success {
            echo '🎉 构建成功!'
            script {
                // 发送成功通知
                emailext (
                    subject: "✅ 构建成功: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                    body: """
                        <h2>🎉 构建成功通知</h2>
                        <p><strong>项目:</strong> ${env.JOB_NAME}</p>
                        <p><strong>构建编号:</strong> ${env.BUILD_NUMBER}</p>
                        <p><strong>部署环境:</strong> ${params.DEPLOY_ENV}</p>
                        <p><strong>应用地址:</strong> <a href="${env.APP_URL}">${env.APP_URL}</a></p>
                        <p><strong>构建时间:</strong> ${new Date().format('yyyy-MM-dd HH:mm:ss')}</p>
                        <p><strong>Git提交:</strong> ${env.GIT_COMMIT_SHORT}</p>
                        
                        <p>构建详情请查看: <a href="${env.BUILD_URL}">点击查看</a></p>
                    """,
                    mimeType: 'text/html',
                    to: 'team@company.com'
                )
            }
        }
        
        failure {
            echo '❌ 构建失败!'
            script {
                // 发送失败通知
                emailext (
                    subject: "❌ 构建失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                    body: """
                        <h2>❌ 构建失败通知</h2>
                        <p><strong>项目:</strong> ${env.JOB_NAME}</p>
                        <p><strong>构建编号:</strong> ${env.BUILD_NUMBER}</p>
                        <p><strong>失败阶段:</strong> ${env.STAGE_NAME}</p>
                        <p><strong>构建时间:</strong> ${new Date().format('yyyy-MM-dd HH:mm:ss')}</p>
                        
                        <p>请及时处理构建问题。</p>
                        <p>构建详情请查看: <a href="${env.BUILD_URL}">点击查看</a></p>
                        <p>控制台日志: <a href="${env.BUILD_URL}console">查看日志</a></p>
                    """,
                    mimeType: 'text/html',
                    to: 'team@company.com'
                )
            }
        }
        
        unstable {
            echo '⚠️ 构建不稳定!'
            // 处理不稳定状态的逻辑
        }
    }
}

6. Pipeline详解

6.1 声明式Pipeline vs 脚本式Pipeline

声明式Pipeline(推荐)
// 声明式Pipeline - 结构化、易读
pipeline {
    agent any
    
    tools {
        maven 'Maven-3.8'
        jdk 'JDK-11'
    }
    
    environment {
        MAVEN_OPTS = '-Xmx1024m'
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean compile'
            }
        }
        
        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }
    }
}
脚本式Pipeline(灵活)
// 脚本式Pipeline - 更灵活,但复杂
node {
    try {
        stage('Checkout') {
            checkout scm
        }
        
        stage('Build') {
            if (isUnix()) {
                sh 'mvn clean compile'
            } else {
                bat 'mvn clean compile'
            }
        }
        
        stage('Test') {
            if (env.BRANCH_NAME == 'main') {
                sh 'mvn test'
                junit 'target/surefire-reports/*.xml'
            } else {
                echo 'Skipping tests for feature branch'
            }
        }
        
    } catch (Exception e) {
        currentBuild.result = 'FAILURE'
        throw e
    } finally {
        cleanWs()
    }
}

6.2 Pipeline高级特性

并行执行
pipeline {
    agent none
    
    stages {
        stage('Parallel Testing') {
            parallel {
                stage('Unit Tests') {
                    agent { label 'linux' }
                    steps {
                        sh 'mvn test'
                    }
                    post {
                        always {
                            junit 'target/surefire-reports/*.xml'
                        }
                    }
                }
                
                stage('Integration Tests') {
                    agent { label 'docker' }
                    steps {
                        sh 'mvn verify -Pintegration-tests'
                    }
                }
                
                stage('Security Scan') {
                    agent any
                    steps {
                        sh 'sonar-scanner'
                    }
                }
            }
        }
        
        stage('Deploy') {
            steps {
                echo 'All tests passed, deploying...'
            }
        }
    }
}
条件执行
pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
        
        stage('Deploy to Dev') {
            when {
                branch 'develop'
            }
            steps {
                sh './deploy.sh dev'
            }
        }
        
        stage('Deploy to Staging') {
            when {
                branch 'main'
            }
            steps {
                sh './deploy.sh staging'
            }
        }
        
        stage('Deploy to Production') {
            when {
                allOf {
                    branch 'main'
                    environment name: 'DEPLOY_TO_PROD', value: 'true'
                }
            }
            steps {
                input message: 'Deploy to production?', ok: 'Deploy'
                sh './deploy.sh production'
            }
        }
        
        stage('Weekend Deployment') {
            when {
                // 只在工作日部署
                not { 
                    anyOf {
                        expression { return Date.parse("EEE", new Date().format("EEE")) in ["Sat", "Sun"] }
                    }
                }
            }
            steps {
                echo 'Deploying on weekday'
            }
        }
    }
}
矩阵构建
pipeline {
    agent none
    
    stages {
        stage('Build Matrix') {
            matrix {
                axes {
                    axis {
                        name 'JAVA_VERSION'
                        values '8', '11', '17'
                    }
                    axis {
                        name 'OS'
                        values 'linux', 'windows', 'mac'
                    }
                }
                excludes {
                    exclude {
                        axis {
                            name 'JAVA_VERSION'
                            values '8'
                        }
                        axis {
                            name 'OS'
                            values 'mac'
                        }
                    }
                }
                stages {
                    stage('Build') {
                        agent {
                            label "${OS}"
                        }
                        tools {
                            jdk "JDK-${JAVA_VERSION}"
                        }
                        steps {
                            sh "java -version"
                            sh "mvn clean package"
                        }
                    }
                }
            }
        }
    }
}

6.3 共享库

创建可重用的Pipeline代码:

共享库结构
jenkins-shared-library/
├── vars/
│   ├── buildJavaApp.groovy
│   ├── deployApp.groovy
│   └── sendNotification.groovy
├── src/
│   └── com/
│       └── company/
│           └── jenkins/
│               └── Utils.groovy
└── resources/
    ├── scripts/
    │   └── deploy.sh
    └── templates/
        └── email.html
共享库代码
// vars/buildJavaApp.groovy
def call(Map config) {
    pipeline {
        agent any
        
        tools {
            maven config.mavenVersion ?: 'Maven-3.8'
            jdk config.jdkVersion ?: 'JDK-11'
        }
        
        stages {
            stage('Checkout') {
                steps {
                    git url: config.gitUrl, branch: config.branch ?: 'main'
                }
            }
            
            stage('Build') {
                steps {
                    sh 'mvn clean compile'
                }
            }
            
            stage('Test') {
                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: 'Coverage Report'
                        ])
                    }
                }
            }
            
            stage('Package') {
                steps {
                    sh 'mvn package -DskipTests'
                    archiveArtifacts artifacts: 'target/*.jar'
                }
            }
            
            stage('Deploy') {
                when {
                    expression { config.deploy == true }
                }
                steps {
                    deployApp([
                        environment: config.environment,
                        artifact: 'target/*.jar'
                    ])
                }
            }
        }
        
        post {
            always {
                sendNotification([
                    status: currentBuild.result,
                    recipients: config.notifications
                ])
            }
        }
    }
}

// vars/deployApp.groovy
def call(Map config) {
    script {
        def environment = config.environment
        def artifact = config.artifact
        
        echo "Deploying ${artifact} to ${environment}"
        
        switch(environment) {
            case 'dev':
                sh "./deploy.sh dev ${artifact}"
                break
            case 'staging':
                sh "./deploy.sh staging ${artifact}"
                break
            case 'production':
                input message: 'Deploy to production?', ok: 'Deploy'
                sh "./deploy.sh production ${artifact}"
                break
            default:
                error "Unknown environment: ${environment}"
        }
    }
}

// vars/sendNotification.groovy
def call(Map config) {
    script {
        def status = config.status ?: currentBuild.result
        def recipients = config.recipients ?: 'team@company.com'
        
        def subject = "Jenkins Build ${status}: ${env.JOB_NAME} - ${env.BUILD_NUMBER}"
        def body = """
            Build ${status}!
            
            Job: ${env.JOB_NAME}
            Build Number: ${env.BUILD_NUMBER}
            Build URL: ${env.BUILD_URL}
            
            Console Output:
            ${env.BUILD_URL}console
        """
        
        if (status == 'SUCCESS') {
            body = "✅ " + body
        } else {
            body = "❌ " + body
        }
        
        emailext(
            subject: subject,
            body: body,
            to: recipients
        )
    }
}
使用共享库
// Jenkinsfile
@Library('jenkins-shared-library') _

buildJavaApp([
    gitUrl: 'https://github.com/company/my-app.git',
    branch: 'main',
    mavenVersion: 'Maven-3.8',
    jdkVersion: 'JDK-11',
    deploy: true,
    environment: 'staging',
    notifications: 'team@company.com'
])

7. 插件系统

7.1 必备插件推荐

基础功能插件
Git插件:
  - Git: Git仓库集成
  - GitHub: GitHub集成
  - GitLab: GitLab集成
  - Bitbucket: Bitbucket集成

构建工具插件:
  - Maven Integration: Maven项目支持
  - Gradle: Gradle项目支持
  - NodeJS: Node.js项目支持
  - Docker: Docker容器支持

通知插件:
  - Email Extension: 增强邮件通知
  - Slack Notification: Slack集成
  - DingTalk: 钉钉通知
  - WeChat Work: 企业微信通知
质量管理插件
代码质量:
  - SonarQube Scanner: 代码质量检查
  - Checkstyle: Java代码风格检查
  - FindBugs: Java静态分析
  - PMD: 代码质量分析

测试报告:
  - JUnit: 单元测试报告
  - TestNG Results: TestNG测试报告
  - Coverage: 代码覆盖率报告
  - Performance: 性能测试报告

安全扫描:
  - OWASP Dependency Check: 依赖安全检查
  - Anchore Container Image Scanner: 容器镜像安全扫描

7.2 插件安装和配置

通过Web界面安装
1. 进入 Manage Jenkins → Manage Plugins
2. 选择 Available 标签页
3. 搜索需要的插件
4. 选择插件并点击 "Install without restart"
5. 等待安装完成
通过命令行安装
# 使用jenkins-cli安装插件
java -jar jenkins-cli.jar -s http://localhost:8080/ install-plugin git
java -jar jenkins-cli.jar -s http://localhost:8080/ install-plugin maven-plugin
java -jar jenkins-cli.jar -s http://localhost:8080/ install-plugin docker-plugin

# 重启Jenkins
java -jar jenkins-cli.jar -s http://localhost:8080/ restart
通过插件配置文件批量安装
# plugins.txt
git:latest
maven-plugin:latest
docker-plugin:latest
email-ext:latest
slack:latest
sonar:latest
junit:latest
workflow-aggregator:latest
blueocean:latest
# 使用Docker安装插件
FROM jenkins/jenkins:lts
COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt

7.3 常用插件配置示例

Blue Ocean配置
// Blue Ocean提供现代化的Pipeline视图
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                echo 'Building...'
            }
        }
        stage('Test') {
            parallel {
                stage('Unit Tests') {
                    steps {
                        echo 'Running unit tests...'
                    }
                }
                stage('Integration Tests') {
                    steps {
                        echo 'Running integration tests...'
                    }
                }
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying...'
            }
        }
    }
}
SonarQube集成
pipeline {
    agent any
    
    tools {
        jdk 'JDK-11'
        maven 'Maven-3.8'
    }
    
    environment {
        SONAR_TOKEN = credentials('sonar-token')
    }
    
    stages {
        stage('Checkout') {
            steps {
                git 'https://github.com/company/project.git'
            }
        }
        
        stage('Build') {
            steps {
                sh 'mvn clean compile'
            }
        }
        
        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }
        
        stage('SonarQube Analysis') {
            steps {
                withSonarQubeEnv('SonarQube') {
                    sh """
                        mvn sonar:sonar \
                        -Dsonar.projectKey=my-project \
                        -Dsonar.host.url=${SONAR_HOST_URL} \
                        -Dsonar.login=${SONAR_TOKEN}
                    """
                }
            }
        }
        
        stage('Quality Gate'

网站公告

今日签到

点亮在社区的每一天
去签到