Skip to content

Pipeline

Jenkins Pipeline 是用 代码(Groovy DSL) 描述的自动化流程,支持版本控制,重现性好。

两种主要类型:

  • Declarative Pipeline(声明式) ✅ 推荐,语法清晰易维护
  • Scripted Pipeline(脚本式) 适合高级场景,写法更灵活但复杂

执行单位

  • Agent:指定在哪个节点/容器中运行任务
  • Stage:阶段,表示一个阶段性任务(如 构建、测试、部署)
  • Step:步骤,具体的命令或操作
  • Environment:环境变量配置
  • Post:执行完阶段或 Pipeline 后的清理逻辑(如 always, success, failure)

语法

groovy
pipeline {
  agent any  // 或 kubernetes、docker、label、自定义

  environment {
    MAVEN_OPTS = "-Dmaven.repo.local=/cache/.m2"
  }

  options {
    timeout(time: 30, unit: 'MINUTES')
    skipDefaultCheckout() // 禁用自动 checkout
  }

  parameters {
    string(name: 'BRANCH', defaultValue: 'main', description: '构建分支')
  }

  stages {
    stage('Checkout') {
      steps {
        git branch: "${params.BRANCH}", url: 'https://github.com/xxx/your-repo.git'
      }
    }

    stage('Build') {
      steps {
        sh 'mvn clean package -DskipTests'
      }
    }

    stage('Deploy') {
      steps {
        sshagent(['ssh-key-cred-id']) {
          sh '''
          ssh user@host "docker run -d your-image"
          '''
        }
      }
    }
  }

  post {
    success {
      echo "构建成功!"
    }
    failure {
      echo "构建失败!"
    }
  }
}

Agent

  1. 全局 Agent(整个 Pipeline 使用同一个环境)
groovy
agent {
  kubernetes {
    yamlFile 'jenkins/agent-pod.yaml'  // 指定 agent pod 定义
  }
}
  1. 分阶段 Agent(每个 Stage 使用不同的 agent)
groovy
stage('Build') {
  agent {
    docker {
      image 'maven:3.9.6-eclipse-temurin-17'
      args '-v /root/.m2:/root/.m2'
    }
  }
  steps {
    sh 'mvn clean package'
  }
}

自定义的 Agent

  1. 构建 Agent 镜像
dockerfile
FROM jenkins/inbound-agent:4.13.3-1

USER root

# 安装依赖
RUN apt-get update && apt-get install -y curl tar unzip && rm -rf /var/lib/apt/lists/*

# 安装 JDK 8(Temurin)
ENV JAVA_VERSION=8u402-b06
ENV JAVA_HOME=/opt/java/openjdk
RUN mkdir -p $JAVA_HOME && \
    curl -L https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u402-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u402b06.tar.gz \
    | tar -xz -C $JAVA_HOME --strip-components=1 && \
    ln -s $JAVA_HOME/bin/java /usr/bin/java && \
    ln -s $JAVA_HOME/bin/javac /usr/bin/javac

ENV PATH=$JAVA_HOME/bin:$PATH

# 安装 Maven
ENV MAVEN_VERSION=3.9.6
RUN curl -fsSL https://downloads.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
    | tar -xz -C /opt && \
    ln -s /opt/apache-maven-${MAVEN_VERSION} /opt/maven

ENV MAVEN_HOME=/opt/maven
ENV PATH=$MAVEN_HOME/bin:$PATH

# 切回 jenkins 用户
USER jenkins
  1. 编辑 Helm jenkins values
yaml
agent:
  customJenkinsLabels: build-agent
  image: your-registry/jenkins-agent:jdk17-maven396
  tag: latest
  alwaysPullImage: true
  1. upgrade
shell
helm upgrade jenkins jenkins/jenkins -f values.yaml

环境变量

enironment

groovy
pipeline {
    agent any
    environment {
        MY_NAME = "ChatGPT"
        BUILD_ENV = "production"
    }
    stages {
        stage('Print Env') {
            steps {
                echo "Name: ${MY_NAME}"
                echo "Environment: ${env.BUILD_ENV}"
            }
        }
    }
}

stage 或者 step

  • 在某个 stage 或 step 中临时设置
groovy
pipeline {
    agent any
    stages {
        stage('Temp Env') {
            steps {
                withEnv(["TEMP_VAR=123", "FOO=bar"]) {
                    sh 'echo $TEMP_VAR'
                    sh 'echo $FOO'
                }
            }
        }
    }
}

shell

  • 在 Shell 中直接定义(仅限 sh、bat 命令作用域)
groovy
pipeline {
    agent any
    stages {
        stage('Inline Shell') {
            steps {
                sh '''
                    export TEMP_VAR=inline
                    echo $TEMP_VAR
                '''
            }
        }
    }
}

预定义环境变量

变量名含义
BUILD_NUMBER当前构建编号
BUILD_ID构建 ID(时间戳)
JOB_NAME当前 Job 名称
WORKSPACE当前工作目录
BRANCH_NAMESCM 分支名称(如 Git 分支)
GIT_COMMIT当前提交的 Git hash 值
shell
echo "Build number: ${env.BUILD_NUMBER}"

参数化构建

Jenkins 会在用户点击“Build with Parameters”按钮时弹出这些参数选项,让用户输入或选择

groovy
pipeline {
    agent any

    parameters {
        string(name: 'BRANCH', defaultValue: 'main', description: 'Git 分支')
        choice(name: 'ENV', choices: ['dev', 'test', 'prod'], description: '部署环境')
    }

    environment {
        // 可以设置为环境变量
        DEPLOY_ENV = "${params.ENV}"
    }

    stages {
        stage('Checkout') {
            steps {
                echo "拉取分支:${params.BRANCH}"
                checkout([$class: 'GitSCM',
                    branches: [[name: "*/${params.BRANCH}"]],
                    userRemoteConfigs: [[url: 'git@github.com:your/repo.git']]
                ])
            }
        }

        stage('Deploy') {
            steps {
                echo "部署环境是:${params.ENV}"
                sh '''
                    echo 正在部署到环境: $DEPLOY_ENV
                '''
            }
        }
    }
}

