← 返回文档导航

BeeX App CI/CD · Mac mini 自托管构建机方案

iOS / Android 构建 · H5 离线包打包 · TestFlight / APK 分发 · 飞书通知
结论:把放在印尼的 Mac mini 做成 BeeX App 专用构建机。它只负责 App 打包、签名、上传和通知; 不承载 Java 服务、数据库、Redis,也不作为线上业务服务器。
当前状态:Mac mini 已有;Tailscale 私网已连通;SSH 已可登录。Flutter、Android 工具链、Java 17、CocoaPods、Fastlane、pnpm 已安装;GitHub SSH key 已配置,App/H5 仓库已拉取,Android 88.88.88 测试 APK 已在 Mac mini 上构建通过。当前只剩完整 Xcode 未安装/未切换,Runner、iOS 签名上传、飞书通知待配置。

一、为什么要这样做

问题说明方案
iOS 必须依赖 macOSiOS 打包、签名、上传 TestFlight 都需要 Xcode 环境。用 Mac mini 做固定构建机。
App 需要快速发测试包BeeX 当前是 Flutter 壳 + H5 离线包,业务迭代频繁。流水线自动拉 H5 包、打进 App、出 iOS/Android 测试包。
团队需要可追踪谁触发、构建哪个 commit、产物在哪、失败日志在哪,必须可查。流水线 + 飞书通知 + OSS 产物归档。
印尼网络是真实环境Mac mini 在印尼,适合观察部分网络问题,但不适合跑线上业务。只做构建节点,不开放公网服务。

二、边界:做什么 / 不做什么

要做
iOS 打包、Android 打包、H5 离线包内置、签名、上传 TestFlight、APK 上传 OSS、飞书通知。
不做
不跑主业务服务、不跑管理后台服务、不跑 MySQL/Redis、不承接线上用户请求。
必须保证
不暴露公网 SSH;密钥最小权限;Runner 只接受可信分支或手动触发。

三、总体架构

