Skip to content

Commit d7856fd

Browse files
committed
Allow get_latest_release action to use plist, and make plist path more flexible
1 parent 83d616c commit d7856fd

5 files changed

+130
-102
lines changed

lib/fastlane/plugin/firebase_app_distribution/actions/firebase_app_distribution_action.rb

+1-29
Original file line numberDiff line numberDiff line change
@@ -142,34 +142,6 @@ def self.test_password_from_params(params)
142142
test_password && test_password.sub(/\r?\n$/, "")
143143
end
144144

145-
def self.app_id_from_params(params)
146-
if params[:app]
147-
app_id = params[:app]
148-
elsif xcode_archive_path
149-
plist_path = params[:googleservice_info_plist_path]
150-
app_id = get_ios_app_id_from_archive_plist(xcode_archive_path, plist_path)
151-
end
152-
if app_id.nil?
153-
UI.crash!(ErrorMessage::MISSING_APP_ID)
154-
end
155-
app_id
156-
end
157-
158-
def self.xcode_archive_path
159-
# prevents issues on cross-platform build environments where an XCode build happens within
160-
# the same lane
161-
return nil if lane_platform == :android
162-
163-
# rubocop:disable Require/MissingRequireStatement
164-
Actions.lane_context[SharedValues::XCODEBUILD_ARCHIVE]
165-
# rubocop:enable Require/MissingRequireStatement
166-
end
167-
168-
def self.lane_platform
169-
# to_sym shouldn't be necessary, but possibly fixes #376
170-
Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]&.to_sym
171-
end
172-
173145
def self.platform_from_app_id(app_id)
174146
if app_id.include?(':ios:')
175147
:ios
@@ -492,7 +464,7 @@ def self.available_options
492464
optional: true),
493465
FastlaneCore::ConfigItem.new(key: :googleservice_info_plist_path,
494466
env_name: "GOOGLESERVICE_INFO_PLIST_PATH",
495-
description: "Path to your GoogleService-Info.plist file, relative to the archived product path",
467+
description: "Path to your GoogleService-Info.plist file, relative to the archived product path (or directly, if no archived product path is found)",
496468
default_value: "GoogleService-Info.plist",
497469
optional: true,
498470
type: String),

lib/fastlane/plugin/firebase_app_distribution/actions/firebase_app_distribution_get_latest_release.rb

+15-6
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,23 @@ def self.run(params)
1919
client = Google::Apis::FirebaseappdistributionV1::FirebaseAppDistributionService.new
2020
client.authorization = get_authorization(params[:service_credentials_file], params[:firebase_cli_token], params[:service_credentials_json_data], params[:debug])
2121

22-
UI.message("⏳ Fetching latest release for app #{params[:app]}...")
23-
24-
parent = app_name_from_app_id(params[:app])
22+
app_id = app_id_from_params(params)
23+
UI.message("⏳ Fetching latest release for app #{app_id}...")
24+
parent = app_name_from_app_id(app_id)
2525

2626
begin
2727
releases = client.list_project_app_releases(parent, page_size: 1).releases
2828
rescue Google::Apis::Error => err
2929
if err.status_code.to_i == 404
30-
UI.user_error!("#{ErrorMessage::INVALID_APP_ID}: #{params[:app]}")
30+
UI.user_error!("#{ErrorMessage::INVALID_APP_ID}: #{app_id}")
3131
else
3232
UI.crash!(err)
3333
end
3434
end
3535

3636
if releases.nil? || releases.empty?
3737
latest_release = nil
38-
UI.important("No releases for app #{params[:app]} found in App Distribution. Returning nil and setting Actions.lane_context[SharedValues::FIREBASE_APP_DISTRO_LATEST_RELEASE].")
38+
UI.important("No releases for app #{app_id} found in App Distribution. Returning nil and setting Actions.lane_context[SharedValues::FIREBASE_APP_DISTRO_LATEST_RELEASE].")
3939
else
4040
# latest_release = append_json_style_fields(response.releases[0].to_h)
4141
latest_release = map_release_hash(releases[0])
@@ -80,10 +80,19 @@ def self.details
8080

