React Native 0.71-RC0 Android 服務中斷事件驗屍報告
現在 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 和 相關討論。
遺憾的是,由於我們從範本搭建新專案的方式,這導致任何使用舊版本的 Android 使用者建置失敗,因為他們會開始下載 0.71.0-rc0
的新成品,而不是他們專案中使用的版本 (例如 0.68.0
)。
事件發生的原因
React Native 範本提供 build.gradle
檔案來建置 Android 應用程式。此檔案包含對 React Native Android 函式庫的相依性,如下所示:implementation("com.facebook.react:react-native:+")
。
重要的是,此相依性的 +
部分 (一個 Gradle 動態版本) 告知 Gradle 選取 React Native 的最高可用版本。使用 Gradle 動態版本被認為是一種反模式,因為它會讓使用者接觸到較低重現性的建置。
我們知道動態版本可能會導致的問題,因此在 0.71
中,我們清理了新的應用程式範本並移除了所有 +
相依性。然而,舊版 React Native 的使用者仍然使用 +
版本。
這導致使用 0.71.0-rc.0
之前 React Native 版本的建置,會查詢所有儲存庫以尋找 React Native 的最高可用版本。由於新推送的 0.71.0-rc.0 在 Maven Central 上成為最高版本,因此使用 0.71.0-rc.0 之前 React Native 版本的建置開始使用來自 0.71.0-rc.0 的成品。本機建置 (例如 0.68.0
) 和 Maven Central (0.71.0-rc.0
) 的成品之間的 React Native 版本不符導致這些建置失敗。
有關此事件區域的更多技術細節,也可在 此 GitHub 議題 上找到。
我們的緩解與解決方式
在 11 月 4 日我們發現問題後,社群立即找到並分享了一個手動解決方法來修復此問題,該方法會將 React Native 釘選到特定版本,從而修正錯誤。
然後,在 11 月 5 日和 6 日的週末,發布團隊為所有先前的 React Native 版本 (低至 0.63) 交付了修補程式版本,這些版本會自動套用修補程式,以便使用者可以更新到已修正的 React Native 版本。
同時,我們 聯繫了 Sonatype,要求移除有問題的成品。
當成品於 11 月 8 日完全從 Maven Central 移除時,問題已完全解決。
事件時間軸
本節包含事件的簡要時間軸。所有時間均為 GMT/UTC +0
- 11 月 4 日 - 下午 5:06:0.71-RC0 發布。
- 11 月 4 日 - 下午 6:20:第一個建置問題報告開啟。
- 11 月 4 日 - 下午 7:45:社群識別出問題。
- 11 月 4 日 - 下午 9:39:溝通解決方法,Expo 為所有使用者部署修復程式。
- 11 月 5 日 - 凌晨 3:04:開啟新議題以溝通狀態和解決方法。
- 11 月 6 日 - 下午 4:11:向 SonaType 發送票證,要求移除成品。
- 11 月 6 日 - 下午 4:40:來自 @reactnative 的第一則推文,附帶確認訊息 + 議題連結。
- 11 月 6 日 - 下午 7:05:決定將 React Native 版本修補回 0.63。
- 11 月 7 日 - 凌晨 12:47:最後一個修補程式版本發布:0.63.5。
- 11 月 8 日 - 下午 8:04:Maven Central 上的成品已完全移除。
- 11 月 10 日 - 上午 11:51:關於事件的議題已關閉。
經驗教訓
雖然在許多方面,觸發此事件的條件自 React Native 0.12.0 以來就已存在,但我們希望確保我們在未來開發和發布 React Native 的基礎更加穩固。以下是一些經驗教訓,以及關於我們將如何調整流程和基礎架構,以便在未來更快、更強大地做出回應的可行措施。
事件應對策略
此事件突顯了我們針對與 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 協助我們移除成品、我們的社群以及辛勤工作以盡快解決此問題的發布團隊。