flowchart LR
  DEV["开发提交代码"]:::dev --> GIT["GitHub / 云效"]:::ci
  GIT --> PIPE["App 构建流水线"]:::ci
  PIPE --> MAC["印尼 Mac mini
自托管 Runner"]:::mac MAC --> H5["拉取 beex-app-h5
构建 H5 离线包"]:::build MAC --> APP["拉取 beex-app
Flutter 构建"]:::build H5 --> SIGN["签名 / 打包"]:::build APP --> SIGN SIGN --> IOS["上传 TestFlight"]:::out SIGN --> APK["APK / AAB 上传 OSS"]:::out IOS --> FEI["飞书通知"]:::notify APK --> FEI classDef dev fill:#fff,stroke:#e8d9b8,color:#1a1410; classDef ci fill:#fef3c7,stroke:#e07c00,color:#7a4f24; classDef mac fill:#ecfeff,stroke:#0891b2,color:#155e75; classDef build fill:#f5f3ff,stroke:#8b5cf6,color:#5b21b6; classDef out fill:#f0fdf4,stroke:#15803d,color:#15803d; classDef notify fill:#fff7ed,stroke:#f97316,color:#9a3412;

四、网络方案

方案推荐度说明当前动作
Tailscale已安装 · 已验证Mac mini 主动连入私有网络,不需要暴露公网端口;你、本机、构建机可以互通。已通过私网 IP 100.100.9.10 完成 SSH 登录。
ZeroTier备用如果 Tailscale 在当地网络不稳定,再切换为备用方案。暂不启用。
WireGuard可选更可控,但配置成本比 Tailscale 高。后续需要再做。
公网 SSH不建议朋友家网络暴露 SSH 风险高,且公网 IP/路由可能不稳定。不采用。
网络铁律:Mac mini 不开放公网入站端口。CI Runner 采用“主动拉任务”的模式:Mac mini 主动连接 GitHub/云效,外部不需要主动打进来。

Tailscale 连通性验收

检查项命令 / 操作通过标准
Mac mini 已登录Mac mini 菜单栏打开 Tailscale,确认已登录 BeeX 使用的 Tailnet。设备列表里能看到 Mac mini。
获取私网 IP在 Mac mini 执行 tailscale ip -4拿到 100.x.x.x 地址。
本机能 ping在你的 Mac 执行 ping 100.x.x.x能收到响应,延迟稳定。
本机能 SSH在你的 Mac 执行 ssh beex-ci@100.x.x.x能登录到独立 CI 用户。
Runner 可出网在 Mac mini 执行 curl -I https://github.comcurl -I https://flow.aliyun.com都能返回 HTTP 响应。

五、构建环境

已验证机器:philMac-mini2.local · macOS 15.6.1 · 架构 arm64 · Tailscale IP 100.100.9.10 · 当前登录用户 a0
Flutter Doctor:Android toolchain 已通过;Network resources 已通过;当前唯一失败项是完整 Xcode 未安装/未切换。
组件用途状态
XcodeiOS 编译、签名、上传。需安装/切换完整 Xcode
Flutter SDKFlutter App 构建。已安装 3.44.2
CocoaPodsiOS Pods 依赖。已安装 1.16.2
Java 17Android / 部分工具链。已安装 17.0.19
Android SDKAndroid APK/AAB 构建。已安装 android-36 / build-tools 36.0.0
Fastlane上传 TestFlight / 管理发布动作。已安装 2.236.1
Git拉取代码。已安装
Node构建 H5 离线包。已安装 v22.22.1
pnpm安装 H5 依赖、构建 H5。已安装 11.1.2
Homebrew安装开发工具链。已安装 6.0.1

六、流水线拆分

流水线触发方式输入输出状态
app-ios-id-test手动 / 指定分支App commit + H5 commit + 版本号TestFlight internal testing待建
app-android-id-test手动 / 指定分支App commit + H5 commit + 版本号APK 下载链接手动构建已通 · Runner 待建
app-ios-id-prod手动确认正式版本号 + 正式签名App Store Connect待建
app-android-id-prod手动确认正式版本号 + release keystoreAAB/APK待建
建议:第一阶段先打通 `app-ios-id-test` 和 `app-android-id-test`。正式包等测试包稳定后再做,避免一开始把证书、版本、环境全搅在一起。

七、构建流程

sequenceDiagram
  participant U as 触发人
  participant CI as 云效/GitHub
  participant M as Mac mini Runner
  participant H as beex-app-h5
  participant A as beex-app
  participant O as OSS
  participant T as TestFlight
  participant F as 飞书群

  U->>CI: 手动触发构建
  CI->>M: 下发任务
  M->>H: 拉取 H5 代码
  M->>H: 构建 H5 离线包
  M->>A: 拉取 App 代码
  M->>A: 写入/替换内置 H5 包
  M->>A: Flutter build ipa / apk
  M->>T: iOS 上传 TestFlight
  M->>O: Android APK 上传 OSS
  M->>F: 发送构建结果、版本、commit、下载链接、日志链接

八、目录与脚本约定

/Users/beex-ci/
  x/
    beex-app/       # Flutter 壳
    beex-app-h5/        # H5 前端
  secrets/
    appstore/AuthKey_xxx.p8
    android/beex-release.jks
  artifacts/
    ios/
    android/
    logs/
脚本说明
scripts/ci_build_ios.sh id-test构建 iOS 测试包,上传 TestFlight。
scripts/ci_build_android.sh id-test构建 Android 测试 APK,上传 OSS。
scripts/package_h5_for_app.sh id-test构建 H5 离线包并写入 Flutter assets。
scripts/notify_feishu_build.sh发送飞书构建结果。

九、密钥与证书

密钥用途保存位置权限要求
App Store Connect API Key上传 iOS 包。Keychain 或 ~/secrets/appstore只给 App 发布相关权限。
iOS 证书 / Profile签名 IPA。macOS Keychain + Profiles 目录。只用于 BeeX App。
Android keystore签名 APK/AAB。~/secrets/android只读;不进 Git。
OSS 上传凭证上传 APK、日志、构建产物。CI Secret / 本机环境变量。只允许目标 bucket 写入。
飞书机器人/应用凭证发送构建通知。CI Secret / 本机环境变量。只给发送消息权限。
安全铁律:Mac mini 上不要放阿里云最高权限 AK/SK,不要把证书和 keystore 提交进 Git。Runner 不跑陌生 fork、不跑未确认分支。

十、初始化步骤

步骤动作验收证据状态
1打通 Tailscale 网络。本机能 ping / ssh 到 Mac mini 私网地址。已验证
2创建独立系统用户 beex-ciRunner 不使用朋友个人账号。待做
3安装 Xcode / Flutter / Android SDK / CocoaPods / Fastlane。flutter doctor 主要项通过。除 Xcode 外已完成
4拉取 App 和 H5 仓库。~/x/beex-app~/x/beex-app-h5 已存在,能执行构建脚本。已完成
5导入 iOS / Android 签名材料。Android release keystore 已导入并打出 APK;iOS 证书等待 Xcode 环境完成后处理。Android 已完成 · iOS 待做
6注册自托管 Runner。云效/GitHub 能看到 runner online。待做
7接入飞书通知。成功/失败都能推送到群。待做

十一、验收标准

能力验收方式状态
网络可达从你的 Mac 通过 Tailscale 私网访问 Mac mini。已通过
iOS 手动构建Mac mini 上执行脚本,成功生成 IPA。待验
iOS 自动上传TestFlight 出现新构建版本。待验
Android 手动构建Mac mini 上执行 APP_VERSION=88.88.88 BUILD_NUMBER=1 scripts/build_android.sh test apk,成功生成 APK。已通过
Android 产物归档APK 上传 OSS,飞书消息里有下载链接。待验
失败可定位构建失败时飞书能看到失败阶段和日志链接。待验

十二、当前推进顺序

第一优先级:Tailscale 与 SSH 已通过,基础工具链已装好,GitHub SSH key 已添加,App/H5 仓库已拉取,Android 测试 APK 已手动构建通过。下一步先解决完整 Xcode,再做 iOS 手动构建和 TestFlight 上传。手动构建稳定后,再接 Runner;Runner 稳定后,再接飞书通知和产物归档。
推荐顺序:完整 Xcode → iOS 手动构建 → TestFlight 上传 → Runner → Android/OSS 产物归档 → 飞书通知 → 固化脚本