# Android CI/CD with Jenkins & Fastlane > 本文件僅描述技術流程與設計思路,所有名稱與範例皆為示意用途。 --- ## 📌 專案說明 本專案使用 **Jenkins(macOS Agent)** 搭配 **Expo、Gradle、Fastlane**, 實作 **Android App Bundle(AAB)** 的自動建置與上傳至 **Google Play Console(Internal Testing)**。 所有敏感資訊(如 **Keystore、Google Play Service Account**) 皆由 **Jenkins Credentials** 統一管理,**不進入版本控制系統**, 確保 CI/CD 流程的安全性。 --- ## 🎯 專案目標 - 自動化 Expo Android 專案建置流程 - 在 CI 環境中安全注入 Android Release Signing - 產生 Android App Bundle(`.aab`) - 使用 Fastlane 自動上傳至 Google Play Console - 建立一套: - ✅ 可重現 - ✅ 可維護 - ✅ 可交接 的 CI/CD 流程 --- ## 🏗️ CI 架構概述 ### Jenkins Controller - Pipeline 定義 - 任務調度與執行管理 ### macOS Agent(MacBook / Mac mini) - 執行 Expo、Gradle、Fastlane - 使用本地安裝環境: - Android SDK - Java - Node.js --- ## 🧰 使用工具 - **Jenkins**:CI Pipeline 管理 - **Expo**:React Native Android Prebuild - **Gradle**:Android AAB 建置 - **Fastlane(supply)**:Google Play 上傳 - **Google Play Service Account**:Google Play Developer API 存取 --- ## 📁 專案目錄結構 ```text . ├─ Jenkinsfile ├─ fastlane/ │ └─ Fastfile ├─ scripts/ │ └─ patch-android-signing.js ├─ android/ │ └─ app/ │ └─ build/ │ └─ outputs/ │ └─ bundle/ │ └─ release/ │ └─ app-release.aab ├─ app/ ├─ ios/ └─ package.json ``` ## 說明 - `android/`、`ios/` 由 **Expo Prebuild** 動態產生 - `.aab` 為 **CI 產物**,不進入版本控制 - `Jenkinsfile` 置於 **Repository Root** --- ## Jenkins Pipeline 流程 ### 1. 環境設定 (Environment Setup) Pipeline 啟動時設定以下環境變數: - `ANDROID_HOME`:Android SDK 路徑 - `PATH`:包含 Node.js 與 Android `platform-tools` - `GRADLE_USER_HOME`:指向 Jenkins Workspace - `CI=true`:確保工具以 CI 模式執行 --- ### 2. 相依套件安裝 (Dependencies) - Checkout 原始碼 - 使用 Yarn 安裝 JavaScript 套件 - 使用 `--frozen-lockfile` 鎖定套件版本 --- ### 3. Expo Android Prebuild 執行指令: ```bash yarn expo prebuild --platform android --clean ``` ## - 每次 CI 皆重新產生 乾淨的 Android 原生專案 - 確保 build.gradle 與相關設定為最新狀態 --- ### 4. Android Release Signing 注入 CI 執行期間完成以下動作: - 從 **Jenkins Credentials** 注入 Keystore - 動態產生 `keystore.properties` - 執行自製 Script: - `scripts/patch-android-signing.js` - 自動 Patch: - `android/app/build.gradle` - 確保 Release Build 使用正確的 Signing Config --- ### 5. Android AAB 建置 執行 Gradle 指令: ```bash ./gradlew bundleRelease ``` 產出檔案 ```bash android/app/build/outputs/bundle/release/app-release.aab ``` --- ### 6. AAB 定位與上傳準備 Jenkins 在上傳前進行以下處理: - 固定工作目錄為 **Repository Root** - 僅搜尋 `bundle/release/` 目錄 - 將 AAB 路徑轉為 **絕對路徑** 並設定以下環境變數: - `AAB_PATH` - `SUPPLY_JSON_KEY` --- ### 7. applicationId 自動取得 Jenkins 從 `android/app/build.gradle` 解析: ```gradle applicationId "com.example.app" ``` 並設定環境變數: ```gradle PACKAGE_NAME=com.example.app ``` 確保 Fastlane 使用正確的 Package Name。 --- 🚀 Fastlane 設計說明 - Fastlane 僅負責上傳 - 不參與建置流程 Fastfile 範例 ``` default_platform(:android) platform :android do lane :play_internal do upload_to_play_store( aab: ENV["AAB_PATH"], track: "internal", package_name: ENV["PACKAGE_NAME"], json_key: ENV["SUPPLY_JSON_KEY"], skip_upload_metadata: true, skip_upload_images: true, skip_upload_screenshots: true, skip_upload_changelogs: true ) end end ``` ## 安全性設計 - 所有機密資料皆由 **Jenkins Credentials** 管理 - Repository **不包含**: - Keystore - Service Account JSON - Build Outputs - 可直接移轉至其他 macOS Jenkins Agent(如 Mac mini) --- ## 結論 此 CI/CD 流程透過明確的責任分離: - **Jenkins** - 建置流程控制 - 環境準備 - 參數推導 - **Fastlane** - Google Play 上傳 成功建立一套 **穩定、安全、可維護** 的 Android AAB 自動化流程, 適合長期運行與團隊交接使用。