在自动化构建和部署的世界里,Jenkins如同一位不知疲倦的工厂主管,而正确配置项目选项就是为这位主管提供清晰的工作说明书。
作为一名开发者,你是否曾经历过这样的困境:深夜加班手动部署服务器,反复检查每一步操作,生怕一不小心就把生产环境搞崩了?或是好不容易写完代码,却要在不同的环境中反复配置,耗费大量时间和精力?
Jenkins就像是你团队中的一位永不疲倦的构建工程师,它能够帮你自动化完成编译、测试、部署等一系列繁琐任务。但要让这位"工程师"高效工作,就需要深入了解Jenkins项目的各种配置选项。
想象一下,当你正确配置了Jenkins项目后,它能够做到:代码一提交就自动构建、自动运行测试、自动部署到相应环境,甚至在构建失败时自动发送通知给相关负责人。这样的自动化流程不仅节省了大量时间,也显著降低了人为错误的发生概率。
本文将带你深入浅出地了解Jenkins项目的核心配置选项,并通过实际示例展示如何充分发挥其能力。无论你是初学Jenkins的新手,还是有一定经验想要深入理解的老手,这篇文章都会对你有所帮助。
当你第一次接触Jenkins,可能会被各种项目类型搞得眼花缭乱。就像你要完成不同的任务需要选择合适的工具一样,在Jenkins中也要根据需求选择合适的项目类型。
Jenkins主要提供以下几种项目类型:
Freestyle project(自由风格项目):这是Jenkins的基础功能,可以用它来执行各种构建任务,它只能构建在一个电脑上。如果没有太多的需求,这个job基本够用了,它包含了所有基础功能。Pipeline(流水线):真实的工作环境有很多job,比如先编译,然后执行静态代码检查、单元测试、然后部署服务器、服务器重启、进行UI测试等。我们需要对这些job进行一些设置将它们的上下游关系配置好。这个时候就需要pipeline配置了。External job(外部任务):用来监视外部执行的job。Multi-configuration project(多配置项目):可以让job跑在不同的机器上。这需要添加机器(节点)。文件夹:这是一种可以把多个项目归类到一起的方式,而不是项目本身的类型。它就像操作系统中的目录文件夹。文件夹名称是项目路径的一部分。对于初学者来说,自由风格项目是最容易上手的类型,它提供了清晰的图形化界面和相对简单的配置选项。而随着项目复杂度的增加,Pipeline会成为更强大的选择,它允许你使用代码定义整个构建流程,更容易版本控制和复用。
就像我们要完成任何工作都需要先了解基本要求一样,Jenkins项目的General部分就是为项目定义基本属性的地方。
在General部分,你会找到以下重要设置:
Project name(项目名称):项目的标识符,最好起一个有意义且易于理解的名字。Description(项目描述):对项目进行简单描述,多人协作时请一定要加上。可以包括项目名称、部署的IP地址、部署远程的目录、日志路径等信息。Discard old builds(丢弃旧的构建):每次构建相关的文件都会保存下来,将会渐渐耗光磁盘空间。为此提供两种方式供选择:Days to keep builds(保留构建的天数)和 Max # of builds to keep(要保留的最大构建数量)。例如,可以设置Days to keep builds为30天,Max # of builds to keep为10。This project is parameterized(项目参数化):可以设置用户可输入的参数,没有输入则使用默认值,有字符串、多行字符串、布尔值等可以设置。参数化构建极大地提高了Jenkins项目的灵活性,允许在构建时动态传入值。Disable this project(禁用此项目):停止这个job,当例如源码不可用时,可以暂时勾选这个停止build。Execute concurrent builds if necessary(必要时并发构建):如果可以会并发执行build。勾选上后,如果有足够的线程池则会并发,否则不会。并发构建会在不同的workspace中。Restrict where this project can be run(限制运行位置):设置是否必须在某个特定标签的机器上运行。如果是分布式部署或者迁移job,注意移除或修改此项配置。Quiet period(安静期):配置等待未发生提交变化的时间。由于Jenkins检测到代码变化时,就自动立即构建,但是有些情况下,需要多次提交代码到版本控制系统上,此时可能发生代码还没完整提交就开始构建,造成构建失败。为防止此种情况发生,可以配置值X,则Jenkins会在代码变化后等待X秒,如果没再发生代码提交,才开始构建,保证稳定性。源码管理是Jenkins项目的核心之一,它定义了Jenkins从哪里以及如何获取你的源代码。
Git源码管理
当使用Git进行源码管理时,有两种方式(SSH或HTTPS),任选一种即可。
使用SSH方式: 在本地使用Git生成key:
ssh-keygen -t rsa -C "邮箱地址"将公钥信息添加到Git服务器的SSH keys里在Repository URL输入Git项目SSH地址,添加SSH私钥作为凭证
使用HTTPS方式:在Repository URL输入Git项目HTTPS地址,并添加用户名和密码作为凭证。
在Git配置中,Branches to build指定要构建的分支。对于参数化构建,可以使用变量如
${GIT_COMMIT},对应参数化构建过程中使用的GIT参数名称。
Subversion源码管理
配置相对简单:在Repository URL输入项目的SVN地址,在凭证里添加用户名、密码即可。
选择哪种源码管理工具主要取决于你的项目需求。Git由于其分布式特性和强大的分支管理能力,已成为大多数新项目的首选。但无论选择哪种,正确的源码管理配置都是自动化构建流程的基础。
构建触发器决定了Jenkins项目何时以及如何自动启动,就像给Jenkins设置了一个自动开关。
Trigger builds remotely(远程触发):外部通过URL命令触发,拼接token和URL就可以进行远程触发了。例如,可以通过访问
JENKINS_URL/job/JOBNAME/build?token=TOKENNAME来触发构建。Build after other projects are built(在其他项目构建后构建):监控其他job的构建状态,触发此job。如监听代码提交,然后触发UITest,静态分析等。这对于建立构建流水线非常有用。Build periodically(定期构建):定时触发,它不检查源码是否发生变化。例如,
H 9 * * 1-5表示周一至周五,每天9:00构建一次。定期构建适用于需要定期执行的任务,如每日夜间构建。Poll SCM(轮询SCM):定时检查源码变更,根据SCM软件的版本号,如果有更新就checkout最新代码下来,然后执行构建动作。例如,
H/10 * * * *表示每10分钟检查一次源码变化。与定期构建的区别在于,Poll SCM会检查代码是否更新,只有更新了代码才会触发,而定期构建只是定时执行,不判断代码是否更新。
构建触发器的选择策略
对于持续集成环境,Poll SCM通常是最佳选择,因为它确保只有在代码实际发生变化时才会触发构建,节省资源。对于需要定期执行的任务,如 nightly builds(夜间构建),Build periodically更为合适。
如果需要建立复杂的构建流水线,Build after other projects are built可以让多个项目按照特定顺序触发。
构建环境选项允许你定制构建执行的环境,为构建过程提供额外的控制和功能。
Delete workspace before build starts(构建前删除工作空间):在构建前清理工作空间,确保每次构建都从一个干净的环境开始。还可以设置只删除特定的文件。Abort the build if it's stuck(构建卡住时中止):构建阻塞的时候,根据超时策略处理。可以设置超时策略(绝对时间、相对时间、根据以前的构建时间判断等)和超时后的处理(终结、标记为失败或写描述)。Add timestamps to the Console Output(给控制台输出添加时间戳):在输出界面添加时间戳,方便调试和日志分析。Use secret text(s) or file(使用密文):用于全局性的管理密码等,勾选后会在下方出现Binding,输入需要的用户名、密码证书等就可以了。构建环境的正确配置可以大大提高构建的可靠性和可维护性。例如,定期清理工作空间可以避免残留文件影响构建结果,而设置超时策略可以防止卡住的构建无限期占用执行器资源。
构建部分是Jenkins项目的核心,所有的任务都是通过构建步骤完成的。可以根据需求建立一个或者多个构建步骤,这些步骤是串行执行的,一个失败,后面的步骤都不会执行了。
常见的构建步骤包括:
Execute Windows batch command(执行Windows批处理命令):执行Windows下的命令,类似于在计算机端输入cmd。例如:
python D:project est.py。Execute shell(执行Shell脚本):执行Linux下的脚本命令。例如:
python /Users/pc009/desktop/project/test.py。Invoke Gradle script(调用Gradle脚本):专门用于执行Gradle构建的步骤。
对于复杂的构建过程,可以顺序添加多个构建步骤,形成一条构建流水线。例如:
第一个构建执行Python的环境部署脚本第二个构建执行Python自动化测试脚本Jenkins推荐将过长的命令写到下载的源码里,由构建步骤中的shell命令调用。Jenkins执行的时候会默认把所有的命令都打印出来,这样方便调试。
构建后操作是在构建完成后执行的一些收尾工作,无论构建成功还是失败都会执行到这一步。
常用的构建后操作包括:
Build other projects(构建其他项目):完成之后执行另外一个构建任务,只需要输入已存在的项目即可。可以设置触发下一个构建的条件:只有构建稳定时触发、构建不稳定也依然触发、即便构建失败也会触发。E-mail Notification(邮件通知):发送邮件常用功能,只需要输入收件人的邮箱地址即可。可以设置每次不稳定的构建都发送邮件通知,或单独发送邮件给对方构建造成不良影响的责任人。Publish HTML reports(发布HTML报告):发布HTML报告,可以配置HTML目录、索引页面和报告标题等。Editable Email Notification(可编辑邮件通知):更灵活的邮件通知配置,可以自定义邮件主题、内容类型和默认内容等。合理的构建后操作能够让团队及时了解构建状态,自动生成测试报告,并触发下游任务,形成完整的自动化流程。
Pipeline是通过Jenkinsfile描述的流水线,采用代码即基础设施(Infrastructure as Code)的理念,将整个构建流程定义为代码。
与自由风格项目相比,Pipeline具有以下优势:
版本控制:Pipeline定义(Jenkinsfile)可以与其他源代码一起存储在版本控制系统中可复用性:可以在多个项目间复用Pipeline定义复杂流程支持:更容易实现复杂的构建流程,如并行执行、条件判断等可维护性:通过代码定义流程,更容易理解和维护Jenkinsfile的组成主要包括:
指定node节点/workspace指定运行选项指定stages阶段指定构建后操作agent部分
agent用于指定pipeline的执行位置,可选参数包括:
any:表示任何可用的节点上执行pipelinenone:为agent的默认值label:表示在指定节点上运行node:表示允许额外的选项示例:
agent {
node {
label "master" // 指定运行节点的标签或名称
customWorkspace "${workspace}" // 指定运行的工作目录(可选)
}
}
options部分
options指令允许从流水线内部配置特定的流水线选项:
buildDiscarder:为最近的流水线运行的特定数量保存组件和控制台输出disableConcurrentBuilds:不允许同时执行流水线,可防止同时访问共享资源timeout:设置流水线超时时间retry:失败后重新尝试的次数示例:
options {
timestamps() // 在日志中打印时间
skipDefaultCheckout() // 删除隐式的checkout scm 语句
disableConcurrentBuilds() // 禁止并行
timeout(time:1, unit:'HOURS') // 流水线超时设置为1H
}
stages部分
stages包含了一个或多个stage指令,用于连接交付过程中每个离散的部分。
示例:
stages{
stage("PullCode") { // 阶段名称
steps { // 步骤
timeout(time:5, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("获取代码")
}
}
}
}
stage("Build") { // 阶段名称
steps { // 步骤
timeout(time:20, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("应用打包")
}
}
}
}
}
post部分
post用于定义构建后的操作,根据构建结果执行不同的动作:
always{}:总是执行success{}:成功后执行failure{}:失败后执行aborted{}:取消后执行changed{}:当流水线或阶段完成状态和之前不同时执行unstable{}:当流水线或阶段状态为unstable时执行示例:
post {
always {
println("总是执行")
}
success {
script {
currentBuild.description += "
构建成功!"
}
}
failure {
script {
currentBuild.description += "
构建失败!"
}
}
}
让我们通过一个完整的示例来演示如何配置一个自由风格的Jenkins项目,用于构建和部署Java Web应用。
项目概述
这是一个典型的Java Web应用,使用Git进行版本控制,Maven进行构建,需要部署到远程Tomcat服务器。
配置步骤
General设置 项目名称:
java-web-app描述:
Java Web应用自动化构建与部署丢弃旧构建:保留最近10个构建参数化构建:添加Git参数(分支选择)、字符串参数(部署环境)和布尔参数(是否跳过测试)
源码管理
选择GitRepository URL:
https://github.com/example/java-web-app.git分支指定:
${GIT_BRANCH}(使用参数化构建中定义的变量)凭证:添加GitHub用户名和密码
构建触发器
轮询SCM:
H/5 * * * *(每5分钟检查一次代码变更)构建后构建其他项目:仅当构建稳定时触发UI测试任务
构建环境
删除工作空间 before build starts:确保每次构建从干净环境开始添加时间戳到控制台输出:便于日志分析
构建
# 根据参数决定是否跳过测试
if [ "$SKIP_TESTS" = "true" ]; then
mvn clean package -DskipTests
else
mvn clean package
fi
# 生成可执行文件并打包
tar -zcf target/web-app.tar.gz -C target/ webapp.war
增加构建步骤:Execute shell命令:
构建后操作
归档制品:
target/*.war(保存生成的WAR包)发布JUnit测试结果报告:
target/surefire-reports/*.xmlEditable Email Notification:配置邮件通知,包含构建结果和指向构建详情的链接
以下是一个完整的Pipeline示例,展示了如何实现Java应用的完整CI/CD流水线:
pipeline {
agent {
node {
label 'master'
customWorkspace "${workspace}"
}
}
parameters {
string(name: 'BRANCH', defaultValue: 'master', description: '构建分支')
booleanParam(name: 'SKIP_TESTS', defaultValue: false, description: '是否跳过测试')
choice(name: 'DEPLOY_ENV', choices: ['dev', 'staging', 'prod'], description: '部署环境')
}
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
disableConcurrentBuilds()
timeout(time: 30, unit: 'MINUTES')
}
environment {
// 定义环境变量
JAVA_HOME = '/usr/lib/jvm/java-11-openjdk'
MAVEN_OPTS = '-Xmx2g -XX:MaxMetaspaceSize=512m'
// 使用凭据
SONAR_QUBE_SCANNER = credentials('sonar-qube-scanner')
}
stages {
stage('代码检出') {
steps {
git branch: "${params.BRANCH}",
url: 'https://github.com/example/java-web-app.git',
credentialsId: 'github-credential'
}
}
stage('代码质量检查') {
steps {
withSonarQubeEnv('sonar-qube') {
sh """
mvn sonar:sonar
-Dsonar.projectKey=java-web-app
-Dsonar.projectName='Java Web Application'
"""
}
}
}
stage('编译与测试') {
steps {
script {
if (params.SKIP_TESTS) {
sh 'mvn clean compile -DskipTests'
} else {
sh 'mvn clean compile'
}
}
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
stage('构建制品') {
steps {
sh 'mvn package -DskipTests'
archiveArtifacts 'target/*.war'
}
}
stage('部署到环境') {
steps {
script {
if (params.DEPLOY_ENV == 'dev') {
sh 'ansible-playbook -i inventories/dev deploy.yml'
} else if (params.DEPLOY_ENV == 'staging') {
sh 'ansible-playbook -i inventories/staging deploy.yml'
} else if (params.DEPLOY_ENV == 'prod') {
input message: '确认部署到生产环境?', ok: '确认'
sh 'ansible-playbook -i inventories/prod deploy.yml'
}
}
}
}
}
post {
always {
emailext (
subject: "构建通知: ${env.JOB_NAME} - ${env.BUILD_NUMBER} - ${currentBuild.result}",
body: """
<p>项目:${env.JOB_NAME}</p>
<p>构建编号:${env.BUILD_NUMBER}</p>
<p>构建状态:${currentBuild.result}</p>
<p>构建地址:<a href="${env.BUILD_URL}">${env.BUILD_URL}</a></p>
<p>构建日志:<a href="${env.BUILD_URL}console">${env.BUILD_URL}console</a></p>
""",
to: "team@example.com"
)
}
success {
script {
currentBuild.description = "构建成功 - 部署到: ${params.DEPLOY_ENV}"
}
}
failure {
script {
currentBuild.description = "构建失败"
}
}
}
}
这个Pipeline示例展示了:
多环境参数化部署:允许选择部署到开发、预发布或生产环境完整的CI/CD阶段:从代码检直到部署的全流程自动化人工确认:在生产环境部署前需要手动确认灵活的通知机制:根据构建结果发送详细的通知邮件并行执行
对于大型项目,可以利用Jenkins的并行执行功能来加速构建过程:
stage('并行测试') {
parallel {
stage('单元测试') {
steps {
sh 'mvn test'
}
}
stage('集成测试') {
steps {
sh 'mvn integration-test'
}
}
stage('静态代码分析') {
steps {
sh 'mvn checkstyle:checkstyle pmd:pmd'
}
}
}
}
构建缓存优化
合理配置缓存可以显著提升构建速度:
Maven本地仓库缓存:在多次构建间保留Maven依赖Node.js node_modules缓存:前端项目可以缓存node_modulesDocker层缓存:在Docker构建中使用层缓存凭据管理
永远不要在脚本或配置文件中硬编码密码,使用Jenkins的凭据管理:
environment {
// 使用Jenkins凭据ID
DB_PASSWORD = credentials('database-password')
API_TOKEN = credentials('api-token')
}
权限控制
使用基于角色的权限管理,遵循最小权限原则对敏感操作设置人工确认环节定期审查和更新访问权限日志管理
使用
timestamps插件为控制台输出添加时间戳定期归档和清理旧构建日志设置合理的日志保留策略
资源清理
设置合理的保留策略,防止磁盘空间耗尽:
options {
buildDiscarder(
logRotator(
daysToKeepStr: '30',
numToKeepStr: '50',
artifactDaysToKeepStr: '7',
artifactNumToKeepStr: '10'
)
)
}
健康度监控
设置构建超时时间,避免无限期等待配置构建资源监控,如CPU、内存使用情况使用Jenkins监控插件跟踪构建趋势和性能指标通过本文的详细介绍,相信你已经对Jenkins项目选项有了全面的了解。从基础的自由风格项目到强大的Pipeline,从简单的构建到复杂的CI/CD流水线,Jenkins提供了丰富而灵活的功能来满足各种自动化需求。
关键在于,Jenkins项目的高效运作离不开对各项配置选项的深入理解和合理运用。每个项目都有其独特的需求,没有一种配置能够适合所有场景。通过不断实践和优化,你会逐渐找到最适合自己项目的配置方案。
记住,好的Jenkins配置应该像精心设计的工厂流水线一样,高效、可靠且易于维护。它能够让团队从繁琐的重复工作中解放出来,专注于更有价值的开发任务。
开始你的Jenkins自动化之旅吧,让这位不知疲倦的"构建工程师"为你的项目保驾护航!