Fastlane 自动发布iOS应用

断断续续花了3天时间折腾了一下Fastlane自动发布,搞定一行命令发布内测版:

fast dev "1、修复重复做动作挑战记录无法上传的问题"

ATTENTION:

这不是一个手把手教你安装的教程,但能覆盖绝大部分的问题。

如果你碰到任何问题,跳到“坑们”这个环节寻找解决方法。

原由

发布内测版本太痛苦啦,咱们的项目基于Swift 3,Archive一次大概5、6分钟。然后经过手工导出IPA,上传蒲公英。全部是手工操作,总要等。一次折腾下来20分钟以上吧。

其实那都还算不错了,如果是上传Testflight,那就蛋碎了。

AppleID

用Fastlane发布可以解决的账号问题:

  • 不需要给开发人员itunesConnect的账号
  • 开发人员在没有itunesConnect的账号的情况下,可以上传版本

开发人员是否需要AppleID和公司账户授权?

需要,用管理员账号给开发人员的AppleID授权User权限。

因为Xcode 8可以自己管理Development的证书,我折腾的时候没有AppleID会有无法签名的错误。

  • 也有可能是因为我们用Fastlane的Match工具删除了之前所有的证书,所有才有问题。大家感兴趣可以自己折腾一下。

管理证书

干掉所有证书

match是fastlane工具集下面的一个单独的命令。就是用这个工具把证书托管在单独的代码库中。

你可以干掉所有证书

  • 准备好用于存放证书的代码库:

https://github.com/xxx/certificates ,设为私有仓库,开发人员都给一下可写权限。

  • 干掉之前乱七八糟的证书
match nuke development
match nuke appstore
  • 干掉所有证书并不会影响AppStore上已经发布的应用
  • 推送证书它是不会碰的

生成新的证书

cd $CODE_DIR # 替换成你自己的目录
'' export MATCH_PASSWORD="xxxxxxx"
'' match development
'' match appstore
'' match adhoc
  • MATCH_PASSWORD是有用的,用于加密你的代码库中的证书
  • 以上三个match只需要执行一次,后续都加 — readonly选项

编译上传和项目管理

代码和编译的目录

建议copy一份代码,到一个单独的目录用于编译。这样,编译代码的时候不影响开发。

比如,你有两个目录:

/Users/username/project

/Users/username/projectbuild

  • 始终在project目录下写代码
  • 在projectbuild目录中编译

注意:不要再手工修改版本号,fastlane可以帮你搞定。

清理原有证书并下载新的开发证书

Xcode -> Preferences -> AppleIDs ,选择一个AppleID -> ViewDetails

在其中删除旧的证书,并下载新的开发证书。

编译、打包和上传

先测试一下获取证书:

cd $CODE_DIR # 替换成你自己的目录
export MATCH_PASSWORD="替换成你自己的密码"
match development --readonly
match appstore --readonly
match adhoc --readonly

其他都由脚本搞定,最终只需要执行:

fast dev/beta/release "release_note"

如果在上传环节出现问题可以用如下命令再上传一次:

fast aws "release_note"

上传到S3,无需自己做下载页面

pgyer的上传可靠性不太好,自己测试10有6、7传不成功。虽然写了个专门上传的命令,但觉得还是不好,所以改成上传到aws了。

配置文件

fastlane/Appfile: 可以在里面修改为appleID

fastlane/Fastfile: fastlane的命令在此定义

fastlane/Matchfile: 定义certificates的代码库地址

资源

官方文档:doc.fastlane.tools

安装各种依赖的脚本(已经安装homebrew的情况):

如果遇到问题见:坑2

sudo gem update --system 
brew install ruby --verbose
brew upgrade openssl --verbose
sudo gem install fastlane
sudo gem install match
sudo gem install rest-client
sudo gem install pry
sudo gem install spaceship
sudo gem install aws-sdk-v1 # s3上传要用

Fastlane的配置文件和脚本示例:

坑们

第1坑:ruby的版本太低

match init

09:46:20: Connection reset by peer — SSLconnect

ruby和openssl版本太低

第2坑:brew update没有权限

brew update

报错:

fatal: cannot create directory at ‘.github’: Permission denied

sudo gem install fastlane

但是报错:

While executing gem … (TypeError) no implicit conversion of nil into String

sudo chown -R $(whoami):admin /usr/local
cd /usr/local
git reset --hard
git clean -df
brew update --verbose

第3坑:在旧版安装ruby下安装fastlane后要重新安装

sudo gem install fastlane
sudo gem install match

第4坑:Matchfile中设置的AppleID要有Admin的权限

如果没有Admin的权限是不可以生成新的证书的。

第5坑:打开了2步验证无法上传到Testflight

[15:10:33]: [Transporter Error Output]: Please sign in with an app-specific password. You can create one at appleid.apple.com. (-22910)
[15:10:33]: Transporter transfer failed.

在AppleID中创建一个App Specific Password,然后重新运行一下fastlane action,会重新提醒输入App Specific Password。

第6坑:pgyer很容易上传失败,用s3代替了

用curl发送IPA文件到pgyer.com,很容易上传失败。加了几个timeout的header刚开始看起来好了一点,

第7坑:sentry plugin不可用,用sentry-cli代替

按官方的首先要安装sentry plugin,看提示。但是安装好了貌似授权业有问题。用sentry-cli代替。sentry-cli也有entity too large的问题,暂时不用。

第8坑:AWS的s3没有写权限和http访问权限

上传的时候AccessDenied

正确的姿势是:在aws中创建一个独立的用户fastlane,在policy中分配s3的一些权限,然后在bucket的policy中设置权限。

  • 创建一个policy给readObject、putObject等的基础的权限,建议不给deleteObject的权限。
  • 在bucket properties中要Edit bucket policy
  • policy内容
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws-cn:s3:::fastlane/*"
},
{
"Sid": "allow-user-fastlane-writable",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws-cn:iam::367438093323:user/fastlane"
},
"Action": [
"s3:AbortMultipartUpload",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws-cn:s3:::fastlane/*"
}
]
}
Like what you read? Give can xiang a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.