iOS 应用的 CI/CD 流水线中,打包后的 IPA 上传到 App Store Connect 通常依赖 Mac 环境上的 Xcode 或 Transporter。如果 Jenkins 跑在 Linux 或 Windows 上,上传这步就成了瓶颈。Appuploader 的命令行版可以嵌入 Jenkins 流水线,在非 Mac 环境下完成上传。

Jenkins 中 iOS 构建的常见做法

iOS 项目的 Jenkins 流水线通常分几步:拉代码 → 安装依赖 → 编译打包 → 签名 → 上传。前面几步可以在 Linux 或 Windows 上完成(拉代码、安装 Pod、运行脚本),但编译和上传通常依赖 Mac。

一种做法是 Jenkins Master 跑在 Linux 上,注册一台 Mac 作为 Jenkins Slave 专门处理 iOS 构建。编译完成后再由同一个 Slave 上传 IPA。缺点是 Mac Slave 资源占用高,如果只是上传操作其实不需要 Mac 环境。

另一种做法是将编译和上传解耦——编译在 Mac Slave 上完成,产生 IPA 后传输到 Linux 构建机,再由 Linux 执行上传。上传步骤不依赖 Xcode 或 Transporter。

Appuploader 命令行版集成

Appuploader 提供命令行版本,可以在 Linux 和 Windows 上直接调用上传功能。命令格式:appuploader_cli --upload-app -f Payload.ipa -u user@example.com -p xxxx-xxxx-xxxx-xxxx --type ios

参数说明:–upload-app 指定上传操作,-f 指定 IPA 文件路径,-u 指定 Apple 开发者账号,-p 指定 App 专用密码(不是登录密码),–type ios 指定上传平台类型。

在 Jenkins 的 Configure 里添加一个 Execute Shell 或 Execute Windows Batch Command 步骤,填入这个命令。也可以在 Pipeline 脚本中用 sh 或 bat 步骤调用。

Jenkins Pipeline 配置示例

在 Jenkinsfile 添加一个 stage:

1stage('Upload IPA to App Store') {
2    agent { label 'linux' }
3    steps {
4        sh 'appuploader_cli --upload-app -f build/App.ipa -u $APPLE_ID -p $APP_PASSWORD --type ios'
5    }
6}

Apple 开发者账号和专用密码建议通过 Jenkins 的 Credentials Binding 插件注入环境变量,不要硬编码在脚本中。添加一个 withCredentials 步骤引用凭证。

上传前的准备

在 Jenkins 上执行上传操作之前需要准备好几样东西。IPA 文件必须已用发布证书签名。Apple 开发者账号需要开启双因素认证,并在 Apple ID 页面生成 App 专用密码。这个专用密码和登录密码不同,上传工具用专用密码做身份验证。

如果在 Pipeline 中上传后构建版本没有立刻出现在 App Store Connect 上,可以在脚本中增加一个等待和轮询的步骤,检查指定版本号是否已经出现。如果返回错误检查 Bundle ID 是否匹配和版本号是否重复。

多通道和重试

Appuploader 提供多条上传通道。如果默认通道上传失败可以在命令中指定其他通道。在网络不稳定的 CI 环境中,建议在 Jenkins 任务中配置重试机制——上传失败后等待几秒换通道重试。

命令行版比界面版稳定,适合无人值守的自动化场景。命令行版本输出的日志可以直接显示在 Jenkins 的控制台中,方便排查上传失败的原因。

建议

将 IPA 上传从 Mac 环境剥离出来后,Jenkins 的 iOS 流水线可以更灵活地分配资源。编译仍然依赖 Mac Slave,但上传可以交给 Linux 或 Windows 节点,节省 Mac 节点的占用时间。