-
Notifications
You must be signed in to change notification settings - Fork 5.6k
/
build_watcher.rb
137 lines (112 loc) 路 6.5 KB
/
build_watcher.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
require 'spaceship/connect_api'
require_relative 'ui/ui'
module FastlaneCore
class BuildWatcher
VersionMatches = Struct.new(:version, :builds)
class << self
# @return The build we waited for. This method will always return a build
def wait_for_build_processing_to_be_complete(app_id: nil, platform: nil, train_version: nil, app_version: nil, build_version: nil, poll_interval: 10, strict_build_watch: false, return_when_build_appears: false, return_spaceship_testflight_build: true, select_latest: false)
# Warn about train_version being removed in the future
if train_version
UI.deprecated(":train_version is no longer a used argument on FastlaneCore::BuildWatcher. Please use :app_version instead.")
app_version = train_version
end
# Warn about strict_build_watch being removed in the future
if strict_build_watch
UI.deprecated(":strict_build_watch is no longer a used argument on FastlaneCore::BuildWatcher.")
end
platform = Spaceship::ConnectAPI::Platform.map(platform) if platform
UI.message("Waiting for processing on... app_id: #{app_id}, app_version: #{app_version}, build_version: #{build_version}, platform: #{platform}")
showed_info = false
loop do
matched_build, app_version_queried = matching_build(watched_app_version: app_version, watched_build_version: build_version, app_id: app_id, platform: platform, select_latest: select_latest)
if matched_build.nil? && !showed_info
UI.important("Read more information on why this build isn't showing up yet - https://github.com/fastlane/fastlane/issues/14997")
showed_info = true
end
report_status(build: matched_build)
# Processing of builds by AppStoreConnect can be a very time consuming task and will
# block the worker running this task until it is completed. In some cases,
# having a build resource appear in AppStoreConnect (matched_build) may be enough (i.e. setting a changelog)
# so here we may choose to skip the full processing of the build if return_when_build_appears is true
if matched_build && (return_when_build_appears || matched_build.processed?)
if !app_version.nil? && app_version != app_version_queried
UI.important("App version is #{app_version} but build was found while querying #{app_version_queried}")
UI.important("This shouldn't be an issue as Apple sees #{app_version} and #{app_version_queried} as equal")
UI.important("See docs for more info - https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102364")
end
if return_spaceship_testflight_build
return matched_build.to_testflight_build
else
return matched_build
end
end
sleep(poll_interval)
end
end
private
# Remove leading zeros ( https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102364 )
def remove_version_leading_zeros(version: nil)
return version.instance_of?(String) ? version.split('.').map { |s| s.to_i.to_s }.join('.') : version
end
def matching_build(watched_app_version: nil, watched_build_version: nil, app_id: nil, platform: nil, select_latest: false)
# Get build deliveries (newly uploaded processing builds)
watched_app_version = remove_version_leading_zeros(version: watched_app_version)
watched_build_version = remove_version_leading_zeros(version: watched_build_version)
# App Store Connect will allow users to upload X.Y is the same as X.Y.0 and treat them as the same version
# However, only the first uploaded version format will be the one that is queryable
# This could lead to BuildWatcher never finding X.Y.0 if X.Y was upoaded first as X.Y will only yield results
#
# This will add an additional request to search for both X.Y and X.Y.0 but
# will give preference to the version format specified passed in
watched_app_version_alternate = alternate_version(watched_app_version)
versions = [watched_app_version, watched_app_version_alternate].compact
version_matches = versions.map do |version|
match = VersionMatches.new
match.version = version
match.builds = Spaceship::ConnectAPI::Build.all(
app_id: app_id,
version: version,
build_number: watched_build_version,
platform: platform
)
match
end.flatten
# Raise error if more than 1 build is returned
# This should never happen but need to inform the user if it does
matched_builds = version_matches.map(&:builds).flatten
if matched_builds.size > 1 && !select_latest
error_builds = matched_builds.map do |build|
"#{build.app_version}(#{build.version}) for #{build.platform} - #{build.processing_state}"
end.join("\n")
error_message = "FastlaneCore::BuildWatcher found more than 1 matching build: \n#{error_builds}"
UI.crash!(error_message)
end
version_match = version_matches.reject do |match|
match.builds.empty?
end.first
matched_build = version_match&.builds&.first
return matched_build, version_match&.version
end
def alternate_version(version)
return nil if version.nil?
version_info = Gem::Version.new(version)
if version_info.segments.size == 3 && version_info.segments[2] == 0
return version_info.segments[0..1].join(".")
elsif version_info.segments.size == 2
return "#{version}.0"
end
return nil
end
def report_status(build: nil)
if build && !build.processed?
UI.message("Waiting for App Store Connect to finish processing the new build (#{build.app_version} - #{build.version}) for #{build.platform}")
elsif build && build.processed?
UI.success("Successfully finished processing the build #{build.app_version} - #{build.version} for #{build.platform}")
else
UI.message("Waiting for the build to show up in the build list - this may take a few minutes (check your email for processing issues if this continues)")
end
end
end
end
end