如何在Jenkins两个构建间运行abidiff进行ABI差异检测?
在Jenkins CI中集成abidiff对比同分支上一次成功构建的二进制文件
我来给你几个实用的方案,帮你搞定这个问题——核心就是拿到同分支上一次成功构建的工件,再用abidiff做对比:
方案一:用Copy Artifacts插件(最省心的方式)
这是最直接的方法,不用自己折腾构建编号和路径,插件帮你搞定工件拷贝:
- 先配置工件归档:在你的Jenkins项目的「Post-build Actions」里添加「Archive the artifacts」,填写你要对比的二进制文件路径(比如
**/your-binary-file),确保每次成功构建都会归档这个文件。 - 安装Copy Artifacts插件:在Jenkins插件管理里搜索并安装「Copy Artifacts Plugin」。
- 添加拷贝步骤:在构建流程中,添加「Copy artifacts from another project」步骤:
- 项目名称选你当前的Job(如果是多分支流水线,要勾选「Use same project name with parameterized branch」,指定分支为当前构建的分支)
- 构建选择「Last successful build」
- 在「Artifacts to copy」里填写和归档时一样的二进制文件路径,目标路径可以填
./previous-build/(方便区分当前和历史文件)
- 运行abidiff:在后续的「Execute Shell」步骤里,直接对比当前构建的二进制和拷贝来的文件:
abidiff ./path/to/current-binary ./previous-build/your-binary-file
方案二:用Groovy脚本获取上一次成功构建编号(适合自定义路径场景)
如果你不想用插件,或者需要直接访问历史构建的文件路径,可以用Groovy脚本把上一次成功构建的编号存入环境变量:
自由风格项目:
- 添加「Execute system Groovy script」步骤,写入以下代码:
def job = Jenkins.instance.getItem(env.JOB_NAME) // 如果是多分支项目,需要先拿到对应的分支Job // def job = Jenkins.instance.getItemByFullName("${JOB_NAME}/${BRANCH_NAME}") def lastSuccessBuild = job.getLastSuccessfulBuild() if (lastSuccessBuild) { env.LAST_SUCCESS_BUILD_NUM = lastSuccessBuild.getNumber().toString() println "Found last successful build number: ${env.LAST_SUCCESS_BUILD_NUM}" } else { println "No previous successful build found!" } - 在后续的「Execute Shell」步骤里,就可以用这个环境变量拼接历史文件的路径了(比如Jenkins归档的默认路径):
注意:如果你的构建是在代理节点上运行,直接访问# 假设归档的文件存在Jenkins主目录的归档路径下 PREVIOUS_BINARY="$JENKINS_HOME/jobs/$JOB_NAME/builds/$LAST_SUCCESS_BUILD_NUM/archive/path/to/your-binary" CURRENT_BINARY="./path/to/current-binary" abidiff $CURRENT_BINARY $PREVIOUS_BINARYJENKINS_HOME可能有权限或跨节点的问题,这种情况还是推荐用方案一的Copy Artifacts插件。
Pipeline项目:
如果用的是Jenkinsfile,直接在Pipeline里用Groovy代码获取:
pipeline { agent any stages { stage('Get Last Successful Build') { steps { script { def lastSuccessBuild = currentBuild.rawBuild.getPreviousSuccessfulBuild() if (lastSuccessBuild) { env.LAST_SUCCESS_BUILD_NUM = lastSuccessBuild.getNumber().toString() } else { error("No previous successful build to compare!") } } } } stage('Copy Previous Binary') { steps { // 或者用copyArtifacts步骤,和方案一类似 copyArtifacts( projectName: env.JOB_NAME, selector: lastSuccessful(), filter: 'path/to/your-binary', target: 'previous-build/' ) } } stage('Run abidiff') { steps { sh 'abidiff ./path/to/current-binary ./previous-build/your-binary' } } } }
备选方案:用GIT_PREVIOUS_SUCCESSFUL_COMMIT重新构建(不推荐但可用)
如果你没有归档工件,也可以用这个Git Commit SHA拉取历史代码重新构建二进制,不过缺点是会重复构建,耗时且可能因环境差异导致构建结果不一致:
# 保存当前分支的Commit CURRENT_COMMIT=$GIT_COMMIT # 切换到上一次成功构建的Commit git checkout $GIT_PREVIOUS_SUCCESSFUL_COMMIT # 重新构建二进制(替换成你的构建命令) make clean && make # 备份历史二进制 cp ./path/to/your-binary ./previous-binary # 切回当前Commit git checkout $CURRENT_COMMIT # 重新构建当前二进制(如果还没构建的话) make # 对比 abidiff ./path/to/your-binary ./previous-binary
最后补充一句:不管用哪种方案,都建议在abidiff执行后根据输出做后续处理——比如如果检测到ABI差异,就标记构建为不稳定,或者触发版本号更新的流程。
内容的提问来源于stack exchange,提问作者Tim Angus
相关产品推荐
相关产品推荐

