跳至主内容

React Native 0.71-RC0 Android 构建中断事故分析

· 1 分钟阅读
Nicola Corti
Nicola Corti
Software Engineer @ Meta
Lorenzo Sciandra
Lorenzo Sciandra
Senior Software Engineer @ Microsoft
非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

随着 0.71 正式版的发布,我们有必要说明在 2022 年 11 月 4 日发布首个 React Native 和 Expo Android 构建的 0.71 候选版本时,导致所有 React Native 版本 Android 构建中断的具体情况。

参与处理该事故的贡献者近期召开了复盘会议,详细讨论了事故原因、经验教训以及未来避免类似故障的改进措施。

事故经过

2022 年 11 月 4 日,我们在多个公共仓库发布了 React Native 0.71.0-rc0 版本,这是 0.71 的首个候选版本。

该候选版本的重大变更是将工件发布至 Maven Central 而非从源码构建,从而提升构建速度。具体实施方案详见 RFC#508相关讨论

遗憾的是,由于项目模板初始化新工程的方式存在缺陷,所有使用旧版本的用户在构建时开始下载 0.71.0-rc0 的新工件(而非其项目实际使用的版本如 0.68.0),导致构建失败。

根本原因

React Native 模板提供的 build.gradle 文件包含如下 Android 依赖声明: implementation("com.facebook.react:react-native:+").

其中的 + 符号(即 Gradle 动态版本)会指示 Gradle 自动选择最高版本的 React Native。使用动态版本被视为反模式,因其可能导致构建结果不可复现。

我们知晓动态版本可能引发的问题,因此在 0.71 版本中清理了新应用模板并移除了所有 + 依赖声明。但旧版本用户仍在使用含 + 的模板。

这导致所有低于 0.71.0-rc.0 的 React Native 版本在构建时自动检索仓库中可用的最高版本。由于新发布的 0.71.0-rc.0 成为最高版本,低于此版本的构建开始错误使用 0.71.0-rc.0 的工件。本地构建版本(如 0.68.0)与 Maven Central 工件版本(0.71.0-rc.0)不匹配最终导致构建失败。

该事件的技术细节可参阅 GitHub 相关 issue

应对措施

11 月 4 日确认问题后,社区迅速找到并分享了手动解决方案:通过指定确切版本号修复依赖声明。

随后在 11 月 5 日至 6 日的周末,发布团队为所有历史版本(下至 0.63)推送了补丁更新,自动修复该问题,用户只需更新至修复后的 React Native 版本即可。

与此同时,我们 联系了 Sonatype 请求移除问题工件。

11 月 8 日问题工件从 Maven Central 彻底移除后,事故完全解决。

时间线

本节简要记录了事件时间线,所有时间均为 GMT/UTC+0 时区

经验总结

虽然引发本次事故的技术隐患自 React Native 0.12.0 版本就已存在,我们将确保未来开发和发布流程的基础更加牢固。以下是本次事件的经验总结及后续改进措施:

事件响应策略

本次事件暴露了我们在处理 React Native 开源项目相关事故时的响应策略缺陷。

社区在 2 小时内快速找到了临时解决方案。但由于缺乏对问题影响范围的实时评估能力,以及为旧版本修复的技术复杂度,我们当时依赖受影响用户自行在 GitHub 问题页发现解决方案。

耗时 48 小时后,我们才意识到该问题的广泛影响范围,并认识到不能依赖所有用户自行查找 GitHub 解决方案。因此必须优先实施更复杂的主动修复方案来自动修复用户项目。

我们将重新评估"依赖开发者手动应用临时方案"与"部署自动修复"的决策标准,同时探索获取生态系统健康实时数据的可行方案。

版本支持策略

通过 rn-versions 工具可视化数据可见,为覆盖事故发生时 90% 以上的 React Native 开发者群体,我们必须向下兼容至 0.63 版本发布补丁。

我们认为这是由于 React Native 的升级体验历来充满摩擦所致。我们正在研究改进升级体验的方法,使其更顺畅、更快速,以缓解生态系统碎片化的问题。

发布新版本的 React Native 绝不应影响使用旧版本的用户,对于此次事件对您工作流程造成的干扰,我们深表歉意。

同时,我们也想强调保持依赖项和 React Native 最新版本的重要性,这样才能受益于我们引入的改进和安全措施。该事件发生时,官方的版本支持政策正处于制定阶段,尚未正式公布或强制执行。

未来,我们将通过官方渠道公布支持政策,并考虑在 npm 上弃用旧版 React Native

改进第三方库测试和最佳实践

此事件凸显了改进发布测试和优化第三方库指导的重要性。

在测试方面,由于缺乏稳定版本现有的自动化流程和测试机制,发布向下兼容至 0.63.x 的版本面临巨大挑战。我们认识到发布和测试基础设施的重要性,未来将加大投入力度。

具体而言,我们现在鼓励并将支持将第三方库测试纳入 React Native 发布流程。同时我们还在核心贡献者 Discord 服务器中新增了沟通渠道和角色。

此外,我们与 create-react-native-library 的维护方 Callstack 展开了深度合作,旨在改进库模板并确保其遵循所有必要的最佳实践以实现与 React Native 项目的无缝集成。新版本的 create-react-native-library 现已完全兼容 0.71 项目,同时保持向后兼容性。

总结

我们为此次事件给全球开发者工作流程造成的干扰深表歉意。如上所述,我们已开始采取行动巩固基础架构——更多工作正在进行中。

希望通过分享这些见解,能帮助大家更好地理解本次事件,并能借鉴我们的经验教训,在您自己的工具和项目中应用更佳实践。

最后,我们要再次感谢 Sonatype 协助我们移除问题构件,感谢社区成员和发布团队为此事件不眠不休的及时响应。