依赖版本稳定下来以后,发布检查仍然有一个容易被遗漏的环节:工程里引入的组件不只有代码,还有许可证要求、来源说明,以及可能发生的数据处理行为。一个 UI 工具包通常与一个网络统计组件承担不同的职责,如果只按依赖数量判断合规状态,就会把本来需要分别审查的事项混为一谈。

继续沿用上一章的应用发布工作台,这次不另建一份包列表,而是在已确认的依赖身份和版本快照上增加许可证、使用目的、提供方与数据字段。这样可以避免两个表格分别维护后产生版本错位:版本升级、模块移除或依赖用途变化,都会触发关联信息的重新核对。

依赖许可与隐私披露联动核对

不要用包名推断许可结论

一个名称里带 ui 的包可能包含图像处理代码、网络访问逻辑或传递性依赖;一个公开仓库中的组件,也不意味着使用方式没有条件。许可审查应该对应实际使用版本的许可文本,记录来源、权利归属以及项目采用的分发方式。版本变化后,原先的许可证清单应重新确认,因为上游可能调整了依赖内容或附加文件。

从工程角度看,这一步最容易做错的是把“查到许可证名称”当作审查结束。即使版本清单写着 MIT 或 Apache-2.0,也需要知道文本从哪里取得,是否携带附加通知,是否包含独立授权的资源。发布工作台的状态可以区分“已收集”“待复核”“已确认”,让技术同学与负责许可复核的人共享准确的信息,而不是简单打一个绿色勾。

需要先区分三方库和内部组件。内部组件同样要记录负责人和源码位置,但许可处理方式不一定与外部引入的库相同。对于开发期辅助工具,可以独立标记为开发用途,避免把未参与目标包的工具直接列入面向用户的 SDK 清单。另一方面,运行期的间接依赖如果承担数据处理,也不能因为它不是直接声明就被忽略。

一份清单服务两种审查

发布工作台将依赖清单拆成两组相互关联的字段:一组关注软件分发,保存名称、版本、许可证标识、文本来源和复核状态;另一组关注数据处理,保存提供方、数据类型、使用目的、接收方、处理方式和隐私政策页面对应条目。记录中还需要一个明确的布尔值表示该组件是否进入本次发布内容。

字段完整和业务合规并非同一回事。脚本适合核对漏填、版本错配、数据字段不一致,以及清单与发布文案之间的遗漏;许可证条件解释与个人信息处理方式仍需要依据实际代码和相应文档作专业复核。这样的分工能把重复劳动交给程序,把需要判断的事项留给了解工程的人。

下面用两条示例依赖记录建立检查模型。示例包名不指向具体公开软件包,许可和数据字段只用于说明数据结构。正式数据应该由当前版本的组件发布内容、文档以及工程接入方式共同确定。

const inventory = [
  {
    name: '@sample/ui-kit', version: '1.2.0', shipped: true,
    license: 'MIT', licenseRef: '仓库已归档的许可证文本',
    provider: '组件维护方', data: [], purpose: ''
  },
  {
    name: '@sample/metrics', version: '0.8.0', shipped: true,
    license: 'Apache-2.0', licenseRef: '仓库已归档的许可证文本',
    provider: '统计服务维护方', data: ['使用事件'], purpose: '功能质量统计'
  }
];
const disclosure = [
  { name: '@sample/metrics', version: '0.8.0',
    provider: '统计服务维护方', data: ['使用事件'], purpose: '功能质量统计' }
];
function keyOf(item) {
  return `${item.name}@${item.version}`;
}

做字段检查,不做隐含推断

数据表中“没有填写处理的数据”与“确认不处理相关数据”不是一个意思。建议用空数组表达已经核对后的无数据项,用字段缺失表达待补充。对于确实涉及数据处理的组件,使用目的、提供方和版本缺一不可。一个组件若变更了处理内容,不能仅通过版本号保持不变就认定隐私文案可以沿用。

同样,发布工作台不应把外部仓库的许可名称自动映射成某个“允许发布”结论。不同授权条件涉及通知、修改标识、再分发安排和其他义务,程序能做的是确保对应材料被看见、被归档、被更新。把所有组件都使用同一个静态合规模板,往往会掩盖本来应该单独核对的差异。

开发环境中的依赖许可字段与披露映射

第二段代码将“缺字段”和“已收集但待复核”分开。发布候选表的包与版本必须和上一章的依赖快照一致;这里展示的是单表内部完整性检查,后续可以再用相同键连接快照。

