Jenkins Pipeline入门 - 用代码定义你的构建流程

Jenkins Pipeline入门

一、前言

上一篇文章我们学习了Freestyle项目的使用。虽然Freestyle项目简单易用,但当你需要更复杂的构建流程时,它就显得力不从心了。Jenkins Pipeline是现代Jenkins的核心特性,它用代码来定义整个构建流程,让CI/CD变得既强大又灵活。

二、什么是Jenkins Pipeline

2.1 Pipeline vs Freestyle

先来看一个直观的对比:

Freestyle项目:
✅ 图形界面配置,上手简单
✅ 适合简单的构建任务
❌ 无法定义复杂的流程
❌ 配置无法版本控制
❌ 难以复用和迁移

Pipeline项目:
✅ 代码定义流程,强大灵活
✅ 支持复杂的条件判断和循环
✅ Jenkinsfile可以和代码一起版本控制
✅ 可复用、可迁移、可审计
❌ 需要学习Groovy DSL语法

2.2 Pipeline的核心概念

  • Pipeline(流水线):整个构建流程的定义,从代码拉取到部署上线
  • Node(节点):Pipeline执行的环境,可以是Master或Agent
  • Stage(阶段):Pipeline中的一个逻辑步骤,如"编译"、"测试"、"部署"
  • Step(步骤):Stage中的具体操作,如 shgitecho
  • Agent(代理):指定Pipeline在哪个节点上执行

2.3 两种Pipeline语法

Jenkins支持两种Pipeline语法:

  • Declarative Pipeline(声明式):新语法,结构化强,推荐使用
  • Scripted Pipeline(脚本式):旧语法,更灵活但更复杂

本文重点讲解 Declarative Pipeline,这是目前推荐的方式。

三、Declarative Pipeline基础语法

3.1 最简单的Pipeline

pipeline {
    agent any
    
    stages {
        stage('Hello') {
            steps {
                echo 'Hello, Jenkins Pipeline!'
            }
        }
    }
}

解析:

  • pipeline:声明这是一个Pipeline
  • agent any:可以在任何可用节点上执行
  • stages:包含所有阶段的容器
  • stage('Hello'):定义一个名为"Hello"的阶段
  • steps:阶段内的具体步骤
  • echo:输出文本到控制台

3.2 多阶段Pipeline

pipeline {
    agent any
    
    stages {
        stage('Checkout') {
            steps {
                echo '拉取代码...'
                git 'https://github.com/username/project.git'
            }
        }
        
        stage('Build') {
            steps {
                echo '编译构建...'
                sh 'mvn clean package -DskipTests'
            }
        }
        
        stage('Test') {
            steps {
                echo '运行测试...'
                sh 'mvn test'
            }
        }
        
        stage('Deploy') {
            steps {
                echo '部署上线...'
                sh './deploy.sh'
            }
        }
    }
}

这个Pipeline定义了四个阶段:拉取代码 → 编译构建 → 运行测试 → 部署上线。在Jenkins的Stage View中,你会看到非常直观的阶段视图。

四、Agent详解

agent指令决定Pipeline在哪里执行。

4.1 agent类型

// 在任何可用节点执行
agent any

// 不在agent上执行(需要在每个stage单独指定)
agent none

// 在指定标签的节点执行
agent { label 'linux && docker' }

// 在Docker容器中执行
agent {
    docker {
        image 'maven:3.8-openjdk-17'
        args '-v $HOME/.m2:/root/.m2'
    }
}

// 在Kubernetes Pod中执行
agent {
    kubernetes {
        yaml '''
        apiVersion: v1
        kind: Pod
        spec:
          containers:
          - name: maven
            image: maven:3.8-openjdk-17
            command:
            - cat
            tty: true
        '''
    }
}

4.2 不同阶段使用不同agent

pipeline {
    agent none  // 全局不指定agent
    
    stages {
        stage('Build') {
            agent { 
                docker { 
                    image 'maven:3.8-openjdk-17' 
                } 
            }
            steps {
                sh 'mvn clean package'
            }
        }
        
        stage('Test') {
            agent { 
                docker { 
                    image 'node:18-alpine' 
                } 
            }
            steps {
                sh 'npm test'
            }
        }
        
        stage('Deploy') {
            agent { label 'production' }
            steps {
                sh './deploy.sh'
            }
        }
    }
}

五、环境变量

5.1 定义环境变量

pipeline {
    agent any
    
    environment {
        APP_NAME = 'my-application'
        VERSION = "1.0.${BUILD_NUMBER}"
        DEPLOY_ENV = 'production'
    }
    
    stages {
        stage('Build') {
            steps {
                echo "应用名称: ${APP_NAME}"
                echo "构建版本: ${VERSION}"
                echo "部署环境: ${DEPLOY_ENV}"
            }
        }
    }
}

5.2 使用凭据作为环境变量

pipeline {
    agent any
    
    environment {
        // 引用Jenkins凭据
        DOCKER_CREDS = credentials('docker-hub-credentials')
        DB_PASSWORD = credentials('db-password')
    }
    
    stages {
        stage('Docker Push') {
            steps {
                sh 'docker login -u ${DOCKER_CREDS_USR} -p ${DOCKER_CREDS_PSW}'
                sh 'docker push myapp:${VERSION}'
            }
        }
    }
}

注意:使用credentials()函数时,用户名和密码会自动拆分为 变量名_USR变量名_PSW

六、Jenkinsfile

Jenkinsfile是Pipeline的代码文件,通常放在项目根目录,和代码一起提交到Git仓库。