构建示例

Groovy
pipeline {
  agent {
    kubernetes {
      label 'build-agent'
      yaml """
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: maven
    image: your-registry/jenkins-agent:jdk8-maven396
    command:
    - cat
    tty: true
"""
    }
  }

  environment {
    // 远程服务器SSH配置
    REMOTE_HOST = 'your.remote.server.ip'
    REMOTE_USER = 'your_ssh_user'
    // 需在 Jenkins 凭据管理添加 SSH 私钥
    SSH_KEY = credentials('your-ssh-key-id')
    DOCKER_IMAGE = "your-docker-repo/your-app:latest"
  }

  stages {
    stage('Checkout') {
      steps {
        git branch: 'main', url: 'git@github.com:your/repo.git'
      }
    }

    stage('Build') {
      steps {
        sh 'mvn clean package -DskipTests'
      }
    }

    stage('Docker Build & Push') {
      steps {
        script {
          docker.withRegistry('https://registry.hub.docker.com', 'dockerhub-credentials') {
            def appImage = docker.build(DOCKER_IMAGE)
            appImage.push()
          }
        }
      }
    }

    stage('Deploy') {
      steps {
        script {
          sshagent(credentials: ['your-ssh-key-id']) {
            sh """
              ssh -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} \\
              'docker pull ${DOCKER_IMAGE} && \\
               docker stop your-container-name || true && \\
               docker rm your-container-name || true && \\
               docker run -d --name your-container-name -p 8080:8080 ${DOCKER_IMAGE}'
            """
          }
        }
      }
    }
  }
}

并行顺序构建

groovy
pipeline {
  agent any

  stages {
    stage('准备阶段') {
      steps {
        echo "准备环境..."
      }
    }

    stage('并行构建模块') {
      parallel {
        stage('模块 A') {
          steps {
            echo "构建模块 A"
          }
        }
        stage('模块 B') {
          steps {
            echo "构建模块 B"
          }
        }
      }
    }

    stage('部署阶段') {
      steps {
        echo "部署中..."
      }
    }
  }
}
  • 动态构建
groovy
def modules = ['a', 'b', 'c']

pipeline {
  agent any
  stages {
    stage('动态并行') {
      steps {
        script {
          def builds = [:]
          for (int i = 0; i < modules.size(); i++) {
            def m = modules[i]
            builds["构建-${m}"] = {
              echo "构建模块 ${m}"
            }
          }
          parallel builds
        }
      }
    }
  }
}

最佳实践

使用 Jenkinsfile

  • 在项目仓库根目录下创建一个名为 Jenkinsfile 的文件。
  • 它使用 Groovy DSL 编写,描述整个流水线逻辑。
  • 支持 声明式(declarative) 或 脚本式(scripted) 两种语法。