02 fastlane自动化IOS工程(二)-证书的管理和使用
1 为什么要管理certificates
和profiles
?
在团队开发或是其它的情况而导致一个项目有多台机器在开发时。这时就需要把同样的certificates
和profile
手动更新到不同的机器上。这样才有权限对
项目进行开发与发布。而项目的profile
或certificates
的变动也会导致以上的操作再来一次。这样的操作过于重复与枯燥,浪费大量不必要的时间。所以需要
有一种统一的方式来管理这些certificates
或profiles
的变动,然后又能统一地同步到所以机器上,而不影响其它机器的项目开发。而在fastlane
中,这
种方法号match
。它是通过把certificates
和profiles
收集起来在同一个地方,如: git
等等方式,然后不同的机器就通过这种方法来实现本地的certificates
或profiles
的变更同步。
2 准备工作
2.1 能基本使用fastlane
对fastlane
有个基本的使用认识。如果不是新手,也可能参考《01 fastlane自动化IOS工程(一)-本地入门使用篇》。
本文的项目正是基于《01 fastlane自动化IOS工程(一)-本地入门使用篇》
而来的。
2.2 创建一个私人git
仓库用来保存profiles
和certificates
本文举例用的是git@github.com:wuchuheng/certificates.git 的私人仓库来保存这些文件。
3 初始化match
$ fastlane match init
[✔] 🚀
[11:04:56]: fastlane match supports multiple storage modes, please select the one you want to use:
1. git
2. google_cloud
3. s3
4. gitlab_secure_files
? 1 #<-- 这里选择1, 也就是git
[11:05:21]: Please create a new, private git repository to store the certificates and profiles there
[11:05:21]: URL of the Git Repo: git@github.com:wuchuheng/certificates.git #<-- 填写上用于保存的git仓库
[11:05:31]: Successfully created './Matchfile'. You can open the file using a code editor.
[11:05:31]: You can now run `fastlane match development`, `fastlane match adhoc`, `fastlane match enterprise` and `fastlane match appstore`
[11:05:31]: On the first run for each environment it will create the provisioning profiles and
[11:05:31]: certificates for you. From then on, it will automatically import the existing profiles.
[11:05:31]: For more information visit https://docs.fastlane.tools/actions/match/
然后会生成
fastlane/Matchfile
.
cat Matchfile
git_url("git@github.com:wuchuheng/certificates.git")
storage_mode("git")
type("development") # The default type, can be: appstore, adhoc, enterprise or development
# app_identifier(["tools.fastlane.app", "tools.fastlane.app2"])
# username("user@fastlane.tools") # Your Apple Developer Portal username
# For all available options run `fastlane match --help`
# Remove the # in the beginning of the line to enable the other options
# The docs are available on https://docs.fastlane.tools/actions/match
4 同步development和app store的certificates和profiles
$ fastlane match development
[✔] 🚀
[11:13:37]: fastlane detected a Gemfile in the current directory
[11:13:37]: However, it seems like you didn't use `bundle exec`
[11:13:37]: To launch fastlane faster, please use
[11:13:37]:
[11:13:37]: $ bundle exec fastlane match development
[11:13:37]:
[11:13:37]: Get started using a Gemfile for fastlane https://docs.fastlane.tools/getting-started/ios/setup/#use-a-gemfile
[11:13:38]: Successfully loaded '/Users/wuchuheng/Desktop/myprojects/wuchuheng/ios/wuchuheng/fastlane/Matchfile' 📄
fastlane match appstore
[✔] 🚀
[12:02:13]: fastlane detected a Gemfile in the current directory
[12:02:13]: However, it seems like you didn't use `bundle exec`
[12:02:13]: To launch fastlane faster, please use
[12:02:13]:
[12:02:13]: $ bundle exec fastlane match appstore
[12:02:13]:
[12:02:13]: Get started using a Gemfile for fastlane https://docs.fastlane.tools/getting-started/ios/setup/#use-a-gemfile
[12:02:15]: Successfully loaded '/Users/wuchuheng/Desktop/myprojects/wuchuheng/ios/wuchuheng/fastlane/Matchfile' 📄
然后执行过后,会在开发都平台上生成以
match
为前缀的对应的profiles
再然后,也会把对应的
certificates
和profiles
上传到git上
5 测试本地的match能否使用正常
5.1 在xcode中使用已经生成的profiles
在xcode中打开项目,然后:
5.2 去除fastlane/Fastfile中的下载certificates和profiles步骤
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index b2f1b3c..6bbddb7 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -18,8 +18,8 @@ default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
- get_certificates # invokes cert
- get_provisioning_profile
increment_build_number(xcodeproj: "wuchuheng.xcodeproj")
build_app(scheme: "wuchuheng")
upload_to_testflight
5.3 本地执行fastlane流程
$ fastlane beta
fastlane beta
[✔] 🚀
[12:30:31]: fastlane detected a Gemfile in the current directory
[12:30:31]: However, it seems like you didn't use `bundle exec`
[12:30:31]: To launch fastlane faster, please use
[12:30:31]:
[12:30:31]: $ bundle exec fastlane beta
[12:30:31]:
[12:30:31]: Get started using a Gemfile for fastlane https://docs.fastlane.tools/getting-started/ios/setup/#use-a-gemfile
[12:30:32]: ------------------------------
[12:30:32]: --- Step: default_platform ---
[12:30:32]: ------------------------------
[12:30:32]: Driving the lane 'ios beta' 🚀
[12:30:32]: ------------------------------------
[12:30:32]: --- Step: increment_build_number ---
[12:30:32]: ------------------------------------
Current version of project wuchuheng is: 19
...
+------+------------------------+-------------+
| fastlane summary |
+------+------------------------+-------------+
| Step | Action | Time (in s) |
+------+------------------------+-------------+
| 1 | default_platform | 0 |
| 2 | increment_build_number | 1 |
| 3 | build_app | 15 |
| 4 | upload_to_testflight | 218 |
+------+------------------------+-------------+
[12:34:27]: fastlane.tools finished successfully 🎉
提示
在发布的过程中会要求一个指定密码: FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD, 这个密码需要到appleid.apple.com 进行生成
结果流程是能跑通的。
5.4 提交代码
本次操作要提交的代码
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index b2f1b3c..e9c9a09 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -18,8 +18,6 @@ default_platform(:ios)
+
+desc "Download certificates from the git"
+lane :syncCertificates do
+ match(type: "appstore")
+ match(type: "development")
+end
+
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
- get_certificates # invokes cert
- get_provisioning_profile
increment_build_number(xcodeproj: "wuchuheng.xcodeproj")
build_app(scheme: "wuchuheng")
upload_to_testflight
diff --git a/fastlane/report.xml b/fastlane/report.xml
index f1fb1ac..0fc18d8 100644
diff --git a/wuchuheng.xcodeproj/project.pbxproj b/wuchuheng.xcodeproj/project.pbxproj
index 79a2ba3..a82bb04 100644
--- a/wuchuheng.xcodeproj/project.pbxproj
+++ b/wuchuheng.xcodeproj/project.pbxproj
@@ -417,7 +417,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 17;
+ CURRENT_PROJECT_VERSION = 20;
DEVELOPMENT_ASSET_PATHS = "\"wuchuheng/Preview Content\"";
DEVELOPMENT_TEAM = 5D6L6979M7;
ENABLE_PREVIEWS = YES;
@@ -434,7 +434,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.wuchuheng;
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE_SPECIFIER = com.wuchuheng_airDeveloper;
+ PROVISIONING_PROFILE_SPECIFIER = "match Development com.wuchuheng 1672977205";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -449,7 +449,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 17;
+ CURRENT_PROJECT_VERSION = 20;
DEVELOPMENT_ASSET_PATHS = "\"wuchuheng/Preview Content\"";
DEVELOPMENT_TEAM = 5D6L6979M7;
ENABLE_PREVIEWS = YES;
@@ -466,7 +466,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.wuchuheng;
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE_SPECIFIER = com.wuchuheng_airRelease;
+ PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.wuchuheng";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -479,7 +479,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 17;
+ CURRENT_PROJECT_VERSION = 20;
DEVELOPMENT_TEAM = 5D6L6979M7;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.5;
@@ -499,7 +499,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 17;
+ CURRENT_PROJECT_VERSION = 20;
DEVELOPMENT_TEAM = 5D6L6979M7;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.5;
@@ -518,7 +518,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 17;
+ CURRENT_PROJECT_VERSION = 20;
DEVELOPMENT_TEAM = 5D6L6979M7;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
@@ -536,7 +536,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 17;
+ CURRENT_PROJECT_VERSION = 20;
DEVELOPMENT_TEAM = 5D6L6979M7;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
$ git add -A
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: .gitignore
modified: fastlane/Fastfile
new file: fastlane/Matchfile
modified: fastlane/report.xml
deleted: wuchuheng.app.dSYM.zip
modified: wuchuheng.xcodeproj/project.pbxproj
$ git commit -m 'feat: init match'
$ git commit -m 'feat: init match'
[main 34d6016] feat: init match
7 files changed, 181 insertions(+), 48 deletions(-)
create mode 100644 .gitignore
create mode 100644 fastlane/Matchfile
rewrite fastlane/report.xml (60%)
create mode 100644 tmp
delete mode 100644 wuchuheng.app.dSYM.zip
6 在别的机器通过match进行profiles和certificates的导入与使用
$ git clone git@github.com:wuchuheng/com.wuchuheng.ios.helloWorld.git # 下载项目
$ cd com.wuchuheng.ios.helloWorld
$ fastlane syncCertificates # 同步证书流程
$ fastlane beta # 执行构建和发布流程
执行的结果也是ok的
7 文中涉及到的变量
- fastlane match password: 这是fastlane在同步
git
中的证书(certificates)到本地或线上时,需要用到的密码 - specific password: 这是
beta
流程在发布应用时,需要用到的密码,在 appleid.apple.com进行申请。
8 总结
本文主要是解决证书的更新和同步的问题,从一台主机上进行app
的开发,然后把证书(certificates)和相关的配置(profiles)同步到git,
而其它的开发机器就可以执行同步证书(certificate)的流程来实现证书的更新。从而节省各种手动导入造成的时间浪费。