Google Play 警告消不掉:Fastlane 上傳 Native Debug Symbols 的三個陷阱

那個怎麼都消不掉的警告 Google Play Console 上掛著一則警告:「App Bundle 含有原生程式碼,而您尚未上傳偵錯符號檔」。 先釐清幾個名詞,因為 Google Play 的警告訊息把不同的東西混在一起講: 檔案 用途 來源 Native Debug Symbols (.so) 還原 C/C++ native crash 的堆疊追蹤 Flutter 引擎、NDK、第三方 SDK R8 Mapping (mapping.txt) 還原 Java/Kotlin 被 R8 混淆後的類別名稱 Gradle build(minifyEnabled true) 兩者都要上傳,Google Play 才不會抱怨。Flutter 專案兩者都需要:引擎帶了 .so,Gradle 開了 R8。 整體流程:Build → Detect → Upload 在看個別陷阱前,先理解正確的 CI 流程應該長什麼樣: 關鍵原則:上傳邏輯綁定 build 產物,不綁定部署環境。只要 build 裡有 .so 或 mapping.txt,就上傳。不管是 staging 還是 production。 但從這個目標到實際跑通,踩了三個完全不同性質的坑。 陷阱一:File.expand_path 的基準不是你以為的那個 第一版的 Fastfile 寫死了路徑: ...

February 24, 2026 · 2 分鐘 · Peter

15 次 Build Failed:一場 Jenkins + Flutter CI/CD 的史詩級除錯之旅

前言:當 Build Failed 成為日常 在過去的 19 個小時裡,我經歷了 15 次 build failed,產生了 15 個 fix commits。如果你覺得這很誇張,讓我告訴你更誇張的:最後一個 bug 是 git describe 在多個 tag 指向同一 commit 時會隨機返回其中一個。 是的,隨機。在 CI/CD Pipeline 裡。 這篇文章完整記錄這場除錯馬拉松,從最初的 Fastlane 版本問題,到 Discord 通知功能的實作與修復,再到 Ruby 相容性地獄,最後揭開 git 鮮為人知的行為。泡杯咖啡,這會是一段旅程。 第一章:Fastlane 與 Bundler 的糾葛 問題 1:Fastlane 版本不一致 Commit: fix(jenkins): use bundle exec for fastlane to ensure version consistency Jenkins 機器上有全域安裝的 Fastlane,但版本與 Gemfile.lock 指定的不同。這導致某些 action 行為不一致。 // Before: 使用全域 fastlane sh 'fastlane ios build' // After: 透過 Bundler 執行,確保版本一致 sh 'bundle exec fastlane ios build' 學習:在 CI 環境中,永遠使用 bundle exec 執行 Ruby 工具,確保版本與 lockfile 一致。 ...

December 21, 2025 · 5 分鐘 · Peter