8181
def self.available_options
8282
[
83+
# iOS Specific
84+
FastlaneCore::ConfigItem.new(key: :googleservice_info_plist_path,
85+
env_name: "GOOGLESERVICE_INFO_PLIST_PATH",
86+
description: "Path to your GoogleService-Info.plist file, relative to the archived product path (or directly, if no archived product path is found)",
87+
default_value: "GoogleService-Info.plist",
88+
optional: true,
89+
type: String),
90+
91+
# General
8392
FastlaneCore::ConfigItem.new(key: :app,
8493
env_name: "FIREBASEAPPDISTRO_APP",
8594
description: "Your app's Firebase App ID. You can find the App ID in the Firebase console, on the General Settings page",
86-
optional: false,
95+
optional: true,
8796
type: String),
8897
FastlaneCore::ConfigItem.new(key: :firebase_cli_token,
8998
description: "Auth token generated using Firebase CLI's login:ci command",

lib/fastlane/plugin/firebase_app_distribution/helper/firebase_app_distribution_helper.rb

+38-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'fastlane/action'
12
require 'fastlane_core/ui/ui'
23
require 'cfpropertylist'
34
require 'google/apis/core'
@@ -36,15 +37,49 @@ def string_to_array(string, delimiter = /[,\n]/)
3637
string.strip.split(delimiter).map(&:strip)
3738
end
3839

40+
def app_id_from_params(params)
41+
plist_path = params[:googleservice_info_plist_path]
42+
if params[:app]
43+
app_id = params[:app]
44+
elsif xcode_archive_path
45+
app_id = get_ios_app_id_from_archive_plist(xcode_archive_path, plist_path)
46+
elsif plist_path
47+
app_id = get_ios_app_id_from_plist(plist_path)
48+
end
49+
if app_id.nil?
50+
UI.crash!(ErrorMessage::MISSING_APP_ID)
51+
end
52+
app_id
53+
end
54+
55+
def lane_platform
56+
# to_sym shouldn't be necessary, but possibly fixes #376
57+
Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]&.to_sym
58+
end
59+
60+
def xcode_archive_path
61+
# prevents issues on cross-platform build environments where an XCode build happens within
62+
# the same lane
63+
return nil if lane_platform == :android
64+
65+
# rubocop:disable Require/MissingRequireStatement
66+
Actions.lane_context[Actions::SharedValues::XCODEBUILD_ARCHIVE]
67+
# rubocop:enable Require/MissingRequireStatement
68+
end
69+
3970
def parse_plist(path)
4071
CFPropertyList.native_types(CFPropertyList::List.new(file: path).value)
4172
end
4273

43-
def get_ios_app_id_from_archive_plist(archive_path, plist_path)
74+
def get_ios_app_id_from_archive_plist(archive_path, relative_plist_path)
4475
app_path = parse_plist("#{archive_path}/Info.plist")["ApplicationProperties"]["ApplicationPath"]
4576
UI.shell_error!("can't extract application path from Info.plist at #{archive_path}") if app_path.empty?
46-
identifier = parse_plist("#{archive_path}/Products/#{app_path}/#{plist_path}")["GOOGLE_APP_ID"]
47-
UI.shell_error!("can't extract GOOGLE_APP_ID") if identifier.empty?
77+
return get_ios_app_id_from_plist("#{archive_path}/Products/#{app_path}/#{relative_plist_path}")
78+
end
79+
80+
def get_ios_app_id_from_plist(plist_path)
81+
identifier = parse_plist(plist_path)["GOOGLE_APP_ID"]
82+
UI.shell_error!("can't extract GOOGLE_APP_ID from #{plist_path}") if identifier.empty?
4883
return identifier
4984
end
5085

spec/firebase_app_distribution_action_spec.rb

-64
Original file line numberDiff line numberDiff line change
@@ -107,70 +107,6 @@
107107
end
108108
end
109109

110-
describe '#xcode_archive_path' do
111-
it 'returns the archive path is set, and platform is not Android' do
112-
allow(Fastlane::Actions).to receive(:lane_context).and_return({
113-
XCODEBUILD_ARCHIVE: '/path/to/archive'
114-
})
115-
expect(action.xcode_archive_path).to eq('/path/to/archive')
116-
end
117-
118-
it 'returns nil if platform is Android' do
119-
allow(Fastlane::Actions).to receive(:lane_context).and_return({
120-
XCODEBUILD_ARCHIVE: '/path/to/archive',
121-
PLATFORM_NAME: :android
122-
})
123-
expect(action.xcode_archive_path).to be_nil
124-
end
125-
126-
it 'returns nil if the archive path is not set' do
127-
allow(Fastlane::Actions).to receive(:lane_context).and_return({})
128-
expect(action.xcode_archive_path).to be_nil
129-
end
130-
end
131-
132-
describe '#app_id_from_params' do
133-
it 'returns the app id from the app parameter if set' do
134-
expect(action).not_to(receive(:xcode_archive_path))
135-
136-
params = { app: 'app-id' }
137-
result = action.app_id_from_params(params)
138-
139-
expect(result).to eq('app-id')
140-
end
141-
142-
it 'raises if the app parameter is not set and there is no archive path' do
143-
allow(action).to receive(:xcode_archive_path).and_return(nil)
144-
145-
params = {}
146-
expect { action.app_id_from_params(params) }
147-
.to raise_error(ErrorMessage::MISSING_APP_ID)
148-
end
149-
150-
it 'returns the app id from the plist if the archive path is set' do
151-
allow(action).to receive(:xcode_archive_path).and_return('/path/to/archive')
152-
allow(action).to receive(:get_ios_app_id_from_archive_plist)
153-
.with('/path/to/archive', '/path/to/plist')
154-
.and_return('app-id-from-plist')
155-
156-
params = { googleservice_info_plist_path: '/path/to/plist' }
157-
result = action.app_id_from_params(params)
158-
159-
expect(result).to eq('app-id-from-plist')
160-
end
161-
162-
it 'raises if the app parameter is not set and the plist is empty' do
163-
allow(action).to receive(:xcode_archive_path).and_return('/path/to/archive')
164-
allow(action).to receive(:get_ios_app_id_from_archive_plist)
165-
.with('/path/to/archive', '/path/to/plist')
166-
.and_return(nil)
167-
168-
params = { googleservice_info_plist_path: '/path/to/plist' }
169-
expect { action.app_id_from_params(params) }
170-
.to raise_error(ErrorMessage::MISSING_APP_ID)
171-
end
172-
end
173-
174110
describe '#release_notes' do
175111
before do
176112
allow(Fastlane::Actions.lane_context).to receive('[]')

spec/firebase_app_distribution_helper_spec.rb

+76
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,80 @@
136136
end.to raise_error("Unsupported distribution file format, should be .ipa, .apk or .aab")
137137
end
138138
end
139+
140+
describe '#xcode_archive_path' do
141+
it 'returns the archive path is set, and platform is not Android' do
142+
allow(Fastlane::Actions).to receive(:lane_context).and_return({
143+
XCODEBUILD_ARCHIVE: '/path/to/archive'
144+
})
145+
expect(helper.xcode_archive_path).to eq('/path/to/archive')
146+
end
147+
148+
it 'returns nil if platform is Android' do
149+
allow(Fastlane::Actions).to receive(:lane_context).and_return({
150+
XCODEBUILD_ARCHIVE: '/path/to/archive',
151+
PLATFORM_NAME: :android
152+
})
153+
expect(helper.xcode_archive_path).to be_nil
154+
end
155+
156+
it 'returns nil if the archive path is not set' do
157+
allow(Fastlane::Actions).to receive(:lane_context).and_return({})
158+
expect(helper.xcode_archive_path).to be_nil
159+
end
160+
end
161+
162+
describe '#app_id_from_params' do
163+
it 'returns the app id from the app parameter if set' do
164+
expect(helper).not_to(receive(:xcode_archive_path))
165+
166+
params = { app: 'app-id' }
167+
result = helper.app_id_from_params(params)
168+
169+
expect(result).to eq('app-id')
170+
end
171+
172+
it 'raises if the app parameter is not set and there is no archive path' do
173+
allow(helper).to receive(:xcode_archive_path).and_return(nil)
174+
175+
params = {}
176+
expect { helper.app_id_from_params(params) }
177+
.to raise_error(ErrorMessage::MISSING_APP_ID)
178+
end
179+
180+
it 'returns the app id from the plist if the archive path is set' do
181+
allow(helper).to receive(:xcode_archive_path).and_return('/path/to/archive')
182+
allow(helper).to receive(:get_ios_app_id_from_archive_plist)
183+
.with('/path/to/archive', '/path/to/plist')
184+
.and_return('app-id-from-plist')
185+
186+
params = { googleservice_info_plist_path: '/path/to/plist' }
187+
result = helper.app_id_from_params(params)
188+
189+
expect(result).to eq('app-id-from-plist')
190+
end
191+
192+
it 'returns the app id from the plist if there is no archive path and it is found directly at the given path' do
193+
allow(helper).to receive(:xcode_archive_path).and_return(nil)
194+
allow(helper).to receive(:get_ios_app_id_from_plist)
195+
.with('/path/to/plist')
196+
.and_return('app-id-from-plist')
197+
198+
params = { googleservice_info_plist_path: '/path/to/plist' }
199+
result = helper.app_id_from_params(params)
200+
201+
expect(result).to eq('app-id-from-plist')
202+
end
203+
204+
it 'raises if the app parameter is not set and the plist is empty' do
205+
allow(helper).to receive(:xcode_archive_path).and_return('/path/to/archive')
206+
allow(helper).to receive(:get_ios_app_id_from_archive_plist)
207+
.with('/path/to/archive', '/path/to/plist')
208+
.and_return(nil)
209+
210+
params = { googleservice_info_plist_path: '/path/to/plist' }
211+
expect { helper.app_id_from_params(params) }
212+
.to raise_error(ErrorMessage::MISSING_APP_ID)
213+
end
214+
end
139215
end

0 commit comments

Comments
 (0)