fastlane-plugin-fastci 0.0.30 → 0.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  require 'gym'
2
2
  require 'fastlane_core'
3
3
  require 'fastlane/action'
4
+ require 'fastlane/plugin/fastci/helper/app_store_resources_helper'
4
5
  include Fastlane::Helper
5
6
 
6
7
  module Fastlane
@@ -17,7 +18,7 @@ module Fastlane
17
18
  is_detect_duplicity_code = params[:is_detect_duplicity_code] || false
18
19
  is_detect_unused_code = params[:is_detect_unused_code] || false
19
20
  is_detect_unused_image = params[:is_detect_unused_image] || false
20
- release_notes = params[:release_notes] || ''
21
+ store_options = store_upload_options(params, export_method)
21
22
  configuration = 'Release' if %w[app-store testFlight].include?(export_method)
22
23
  is_notice_dingding = params[:is_notice_dingding].nil? ? true : params[:is_notice_dingding]
23
24
  # 统一发送钉钉消息匿名函数
@@ -145,14 +146,7 @@ module Fastlane
145
146
  notiText = "🚀🚀🚀🚀🚀🚀\n\n#{scheme}-iOS-打包完成\n\n#{version}_#{build}_#{export_method}\n\n🚀🚀🚀🚀🚀🚀"
146
147
  send_dingding_notice.call(notiText)
147
148
 
148
- if CommonHelper.is_validate_string(Environment.connect_key_id) && CommonHelper.is_validate_string(Environment.connect_issuer_id)
149
- # 根据 export_method 决定是否为 TestFlight
150
- is_test_flight = export_method == 'testFlight'
151
-
152
- other_action.upload_store(
153
- release_notes: release_notes,
154
- isTestFlight: is_test_flight
155
- )
149
+ if upload_store_if_configured(store_options, version: version, build: build)
156
150
  notiText = "🚀🚀🚀🚀🚀🚀\n\n#{scheme}-iOS-上传完成\n\n#{version}_#{build}_#{export_method}\n\n🚀🚀🚀🚀🚀🚀"
157
151
  send_dingding_notice.call(notiText)
158
152
  end
@@ -267,12 +261,67 @@ module Fastlane
267
261
  UI.message('*************| 脚本完成 |*************')
268
262
  end
269
263
 
264
+ # 构建前准备商店上传参数,开启资源功能却漏配路径时立即报错。
265
+ def self.store_upload_options(params, export_method)
266
+ config_path = AppStoreResourcesHelper.upload_config_path(params, app_store: export_method == 'app-store')
267
+ options = {
268
+ release_notes: params[:release_notes] || '',
269
+ isTestFlight: export_method == 'testFlight',
270
+ # 显式透传 false,避免下层 Action 从环境变量重新开启本次已关闭的功能。
271
+ app_store_resources_enabled: !config_path.nil?
272
+ }
273
+ options[:app_store_resources_config_path] = config_path if config_path
274
+ options
275
+ end
276
+
277
+ # 根据凭据或已开启的资源配置判断是否上传,单独存在资源路径不能触发上传。
278
+ def self.store_upload_configured?(options)
279
+ has_p8_key = CommonHelper.is_validate_string(Environment.connect_key_id) &&
280
+ CommonHelper.is_validate_string(Environment.connect_issuer_id)
281
+ has_api_key_json = CommonHelper.is_validate_string(Environment.app_store_connect_api_key_path)
282
+ has_p8_key || has_api_key_json || options[:app_store_resources_enabled]
283
+ end
284
+
285
+ # 上传本次产物,并返回是否执行了上传,供主流程决定是否发送完成通知。
286
+ def self.upload_store_if_configured(options, version:, build:)
287
+ return false unless store_upload_configured?(options)
288
+
289
+ upload_options = options.dup
290
+ if upload_options[:app_store_resources_enabled]
291
+ # 使用真实产物信息覆盖资源配置,避免选中 JSON 中残留的旧版本或 Build。
292
+ upload_options.merge!(
293
+ app_identifier: Environment.bundleID,
294
+ app_version: version.to_s,
295
+ build_number: build.to_s
296
+ )
297
+ end
298
+ other_action.upload_store(upload_options)
299
+ true
300
+ end
301
+
302
+ private_class_method :store_upload_options, :store_upload_configured?, :upload_store_if_configured
303
+
270
304
  def self.description
271
305
  '打包'
272
306
  end
273
307
 
274
308
  def self.available_options
