You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jenkins两个构建间运行abidiff进行ABI差异检测?

在Jenkins CI中集成abidiff对比同分支上一次成功构建的二进制文件

我来给你几个实用的方案,帮你搞定这个问题——核心就是拿到同分支上一次成功构建的工件,再用abidiff做对比:

方案一:用Copy Artifacts插件(最省心的方式)

这是最直接的方法,不用自己折腾构建编号和路径,插件帮你搞定工件拷贝:

  1. 先配置工件归档:在你的Jenkins项目的「Post-build Actions」里添加「Archive the artifacts」,填写你要对比的二进制文件路径(比如**/your-binary-file),确保每次成功构建都会归档这个文件。
  2. 安装Copy Artifacts插件:在Jenkins插件管理里搜索并安装「Copy Artifacts Plugin」。
  3. 添加拷贝步骤:在构建流程中,添加「Copy artifacts from another project」步骤:
    • 项目名称选你当前的Job(如果是多分支流水线,要勾选「Use same project name with parameterized branch」,指定分支为当前构建的分支)
    • 构建选择「Last successful build」
    • 在「Artifacts to copy」里填写和归档时一样的二进制文件路径,目标路径可以填./previous-build/(方便区分当前和历史文件)
  4. 运行abidiff:在后续的「Execute Shell」步骤里,直接对比当前构建的二进制和拷贝来的文件:
    abidiff ./path/to/current-binary ./previous-build/your-binary-file
    

方案二:用Groovy脚本获取上一次成功构建编号(适合自定义路径场景)

如果你不想用插件,或者需要直接访问历史构建的文件路径,可以用Groovy脚本把上一次成功构建的编号存入环境变量:

自由风格项目:

  1. 添加「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!"
    }
    
  2. 在后续的「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_BINARY
    
    注意:如果你的构建是在代理节点上运行,直接访问JENKINS_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:13:56