buildVersion 没变,测试报告却对不上包:HarmonyOS 7 Hvigor 多构建模式怎么生成唯一产物身份

测试报告写着 2.3.0,安装包也显示 2.3.0,但修复代码在一台设备上存在、另一台上却没有。继续查才发现免费版 release 和内部版 debug 共用了 versionName,buildVersion 也没有随流水线变化。官方工程级 build-profile.json5 同时支持 products、buildModeSet、versionCode、versionName、buildVersion 与 output.artifactName;这些字段不是装饰,它们应该共同回答“这份包到底从哪里来”。

Hvigor多产品多模式构建的唯一产物身份链

验证边界:本文依据文末当前华为官方资料整理。应用侧状态模型与第二段断言已在本机 Node.js 环境执行;当前本机 SDK 为 API 24,且没有连接 HDC 真机,因此不把主机断言描述成 API 26 编译、真机性能、云端设备或 AppGallery 后台验证。

构造两个同名产物,让人工核对必然失败

分别构建 product=free/buildMode=release 与 product=internal/buildMode=debug,保持 versionName 相同,并让默认输出都落成 entry-default-signed.hap。把两份包依次上传到共享目录。记录 product、buildMode、versionCode、versionName、buildVersion、commitShort、artifactSha256 和 pipelineRunId。仅凭文件名与版本名无法区分时,问题已经复现。

案例一:debug 与 release 同版本名,报告被挂到错误构建

版本名面向用户,不应承担流水线唯一身份。内部测试截图必须展示 buildVersion 或应用内构建收据;报告归档使用 artifactId,而不是人工输入“2.3.0”。

案例二:多个 product 共用输出名,后构建覆盖前构建

多目标产物可以面向不同配置和渠道。若 output.artifactName 不包含 product/buildMode,CI 工作区会发生覆盖,签名、测试和上传步骤可能拿到不同文件。构建后应立即计算摘要并冻结路径。

四层身份各自解决不同问题

versionName 面向用户,versionCode 负责升级顺序,buildVersion 表示构建批次,artifactSha256 锁定最终字节。再加 product、buildMode 与 commitShort,就能从测试报告反查源代码与构建配置。不要用某一个字段替代全部身份。

产物名要可读,摘要负责不可抵赖

推荐输出名包含 app-product-buildMode-versionName-buildVersion,方便人眼扫描;机器流转仍以 artifactSha256 为主键。重签名或重新打包会改变摘要,必须生成新 artifactId,不能沿用旧测试结果。

上传前做一次反向验真

使用官方拆包/验包能力读取版本和构建信息,与流水线清单比对。只有 product、buildMode、版本、签名类型和摘要全部匹配,才能把测试报告、公开测试任务或上架记录绑定到该包。

可复用的工程切片

type ArtifactReceipt = {
  product: string; buildMode: string; versionName: string
  versionCode: number; buildVersion: string
  commitShort: string; sha256: string
}
function artifactId(x: ArtifactReceipt): string {
  return [x.product,x.buildMode,x.versionCode,x.buildVersion,x.commitShort,x.sha256.slice(0,12)].join('-')
}

第一段是接入目标环境时需要保留的工程结构,不等同于本文已经完成 API 26 真机验证。下面把最容易出错的应用侧判定抽成独立断言,先把状态所有权、版本身份或证据完整性跑通。

function id(x){return [x.product,x.mode,x.code,x.build,x.sha.slice(0,8)].join('-')}
const a=id({product:'free',mode:'release',code:23,build:'b901',sha:'abcdef0011'});
const b=id({product:'internal',mode:'debug',code:23,build:'b901',sha:'abcdef0011'});
if(a===b) throw new Error('不同 product/buildMode 产物身份碰撞');
if(!a.includes('b901')) throw new Error('构建批次未写入身份');

三种做法放在一起看

做法可取之处主要代价
只用 versionName用户易读同版本多包无法区分
只用 CI 流水线编号生成方便脱离流水线后不可自证
配置字段 + 包摘要 + 构建收据可追溯且可验真需要构建和发布链共同执行

使用第三种。可读文件名服务人工,artifactId 与摘要服务自动化,拆包读回负责阻止“清单和包不是同一个”。

最终交付与回归项

一份 artifact-receipt.json、唯一 artifactId 规则、输出命名规则和上传前验真脚本。测试、公开测试与上架记录统一引用 artifactId。

  • product 与 buildMode 已进入产物身份。
  • versionCode、versionName、buildVersion 分工明确。
  • 构建完成后立即计算最终包摘要。
  • 重签名或重打包会生成新身份。
  • 上传前读取包内信息与清单对账。

“版本号一样”只能说明用户看到的标签一样,不能说明两个文件相同。让配置、代码和最终字节共同签名产物身份,测试结论才不会串包。

当前官方资料

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