275
309
  [
310
+ FastlaneCore::ConfigItem.new(
311
+ key: :app_store_resources_enabled,
312
+ env_name: 'APP_STORE_RESOURCES_ENABLED',
313
+ description: '商店资源总开关,默认关闭,仅 app-store 打包时生效',
314
+ optional: true,
315
+ default_value: false,
316
+ type: Boolean
317
+ ),
318
+ FastlaneCore::ConfigItem.new(
319
+ key: :app_store_resources_config_path,
320
+ env_name: 'APP_STORE_RESOURCES_CONFIG_PATH',
321
+ description: 'App Store 资源发布 JSON 路径,开启商店资源总开关后必填',
322
+ optional: true,
323
+ type: String
324
+ ),
276
325
  FastlaneCore::ConfigItem.new(
277
326
  key: :is_upload_zealot_dsym,
278
327
  env_name: 'ZEALOT_UPLOAD_DSYM',
@@ -1,4 +1,6 @@
1
1
  require 'fastlane/action'
2
+ require 'json'
3
+ require 'fastlane/plugin/fastci/helper/app_store_resources_helper'
2
4
  include Fastlane::Helper
3
5
 
4
6
  module Fastlane
@@ -6,62 +8,141 @@ module Fastlane
6
8
  # 上传 AppStore
7
9
  class UploadStoreAction < Action
8
10
  def self.run(params)
11
+ resource_params, api_key_options = prepare_upload(params)
9
12
 
10
- release_notes = JSON.parse(params[:release_notes] || "") rescue nil
13
+ if params[:isTestFlight]
14
+ upload_testflight(api_key_options)
15
+ else
16
+ upload_app_store(resource_params, api_key_options)
17
+ end
18
+ end
11
19
 
12
- other_action.app_store_connect_api_key(
13
- key_id: Environment.connect_key_id,
14
- issuer_id: Environment.connect_issuer_id,
15
- key_filepath: File.expand_path("#{Environment.package_file_folder_name}/AuthKey_#{Environment.connect_key_id}.p8"),
16
- duration: 1200, # optional (maximum 1200)
17
- in_house: false # optional but may be required if using match/sigh
20
+ # 上传前统一准备认证和资源,确保配置错误或资源缺失在 IPA 上传前被发现。
21
+ def self.prepare_upload(params)
22
+ resource_params = load_store_resources(params)
23
+ api_key_options = AppStoreResourcesHelper.authentication_options(resource_params || {}, other_action)
24
+ if resource_params
25
+ resource_params.merge!(api_key_options)
26
+ resource_params = AppStoreResourcesHelper.prepare(resource_params)
27
+ end
28
+ [resource_params, api_key_options]
29
+ end
30
+
31
+ # 只有显式开启的 App Store 流程读取资源配置,关闭时不解析路径或更新说明。
32
+ def self.load_store_resources(params)
33
+ config_path = AppStoreResourcesHelper.upload_config_path(params, app_store: !params[:isTestFlight])
34
+ return nil unless config_path
35
+
36
+ AppStoreResourcesHelper.load_params(
37
+ app_store_resources_enabled: true,
38
+ config_path: config_path,
39
+ app_identifier: params[:app_identifier],
40
+ app_version: params[:app_version],
41
+ build_number: params[:build_number],
42
+ release_notes: parse_release_notes(params[:release_notes])
18
43
  )
44
+ end
19
45
 
20
- if params[:isTestFlight]
21
- UI.message("*************| 开始上传 TestFlight |*************")
22
- other_action.upload_to_testflight(
23
- skip_waiting_for_build_processing: true
24
- )
25
- else
26
- UI.message("*************| 开始上传 AppStore |*************")
27
-
28
- # 构建上传参数,只有当 release_notes 有效时才添加
29
- upload_options = {
30
- skip_metadata: false,
31
- skip_screenshots: true,
32
- run_precheck_before_submit: false,
33
- precheck_include_in_app_purchases: false,
34
- force: true,
35
- submit_for_review: false,
36
- automatic_release: false
37
- }
38
-
39
- # 只有当 release_notes 不为 nil 且不为空时才添加
40
- if release_notes && !release_notes.empty?
41
- upload_options[:release_notes] = release_notes
42
- end
43
-
44
- other_action.upload_to_app_store(upload_options)
46
+ # 保留原 JSON 字符串接口;空值或无效 JSON 不覆盖资源文件中的更新说明。
47
+ def self.parse_release_notes(value)
48
+ JSON.parse(value || '')
49
+ rescue JSON::ParserError, TypeError
50
+ nil
51
+ end
52
+
53
+ # TestFlight 沿用现有上传方式,不执行 App Store 资源流程。
54
+ def self.upload_testflight(api_key_options)
55
+ UI.message('*************| 开始上传 TestFlight |*************')
56
+ other_action.upload_to_testflight({ skip_waiting_for_build_processing: true }.merge(api_key_options))
57
+ end
58
+
59
+ # 先上传 IPA,再处理已校验的资源;返回 IPA 上传结果以兼容已有 lane。
60
+ def self.upload_app_store(resource_params, api_key_options)
61
+ UI.message('*************| 开始上传 AppStore |*************')
62
+ upload_options = app_store_upload_options(resource_params).merge(api_key_options)
63
+ upload_result = other_action.upload_to_app_store(upload_options)
64
+ if resource_params
65
+ # 新版本判断已在 IPA 上传前完成,之后直接使用确认过的资源上传开关。
66
+ other_action.app_store_resources(resource_params.merge(upload_metadata_on_new_version: false))
45
67
  end
68
+ upload_result
46
69
  end
47
70
 
71
+ # IPA 阶段始终关闭资源上传,避免默认目录或 Deliverfile 绕过资源总开关。
72
+ def self.app_store_upload_options(resource_params)
73
+ options = {
74
+ skip_metadata: true,
75
+ skip_screenshots: true,
76
+ # deliver 的截图同步分支不受 skip_screenshots 控制,必须一并关闭。
77
+ sync_screenshots: false,
78
+ overwrite_screenshots: false,
79
+ run_precheck_before_submit: false,
80
+ precheck_include_in_app_purchases: false,
81
+ force: true,
82
+ submit_for_review: false,
83
+ automatic_release: false
84
+ }
85
+ if resource_params
86
+ options[:app_identifier] = resource_params[:app_identifier]
87
+ options[:app_version] = resource_params[:app_version] if resource_params[:app_version]
88
+ end
89
+ options
90
+ end
91
+
92
+ private_class_method :prepare_upload, :load_store_resources, :parse_release_notes,
93
+ :upload_testflight, :upload_app_store, :app_store_upload_options
94
+
48
95
  def self.description
49
96
  "上传 AppStore"
50
97
  end
51
98
 
52
99
  def self.available_options
53
100
  [
101
+ FastlaneCore::ConfigItem.new(
102
+ key: :app_store_resources_enabled,
103
+ env_name: 'APP_STORE_RESOURCES_ENABLED',
104
+ description: '商店资源总开关,默认关闭;关闭时仅上传 IPA,不更新元数据或截图',
105
+ optional: true,
106
+ default_value: false,
107
+ type: Boolean
108
+ ),
54
109
  FastlaneCore::ConfigItem.new(
55
110
  key: :release_notes,
56
111
  description: "更新文案, 格式为 { \"zh-Hans\": \"修复问题\", \"en-US\": \"bugfix\"} JSON 字符串",
57
- optional: false,
112
+ optional: true,
58
113
  type: String
59
114
  ),
60
115
  FastlaneCore::ConfigItem.new(
61
116
  key: :isTestFlight,
62
117
  description: "是否为 TestFlight 打包",
63
- optional: false,
118
+ optional: true,
119
+ default_value: false,
64
120
  type: Boolean
121
+ ),
122
+ FastlaneCore::ConfigItem.new(
123
+ key: :app_store_resources_config_path,
124
+ env_name: 'APP_STORE_RESOURCES_CONFIG_PATH',
125
+ description: 'App Store 资源发布 JSON 路径,开启商店资源总开关后必填',
126
+ optional: true,
127
+ type: String
128
+ ),
129
+ FastlaneCore::ConfigItem.new(
130
+ key: :app_identifier,
131
+ description: '本次构建的 Bundle ID,覆盖资源配置',
132
+ optional: true,
133
+ type: String
134
+ ),
135
+ FastlaneCore::ConfigItem.new(
136
+ key: :app_version,
137
+ description: '本次构建的版本号,覆盖资源配置',
138
+ optional: true,
139
+ type: String
140
+ ),
141
+ FastlaneCore::ConfigItem.new(
142
+ key: :build_number,
143
+ description: '本次构建的 Build 号,覆盖资源配置',
144
+ optional: true,
145
+ type: String
65
146
  )
66
147
  ]
67
148
  end
@@ -72,4 +153,4 @@ module Fastlane
72
153
 
73
154
  end
74
155
  end
75
- end
156
+ end