function validateInventory(rows) {
  const errors = [];
  const seen = new Set();
  for (const item of rows) {
    const key = keyOf(item);
    if (seen.has(key)) errors.push(`${key}: 重复依赖记录`);
    seen.add(key);
    if (!item.license || !item.licenseRef) errors.push(`${key}: 许可证材料缺失`);
    if (!item.provider) errors.push(`${key}: 提供方未填写`);
    if (!Array.isArray(item.data)) errors.push(`${key}: 数据类型未核对`);
    if (Array.isArray(item.data) && item.data.length && !item.purpose) {
      errors.push(`${key}: 数据使用目的未填写`);
    }
  }
  return errors;
}

让披露文案和实际组件版本对应

第三方组件可能作为 SDK 参与应用的数据处理,也可能只是构建时引用的普通代码。隐私政策的内容应反映实际处理行为,而不是把 dependencies 里的所有包机械复制成 SDK 列表。对确定涉及数据处理的发布组件,发布清单至少需要匹配组件名称与版本、提供方、数据类型和目的;如果缺少匹配条目,应提醒编辑人员补充。

比对时建议采用集合语义。例如数据类型在两张清单中的排列顺序改变,不应产生误报;如果一张表新增“使用事件”,另一张表还停留在旧字段,就必须触发复核。目的文案应保留原有技术含义,不能靠删除字段让两个列表表面一致。条目中记录明确的来源文档,也能让后续版本回归时快速定位变化。

下面将披露信息与发布清单相连。没有数据处理字段的组件无需进入这个映射,已经记录数据处理的组件必须找到版本一致的披露条目。运行时拿到的差异项可以显示在发布工作台,供开发、测试和产品共同处理。

function compareDisclosure(rows, statements) {
  const errors = [];
  const byKey = new Map(statements.map(item => [keyOf(item), item]));
  for (const item of rows) {
    if (!item.shipped || !Array.isArray(item.data) || !item.data.length) continue;
    const target = byKey.get(keyOf(item));
    if (!target) { errors.push(`${keyOf(item)}: 缺少披露条目`); continue; }
    const sameData = JSON.stringify([...item.data].sort()) ===
      JSON.stringify([...(target.data || [])].sort());
    if (!sameData || target.provider !== item.provider ||
        target.purpose !== item.purpose) {
      errors.push(`${keyOf(item)}: 披露信息待更新`);
    }
  }
  return errors;
}
const problems = [...validateInventory(inventory), ...compareDisclosure(inventory, disclosure)];
console.log({ checked: inventory.length, problems });
if (problems.length) process.exitCode = 1;

处理版本更新、移除和间接依赖

一旦依赖基线变化,许可与披露数据就不能继续沿用旧的“已确认”状态。版本升级需要重新检查许可证文本与组件文档;删除组件需要反向查找是否还有其他组件使用它;新增间接依赖需要查看它是否进入发布包以及数据处理路径。对于无网络行为的组件,不能仅因为没有网络权限就判断它与个人信息处理无关,还要结合业务调用链确认使用方式。

工程审查时可以安排两个独立但关联的关口:依赖版本清单确认后冻结候选快照,许可与数据处理清单再以同一个快照版本为键完成复核。如果两次检查之间发生了安装更新,后一个关口要重新取样,避免审查的不是同一套输入。这样新增库、更新库和退库动作都可以关联到同一条变更记录。

手机端的许可与隐私披露核对页面

异常路径也要清楚:没有许可证来源时保留待补充状态;找不到披露条目时指出对应组件与版本;清单读取异常不生成空白的通过报告;遇到名称相同但版本不同的记录,应先解决包身份一致性。尤其不能把数据类型的差集静默忽略,否则每次发布都可能继承错误文案。

为正式发布留下一条稳定链路

HarmonyOS 相关的上架材料通常会涉及 AppGallery Connect 中的应用信息和隐私说明。华为开发者文档也给出了 SDK 信息披露的字段示例,包括名称、提供方、涉及的数据类型、使用目的与隐私政策链接。具体条目应按实际集成的 SDK 及其现行指南填写,不能从示例数据直接复制到正式上架资料中。

这套发布工作台没有把合规检查做成一次性的发布前填表,而是依靠依赖版本键把不同责任人的工作串起来。下一阶段将以同一个候选快照继续核对版本号、发布构建产物和提交清单,避免已经审阅的依赖信息与最终发布包脱节。

参考华为开发者文档:

Logo

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

更多推荐