每次构建都像是一场战斗,而归档构建产物就是打扫战场保存战利品的关键环节!
在软件开发过程中,我们常常遇到这样的场景:深夜完成的构建产物,第二天需要测试时却找不到了;或者急需回滚到上一个版本,却发现关键的jar包不知去向。这时,构建产物的归档就显得尤为重要。
Jenkins作为最流行的持续集成/持续部署(CI/CD)工具,通过其强大的流水线(Pipeline)功能和archiveArtifacts步骤,让构建产物的归档变得简单高效。本文将带你深入探索Jenkins构建作业归档的奥秘,让你的劳动成果不再神秘消失!
一、 什么是构建产物归档?为什么它如此重要?
简单来说,构建产物归档就是将构建过程中生成的重要文件保存起来,以便后续使用。这些文件可能是:
- 编译后的可执行文件(如JAR、WAR、EXE)
- 部署包(如ZIP、TAR.GZ)
- 文档文件(如API文档、使用手册)
- 任何其他有价值的构建输出
在Jenkins中,归档的构建产物会被安全地存储并与具体的构建关联,你可以随时从Jenkins网页界面查看或下载它们。即使工作空间被清理,这些归档的产物也不会丢失,因为它们被保存在了Jenkins的特定目录下。
想象一下这个场景:早上一来公司,Jenkins就给你发了一份漂亮的测试报告邮件,绿色的大勾表示所有测试通过,偶尔有几个失败的测试,也明确指出了失败原因和相关的代码变更——这感觉,比喝一杯星巴克还提神!
测试结果汇总是持续集成中至关重要的一环,它的价值远不止是“告诉谁把代码搞坏了”这么简单:
- 快速反馈,及时修复:开发人员在提交代码后几分钟内就能知道自己的改动是否破坏了现有功能。
- 质量趋势可视化:单个测试用例的失败可能只是偶然,但如果某个模块的测试失败率持续上升,这就是一个危险信号。
- 决策支持:该不该发布?能不能上线?测试覆盖率是多少?通过率多少?这些不应该靠“直觉”判断,而应该基于清晰的测试数据。
- 责任明确(适度“甩锅”):当测试失败时,明确指向某个具体的代码变更,能够减少团队内的互相推诿,把精力集中在解决问题上。
二、 Jenkins归档基础:从简单命令到高级技巧
2.1 archiveArtifacts 步骤基础
在Jenkins中归档构建产物主要依靠archiveArtifacts步骤。下面是一个最简单的示例:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Archive') {
steps {
archiveArtifacts artifacts: 'target/*.jar'
}
}
}
}
这个Pipeline定义了两个阶段:Build阶段使用Maven进行构建,Archive阶段则归档target目录下的所有JAR文件。
archiveArtifacts步骤的基本语法是:
archiveArtifacts artifacts: '文件路径模式', fingerprint: 布尔值
其中,文件路径模式遵循Ant风格的文件匹配语法,支持通配符:
*:匹配零个或多个字符(不包含路径分隔符)**:匹配零个或多个目录?:匹配单个字符
2.2 archiveArtifacts 参数详解
archiveArtifacts步骤提供了多个参数,让你更精确地控制归档行为:
- artifacts(必需参数):指定要归档的文件模式。多个模式可以用逗号分隔。
// 归档特定目录下的JAR文件
archiveArtifacts artifacts: 'target/*.jar'
// 归档多个类型的文件
archiveArtifacts artifacts: 'target/*.jar, build/*.zip, docs/*.pdf'
- fingerprint(可选参数):默认为false。设置为true时,Jenkins会记录文件的指纹信息,用于跟踪文件在不同构建之间的使用情况。这可以帮助你快速找到以下问题的答案:
-
- "我硬盘上的foo.jar来自FOO项目的哪个构建?"
- "BAR项目#51中使用了哪个版本的foo.jar?"
- "包含我对foo.jar #32的bug修复的BAR构建是哪一个?"
2.3 归档的进阶用法
除了基本的文件归档,Jenkins还提供了一些进阶用法:
归档最近成功构建的产物
在某些情况下,你可能只想保留最近几次构建的产物,以避免占用过多磁盘空间。可以在Pipeline中配置buildDiscarder选项:
pipeline {
agent any
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
}
stages {
// 阶段定义
}
}
这个配置会让Jenkins只保留最近10次构建的产物和日志。
在不同作业间传递产物
使用Copy Artifact插件,可以完成不同任务间传输文件。例如,将在A节点构建好的文件打包传递到B节点进行部署:
- 在A节点新增"构建后操作",选择"归档成品(Archive the artifacts)",在"Files to archives"中填写归档文件的名称。
- 在B节点任务中增加构建步骤,选择"Copy artifacts from another project",然后填写需要复制的文件,以及保存的路径。
三、 真实场景实战:一个完整的Java项目归档方案
理论说再多不如动手实践。让我们从一个真实的Java项目示例开始,一步步构建完整的构建产物归档流程。
3.1 环境准备
- Jenkins服务器(2.346以上版本)
- 一个Java项目(我们以Spring Boot为例)
- Maven构建工具
- Git版本控制
3.2 基础Pipeline配置
在Jenkins中新建一个流水线项目,输入以下Pipeline脚本:
pipeline {
agent any
tools {
maven 'M3' // 确保你在Jenkins中配置了Maven安装项并命名为M3
}
stages {
stage('Checkout') {
steps {
git 'https://github.com/yourusername/your-springboot-project.git'
}
}
stage('Build') {
steps {
sh 'mvn clean compile'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml' // 这是关键步骤!
}
}
}
}
}
这段代码中,最神奇的就是junit 'target/surefire-reports/*.xml'这一行。它会自动收集Maven测试生成的XML报告,并在Jenkins界面上以可视化形式展示。
3.3 完整归档Pipeline示例
下面是一个更完整的Pipeline示例,包含了构建、测试、归档和部署等多个阶段:
pipeline {
agent any
tools {
maven 'M3'
jdk 'JDK11'
}
parameters {
choice choices: ['dev', 'test', 'prod'], description: '部署环境', name: 'DEPLOY_ENV'
booleanParam defaultValue: false, description: '是否跳过集成测试', name: 'SKIP_INTEGRATION'
}
stages {
stage('Checkout') {
steps {
git branch: 'main', url: 'https://github.com/company/our-microservice-project.git'
}
}
stage('Unit Test') {
steps {
sh 'mvn clean test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
archiveArtifacts artifacts: 'target/*.jar'
}
}
}
stage('Integration Test') {
when {
expression { params.SKIP_INTEGRATION == false }
}
steps {
sh 'mvn verify -Pintegration'
post {
always {
junit 'target/failsafe-reports/*.xml'
archiveArtifacts artifacts: 'target/*.war'
}
}
}
}
stage('Build Docker Image') {
steps {
script {
sh 'mvn spring-boot:build-image -Dspring-boot.build-image.imageName=myapp:${BUILD_NUMBER}'
}
}
}
stage('Archive Results') {
steps {
archiveArtifacts artifacts: 'target/*.jar, target/*.war, Dockerfile', fingerprint: true
archiveArtifacts artifacts: 'docs/**/*', fingerprint: false
}
}
}
post {
always {
emailext (
subject: "构建通知:${currentBuild.fullDisplayName}",
body: """
<h2>构建信息</h2>
<p>项目:${env.JOB_NAME}</p>
<p>构建号:${env.BUILD_NUMBER}</p>
<p>构建状态:${currentBuild.currentResult}</p>
<p>构建日志:${env.BUILD_URL}console</p>
<p>测试报告:${env.BUILD_URL}testReport</p>
""",
to: "team@company.com",
attachLog: true
)
}
failure {
// 发送紧急通知
sh "curl -H 'Content-Type: application/json' -d '{\"msgtype\":\"text\",\"text\":{\"content\":\"构建失败,请立即检查:${env.BUILD_URL}\"}}' https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"
}
}
}
3.4 查看归档结果
构建完成后,在Jenkins项目页面的"构建历史"中,点击对应的构建号,进入"构建详情"页面。在"构建产物"部分,你可以看到已归档的构建产物,并可以下载。
如果测试失败,Jenkins还会在构建历史中显示红色标识,一眼就能看出问题。
四、 Jenkins归档高级技巧与最佳实践
4.1 使用指纹跟踪依赖关系
当设置fingerprint: true时,Jenkins会为每个归档的文件创建指纹信息。这使得Jenkins能够跟踪哪些构建使用了该文件,从而轻松回答以下问题:
- "我硬盘上的foo.jar来自FOO项目的哪个构建?"
- "BAR项目#51中使用了哪个版本的foo.jar?"
- "包含我对foo.jar #32的bug修复的BAR构建是哪一个?"
4.2 合理的归档策略
为了避免归档过多文件占用大量磁盘空间,建议采用以下策略:
- 只归档必要的文件:不要归档中间生成的文件或临时文件,只归档最终需要的构建产物。
- 使用构建丢弃器:配置
buildDiscarder选项,只保留最近几次构建的产物。 - 定期清理:设置定期的清理任务,删除过期的构建产物。
pipeline {
agent any
options {
buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '5'))
}
// 其他配置
}
这个配置会保留最近20次构建的记录,但只保留最近5次构建的产物。
4.3 与版本控制系统集成
将Jenkinsfile纳入版本控制,以便跟踪流水线的变更历史:
pipeline {
agent any
stages {
stage('Checkout') {
steps {
// 检出代码,包括Jenkinsfile
checkout scm
}
}
// 其他阶段
}
}
4.4 使用post块处理不同情况
post块可以用于根据构建结果执行不同的操作,类似于程序的错误处理机制:
pipeline {
agent any
stages {
// 阶段定义
}
post {
always {
// 无论构建结果如何都会执行
echo '构建完成'
}
success {
// 仅当构建成功时执行
echo '构建成功!'
}
failure {
// 仅当构建失败时执行
echo '构建失败!'
// 发送失败通知
emailext subject: "构建失败: ${currentBuild.fullDisplayName}",
body: "检查构建: ${env.BUILD_URL}",
to: "developers@example.com"
}
unstable {
// 当构建状态为不稳定时执行(例如测试失败)
echo '构建不稳定!'
}
changed {
// 当构建状态与上一次不同时执行
echo '构建状态发生变化'
}
}
}
五、 常见问题与解决方案
5.1 归档文件太大导致磁盘空间不足
问题:归档的文件太大,很快占满了Jenkins服务器的磁盘空间。
解决方案:
- 只归档必要的文件,避免归档中间生成物或临时文件
- 使用构建丢弃器配置自动清理旧构建
- 考虑使用外部存储系统(如AWS S3、Artifactory等)存储大型文件
5.2 归档文件路径不正确
问题:在Pipeline中指定的归档路径不正确,导致无法找到要归档的文件。
解决方案:
- 在归档前使用
sh 'find . -name "*.jar"'或类似命令确认文件路径 - 使用相对路径(相对于工作空间)
- 确保在正确的阶段进行归档(在生成文件的阶段之后)
5.3 权限问题
问题:Jenkins没有权限访问要归档的文件或目标存储位置。
解决方案:
- 检查Jenkins用户的文件系统权限
- 确保Jenkins有权限写入归档目录
- 在Docker容器中运行时,确保挂载的卷有正确权限
六、 结语
通过Jenkins的流水线功能结合Shell脚本,我们可以轻松地实现构建产物的自动化构建和归档。这不仅提高了开发效率,还确保了构建产物的可追溯性和可重用性。
记住,好的归档习惯是高效CI/CD流程的基石。它不仅能让你在需要时快速找到构建产物,还能为问题排查、版本回滚和审计提供重要支持。随着Jenkins功能的不断扩展和插件的丰富,我们可以进一步探索更多高级特性,如并行构建、条件执行等,以优化我们的CI/CD流程。
希望这篇文章能帮助你快速上手Jenkins流水线项目,并在实践中应用Shell脚本进行构建和归档Artifacts。如果你有任何疑问或建议,欢迎在评论区留言讨论。
2万+

被折叠的 条评论
为什么被折叠?



