fastlane-plugin-firebase_app_distribution 0.2.0.pre.3 → 0.2.2.pre.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c591cb4a3b841f9fc26c94f3ff32b78b321ed904cc176e05a053e330543cd535
4
- data.tar.gz: 0114a22cc34eec1970b5b280746b46b9d858407bbb5c1c7b3f3d54842e75b4d5
3
+ metadata.gz: c5ca3144300e192d87eb1e9457152c5484a057dfcb0d492d672da8cbbf983368
4
+ data.tar.gz: ab60ae5cf17ba96547e2278b34c4858149960247fcc593e3bd3cb1794d9eaef9
5
5
  SHA512:
6
- metadata.gz: 493da92f746defa50af47f9b2d920b65fa5fcbfbb085f0be74979fe7f26f684b78697be17c5e32eeac7fe1d0d78667ece5ef7198138358f6831870c382a5d753
7
- data.tar.gz: 7afb5987aa4fd08032d4fa684b9c291d3c4dc762d2978b37bbe4e921ae5730a9a547819a49b61ee2d120617d961b13891b03f17f1ad48deb004eb125b658ad65
6
+ metadata.gz: 14da8737b9424a01aca4e6df1fdc3ce5254343b89e01fbdac31c9e9176cec5b5d351a78dc1d03adc0d1c031207fee049c5a517cf63ce440cf45fa7326cab45a2
7
+ data.tar.gz: eda22a0b5c8cee1b0c990db5f0137c867d7e5a2be8ee7bd30c50811ba80e9b2585e4af5f56bdd82fcaee1adcfa0367286511c6be3fbdf7f550abb69e88941ea6
@@ -20,22 +20,14 @@ module Fastlane
20
20
 
21
21
  def self.run(params)
22
22
  params.values # to validate all inputs before looking for the ipa/apk
23
+
24
+ app_id = app_id_from_params(params)
25
+ platform = lane_platform || platform_from_app_id(app_id)
26
+ binary_path = binary_path_from_platform(platform, params[:ipa_path], params[:apk_path])
27
+
23
28
  auth_token = fetch_auth_token(params[:service_credentials_file], params[:firebase_cli_token])
24
29
  fad_api_client = Client::FirebaseAppDistributionApiClient.new(auth_token, platform)
25
- binary_path = params[:ipa_path] || params[:apk_path]
26
-
27
- if params[:app] # Set app_id if it is specified as a parameter
28
- app_id = params[:app]
29
- elsif platform == :ios
30
- archive_path = Actions.lane_context[SharedValues::XCODEBUILD_ARCHIVE]
31
- if archive_path
32
- app_id = get_ios_app_id_from_archive(archive_path)
33
- end
34
- end
35
30
 
36
- if app_id.nil?
37
- UI.crash!(ErrorMessage::MISSING_APP_ID)
38
- end
39
31
  release_id = fad_api_client.upload(app_id, binary_path, platform.to_s)
40
32
  if release_id.nil?
41
33
  return
@@ -49,7 +41,7 @@ module Fastlane
49
41
  emails = string_to_array(testers)
50
42
  group_ids = string_to_array(groups)
51
43
  fad_api_client.enable_access(app_id, release_id, emails, group_ids)
52
- UI.success("App Distribution upload finished successfully")
44
+ UI.success("🎉 App Distribution upload finished successfully.")
53
45
  end
54
46
 
55
47
  def self.description
@@ -65,16 +57,56 @@ module Fastlane
65
57
  "Release your beta builds with Firebase App Distribution"
66
58
  end
67
59
 
68
- def self.platform
69
- @platform ||= Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
60
+ def self.app_id_from_params(params)
61
+ if params[:app]
62
+ app_id = params[:app]
63
+ elsif xcode_archive_path
64
+ plist_path = params[:googleservice_info_plist_path]
65
+ app_id = get_ios_app_id_from_archive_plist(xcode_archive_path, plist_path)
66
+ end
67
+ if app_id.nil?
68
+ UI.crash!(ErrorMessage::MISSING_APP_ID)
69
+ end
70
+ app_id
71
+ end
72
+
73
+ def self.xcode_archive_path
74
+ # prevents issues on cross-platform build environments where an XCode build happens within
75
+ # the same lane
76
+ return nil if lane_platform == :android
77
+
78
+ Actions.lane_context[SharedValues::XCODEBUILD_ARCHIVE]
79
+ end
80
+
81
+ def self.lane_platform
82
+ Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
83
+ end
84
+
85
+ def self.platform_from_app_id(app_id)
86
+ if app_id.include?(':ios:')
87
+ :ios
88
+ elsif app_id.include?(':android:')
89
+ :android
90
+ end
91
+ end
92
+
93
+ def self.binary_path_from_platform(platform, ipa_path, apk_path)
94
+ case platform
95
+ when :ios
96
+ ipa_path
97
+ when :android
98
+ apk_path
99
+ else
100
+ ipa_path || apk_path
101
+ end
70
102
  end