6.1 Jenkinsfile示例

// Jenkinsfile - 放在项目根目录
pipeline {
    agent any
    
    environment {
        APP_NAME = 'my-app'
        REGISTRY = 'registry.example.com'
    }
    
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        
        stage('Build') {
            steps {
                sh 'mvn clean package -DskipTests'
            }
        }
        
        stage('Test') {
            steps {
                sh 'mvn test'
            }
        }
        
        stage('Docker Build') {
            steps {
                sh "docker build -t ${REGISTRY}/${APP_NAME}:${BUILD_NUMBER} ."
            }
        }
        
        stage('Docker Push') {
            steps {
                withCredentials([usernamePassword(
                    credentialsId: 'docker-hub-credentials',
                    usernameVariable: 'DOCKER_USER',
                    passwordVariable: 'DOCKER_PASS'
                )]) {
                    sh "docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} ${REGISTRY}"
                    sh "docker push ${REGISTRY}/${APP_NAME}:${BUILD_NUMBER}"
                }
            }
        }
    }
    
    post {
        always {
            cleanWs()  // 清理工作空间
        }
        success {
            echo '构建成功!✅'
        }
        failure {
            echo '构建失败!❌'
        }
    }
}

6.2 创建Pipeline项目

在Jenkins中创建Pipeline项目:

  • 1. New Item → 输入名称 → 选择 "Pipeline"
  • 2. 在Pipeline部分,Definition选择 "Pipeline script from SCM"
  • 3. SCM选择 "Git"
  • 4. 填写仓库地址和凭据
  • 5. Script Path填写 "Jenkinsfile"(默认值)
  • 6. 保存并构建

这样Jenkins就会从Git仓库拉取代码,并自动执行Jenkinsfile中定义的流程。

6.3 Pipeline script vs Pipeline script from SCM

  • Pipeline script:直接在Jenkins界面写Pipeline代码。适合测试和学习。
  • Pipeline script from SCM:从Git仓库读取Jenkinsfile。适合生产环境,可以实现Pipeline即代码。

七、Pipeline内置步骤

7.1 常用步骤

// 输出文本
echo 'Hello World'

// 执行Shell命令
sh 'ls -la'
sh returnStdout: true, script: 'git rev-parse HEAD'  // 获取输出

// 执行Windows命令
bat 'dir'

// 检出代码
checkout scm
git 'https://github.com/user/repo.git'
git url: 'https://github.com/user/repo.git', branch: 'main', credentialsId: 'git-creds'

// 等待用户输入
input '确认部署到生产环境?'

// 超时控制
timeout(time: 10, unit: 'MINUTES') {
    sh 'long-running-script.sh'
}

// 重试
retry(3) {
    sh 'flaky-test.sh'
}

// 暂停
sleep(time: 30, unit: 'SECONDS')

7.2 文件操作

// 读取文件
def content = readFile 'config.json'

// 写入文件
writeFile file: 'output.txt', text: 'Hello Jenkins'

// 读取JSON
def config = readJSON file: 'config.json'
echo "App name: ${config.appName}"

// 读取YAML
def yaml = readYaml file: 'docker-compose.yml'

// 归档构建产物
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true

八、post动作

post块定义Pipeline执行完成后的动作,类似于"finally"。

pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
    }
    
    post {
        always {
            // 无论成功还是失败都会执行
            echo 'Pipeline执行完毕'
            cleanWs()  // 清理工作空间
        }
        
        success {
            // 只有成功时执行
            echo '🎉 构建成功!'
            archiveArtifacts artifacts: 'target/*.jar'
            mail to: 'team@company.com',
                 subject: "构建成功: ${JOB_NAME} #${BUILD_NUMBER}",
                 body: "构建成功!详情查看: ${BUILD_URL}"
        }
        
        failure {
            // 只有失败时执行
            echo '💥 构建失败!'
            mail to: 'team@company.com',
                 subject: "构建失败: ${JOB_NAME} #${BUILD_NUMBER}",
                 body: "构建失败,请检查!详情查看: ${BUILD_URL}"
        }
        
        unstable {
            // 构建不稳定时执行
            echo '⚠️ 构建不稳定'
        }
        
        aborted {
            // 构建被中止时执行
            echo '🛑 构建被中止'
        }
        
        changed {
            // 构建状态发生变化时执行
            echo '构建状态发生了变化'
        }
    }
}

九、Pipeline片段生成器

不知道Pipeline语法怎么写?Jenkins内置了片段生成器,帮你自动生成代码!

使用方法:

  • 1. 进入你的Pipeline项目
  • 2. 点击左侧 "Pipeline Syntax"
  • 3. 在"Snippet Generator"中:
  • 4. 选择步骤类型(如sh、git、withCredentials)
  • 5. 填写表单
  • 6. 点击"Generate Pipeline Script"
  • 7. 复制生成的代码到你的Pipeline中

这是学习Pipeline语法的最佳工具!

十、总结

本文详细介绍了Jenkins Pipeline的基础知识:

  • Pipeline概念:用代码定义构建流程,比Freestyle更强大
  • Declarative语法:pipeline → agent → stages → stage → steps
  • Agent配置:any、none、label、docker、kubernetes
  • 环境变量:environment块和credentials()函数
  • Jenkinsfile:Pipeline即代码,和项目一起版本管理
  • 内置步骤:echo、sh、git、timeout、retry等
  • post动作:always、success、failure等条件处理

下一篇我们将学习Pipeline的进阶用法:条件判断、并行执行和更复杂的流程控制!

发表回复

后才能评论