appuploader-cli 接入 CI/CD 自动上传 IPA 教程

构建流水线跑在没有 Mac 的机器上(比如 Windows / Linux 的 CI Runner),最后一步上传却还得有人手动去点按钮,这事挺别扭的。appuploader-cli 可以把这一步变成一条命令:它是「开心上架(AppUploader)」自带的命令行工具,上传不依赖 Xcode,也不依赖 macOS。

第一步:找到可执行文件

装好主程序之后,命令行工具已经在安装目录里了:

  • macOS:AppUploader.app/Contents/Resources/appuploader-cli
  • Windows:主程序 AppUploader.exe 同目录下的 appuploader-cli.exe

进入该目录即可直接运行,或者把这个目录加入 CI Runner 的 PATH 环境变量,方便在脚本里直接调用。

第二步:上传 IPA/PKG

1appuploader-cli upload -f <IPA/PKG 路径> -u <Apple ID> -p <App 专用密码> [--type ios]
参数 说明
-f, --file 要上传的 IPA / PKG 文件路径(必填)
-u, --username Apple ID 邮箱(必填)
-p, --password App 专用密码,格式 xxxx-xxxx-xxxx-xxxx(必填,不是登录密码)
--type 包类型:ios / osx / appletvos / xros,默认 ios

示例:

1appuploader-cli upload -f Payload.ipa -u dev@example.com -p abcd-efgh-ijkl-mnop

上传过程会实时打印进度和结果日志,失败时日志会带上具体原因(如包重复、版本号冲突、签名不匹配等),方便在 CI 日志里直接定位问题。

第三步(可选):本地生成 App Store 资源描述文件

如果只想在上传前先本地校验包内容,或者需要一份 AppStoreInfo.plist 给其他上传工具用,可以用 info 命令,它只做本地分析,不会真正上传:

1appuploader-cli info -u <Apple ID> <文件路径> [-o 输出文件] [--format xml|binary]

--deterministic 参数可以固定 UUID、进程号、时间戳等本会变化的字段,便于在 CI 里逐字节比对输出结果,适合写自动化测试。

接入 CI/CD 流水线的思路

无论是 Jenkins、GitHub Actions 还是其他 CI 系统,接入方式都一样:在构建产出 IPA 之后,加一步执行 appuploader-cli upload 命令,把凭据通过流水线的密钥/环境变量机制注入,避免明文写在脚本里。因为 appuploader-cli 本身不依赖 macOS,你的 CI Runner 也不需要是 Mac 系统。

上传失败时命令的退出码是非 0,所以流水线里直接用退出码判断这一步成败即可,不需要去解析日志:

1set -e
2appuploader-cli upload -f "$WORKSPACE/build/App.ipa" -u "$APPLE_ID" -p "$APP_SPECIFIC_PASSWORD"

用 API 密钥代替个人账号

把某个人的 Apple ID 和密码写进流水线,人一走或者密码一改,自动化就断了。团队场景更合适的是 App Store Connect API 密钥——它属于团队,可以单独吊销:

1appuploader-cli upload -f build/App.ipa \
2  --api-key "$ASC_KEY_ID" \
3  --api-issuer "$ASC_ISSUER_ID" \
4  --private-key AuthKey.p8

密钥在 https://appstoreconnect.apple.com/access/api 生成,.p8 私钥只能下载一次。在 CI 里把 .p8 的内容存成 Secret,用时写成临时文件,用完删掉。这三个参数和 -u/-p 是两种方式,只能选一组。

需要注意的是,密钥方式只支持 .ipa,且这个 Bundle ID 要已经在 App Store Connect 里创建过 App;macOS 的 .pkg 仍然用 -u/-p