← 返回文档导航
结论: 把放在印尼的 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 必须依赖 macOS iOS 打包、签名、上传 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.com 和 curl -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 未安装/未切换。
组件 用途 状态
Xcode iOS 编译、签名、上传。 需安装/切换完整 Xcode
Flutter SDK Flutter App 构建。 已安装 3.44.2
CocoaPods iOS Pods 依赖。 已安装 1.16.2
Java 17 Android / 部分工具链。 已安装 17.0.19
Android SDK Android 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 keystore AAB/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-ci。 Runner 不使用朋友个人账号。 待做
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 产物归档 → 飞书通知 → 固化脚本。
BeeX App CI/CD · Mac mini 自托管构建机方案 · 当前状态以实际构建机验收为准