应用已经能在模拟器里启动,开发者很容易以为离上架只差点击一个“上传”按钮。实际进入发布环节时,最容易耽误进度的往往不是某个 ArkUI 组件,而是三件看起来不起眼的东西:包名与注册应用不一致、构建时仍使用调试签名、版本信息与已经发布的包冲突。更麻烦的是,有些工程在本机可以安装 HAP,却拿着同一个文件准备提交应用市场,直到平台校验时才发现产物类型根本不对。

HarmonyOS 应用签名、构建及提交的技术封面

本文面向一个已经完成页面功能的小型 HarmonyOS 应用,从“准备构建资料”走到“可提交发布包”,讨论配置校验、签名材料、构建产物和验证清单。这里只讲公开、可核实的常规开发流程,不把自动签名与正式发布签名混成一条捷径;对于需要开发者账号操作的证书与审核环节,说明应该确认什么,而不是假设某个账号已经获得发布资格。

先把 HAP、APP 与两套签名分清

先看平台产物的分工。华为 AppGallery Connect 的官方发布 FAQ 明确区分:本地调试通常使用 HAP;应用正式发布使用 APP 包,一个 APP 包可以包含多个 HAP。调试证书与调试 Profile 服务于本地调试,发布证书与发布 Profile 服务于正式发布。调试用 HAP 能否安装还与签名和设备是否注册有关,不能由“模拟器可以运行”直接推导出“所有手机都可以安装”。APP 包也不属于可直接拿来本地安装的普通调试包。

另一处差异是证书责任。自动签名主要简化调试,且是否能够关联注册应用取决于 DevEco Studio 版本、账户、包名和 AGC 环境。正式发布环节应按当前华为开发者中心要求取得发布用证书/Profile,并在构建配置中选用对应材料。维护旧应用尤其要守住密钥连续性:升级包应保持与此前版本相容的签名关系,不能为了让本机报错消失,临时生成新密钥覆盖旧密钥。.p12 与密码属于敏感发布资产,不能写进文章、提交到源码仓库或随安装包打包公开。

技术人员常把“debug/release”理解为仅仅决定日志是否开启,但它还牵涉构建选项、混淆策略和发布链路。官方 DevEco Studio 构建文档给出了 buildMode 与 product 的绑定方式,以及 assembleApp 这一产物构建入口。这里先核对构建模式,再核对签名配置,最后检查得到的 APP 与发布平台的注册信息是否对应。顺序虽然朴素,却能让故障定位容易得多。

版本号是发布契约,不是界面上显示的一行字

工程中 AppScope/app.json5 的 app.bundleName 表达应用包名,versionCode 和 versionName 分别用于版本编码与版本展示。下面是教学示例配置,不包含真实开发者证书或密钥;项目里的图标和字符串资源应由实际资源目录提供。versionCode 的递增策略要结合平台发布规则与已有线上版本核对,不能认为把 versionName 从 1.0 改成 2.0 就自动满足更新条件。

// AppScope/app.json5:展示与发布有关的字段
{
  "app": {
    "bundleName": "com.example.releaseguide",
    "vendor": "example",
    "versionCode": 1000001,
    "versionName": "1.0.1",
    "icon": "$media:app_icon",
    "label": "$string:app_name"
  }
}

注册 AGC 应用时使用的包名必须与工程中的包名对应;当前发布文档也指出,更新现有应用时签名及版本条件必须与既有应用满足平台要求。包名看起来只是字符串,实际上它参与决定这次提交属于哪一个应用。对于企业里有多个构建环境的项目,不应把测试包名和生产包名在脚本中临时互换,随后寄希望于发布工具自动纠正。建议把目标应用 ID、包名、版本号、构建模式与签名配置共同纳入一次发布评审。

可以用一个独立的 TypeScript 校验函数提前发现部分明显配置错误。它不是华为官方工具,也不替代平台包校验;它的价值是让研发人员在正式构建前就知道哪些输入不合理。以下 ReleaseManifest 可以来自自己的 CI 配置解析器,上一版本编码则应来自可信的发布记录,而不是由本机猜测。

// scripts/release-check.ts:工程自有的配置检查逻辑
export interface ReleaseManifest {
  bundleName: string;
  versionCode: number;
  versionName: string;
  buildMode: 'debug' | 'release';
  hasReleaseProfile: boolean;
}