71
103
 
72
104
  def self.available_options
73
- if platform == :ios || platform.nil?
105
+ if lane_platform == :ios || lane_platform.nil?
74
106
  ipa_path_default = Dir["*.ipa"].sort_by { |x| File.mtime(x) }.last
75
107
  end
76
108
 
77
- if platform == :android
109
+ if lane_platform == :android
78
110
  apk_path_default = Dir["*.apk"].last || Dir[File.join("app", "build", "outputs", "apk", "app-release.apk")].last
79
111
  end
80
112
 
@@ -89,6 +121,12 @@ module Fastlane
89
121
  verify_block: proc do |value|
90
122
  UI.user_error!("firebase_app_distribution: Couldn't find ipa file at path '#{value}'") unless File.exist?(value)
91
123
  end),
124
+ FastlaneCore::ConfigItem.new(key: :googleservice_info_plist_path,
125
+ env_name: "GOOGLESERVICE_INFO_PLIST_PATH",
126
+ description: "Path to your GoogleService-Info.plist file, relative to the root of your Xcode project",
127
+ default_value: "GoogleService-Info.plist",
128
+ optional: true,
129
+ type: String),
92
130
  # Android Specific
93
131
  FastlaneCore::ConfigItem.new(key: :apk_path,
94
132
  env_name: "FIREBASEAPPDISTRO_APK_PATH",
@@ -105,9 +143,9 @@ module Fastlane
105
143
  optional: true,
106
144
  type: String),
107
145
  FastlaneCore::ConfigItem.new(key: :firebase_cli_path,
146
+ deprecated: "This plugin no longer uses the Firebase CLI",
108
147
  env_name: "FIREBASEAPPDISTRO_FIREBASE_CLI_PATH",
109
148
  description: "The absolute path of the firebase cli command",
110
- optional: true,
111
149
  type: String),
112
150
  FastlaneCore::ConfigItem.new(key: :groups,
113
151
  env_name: "FIREBASEAPPDISTRO_GROUPS",
@@ -175,18 +213,6 @@ module Fastlane
175
213
  CODE
176
214
  ]
177
215
  end
178
-
179
- ## TODO: figure out if we can surpress color output.
180
- def self.is_firebasecmd_supported?(cmd)
181
- outerr, status = Open3.capture2e(cmd, "--non-interactive", FIREBASECMD_ACTION, "--help")
182
- return false unless status.success?
183
-
184
- if outerr =~ /is not a Firebase command/
185
- return false
186
- end
187
-
188
- true
189
- end
190
216
  end
191
217
  end
192
218
  end
@@ -33,7 +33,7 @@ module Fastlane
33
33
  # Throws a user_error if app_id, emails, or group_ids are invalid
34
34
  def enable_access(app_id, release_id, emails, group_ids)
35
35
  if (emails.nil? || emails.empty?) && (group_ids.nil? || group_ids.empty?)
36
- UI.message("No testers passed in. Skipping this step")
36
+ UI.success("No testers passed in. Skipping this step.")
37
37
  return
38
38
  end
39
39
  payload = { emails: emails, groupIds: group_ids }
@@ -46,7 +46,7 @@ module Fastlane
46
46
  rescue Faraday::ClientError
47
47
  UI.user_error!("#{ErrorMessage::INVALID_TESTERS} \nEmails: #{emails} \nGroups: #{group_ids}")
48
48
  end
49
- UI.success("Added testers/groups successfully.")
49
+ UI.success("Added testers/groups.")
50
50
  end
51
51
 
52
52
  # Posts notes for the specified app release. Skips this
@@ -61,7 +61,7 @@ module Fastlane
61
61
  def post_notes(app_id, release_id, release_notes)
62
62
  payload = { releaseNotes: { releaseNotes: release_notes } }
63
63
  if release_notes.nil? || release_notes.empty?
