ykfastlane 0.3.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e06f98bcfa28e321039c0dd5286884f0df2c68e3524c000c613dcd77cb1a0735
4
+ data.tar.gz: b8efb63fbf7bb0133e54c496ba5963d3a565ae228a1d1e33c360182500f0480f
5
+ SHA512:
6
+ metadata.gz: 1697f0ff64666028c08fb9cc6a2e2e6ced80516c013fabce2d619c47135eb6ae0288a763abd4fcd34fc630db5b5a890ea09b83c00930b260fd986e9fb9ae227c
7
+ data.tar.gz: fbb93bf62301a2774171ae82b0bf0c20f3e974b2c5ec6d2ca3355eb0f40f25325111427663e03f1105483b1534b044947428b9c58cf727deb6ffffa0233f0dd6
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 stephen.chen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,253 @@
1
+ # Ykfastlane
2
+
3
+ iOS 通用打包工具的终端门户工具
4
+
5
+ - [Ykfastlane](#ykfastlane)
6
+ - [Installation](#installation)
7
+ - [Usage](#usage)
8
+ - [基础配置](#基础配置)
9
+ - [证书管理](#证书管理)
10
+ - [打包](#打包)
11
+ - [异常情况处理](#异常情况处理)
12
+ - [License](#license)
13
+ - [建议](#建议)
14
+
15
+ ## Installation
16
+
17
+ 本指令集适用与ruby 2.7.5 ~ 3.0.3
18
+
19
+ - 安装ruby
20
+
21
+ ruby版本管理有两种方式 rvm 与 rbenv, 建议使用rbenv.
22
+ 安装对应的ruby版本,建议使用2.7.5;并切换ruby版本到满足需求的版本。
23
+
24
+ - 安装ykfastlane
25
+
26
+ ```shell
27
+ gem install ykfastlane
28
+ ```
29
+
30
+ - 做基础配置
31
+ - 安装fastlane脚本
32
+
33
+ ## Usage
34
+
35
+ 安装之后,使用 ykfastlane --help 查看使用说明, 功能分为 通用配置,证书管理,打包三部分。
36
+
37
+ ### 基础配置
38
+
39
+ 基础配置帮助指令
40
+ ```shell
41
+ ykfastlane init --help
42
+ ```
43
+ - 设置基础配置 -- ykfastlane init config
44
+
45
+ 本指令集只是一个门户指令,核心打包功能是通过调用fastlane脚本来实现的。
46
+
47
+ 配置:
48
+ - 配置fastlane脚本的远程仓库
49
+
50
+ 此套fastlane脚本是配套脚本;考虑到github的访问问题,可将原始仓库代码迁移到gitlab仓库[^1]。[【原始仓库地址】](https://github.com/stephen5652/ykfastlane_scrip.git)
51
+
52
+ - 配置通知机器人
53
+
54
+ 任务失败时候的,通过企业微信机器人通知开发者[^2]。[【企业微信机器人配置】](https://developer.work.weixin.qq.com/document/path/91770)
55
+
56
+ 用例:
57
+ ```shell
58
+ ykfastlane init config -f https://github.com/stephen5652/ykfastlane_scrip.git -t 5ef50d9f-6426-4c4c-94f8-xxxxxxxxxxxx
59
+ ```
60
+
61
+ - 显示基础配置 -- ykfastlane init list_config
62
+
63
+ 在终端打印基础配置的内容
64
+
65
+ 用例
66
+ ```shell
67
+ ykfastlane init list_config
68
+ ```
69
+
70
+ - 同步fastlane脚本 -- ykfastlane init sync_script
71
+
72
+ 同步远端fastlane脚本,此处可以通过参数下载固定的fastlan仓库,也可以使用环境配置的仓库来下载。
73
+
74
+ 用例:
75
+ ```shell
76
+ ykfastlane init sync_script
77
+ ```
78
+
79
+ ### 证书管理
80
+
81
+ iOS证书管理有多种方案:
82
+
83
+ > - 使用app store connect API进行管理;
84
+ > - 使用fastlane match 管理【适用于单账号】
85
+ > - 半手动管理
86
+
87
+ 考虑到此平台是通用打包平台,且适用于多个Apple账号下的app打包,所以使用半自动管理证书的形式。
88
+ 具体实施方案:
89
+
90
+ > - 账号管理员创建/维护签名证书和描述文件,并上传至证书仓库;
91
+ > - 开发者电脑,打包机同步证书仓库,并安装证书和描述文件;
92
+ > - 各个项目配置手动签名配置;
93
+ > - 打包平台依据项目签名配置,进行打包。
94
+
95
+ 操作步骤:
96
+
97
+ - 管理员,开发者,打包机电脑配置证书仓库
98
+
99
+ 指令集通过git仓库来维护证书。
100
+
101
+ 指令
102
+ ```shell
103
+ ykfastlane certificate edit_config -r http://xxx.xxx.com/xxx.git
104
+ ```
105
+
106
+ 指令集支持显示证书仓库配置
107
+
108
+ 指令:
109
+ ```shell
110
+ ykfastlane certificate list_config
111
+ ```
112
+
113
+ - 管理员更新证书
114
+
115
+ 使用脚本平台,更新证书,并推送至证书仓库
116
+
117
+ 指令:
118
+
119
+ ```shell
120
+ ykfastlane certificate update_cer -c /Users/xxx/xxx/xxxx.p12 -p xxxx
121
+ ```
122
+
123
+ - 管理员更新描述文件
124
+
125
+ 使用脚本平台,更新描述文件,并推送至证书仓库。
126
+
127
+ 指令:
128
+
129
+ ```shell
130
+ ykfastlane certificate update_profile -p /Users/xxx/xxx/xxx.mobileprovision
131
+ ```
132
+
133
+ - 同步证书和描述文件
134
+
135
+ 开发者,打包机通过平台同步证书仓库。
136
+
137
+ 指令:
138
+
139
+ ```shell
140
+ ykfastlane certificate sync-cer
141
+ ```
142
+
143
+ - 显示证书和描述文件
144
+
145
+ 指令集支持显示证书仓库中的证书和描述文件
146
+
147
+ 指令:
148
+
149
+ ```shell
150
+ ykfastlane certificate list_cers
151
+ ```
152
+
153
+ - 缺点
154
+
155
+ 此种形式的证书管理,也是存在缺点的。
156
+
157
+ 缺点:
158
+
159
+ - 多个Apple账号的证书在同一个git仓库管理;
160
+ - 每台电脑都安装了所有Apple账号的证书和项目描述文件。
161
+
162
+ ### 打包
163
+
164
+ 指令集通过调用fastlane脚本进行打包,依据发不的平台,分为三种打包:fir平台,蒲公英平台,TF
165
+
166
+ - fir打包
167
+
168
+ - 打包指令帮助:
169
+
170
+ ```shell
171
+ ykfastlane archive fire --help
172
+ ```
173
+
174
+ - 使用方式
175
+
176
+ 支持两种打包方式, 在.xcworkspace 路径打包 / 在其他目录打包。
177
+
178
+ > 在 .xcworkspace 同级打包
179
+ > ```shell
180
+ > ykfastlane archive fire -s XXXX -f xxxx -e enterprise -n "iOS测试包" -w xxxx
181
+ > ```
182
+
183
+ > 在其他目录打包:
184
+ 由于.xcworkspace未必在git仓库根目录,所以可以用参数 -x 指定 .xcworkspace 的相对路径 </br>
185
+ 如果终端工作路径在 .xcworkspace同级目录,则可以不使用参数 -x </br>
186
+ 如果不用专门通知企业微信业务群,可以不指定 -w 参数,会默认使用env中配置的企微机器人。</br>
187
+ > ```shell
188
+ > ykfastlane archive fire -s XXXX -x ~/users/xxx/xxx/xxxx.xcworkspace -f xxxx -e enterprise -n "iOS测试包" -w xxxx
189
+ > ```
190
+
191
+ - 蒲公英打包
192
+
193
+ 使用方式同 fir 打包
194
+
195
+
196
+ - TF打包
197
+
198
+ 由于TF打包一定是app store包,所以此指令没有 -e 参数,无法指定包类型
199
+ - 打包指令帮助:
200
+ ```shell
201
+ ykfastlane archive tf --help
202
+ ```
203
+
204
+ - 使用方式
205
+
206
+ 通用支持两种打包方式, 通过 -x 参数来指定 .xcworkspace 的路径
207
+ > 此处需要特别说明 -u -p -w -c 参数 </br>
208
+ -u 开发者的Apple ID </br>
209
+ -p 开发者Apple ID的App专属密钥[^3]。[【传送门】](https://appleid.apple.com/account/manage) </br>
210
+ -w 企微机器人,如果不指定,则默认使用env中配置的机器人。 </br>
211
+ -c 是否需要pod install, 默认不执行。
212
+
213
+ 指令范例:
214
+ ```shell
215
+ ykfastlane archive tf -s XXX -u xxxx.@xxx.com -p xxxx-xxxx-xxxx-xxxx -n iOS测试包 -w xxxxx -c 1
216
+ ```
217
+
218
+ ## 异常情况处理
219
+
220
+ - public_suffix 版本冲突
221
+
222
+ - 清空gem
223
+
224
+ ```shell
225
+ gem clean
226
+ ```
227
+
228
+ - 卸载 public_suffix
229
+
230
+ ```shell
231
+ gem uninstall public_suffix
232
+ ```
233
+
234
+ ## License
235
+
236
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
237
+
238
+ [^1]:fastlane脚本原始仓库地址: https://github.com/stephen5652/ykfastlane_scrip.git
239
+
240
+ [^2]:企业微信机器人配置网址: https://developer.work.weixin.qq.com/document/path/91770
241
+
242
+ [^3]: 配置App专属密钥的网址: https://appleid.apple.com/account/manage
243
+
244
+
245
+ ### 建议
246
+
247
+ fire-api-token 做全局配置
248
+
249
+ tf tag参数化,可以控制是否打tag
250
+
251
+ builde 号不交付苹果管理,指令集也不管理,交由工程配置
252
+
253
+ 显示打包结果的存储路径
data/bin/ykfastlane ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+
5
+ puts "call ykfastlane"
6
+
7
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
8
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
9
+
10
+ # You can add fixtures and/or initialization code here to make experimenting
11
+ # with your gem easier. You can also use a different console, if you like.
12
+
13
+ # (If you use this, don't forget to add pry to your Gemfile!)
14
+ # require "pry"
15
+ # Pry.start
16
+ require 'interface'
17
+ puts "call ykfastlane:#{YKFastlane::VERSION}"
18
+
19
+ puts "ykfastlane start"
20
+ YKFastlane::Interface.start(ARGV)
@@ -0,0 +1,89 @@
1
+ require 'rails'
2
+ require 'thor'
3
+
4
+ require "ykfastlane/helper"
5
+
6
+ module YKFastlane
7
+
8
+ class SubCommandBase < Thor
9
+ class_option :verbose, :type => :boolean
10
+ def self.exit_on_failure?
11
+ true
12
+ end
13
+
14
+ def self.banner(command, namespace = nil, subcommand = false)
15
+ "#{basename} #{subcommand_prefix} #{command.usage}"
16
+ end
17
+
18
+ def self.subcommand_prefix
19
+ self.name.gsub(%r{.*::}, '').gsub(%r{^[A-Z]}) { |match| match[0].downcase }.gsub(%r{[A-Z]}) { |match| "-#{match[0].downcase}" }
20
+ end
21
+ end
22
+
23
+ class YKFastlaneExecute
24
+ def self.executeCommand(commandShell_pre, commandShell, workTitle)
25
+ excuteStr = " "
26
+ excuteStr << "#{commandShell_pre} && " unless commandShell_pre.blank?
27
+ excuteStr << commandShell unless commandShell.blank?
28
+
29
+ puts "START COMMAND:#{excuteStr}"
30
+ code = 1
31
+ system(excuteStr)
32
+ result = $?
33
+ puts "command result[#{result.class}]:#{result}"
34
+ code = result.exitstatus if result.is_a?(Process::Status)
35
+
36
+ #### 以下代码注释,因为fastlane脚本中做了任务失败时候的通知
37
+ # if code != 0
38
+ # #任务失败, 此处需要发送企业微信的通知到开发群
39
+ # puts "should report error to developer group"
40
+ # noticeCmd = commandShell_pre
41
+ # commandShell = commandShell.gsub!( " ", "\\ " )
42
+ # commandShell = commandShell.gsub!( "\"", "\\\"")
43
+ # noticeCmd << "&&fastlane wx_message_notice wx_notice_token:#{Helper::YKWECHAT_ROBOT_TOKEN} msg_title:\"CI work failed\" notice_message:\"#{commandShell}\""
44
+ # puts "notice_command:#{noticeCmd}"
45
+ # system(noticeCmd)
46
+ # end
47
+
48
+ code
49
+ end
50
+
51
+ def self.exchangOptionMapToStr(optionHash)
52
+ paras = {}
53
+ optionHash.each_pair { |k, v| paras[k] = v }
54
+ puts "paras:#{paras.dup}"
55
+
56
+ puts "YKRUNING_PATH:#{Helper::YKRUNING_PATH}"
57
+ workspace_path = Helper::YKRUNING_PATH
58
+ workspace_path = paras["xcworkspace"] unless paras["xcworkspace"].blank?
59
+ paras[:xcworkspace] = workspace_path
60
+ paras[:script_run_path] = Helper::YKRUNING_PATH
61
+
62
+ puts "options_after:#{paras}"
63
+ option_str = ""
64
+ paras.each_pair do |k, v|
65
+ option_str << " #{k}:\"#{v}\""
66
+ end
67
+ option_str
68
+ end
69
+
70
+ def self.executeFastlaneLane(lane_name, optionHash)
71
+ dict = {}
72
+ dict.update(optionHash)
73
+ if dict[:wxwork_access_token].blank?
74
+ wxtoken = YKFastlane::Helper.load_config_value(YKFastlane::Helper::K_wx_access_token)
75
+ dict.update({:wxwork_access_token => wxtoken})
76
+ end
77
+
78
+ option_str = exchangOptionMapToStr(dict)
79
+ command = "bundle exec fastlane #{lane_name} #{option_str}" unless option_str.blank?
80
+
81
+ command_pre = "export LANG=en_US.UTF-8 && export LANGUAGE=en_US.UTF-8 && export LC_ALL=en_US.UTF-8 && which ruby"
82
+ command_pre << " && cd #{YKFastlane::Helper.fastlane_script()}"
83
+
84
+ executeCommand(command_pre, command, lane_name)
85
+ end
86
+
87
+ end
88
+
89
+ end
@@ -0,0 +1,152 @@
1
+ require "actions/YKFastlaneExecute"
2
+ require 'ykfastlane/version'
3
+ require 'ykfastlane/tools'
4
+ require 'ykfastlane/helper'
5
+ require 'actions/archiveHelper'
6
+ module YKFastlane
7
+
8
+ class Archive < YKFastlane::SubCommandBase
9
+ include YKFastlane::ArchiveHelper
10
+
11
+ desc "display_product_path", "display archive output path"
12
+
13
+ def display_product_path()
14
+ YKFastlane::Tools.UI(YKARCHIVE_PRODUCT_PATH)
15
+ end
16
+
17
+ desc 'platform_edit_user', "edit or update platform user"
18
+ option :pgyer_user, :type => :string, :aliases => :u, :required => false, :desc => 'pgyer 平台 user'
19
+ option :pgyer_api, :type => :string, :aliases => :a, :required => false, :desc => 'pgyer 平台 api, 配置链接: https://appleid.apple.com/account/manage'
20
+ option :fir_api_token, :type => :string, :aliases => :f, :required => false, :desc => 'fir 平台 api token'
21
+ option :apple_account, :type => :string, :aliases => :c, :required => false, :desc => 'apple id'
22
+ option :apple_password, :type => :string, :aliases => :p, :required => false, :desc => 'apple id 专属app密钥, 配置链接: https://appleid.apple.com/account/manage'
23
+
24
+ def platform_edit_user()
25
+ puts "archive platform_edit_user"
26
+ if options[:pgyer_user].blank? == false && options[:pgyer_api].blank? == false # pgyer
27
+ pgyerinfo = {
28
+ K_archiveEnv_pgyer_api => options[:pgyer_api],
29
+ K_archiveEnv_pgyer_user => options[:pgyer_user]
30
+ }
31
+ self.update_archive_map(YKFastlane::ArchiveHelper::K_archiveEnv_config_pgyer, pgyerinfo)
32
+ puts "archive update pgyer info success"
33
+ end
34
+
35
+ if options[:fir_api_token].blank? == false #fir
36
+ fir_info = {
37
+ K_archiveEnv_firApiToken => options[:fir_api_token]
38
+ }
39
+ self.update_archive_map(YKFastlane::ArchiveHelper::K_archiveEnv_config_fir, fir_info)
40
+ puts "archive update fir info success"
41
+ end
42
+
43
+ if options[:apple_password].blank? == false && options[:apple_password].blank? == false # tf
44
+ tf_info = {
45
+ K_archiveEnv_tf_account => options[:apple_account],
46
+ K_archiveEnv_tf_password => options[:apple_password]
47
+ }
48
+ self.update_archive_map(YKFastlane::ArchiveHelper::K_archiveEnv_config_tf, tf_info)
49
+ puts "archive update tf info success"
50
+ end
51
+ end
52
+
53
+ desc "list_platform_user", "display the ipa bump platform user map"
54
+
55
+ def list_platform_user()
56
+ self.list_user_map()
57
+ end
58
+
59
+ desc "list_profiles", "print archive profiles info"
60
+ def list_profiles()
61
+ code = YKFastlaneExecute.executeFastlaneLane("list_profile_configs", options)
62
+ exit(code)
63
+ end
64
+
65
+ desc "upload_tf", "upload ipa to test flight, will send failed message to enterprise robot \'#{Helper::YKWECHAT_ROBOT_TOKEN}\'"
66
+ option :ipa, :required => true, :type => :string, :aliases => :i, :desc => 'scheme name'
67
+ option :user_name, :type => :string, :aliases => :u, :desc => 'apple id, 如果不传递,则使用env配置的'
68
+ option :pass_word, :type => :string, :aliases => :p, :desc => 'apple id 专属app密钥, 如果不传递,则使用env配置的 配置链接: https://appleid.apple.com/account/manage'
69
+ option :wxwork_access_token, :type => :string, :aliases => :t, :desc => '微信机器人token, 用以通知到相关业务群,如果没有, 则会使用配置中的机器人, 如果依旧没有, 则不通知企业微信,但是业务依旧成功'
70
+ option :note, :type => :string, :aliases => :n, :desc => '通知信息,用以通知相关业务群,如果没有,业务依旧成功'
71
+
72
+ def upload_tf()
73
+ puts "upload_tf"
74
+ if options[:user_name].blank? || options[:pass_word].blank?
75
+ apple_info = self.load_archive_config_dict(YKFastlane::ArchiveHelper::K_archiveEnv_config_tf)
76
+ options.update(apple_dict)
77
+ end
78
+
79
+ code = YKFastlaneExecute.executeFastlaneLane("upload_ipa_to_tf", options)
80
+ exit(code)
81
+ end
82
+
83
+ desc "tf", "archive ios project and upload to TF, will send failed message to enterprise robot \'#{Helper::YKWECHAT_ROBOT_TOKEN}\'"
84
+ option :scheme, :required => true, :type => :string, :aliases => :s, :desc => 'scheme name'
85
+ option :user_name, :type => :string, :aliases => :u, :desc => 'apple id, 如果不传递,则使用env配置的'
86
+ option :pass_word, :type => :string, :aliases => :p, :desc => 'apple id 专属app密钥, 如果不传递,则使用env配置的 配置链接: https://appleid.apple.com/account/manage'
87
+
88
+ option :wxwork_access_token, :type => :string, :aliases => :w, :desc => '企业微信机器人 webhook中的key字段, 如果没有,则使用env中配置的机器人'
89
+ option :note, :type => :string, :aliases => :n, :desc => '测试包发包信息'
90
+ option :xcworkspace, :type => :string, :aliases => :x, :desc => '.xcworkspace 文件相对于指令工作目录的相对路径, 如果.xcworkspace文件在工程根目录,则可以不传递此参数'
91
+ option :cocoapods, :type => :numeric, :aliases => :c, :desc => '是否需要执行pod install, 默认不执行pod install 指令, 1:执行, 非1:不执行'
92
+ option :flutter_directory, :type => :string, :aliases => :d, :desc => '如果有flutter混编, 此参数是 flutter项目的相对路径.'
93
+
94
+ def tf()
95
+ puts "archive_tf"
96
+ if options[:user_name].blank? || options[:pass_word].blank?
97
+ apple_dict = self.load_archive_config_dict(YKFastlane::ArchiveHelper::K_archiveEnv_config_tf)
98
+ if apple_dict != nil && apple_dict.blank?() == false
99
+ options.update(apple_dict)
100
+ end
101
+ end
102
+
103
+ code = YKFastlaneExecute.executeFastlaneLane("archive_tf", options)
104
+ exit(code)
105
+ end
106
+
107
+ desc "pgyer", "archive ios project and upload to pgyer, will send failed message to enterprise robot \'#{Helper::YKWECHAT_ROBOT_TOKEN}\'"
108
+ option :scheme, :required => true, :type => :string, :aliases => :s, :desc => 'scheme name'
109
+ option :pgyer_api, :type => :string, :aliases => :a, :desc => '蒲公英平台的api key; 如果不传,会使用全局配置的 api key'
110
+ option :pgyer_user, :type => :string, :aliases => :u, :desc => '蒲公英平台的user key; 如果不传,会使用全局配置的 user key'
111
+ option :wxwork_access_token, :type => :string, :aliases => :w, :desc => '企业微信机器人 webhook中的key字段, 如果没有,则使用env中配置的机器人'
112
+ option :note, :type => :string, :aliases => :n, :desc => '测试包发包信息'
113
+ option :xcworkspace, :type => :string, :aliases => :x, :desc => '.xcworkspace 文件相对于指令工作目录的相对路径, 如果.xcworkspace文件在工程根目录,则可以不传递此参数'
114
+ option :cocoapods, :type => :numeric, :aliases => :c, :desc => '是否需要执行pod install, 默认不执行pod install 指令, 1:执行, 非1:不执行'
115
+ option :flutter_directory, :type => :string, :aliases => :d, :desc => '如果有flutter混编, 此参数是 flutter项目的相对路径.'
116
+ option :export, :type => :string, :aliases => :e, :desc => '包的类型, app-store, validation,ad-hoc, package, enterprise, development, developer-id, mac-application, 默认为enterprise'
117
+
118
+ def pgyer()
119
+ puts "archive_pgyer"
120
+
121
+ if options[:pgyer_user].blank? || options[:pgyer_api].blank?
122
+ dict = self.load_archive_config_dict(YKFastlane::ArchiveHelper::K_archiveEnv_config_pgyer)
123
+ options.update(dict)
124
+ end
125
+
126
+ code = YKFastlaneExecute.executeFastlaneLane("archive_pgyer", options)
127
+ exit(code)
128
+ end
129
+
130
+ desc "fir", "archive ios project and upload to fir, will send failed message to enterprise robot \'#{Helper::YKWECHAT_ROBOT_TOKEN}\'"
131
+ option :scheme, :required => true, :type => :string, :aliases => :s, :desc => 'scheme name'
132
+ option :fir_api_token, :type => :string, :aliases => :f, :desc => 'Fir平台api token'
133
+ option :wxwork_access_token, :type => :string, :aliases => :w, :desc => '企业微信机器人 webhook中的key字段, 如果没有,则使用env中配置的机器人'
134
+ option :note, :type => :string, :aliases => :n, :desc => '测试包发包信息'
135
+ option :xcworkspace, :type => :string, :aliases => :x, :desc => '.xcworkspace 文件相对于指令工作目录的相对路径, 如果.xcworkspace文件在工程根目录,则可以不传递此参数'
136
+ option :cocoapods, :type => :numeric, :aliases => :c, :desc => '是否需要执行pod install, 默认不执行pod install 指令, 1:执行, 非1:不执行'
137
+ option :flutter_directory, :type => :string, :aliases => :d, :desc => '如果有flutter混编, 此参数是 flutter项目的相对路径.'
138
+ option :export, :type => :string, :aliases => :e, :desc => '包的类型, 包的类型, app-store, validation,ad-hoc, package, enterprise, development, developer-id, mac-application, 默认为enterprise'
139
+
140
+ def fir()
141
+ puts "archive_fir"
142
+ if options[:fir_api_token].blank?
143
+ dict = self.load_archive_config_dict(YKFastlane::ArchiveHelper::K_archiveEnv_config_fir)
144
+ options.update(dict)
145
+ end
146
+
147
+ code = YKFastlaneExecute.executeFastlaneLane("archive_fir", options)
148
+ exit(code)
149
+ end
150
+
151
+ end
152
+ end
@@ -0,0 +1,41 @@
1
+ require 'ykfastlane/version'
2
+ require 'ykfastlane/tools'
3
+ require 'ykfastlane/helper'
4
+ module YKFastlane
5
+
6
+ module ArchiveHelper
7
+ YKARCHIVE_PRODUCT_PATH = File.expand_path(File.join(Dir.home, "iosYeahArchive"))
8
+
9
+ YKARCHIVE_ENV_PATH = File.join(YKFastlane::YKFASTLANE_ENV_PATH, 'archive_config', 'archive_config.yml')
10
+
11
+ K_archiveEnv_config_tf = :test_flight
12
+ K_archiveEnv_tf_account = :user_name
13
+ K_archiveEnv_tf_password = :pass_word
14
+
15
+ K_archiveEnv_config_fir = :fir
16
+ K_archiveEnv_firApiToken = :fir_api_token
17
+
18
+ K_archiveEnv_config_pgyer = :pgyer
19
+ K_archiveEnv_pgyer_user = :pgyer_user
20
+ K_archiveEnv_pgyer_api = :pgyer_api
21
+
22
+ def self.update_archive_map(key, value)
23
+ YKFastlane::Tools.update_yml("", YKARCHIVE_ENV_PATH, key, value)
24
+ end
25
+
26
+ def update_archive_map(key, value)
27
+ YKFastlane::Tools.update_yml("", YKARCHIVE_ENV_PATH, key, value)
28
+ end
29
+
30
+ def load_archive_config_dict(platform_name)
31
+ dict = YKFastlane::Tools.load_yml_value(YKARCHIVE_ENV_PATH, platform_name)
32
+ return dict == nil ? {} : dict
33
+ end
34
+
35
+ def list_user_map()
36
+ YKFastlane::Tools.display_yml(YKARCHIVE_ENV_PATH)
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,92 @@
1
+ require 'actions/YKFastlaneExecute'
2
+ require 'ykfastlane/helper'
3
+ require 'thor'
4
+ require 'openssl'
5
+
6
+ module YKFastlane
7
+ class Certificate < YKFastlane::SubCommandBase
8
+
9
+ desc "sync_apple_profile", "sync and install mobile provision file from apple developer service"
10
+ option :user_name, :require => true, :type => :string, :aliases => :u, :desc => 'apple account'
11
+ option :password, :require => true, :type => :string, :aliases => :p, :desc => 'apple account password'
12
+ option :workspace, :require => false, :type => :string, :aliases => :w, :desc => 'p12 password'
13
+ option :bundle_ids, :require => false, :type => :array, :aliases => :b, :desc => "bundle identifier arr, separate by \" \" once more than one, exaple: 123 456 234"
14
+
15
+ def sync_apple_profile()
16
+ puts "options:#{options}"
17
+ arr = options[:bundle_ids]
18
+ if arr != nil && arr.count > 0
19
+ str = arr.join(",")
20
+ options[:bundle_ids] = str
21
+ end
22
+
23
+ if options[:workspace].blank? == false
24
+ Dir.chdir(Dir.pwd) do
25
+ options[:workspace] = File.expand_path(options[:workspace])
26
+ end
27
+ end
28
+
29
+ puts "options_formatter:#{options}"
30
+ code = YKFastlaneExecute.executeFastlaneLane("sync_apple_profile", options)
31
+ exit! code
32
+ end
33
+
34
+ desc "update_profile", "Update one profile"
35
+ option :profile_path, :require => true, :type => :array, :aliases => :p, :desc => 'profile path'
36
+
37
+ def update_profile()
38
+ result_arr = []
39
+ arr = options[:profile_path]
40
+ if arr != nil && arr.count > 0
41
+ Dir.chdir(Dir.pwd) do
42
+ arr.each do |one|
43
+ path = File.expand_path(one)
44
+ result_arr << path
45
+ end
46
+ end
47
+ end
48
+
49
+ str = result_arr.join(",")
50
+ options[:profile_path] = str unless str.blank?
51
+ puts "options:#{options}"
52
+ code = YKFastlaneExecute.executeFastlaneLane("update_profiles", options)
53
+ exit! code
54
+ end
55
+
56
+ desc "update_cer", "edit certificate & profile for project schem or target"
57
+ option :cer_password, :require => true, :type => :string, :aliases => :p, :desc => 'p12 password'
58
+ option :cer_path, :require => true, :type => :string, :aliases => :c, :desc => 'p12 path'
59
+
60
+ def update_cer()
61
+ puts "options:#{options}"
62
+
63
+ para = {}
64
+ Dir.chdir(Dir.pwd) do
65
+ para[:cer_path] = File.expand_path(options[:cer_path]) unless options[:cer_path].blank?
66
+ end
67
+
68
+ para[:password] = options[:cer_password]
69
+
70
+ code = YKFastlaneExecute.executeFastlaneLane("update_certificate_p12", para)
71
+ exit! code
72
+ end
73
+
74
+ desc "sync_git", "sync certificate & profile git, and will overwrite the existed files once pass the remote_url"
75
+ option :remote_url, :require => false, :type => :string, :aliases => :r, :desc => "git remote url, example:#{YKFastlane::Helper.default_certificate_git_remote}"
76
+
77
+ def sync_git()
78
+ puts "#{method(:sync_git)}--options:#{options}"
79
+ code = YKFastlaneExecute.executeFastlaneLane("sync_certificate_profile", options)
80
+ exit! code
81
+ end
82
+
83
+ desc "list_details", "list certificate details"
84
+
85
+ def list_details()
86
+ puts("certificate list_details")
87
+ code = YKFastlaneExecute.executeFastlaneLane("list_profile_certificate_config", options)
88
+ exit! code
89
+ end
90
+
91
+ end
92
+ end
@@ -0,0 +1,84 @@
1
+ require 'git'
2
+ require 'yaml'
3
+ require 'json'
4
+
5
+ require 'actions/YKFastlaneExecute'
6
+ require 'actions/archiveHelper'
7
+
8
+ module YKFastlane
9
+ class Init < YKFastlane::SubCommandBase
10
+ include Helper
11
+
12
+ desc "sync_script", "sync fast file from the remote"
13
+ long_desc <<-LONGDESC
14
+ 同步远端fastlane脚本,此处可以通过参数下载固定的fastlan仓库,也可以使用环境配置的仓库来下载。
15
+ LONGDESC
16
+ option :fastfile_remote, :aliases => :f, :type => :string, :desc => "fastlane 文件仓库地址, 如果未传递,则使用env中配置的,#{Helper::YKCONFIG_PATH}"
17
+
18
+ def sync_script()
19
+ fastfile_remote = options[:fastfile_remote].blank? ? Helper::load_config_value(Helper::K_fastfile_remote) : options[:fastfile_remote]
20
+
21
+ if fastfile_remote.blank?
22
+ puts "no remote, work failed"
23
+ exit false
24
+ end
25
+
26
+ p = Helper::YKFastlne_SCRIPT_PATH
27
+ p_temp = p + "_temp"
28
+ FileUtils.remove_dir(p_temp, force: true)
29
+
30
+ cloneResult = YKFastlane::Tools.clone_git_repository(fastfile_remote, p_temp)
31
+ if cloneResult != 0
32
+ exit cloneResult
33
+ end
34
+
35
+ if Dir.exist?(p)
36
+ puts "directory exist, so we delete it:#{p}"
37
+ FileUtils.remove_dir(p, true)
38
+ end
39
+
40
+ if File.exist?(File.dirname(p)) == false
41
+ FileUtils.mkdir_p(File.dirname(p))
42
+ end
43
+ FileUtils.mv(p_temp, p, force: true, verbose: true)
44
+
45
+ Dir.chdir(p) do
46
+ system("bundle install --verbose")
47
+ end
48
+ return 0
49
+ end
50
+
51
+ desc 'config', "update configuration file: #{Helper::YKCONFIG_PATH}"
52
+ long_desc <<-LONGDESC
53
+ 本指令集只是一个门户指令,核心打包功能是通过调用fastlane脚本来实现的。
54
+ 需要配置: 1.配置fastlane脚本的远程仓库; 2.配置任务失败时候的反馈企业微信机器人, [【企业微信机器人配置】](https://developer.work.weixin.qq.com/document/path/91770)
55
+ LONGDESC
56
+ option :fastfile_remote, :aliases => :f, :type => :string, :desc => "fastlane 文件的git remote, 可用参数:#{Helper.default_fast_file_remote()}"
57
+ option :wx_access_token, :aliases => :t, :type => :string, :desc => "enterprise wechat robot token"
58
+
59
+ def config()
60
+ puts "options:#{options}"
61
+ Helper.update_config('', Helper::K_fastfile_remote, options[:fastfile_remote]) unless options[:fastfile_remote].blank?
62
+ Helper.update_config('', Helper::K_wx_access_token, options[:wx_access_token]) unless options[:wx_access_token].blank?
63
+ YKFastlane::ArchiveHelper.update_archive_map(Helper::K_wx_access_token, options[:wx_access_token]) unless options[:wx_access_token].blank?
64
+ Helper.display_config_yml
65
+ end
66
+
67
+ desc 'define_fast_execute_path', "指定fastlane文件的路径,此处是为了调试fastlane脚本"
68
+ option :debug_flag, :aliases => :d, :type => :string, :require => true, :desc => "运行调试脚本的开关, 1:运行调试脚本, 其他:运行默认脚本"
69
+ option :fastfile_path, :aliases => :e, :type => :string, :desc => "运行的fastlane 文件的路径,此处是为了调试"
70
+
71
+ def define_fast_execute_path()
72
+ Helper.update_config("debug flag", Helper::K_YK_CONFIG_FASTLANE_DEBUG, options[:debug_flag] ? options[:debug_flag] : 0)
73
+ Helper.update_config("execute path", Helper::K_YK_CONFIG_FASTLANE_SCRIPT, options[:fastfile_path].blank? ? "" : options[:fastfile_path])
74
+ end
75
+
76
+ desc "list_config", "print the env config file: #{Helper::YKCONFIG_PATH}"
77
+
78
+ def list_config()
79
+ Helper.display_config_yml
80
+ end
81
+
82
+ end
83
+
84
+ end
@@ -0,0 +1,29 @@
1
+ require 'actions/YKFastlaneExecute'
2
+ require 'ykfastlane/helper'
3
+ require 'rails'
4
+
5
+ module YKFastlane
6
+ class Pod < YKFastlane::SubCommandBase
7
+ desc 'github_transfer', '迁移github三方库到移开gitlab.'
8
+ long_desc <<-LONGDESC
9
+ 1. 需要在移开gitlab创建一个同名的git仓库.
10
+ 2. 尝试迁移所有tag, 当碰到迁移失败的tag的时候,并不会导致整个迁移的失败;
11
+ 3. 最终会输出迁移成功的数组和失败的数组
12
+ LONGDESC
13
+ option :orignal_url, :aliases => :o, :required => true, :type => :string, :desc => '原始源码仓库'
14
+ option :ykgitlab_url, :aliases => :d, :required => true, :type => :string, :desc => '迁移的目标仓库'
15
+ option :versions, :aliases => :s, :type => :string, :desc => '迁移的目标版本,多个的时候用空格\' \'隔开, 默认遍历尝试迁移所有的版本,比较耗时'
16
+ option :wxwork_access_token, :aliases => :w, :type => :string, :desc => '用于将任务结果传给企业微信'
17
+
18
+ def github_transfer()
19
+ puts "github_pod_transfer"
20
+ if options[:wxwork_access_token].blank?
21
+ wxtoken = YKFastlane::Helper.load_config_value(YKFastlane::Helper::K_wx_access_token)
22
+ options[:wxwork_access_token] = wxtoken unless wxtoken.blank?
23
+ end
24
+
25
+ code = Ykfastlane::YKFastlaneExecute.executeFastlaneLane("github_pod_transfer", options)
26
+ exit(code)
27
+ end
28
+ end
29
+ end
data/lib/interface.rb ADDED
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ykfastlane/version'
4
+
5
+ require 'actions/YKFastlaneExecute'
6
+ require 'actions/archive'
7
+ require 'actions/pod'
8
+ require 'actions/init'
9
+ require 'actions/certificate'
10
+ require 'thor'
11
+
12
+ module YKFastlane
13
+ class Interface < Thor
14
+ include Thor::Actions
15
+ require_relative 'actions/YKFastlaneExecute'
16
+ include YKFastlane::Helper
17
+
18
+ class_option :verbose, :type => :boolean
19
+ def self.exit_on_failure?
20
+ true
21
+ end
22
+
23
+ desc "lanes", 'list all lanes'
24
+
25
+ def lanes()
26
+ puts "lanes"
27
+ code = YKFastlane::YKFastlaneExecute.executeFastlaneLane("lanes", options)
28
+ exit(code)
29
+ end
30
+
31
+ desc "archive", "archive functions"
32
+ subcommand "archive", YKFastlane::Archive
33
+
34
+ desc "pod", "cocoapods functions"
35
+ subcommand "pod", YKFastlane::Pod
36
+
37
+ desc "init", "init ykfastlane"
38
+ subcommand "init", YKFastlane::Init
39
+
40
+ desc "certificate", "manager ios certificate & profile files"
41
+ subcommand "certificate", YKFastlane::Certificate
42
+ end
43
+ end
@@ -0,0 +1,84 @@
1
+ require 'yaml'
2
+ require 'json'
3
+ require 'ykfastlane/tools'
4
+ require 'ykfastlane/version'
5
+ module YKFastlane
6
+ module Helper
7
+ include YKFastlane::Tools
8
+ '' '脚本当前工作路径' ''
9
+ YKRUNING_PATH = File.expand_path(Dir.pwd)
10
+ '' '配置文件放置路径' ''
11
+ YKCONFIG_PATH = File.expand_path(File.join(YKFastlane::YKFASTLANE_ENV_PATH, 'evnConfig.yml'))
12
+
13
+ '' 'fastlane脚本放置路径' ''
14
+ YKFastlne_SCRIPT_PATH = File.expand_path(File.join(YKFastlane::YKFASTLANE_ENV_PATH, 'ykfastlane_script'))
15
+
16
+ def self.load_config_yml()
17
+ Tools.load_yml(Helper::YKCONFIG_PATH)
18
+ end
19
+
20
+ def self.display_config_yml()
21
+ Tools.display_yml(Helper::YKCONFIG_PATH)
22
+ end
23
+
24
+ def self.load_config_value(key)
25
+ Tools.load_yml_value(Helper::YKCONFIG_PATH, key)
26
+ end
27
+
28
+ def self.update_config(qustion, key, value)
29
+ Tools.update_yml(qustion, Helper::YKCONFIG_PATH, key, value)
30
+ end
31
+
32
+ def self.default_git_domain()
33
+ p0 = "http://gitlab."
34
+ p1 = "y"
35
+ p2 = 'ea'
36
+ p3 = "h"
37
+ p4 = "ka"
38
+ p5 = ".com"
39
+ p0 + p1 + p2 + p3 + p4 + p5
40
+ end
41
+
42
+ def self.default_fast_file_remote()
43
+ url1 = "#{self.default_git_domain}/App/iOS/ykfastlane.git"
44
+ url2 = "https://github.com/stephen5652/ykfastlane_scrip.git"
45
+ "" "
46
+ \033[0;32m#{url1}\e[0m or \033[0;32m#{url2}\e[0m
47
+ " ""
48
+ end
49
+
50
+ def self.default_certificate_git_remote()
51
+ url = "#{self.default_git_domain}/App/iOS/certificates/YKCertificateProfiles.git"
52
+ "" "
53
+ \033[0;32m#{url}\e[0m
54
+ " ""
55
+ end
56
+
57
+ '' ' 配置文件key-fastfile_remote' ''
58
+ K_fastfile_remote = :fastfile_remote
59
+
60
+ '' ' 配置文件key-wx_access_token' ''
61
+ K_wx_access_token = :wx_access_token
62
+
63
+ '' '企业微信CI机器人' ''
64
+ YKWECHAT_ROBOT_TOKEN = Helper.load_config_value(Helper::K_wx_access_token)
65
+
66
+ '' 'fastlane脚本路径' ''
67
+ K_YK_CONFIG_FASTLANE_SCRIPT = :fast_file
68
+ '' 'fastlane debug开关' ''
69
+ K_YK_CONFIG_FASTLANE_DEBUG = :fast_file_debug
70
+
71
+ def self.fastlane_script
72
+ path = Helper.load_config_value(K_YK_CONFIG_FASTLANE_SCRIPT)
73
+ debug = Helper.load_config_value(K_YK_CONFIG_FASTLANE_DEBUG)
74
+ puts "path:#{path}"
75
+ puts "debug flag[#{debug.class}]:#{debug}"
76
+ if path.blank? || debug.blank? || debug != "1"
77
+ path = YKFastlne_SCRIPT_PATH
78
+ end
79
+ puts "fastlane file path:#{path}"
80
+ path
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,172 @@
1
+ require 'yaml'
2
+ require 'json'
3
+
4
+ module YKFastlane
5
+
6
+ module Tools
7
+ def self.green(string)
8
+ "\033[0;32m#{string}\e[0m"
9
+ end
10
+
11
+ def self.UI(string)
12
+ puts(self.green(string))
13
+ end
14
+
15
+ def self.show_prompt
16
+ print green(">")
17
+ end
18
+
19
+ def self.yk_ask(question)
20
+ answer = ""
21
+ loop do
22
+ puts "\n#{question}?"
23
+ show_prompt()
24
+ answer = STDIN.gets.chomp
25
+
26
+ break if answer.length > 0
27
+
28
+ print "\nYou need to provide an answer."
29
+ end
30
+ puts "answier:#{answer}"
31
+ answer
32
+ end
33
+
34
+ def self.yk_ask_with_answers(question, possible_answers)
35
+ print "\n#{question}? ["
36
+ print_info = Proc.new {
37
+ possible_answers_string = possible_answers.each_with_index do |answer, i|
38
+ _answer = (i == 0) ? answer.underlined : answer
39
+ print " " + _answer
40
+ print(" /") if i != possible_answers.length - 1
41
+ end
42
+ print " ]\n"
43
+ }
44
+ print_info.call
45
+
46
+ answer = ""
47
+ loop do
48
+ show_prompt()
49
+ answer = STDIN.gets.chomp
50
+
51
+ answer = "yes" if answer == "y"
52
+ answer = "no" if answer == "n"
53
+
54
+ # default to first answer
55
+ if answer == ""
56
+ answer = possible_answers[0].downcase
57
+ print answer.yellow
58
+ end
59
+
60
+ break if possible_answers.map { |a| a.downcase }.include? answer
61
+
62
+ print "\nPossible answers are ["
63
+ print_info.call
64
+ end
65
+
66
+ answer
67
+ end
68
+
69
+ def self.load_yml(path)
70
+ if File.exist?(path) == false
71
+ FileUtils.makedirs(File.dirname(path))
72
+ File.new(path, 'w+')
73
+ end
74
+
75
+ f = File.open(path)
76
+ yml = YAML.load(f, symbolize_names: false)
77
+ f.close
78
+ yml = {} if yml == false #空yml的时候, yml = false
79
+ yml
80
+ end
81
+
82
+ def self.display_yml(path)
83
+ puts Tools::green(JSON.pretty_generate(load_yml(path)))
84
+ end
85
+
86
+ def self.load_yml_value(path, key)
87
+ yml = load_yml(path)
88
+ yml = {} if yml == false #空yml的时候, yml = false
89
+ re = yml[key].blank? ? nil : yml[key]
90
+ re
91
+ end
92
+
93
+ def self.update_yml(qustion, path, key, value)
94
+ yml = load_yml(path)
95
+
96
+ updateFlag = :yes
97
+ if value.blank? #外部未传该参数需要通过问答形式,获取该参数
98
+ value = Tools.yk_ask("please input #{Tools::green(qustion)}")
99
+
100
+ if yml[key].blank? == false #需要确认修改
101
+ puts "#{key} existed:#{yml[key]}"
102
+ updateFlag = Tools.yk_ask_with_answers("Are you sure to update #{self.green(qustion)}", ["Yes", "No"]).to_sym
103
+ end
104
+ end
105
+ yml[key] = value unless updateFlag != :yes
106
+ c_path = Helper::YKCONFIG_PATH
107
+ f = File.open(path, "w+")
108
+ YAML.dump(yml, f, symbolize_names: false)
109
+ f.close
110
+ end
111
+
112
+ def self.over_write_yml_dict(path, dict)
113
+ f = File.open(path, "w+")
114
+ YAML.dump(dict, f, symbolize_names: false)
115
+ f.close
116
+ end
117
+
118
+ def self.clone_git_repository(remote, destinationPath)
119
+ begin
120
+ puts "start clone:#{remote}"
121
+ cloneResult = Git::clone(remote, destinationPath, :log => Logger.new(Logger::Severity::INFO))
122
+ puts "clone_result:#{cloneResult}"
123
+ rescue Git::GitExecuteError => e
124
+ puts "clone failed:#{e}"
125
+ return 1 #任务失败
126
+ end
127
+ return 0
128
+ end
129
+
130
+ def self.git_pull(path)
131
+ begin
132
+ git = Git::open(path)
133
+ git.add()
134
+ git.reset_hard()
135
+ curbranch = git.current_branch
136
+ git.pull('origin', curbranch)
137
+ rescue Git::GitExecuteError => e
138
+ puts "pull remote failed:#{e}"
139
+ return 1 #任务失败
140
+ end
141
+
142
+ return 0
143
+ end
144
+
145
+ def self.git_commit(path, msg)
146
+ git = Git::open(path)
147
+ git.add()
148
+ curbranch = git.current_branch
149
+ begin
150
+ git.commit("update:#{msg}")
151
+ rescue Git::GitExecuteError => e
152
+ puts "commit update execption:#{e}"
153
+ end
154
+
155
+ status = git.status()
156
+ if status.untracked.count != 0 || status.changed.count != 0
157
+ puts "git not clean, work failed"
158
+ return 1
159
+ else
160
+ puts "git clean, work success"
161
+ git.push('origin', curbranch)
162
+ return 0
163
+ end
164
+ end
165
+
166
+ def self.notify_message_to_enterprise_wechat(msg, status)
167
+ puts "should send failed message to enterprise wechat:\"#{self.green(msg)}\""
168
+ exit!(status) unless status == 0
169
+ end
170
+
171
+ end
172
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YKFastlane
4
+ VERSION = "0.3.12"
5
+ YKFASTLANE_ENV_PATH = File.expand_path(File.join(Dir.home, '.ykfastlane_config'))
6
+ end
metadata ADDED
@@ -0,0 +1,183 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ykfastlane
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.12
5
+ platform: ruby
6
+ authors:
7
+ - stephen.chen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-10-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: git
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yaml
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: security
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: openssl
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: json
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: plist
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: public_suffix
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "<"
130
+ - !ruby/object:Gem::Version
131
+ version: 5.0.0
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "<"
137
+ - !ruby/object:Gem::Version
138
+ version: 5.0.0
139
+ description: 基于fastlane的 iOS 打包工具.
140
+ email:
141
+ - stephen5652@126.com
142
+ executables:
143
+ - ykfastlane
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - LICENSE.txt
148
+ - README.md
149
+ - bin/ykfastlane
150
+ - lib/actions/YKFastlaneExecute.rb
151
+ - lib/actions/archive.rb
152
+ - lib/actions/archiveHelper.rb
153
+ - lib/actions/certificate.rb
154
+ - lib/actions/init.rb
155
+ - lib/actions/pod.rb
156
+ - lib/interface.rb
157
+ - lib/ykfastlane/helper.rb
158
+ - lib/ykfastlane/tools.rb
159
+ - lib/ykfastlane/version.rb
160
+ homepage: https://github.com/stephen5652/ykfastlane.git
161
+ licenses:
162
+ - MIT
163
+ metadata: {}
164
+ post_install_message:
165
+ rdoc_options: []
166
+ require_paths:
167
+ - lib
168
+ required_ruby_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: 2.6.0
173
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: '0'
178
+ requirements: []
179
+ rubygems_version: 3.1.6
180
+ signing_key:
181
+ specification_version: 4
182
+ summary: iOS 打包工具.
183
+ test_files: []