export function checkRelease(m: ReleaseManifest,
  registeredBundle: string, publishedCode: number): string[] {
  const problems: string[] = [];
  if (m.bundleName !== registeredBundle) {
    problems.push('包名与注册应用不一致');
  }
  if (!Number.isInteger(m.versionCode) ||
      m.versionCode <= publishedCode) {
    problems.push('版本编码未高于既有发布版本');
  }
  if (!/^\d+\.\d+\.\d+$/.test(m.versionName)) {
    problems.push('版本展示名称未符合项目约定');
  }
  if (m.buildMode !== 'release') {
    problems.push('构建模式不是 release');
  }
  if (!m.hasReleaseProfile) {
    problems.push('未确认发布 Profile 配置');
  }
  return problems;
}

这里的版本名格式是项目内部约定,不是平台唯一允许的字符串形式;versionCode 高于上一版是团队采用的严格门禁,并不能取代应用市场的实际更新判定。hasReleaseProfile 也只是配置管理系统的布尔结果,并不意味着证书有效或密码正确。把自动检查写成“提示风险”而非“证明发布成功”,才能避免脚本本身成为新的误导来源。

签名材料和构建入口应当分别核查

如果工程支持图形化构建,DevEco Studio 可以在工程设置里管理 Signing Configs,并通过 Build 菜单执行 APP 构建。官方示例也提供了命令行方式,适合 CI 环境把构建模式明确写进任务,而不是依赖开发机上一次选择的下拉框状态。下列命令来自官方 Hvigor 构建示例,前提是工程已配置相应产品和 release buildMode;它不负责替你申请证书、生成账号或自动提交审核。

# 在工程根目录执行,前提:已配置 product=default 与 release buildMode
hvigorw --mode project -p product=default -p buildMode=release assembleApp

签名检查建议分层进行。第一层查原始配置:工程是否指向期望的发布证书、Profile 与 keystore,文件是否存在,证书是否过期;第二层查构建环境:本机时间、SDK、JDK 与构建配置绑定是否符合工具要求;第三层查产物:输出的是 APP 还是 HAP,版本号和包名是否是目标值,正式包中是否无意打入测试数据。华为官方签名故障排查文档提到过 signingConfigs.name 与 products.signingConfig 不匹配的情况,也提示本地系统时间不准确可能导致签名失败。这些错误通常不是修改业务代码能解决的。

发布配置、签名材料、构建工具和发布产物的关系

不要把 .p12、证书口令、密钥备份上传到公开问题工单;遇到签名故障时,优先提供去敏后的错误码、构建工具版本和配置字段名。签名材料应保存在团队受控的密钥管理机制中,并为续签和人员离职做好交接。对某些开放能力,还可能需要同步证书指纹和相应授权配置;这些事项属于具体能力的接入约束,不能简单推断所有应用都要开启相同权限。

包校验过关之后,仍然不是“发布完成”

把 APP 上传到 AppGallery Connect 后,平台会执行有效性检查;失败时需要根据报告修正问题,再重新选择可用于发布的包。能上传不等于能发布,检查通过也不等于已经完成内容审核。图标、截图、隐私政策、设备适配范围和应用描述仍属于发布材料的一部分,不能仅把 CI 的构建状态作为产品上线信号。对于只用于测试的包,还要留意上传时选择的使用场景,避免测试专用包没有出现在正式版本选择列表中。

在团队协作中,发布流水线的每一步都应有明确的责任人和可记录的证据:研发确认代码版本与配置,测试确认主要设备和权限交互,发布负责人检查账号与证书,运营检查上架内容。最好用一个轻量门禁表保存“检查项、所需证据、执行状态、负责人”,而不是在群里问一句“应该都没问题吧”。门禁可以包括包名/版本、APP产物、发布签名、资源与权限、隐私内容、设备适配、平台校验和审核状态;只标记实际完成的项目,不提前盖“通过”章。

应用发布从代码冻结到提交审核的检查流程

如果收到签名不匹配提示,应优先核对发布证书/Profile和历史密钥,不要立即清理证书重新创建;如果包名不一致,应回到 AGC 注册信息检查,而不是只修改 UI 标题;如果构建模式错误,应确认 buildModeBinder、产品映射和实际生成产物;如果平台拒绝了包,则以平台返回的检查报告为准。这样做的目标不是让发布步骤越来越多,而是让每次失败都有可定位的位置,避免出现“本机测试一切正常,提交后才发现身份信息错了”的反复返工。

实际使用时,记得把本文示例中的 com.example.releaseguide、版本号和项目资源替换为自己的真实工程配置,签名与平台状态也需要在自己的开发者账号下检查。最终可交付的不是一个“电脑上能跑”的文件,而是一份符合目标应用身份、签名与发布规则的构建产物,以及对应的审查资料。工程发布的可靠性,建立在版本身份可追踪、证书责任可交接、每一项门禁可复核上。 这套习惯比背熟某个版本的菜单位置更值得留在团队里。

官方参考:

Logo

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

更多推荐