64
- UI.message("No release notes passed in. Skipping this step.")
64
+ UI.success("No release notes passed in. Skipping this step.")
65
65
  return
66
66
  end
67
67
  begin
@@ -73,7 +73,7 @@ module Fastlane
73
73
  # rescue Faraday::ClientError
74
74
  # UI.user_error!("#{ErrorMessage::INVALID_RELEASE_ID}: #{release_id}")
75
75
  end
76
- UI.success("Posted release notes.")
76
+ UI.success("Posted release notes.")
77
77
  end
78
78
 
79
79
  # Returns the url encoded upload token used for get_upload_status calls:
@@ -89,7 +89,7 @@ module Fastlane
89
89
  if binary_path.nil? || !File.exist?(binary_path)
90
90
  UI.crash!("#{ErrorMessage.binary_not_found(@binary_type)}: #{binary_path}")
91
91
  end
92
- binary_hash = Digest::SHA256.hexdigest(File.open(binary_path).read)
92
+ binary_hash = Digest::SHA256.hexdigest(read_binary(binary_path))
93
93
 
94
94
  begin
95
95
  response = connection.get(v1_apps_url(app_id)) do |request|
@@ -105,17 +105,25 @@ module Fastlane
105
105
  return upload_token_format(response.body[:appId], response.body[:projectNumber], binary_hash)
106
106
  end
107
107
 
108
+ # Uploads the app binary to the Firebase API
109
+ #
110
+ # args
111
+ # app_id - Firebase App ID
112
+ # binary_path - Absolute path to your app's apk/ipa file
113
+ # platform - 'android' or 'ios'
114
+ #
115
+ # Throws a user_error if an invalid app id is passed in, or if the binary file does not exist
108
116
  def upload_binary(app_id, binary_path, platform)
109
- connection.post(binary_upload_url(app_id), File.open(binary_path).read) do |request|
117
+ connection.post(binary_upload_url(app_id), read_binary(binary_path)) do |request|
110
118
  request.headers["Authorization"] = "Bearer " + @auth_token
111
119
  request.headers["X-APP-DISTRO-API-CLIENT-ID"] = "fastlane"
112
120
  request.headers["X-APP-DISTRO-API-CLIENT-TYPE"] = platform
113
121
  request.headers["X-APP-DISTRO-API-CLIENT-VERSION"] = Fastlane::FirebaseAppDistribution::VERSION
114
122
  end
115
123
  rescue Faraday::ResourceNotFound
116
- UI.crash!("#{ErrorMessage::INVALID_APP_ID}: #{app_id}")
117
- rescue Errno::ENOENT
118
- UI.crash!("#{ErrorMessage.binary_not_found(@binary_type)}: #{binary_path}")
124
+ UI.user_error!("#{ErrorMessage::INVALID_APP_ID}: #{app_id}")
125
+ rescue Errno::ENOENT # Raised when binary_path file does not exist
126
+ UI.user_error!("#{ErrorMessage.binary_not_found(@binary_type)}: #{binary_path}")
119
127
  end
120
128
 
121
129
  # Uploads the binary file if it has not already been uploaded
@@ -133,17 +141,16 @@ module Fastlane
133
141
  upload_token = get_upload_token(app_id, binary_path)
134
142
  upload_status_response = get_upload_status(app_id, upload_token)
135
143
  if upload_status_response.success? || upload_status_response.already_uploaded?
136
- UI.success("This #{@binary_type} has been uploaded before. Skipping upload step.")
144
+ UI.success("This #{@binary_type} has been uploaded before. Skipping upload step.")
137
145
  else
138
- UI.message("This #{@binary_type} has not been uploaded before")
139
- UI.message("Uploading the #{@binary_type}.")
140
146
  unless upload_status_response.in_progress?
147
+ UI.message("⌛ Uploading the #{@binary_type}.")
141
148
  upload_binary(app_id, binary_path, platform)
142
149
  end
143
150
  MAX_POLLING_RETRIES.times do
144
151
  upload_status_response = get_upload_status(app_id, upload_token)
145
152
  if upload_status_response.success? || upload_status_response.already_uploaded?
146
- UI.success("Uploaded #{@binary_type} successfully!")
153
+ UI.success("Uploaded the #{@binary_type}.")
147
154
  break
148
155
  elsif upload_status_response.in_progress?
149
156
  sleep(POLLING_INTERVAL_SECONDS)
@@ -163,14 +170,22 @@ module Fastlane
163
170
  upload_status_response.release_id
