概览
目的:手动点击构建,拉取 gitlab repo 进行构建打包,然后上传到fir.
本文里主要做如下事情:
- 配置 Jenkins 执行 fastlane 脚本,然后上传 fir
- 配置 match 匹配 certification 和 profile
- 配置 fastlane 打包,build number 修改
Jenkins 配置
这里我们只是手动点击构建时,才会进行构建操作,因此没有【构建触发器】配置。又因为是用 fastlane 进行打包操作,所以没有【构建环境】操作。
- 创建实例
- General -> GitHub project
- 填入 project url
- 填入 respository name
- 源码管理 -> Git
- Respositories -> Respository URL
- 填入项目 gitlab 地址
- branches to build
- 填入你想要啦取的分支,例如:*/master
- Respositories -> Respository URL
- 构建
- Execute shell
- command 里填入内容:
fastlane adhoc
- command 里填入内容:
- Execute shell
- 构建后操作
- Archive the artifacts 存档,这里是放倒工程的 jenkin_build 目录下
- 填入:
jenkin_build/*.ipa
- 填入:
- Upload to fir.im 上传到 fir。jenkins-fir 插件可以去 fir 上去找。
- 填入 fir.im Token ,然后验证一下。
- Archive the artifacts 存档,这里是放倒工程的 jenkin_build 目录下
源码管理
构建
构建后操作
match 配置
参考:
match 是用 git 管理证书/profile. 然后,一套证书/profile 可以快速的用在多种设备上。
使用上大致上有2种方式:一种是直接生成新的证书/profile,进行管理。另一种是在之前的证书/profile上进行手工加密/解密,然后匹配存储到 gitlab 上。
对于第一种来说,直接创建一个 gitlab 私有库,空白的什么都没有,然后配置 match 指向这个 repo , fastlane 执行一下就好了。
对于第二种,就需要很复杂的操作了。
- 导出当前正在用的 development/distribution 的 cer/p12。
- 加密
- 导出当前正在用的 profile
- 加密
- 创建 repo ,并创建固定格式的文件夹,将之前创建好的文件放入到对应的目录下。
Fastfile 配置
我们以 Adhoc 打包方式为例子。
在工程根目录下,执行:
fastlane init
// 需要填入repo地址
fastlane match init
然后会生成 fastlane 目录。
fastlane/
├── Appfile
├── Fastfile
├── Matchfile
├── README.md
└── report.xml
在 Fastfile 里添加一个 lane
app_identifier = 'io.github.zlanchun.test'
repo =
desc "match adhoc profile"
lane :matchAdhoc do
match(git_url:"#{repo}",
type:"adhoc",keychain_password:"123",app_identifier:"#{app_identifier}",
readonly: true )
end
match 命令的参数:
- git_url :gitlab 私有库的地址
- type : 类型,可以是:adhoc/appstore/development/enterprise, 这里我们是打 adhoc 包,所以填入 adhoc
- keychain_password: 管理密码
- app_identifier: bundle id
- readonly : 是否可读,如果为 true 则只能从 repo 里拉取,而不能创建。如果为 false ,也是从 repo 里拉取,如果不匹配则自动创建。
我们手动加密证书/profile,所以 readonly 这里配置 true.
生成新证书/profile
把上面的 readonly 改为 false.
执行:
$ fastlane matchAdhoc
根据提示信息输入密码,然后就会创建新的证书/profile ,并推送到 repo 里。
repo 里的内容:
├── README.md
├── certs
│ ├── development
│ │ ├── 22XXXXX8G.cer
│ │ └── 22XXXXX8G.p12
│ └── distribution
│ ├── Y9XXXXX8R.cer
│ └── Y9XXXXX8R.p12
├── match_version.txt
└── profiles
├── adhoc
│ └── AdHoc_io.github.zlanchun.test.mobileprovision
├── appstore
│ └── AppStore_io.github.zlanchun.test.mobileprovision
└── development
└── Development_io.github.zlanchun.test.mobileprovision
匹配现有的 证书/profile
获取正在用的证书的 certId
lookupCertId.rb 会找到你账号下的所有的证书信息(证书ID,时间什么的)
# lookupCertId.rb
require 'spaceship'
Spaceship.login('your@appleid')
Spaceship.select_team
Spaceship.certificate.all.each do |cert|
cert_type = Spaceship::Portal::Certificate::CERTIFICATE_TYPE_IDS[cert.type_display_id].to_s.split("::")[-1]
puts "Cert id: #{cert.id}, name: #{cert.name}, expires: #{cert.expires.strftime("%Y-%m-%d")}, type: #{cert_type}"
end
替换 lookupCertId.rb 中的 your@appleid 为你的 appid 账号,然后命令行里执行:
$ ruby lookupCertId.rb
类似于下面这个样子:
Cert id: 22XXXXX8G, name: iOS Development, expires: 2019-05-21, type: Development
找到你的正在用的证书,保存下来证书ID,之后会用到。
创建 repo 目录结构
在 repo 里创建目录 certs (管理证书)、目录 profiles (管理 profiles)、文件 match_version.txt (记录 fastlane match —version 内容)
├── certs
│ ├── development
│ └── distribution
├── match_version.txt
└── profiles
├── adhoc
├── appstore
└── development
钥匙串导出证书
钥匙串 -> 登录 -> 我的证书 -> 右键导出 certificate.p12 / certificate.cer
将私钥提取到key.pem文件
$ openssl pkcs12 -nocerts -nodes -out key.pem -in certificate.p12
加密 cer/p12
命令如下
openssl aes-256-cbc -k password -in key.pem -out cert_id.p12 -a
执行,123 是密码,需要替换成你自己的
$ openssl aes-256-cbc -k 123 -in key.pem -out cert_id.p12 -a
$ openssl aes-256-cbc -k 123 -in certificate.cer -out cert_id.cer -a
加密 profile
把正在用的 profile 从 apple 上下载下来,然后加密,过程和上一步骤类似。
openssl aes-256-cbc -k password -in development.mobileprovision -out Development_bundle.id.mobileprovision -a
执行,注意导出的文件名是 Type_bundleId.mobileprovision,bundleId 里包含 .
不要写错了。
$ openssl aes-256-cbc -k 123 -in match_AdHoc_ioGithubZlanchunTest.mobileprovision -out AdHoc_io.github.zlanchun.test.mobileprovision -a
推送到 repo
将这些生成的文件放到对应的目录文件里。目录结构参考上面生成新证书的目录结构。
├── certs
│ ├── development
│ │ ├── 22XXXXX8G.cer
│ │ └── 22XXXXX8G.p12
│ └── distribution
│ ├── Y9XXXXX8R.cer
│ └── Y9XXXXX8R.p12
├── match_version.txt
└── profiles
├── adhoc
│ └── AdHoc_io.github.zlanchun.test.mobileprovision
├── appstore
│ └── AppStore_io.github.zlanchun.test.mobileprovision
└── development
└── Development_io.github.zlanchun.test.mobileprovision
match 匹配
$ fastlane matchAdhoc
fastlane 配置
以 Adhoc 为例,包含三个功能:
- 打包
- 匹配 adhoc profile
- 更新 build number (这里是改成当天时间: 年月日)
platform :ios do
app_identifier = 'io.github.zlanchun.test'
currentTime = Time.new.strftime("%Y%m%d")
desc "adhoc"
lane :adhoc do
# 更新 build number,这里写 Info.plist 的相对地址
set_info_plist_value(path: "./Test/Info.plist", key: "CFBundleVersion", value: "#{currentTime}")
gym(
workspace: "Test.xcworkspace",
scheme: "Test",
configuration: "Release",
silent: true,
clean: true,
include_symbols: true,
include_bitcode: true,
export_method: "ad-hoc",
output_directory: "jenkin_build/",
export_options: {
# 匹配 AdHoc profile
provisioningProfiles: {
app_identifier => "match AdHoc #{app_identifier}"
}
}
)
end
end
测试:
$ fastlane adhoc
如果没有报错,则一切成功了。
问题集
{"authType"=>"sa"} (Spaceship::Tunes::Error)
ruby lookupCertInfo.rb
时报错了,找了好久,原来是 iTunes 有个新协议需要确认,gg