创建 Jenkinsfile
创建一个检入到源码管理系统中 [1] 的 Jenkinsfile 带来了一些直接的好处:
- 流水线上的代码评审/迭代
- 对流水线进行审计跟踪
- 流水线的单一可信数据源 ,能够被项目的多个成员查看和编辑。
Jenkinsfile 是一个文本文件,它包含了 Jenkins 流水线的定义并被检入源代码控制仓库。下面的流水线实现了基本的三阶段持续交付流水线。
pipeline {agent anystages {stage('Build') {steps {echo 'Building..'}}stage('Test') {steps {echo 'Testing..'}}stage('Deploy') {steps {echo 'Deploying....'}}}
}
上面的声明式流水线示例包含了实现持续交付流水线的最小必要结构。agent指令是必需的,它指示 Jenkins 为流水线分配一个执行器和工作区。没有 agent 指令的话,声明式流水线不仅无效,它也不可能完成任何工作!默认情况下,agent 指令确保源代码仓库被检出并在后续阶段的步骤中可被使用。
构建
对于许多项目来说,流水线“工作”的开始就是“构建”阶段。通常流水线的这个阶段包括源代码的组装、编译或打包。Jenkinsfile 文件不能替代现有的构建工具,如 GNU/Make、Maven、Gradle 等,而应视其为一个将项目的开发生命周期的多个阶段(构建、测试、部署等)绑定在一起的粘合层。
Jenkins 有许多插件可以用于调用几乎所有常用的构建工具,不过这个例子只是从 shell 步骤(sh)调用 make。sh 步骤假设系统是基于 Unix/Linux 的,对于基于 Windows 的系统可以使用 bat 替代。
pipeline {agent anystages {stage('Build') {steps {sh 'make' archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true }}}
}
sh 步骤调用 make 命令,只有命令返回的状态码为零时才会继续。任何非零的返回码都将使流水线失败。
archiveArtifacts 捕获符合模式(**/target/*.jar
)匹配的交付件并将其保存到 Jenkins master 节点以供后续获取。
测试
运行自动化测试是任何成功的持续交付过程的重要组成部分。因此,Jenkins 有许多测试记录,报告和可视化工具,这些都是由各种插件提供的。最基本的,当测试失败时,让 Jenkins 记录这些失败以供汇报以及在 web UI 中可视化是很有用的。下面的例子使用由 JUnit 插件提供的 junit 步骤。
在下面的例子中,如果测试失败,流水线就会被标记为“不稳定”,这通过 web UI 中的黄色球表示。基于测试报告的记录,Jenkins 还可以提供历史趋势分析和可视化。
pipeline {agent anystages {stage('Test') {steps {sh 'make check || true' junit '**/target/*.xml' }}}
}
使用内联的 shell 条件(sh ‘make || true’)确保 sh 步骤总是看到退出码是零,使 junit 步骤有机会捕获和处理测试报告。在下面处理故障一节中,对它的替代方法有更详细的介绍。
junit 捕获并关联与包含模式(*/target/.xml)匹配的 JUnit XML 文件。
部署
部署可以隐含许多步骤,这取决于项目或组织的要求,并且可能是从发布构建的交付件到 Artifactory 服务器,到将代码推送到生产系统的任何东西。 在示例流水线的这个阶段,“Build(构建)” 和 “Test(测试)” 阶段都已成功执行。从本质上讲,“Deploy(部署)” 阶段只有在之前的阶段都成功完成后才会进行,否则流水线会提前退出。
pipeline {agent anystages {stage('Deploy') {when {expression {currentBuild.result == null || currentBuild.result == 'SUCCESS' }}steps {sh 'make publish'}}}
}
流水线访问 currentBuild.result 变量确定是否有任何测试的失败。在这种情况下,值为 UNSTABLE。
使用 Jenkinsfile 工作
字符串插值
def singlyQuoted = 'Hello'
def doublyQuoted = "World"
def username = 'Jenkins'
echo 'Hello Mr. ${username}'
echo "I said, Hello Mr. ${username}"
其结果是:
Hello Mr. ${username}
I said, Hello Mr. Jenkins
使用环境变量官方
pipeline {agent anystages {stage('Example') {steps {echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"}}}
}
设置环境变量官方
pipeline {agent anyenvironment { CC = 'clang'}stages {stage('Example') {environment { DEBUG_FLAGS = '-g'}steps {sh 'printenv'}}}
}
动态设置环境变量官方
pipeline {agent any environment {CC = """${sh(returnStdout: true,script: 'echo "clang"')}""" EXIT_STATUS = """${sh(returnStatus: true,script: 'exit 1')}"""}stages {stage('Example') {environment {DEBUG_FLAGS = '-g'}steps {sh 'printenv'}}}
}
处理凭据官方
pipeline {agent {}environment {AWS_ACCESS_KEY_ID = credentials('jenkins-aws-secret-key-id')AWS_SECRET_ACCESS_KEY = credentials('jenkins-aws-secret-access-key')}stages {stage('Example stage 1') {steps {}}stage('Example stage 2') {steps {}}}
}
处理参数官方
pipeline {agent anyparameters {string(name: 'Greeting', defaultValue: 'Hello', description: 'How should I greet the world?')}stages {stage('Example') {steps {echo "${params.Greeting} World!"}}}
}
pipeline {agent anystages {stage('Test') {steps {sh 'make check'}}}post {always {junit '**/target/*.xml'}failure {mail to: team@example.com, subject: 'The Pipeline failed :('}}
}