164
171
  end
165
172
 
166
- # Gets the upload status for the app release.
167
- def get_upload_status(app_id, app_token)
173
+ # Fetches the status of an uploaded binary
174
+ #
175
+ # args
176
+ # app_id - Firebase App ID
177
+ # upload_token - URL encoded upload token
178
+ #
179
+ # Returns the release ID on a successful release, otherwise returns nil.
180
+ #
181
+ # Throws a user_error if an invalid app_id is passed in
182
+ def get_upload_status(app_id, upload_token)
168
183
  begin
169
- response = connection.get(upload_status_url(app_id, app_token)) do |request|
184
+ response = connection.get(upload_status_url(app_id, upload_token)) do |request|
170
185
  request.headers["Authorization"] = "Bearer " + @auth_token
171
186
  end
172
187
  rescue Faraday::ResourceNotFound
173
- UI.crash!("#{ErrorMessage::INVALID_APP_ID}: #{app_id}")
188
+ UI.user_error!("#{ErrorMessage::INVALID_APP_ID}: #{app_id}")
174
189
  end
175
190
  return UploadStatusResponse.new(response.body)
176
191
  end
@@ -208,6 +223,11 @@ module Fastlane
208
223
  conn.adapter(Faraday.default_adapter)
209
224
  end
210
225
  end
226
+
227
+ def read_binary(path)
228
+ # File must be read in binary mode to work on Windows
229
+ File.open(path, 'rb').read
230
+ end
211
231
  end
212
232
  end
213
233
  end
@@ -38,7 +38,7 @@ module Fastlane
38
38
  else
39
39
  UI.user_error!(ErrorMessage::MISSING_CREDENTIALS)
40
40
  end
41
- UI.success("Successfully authenticated!")
41
+ UI.success("🔐 Authenticated successfully.")
42
42
  token
43
43
  end
44
44
 
@@ -28,10 +28,10 @@ module Fastlane
28
28
  CFPropertyList.native_types(CFPropertyList::List.new(file: path).value)
29
29
  end
30
30
 
31
- def get_ios_app_id_from_archive(path)
32
- app_path = parse_plist("#{path}/Info.plist")["ApplicationProperties"]["ApplicationPath"]
33
- UI.shell_error!("can't extract application path from Info.plist at #{path}") if app_path.empty?
34
- identifier = parse_plist("#{path}/Products/#{app_path}/GoogleService-Info.plist")["GOOGLE_APP_ID"]
31
+ def get_ios_app_id_from_archive_plist(archive_path, plist_path)
32
+ app_path = parse_plist("#{archive_path}/Info.plist")["ApplicationProperties"]["ApplicationPath"]
33
+ UI.shell_error!("can't extract application path from Info.plist at #{archive_path}") if app_path.empty?
34
+ identifier = parse_plist("#{archive_path}/Products/#{app_path}/#{plist_path}")["GOOGLE_APP_ID"]
35
35
  UI.shell_error!("can't extract GOOGLE_APP_ID") if identifier.empty?
36
36
  return identifier
37
37
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module FirebaseAppDistribution
3
- VERSION = "0.2.0.pre.3"
3
+ VERSION = "0.2.2.pre.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-firebase_app_distribution
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.pre.3
4
+ version: 0.2.2.pre.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Natchev
8
8
  - Manny Jimenez
9
9
  - Alonso Salas Infante
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-08-18 00:00:00.000000000 Z
13
+ date: 2020-09-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: pry
@@ -138,7 +138,7 @@ dependencies:
138
138
  - - ">="
139
139
  - !ruby/object:Gem::Version
140
140
  version: 2.127.1
141
- description:
141
+ description:
142
142
  email:
143
143
  - snatchev@google.com
144
144
  - mannyjimenez@google.com
@@ -162,7 +162,7 @@ homepage: https://github.com/fastlane/fastlane-plugin-firebase_app_distribution
162
162
  licenses:
163
163
  - MIT
164
164
  metadata: {}
165
- post_install_message:
165
+ post_install_message:
166
166
  rdoc_options: []
167
167
  require_paths:
168
168
  - lib
@@ -178,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
178
  version: 1.3.1
179
179
  requirements: []
180
180
  rubygems_version: 3.1.2
181
- signing_key:
181
+ signing_key:
182
182
  specification_version: 4
183
183
  summary: Release your beta builds to Firebase App Distribution. https://firebase.google.com/docs/app-distribution
184
184
  test_files: []