Skip to content

Commit 435a68f

Browse files
authored
Merge pull request #142 from fastlane/v0.2.0
Remove plugin's dependency on the Firebase CLI (v0.2.0.pre.4)
2 parents bb0dfea + 441b5f7 commit 435a68f

14 files changed

+1227
-251
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
source('https://rubygems.org')
22

33
gemspec
4+
gem 'google-api-client', '~> 0.38'
45

56
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
67
eval_gemfile(plugins_path) if File.exist?(plugins_path)

fastlane-plugin-firebase_app_distribution.gemspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ require 'fastlane/plugin/firebase_app_distribution/version'
77
Gem::Specification.new do |spec|
88
spec.name = 'fastlane-plugin-firebase_app_distribution'
99
spec.version = Fastlane::FirebaseAppDistribution::VERSION
10-
spec.authors = ['Stefan Natchev']
11-
spec.email = ['snatchev@google.com']
10+
spec.authors = ['Stefan Natchev', 'Manny Jimenez', 'Alonso Salas Infante']
11+
spec.email = ['snatchev@google.com', 'mannyjimenez@google.com', 'alonsosi@google.com']
1212

1313
spec.summary = 'Release your beta builds to Firebase App Distribution. https://firebase.google.com/docs/app-distribution'
1414
spec.homepage = "https://github.com/fastlane/fastlane-plugin-firebase_app_distribution"

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

Lines changed: 58 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,91 @@
1-
require 'tempfile'
21
require 'fastlane/action'
32
require 'open3'
43
require 'shellwords'
4+
require 'googleauth'
5+
require_relative '../helper/upload_status_response'
56
require_relative '../helper/firebase_app_distribution_helper'
7+
require_relative '../helper/firebase_app_distribution_error_message'
8+
require_relative '../client/firebase_app_distribution_api_client'
9+
require_relative '../helper/firebase_app_distribution_auth_client'
610

711
## TODO: should always use a file underneath? I think so.
812
## How should we document the usage of release notes?
913
module Fastlane
1014
module Actions
1115
class FirebaseAppDistributionAction < Action
12-
DEFAULT_FIREBASE_CLI_PATH = `which firebase`
1316
FIREBASECMD_ACTION = "appdistribution:distribute".freeze
1417

18+
extend Auth::FirebaseAppDistributionAuthClient
1519
extend Helper::FirebaseAppDistributionHelper
1620

1721
def self.run(params)
1822
params.values # to validate all inputs before looking for the ipa/apk
19-
cmd = [Shellwords.escape(params[:firebase_cli_path].chomp), FIREBASECMD_ACTION]
20-
cmd << Shellwords.escape(params[:ipa_path] || params[:apk_path])
21-
if params[:app]
22-
cmd << "--app #{params[:app]}"
23-
else
24-
platform = Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
25-
case platform
26-
when :android
27-
else
28-
archivePath = Actions.lane_context[SharedValues::XCODEBUILD_ARCHIVE]
29-
if archivePath
30-
cmd << "--app"
31-
cmd << findout_ios_app_id_from_archive(archivePath)
32-
end
23+
auth_token = fetch_auth_token(params[:service_credentials_file], params[:firebase_cli_token])
24+
binary_path = params[:ipa_path] || params[:apk_path]
25+
platform = lane_platform || platform_from_path(binary_path)
26+
fad_api_client = Client::FirebaseAppDistributionApiClient.new(auth_token, platform)
27+
28+
if params[:app] # Set app_id if it is specified as a parameter
29+
app_id = params[:app]
30+
elsif platform == :ios
31+
archive_path = Actions.lane_context[SharedValues::XCODEBUILD_ARCHIVE]
32+
if archive_path
33+
app_id = get_ios_app_id_from_archive(archive_path)
3334
end
3435
end
3536

36-
cmd << groups_flag(params)
37-
cmd << testers_flag(params)
38-
cmd << release_notes_flag(params)
39-
cmd << flag_value_if_supplied('--token', :firebase_cli_token, params)
40-
cmd << flag_if_supplied('--debug', :debug, params)
41-
42-
Actions.sh_control_output(
43-
cmd.compact.join(" "),
44-
print_command: false,
45-
print_command_output: true
46-
)
47-
# make sure we do this, even in the case of an error.
48-
ensure
49-
cleanup_tempfiles
37+
if app_id.nil?
38+
UI.crash!(ErrorMessage::MISSING_APP_ID)
39+
end
40+
release_id = fad_api_client.upload(app_id, binary_path, platform.to_s)
41+
if release_id.nil?
42+
return
43+
end
44+
45+
release_notes = get_value_from_value_or_file(params[:release_notes], params[:release_notes_file])
46+
fad_api_client.post_notes(app_id, release_id, release_notes)
47+
48+
testers = get_value_from_value_or_file(params[:testers], params[:testers_file])
49+
groups = get_value_from_value_or_file(params[:groups], params[:groups_file])
50+
emails = string_to_array(testers)
51+
group_ids = string_to_array(groups)
52+
fad_api_client.enable_access(app_id, release_id, emails, group_ids)
53+
UI.success("🎉 App Distribution upload finished successfully.")
5054
end
5155

5256
def self.description
5357
"Release your beta builds with Firebase App Distribution"
5458
end
5559

5660
def self.authors
57-
["Stefan Natchev"]
61+
["Stefan Natchev", "Manny Jimenez Github: mannyjimenez0810, Alonso Salas Infante Github: alonsosalasinfante"]
5862
end
5963

6064
# supports markdown.
6165
def self.details
6266
"Release your beta builds with Firebase App Distribution"
6367
end
6468

65-
def self.available_options
66-
platform = Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
69+
def self.lane_platform
70+
Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
71+
end
6772

68-
if platform == :ios || platform.nil?
73+
def self.platform_from_path(binary_path)
74+
return nil unless binary_path
75+
case binary_path.split('.').last
76+
when 'ipa'
77+
:ios
78+
when 'apk'
79+
:android
80+
end
81+
end
82+
83+
def self.available_options
84+
if lane_platform == :ios || lane_platform.nil?
6985
ipa_path_default = Dir["*.ipa"].sort_by { |x| File.mtime(x) }.last
7086
end
7187

72-
if platform == :android
88+
if lane_platform == :android
7389
apk_path_default = Dir["*.apk"].last || Dir[File.join("app", "build", "outputs", "apk", "app-release.apk")].last
7490
end
7591

@@ -100,22 +116,10 @@ def self.available_options
100116
optional: true,
101117
type: String),
102118
FastlaneCore::ConfigItem.new(key: :firebase_cli_path,
119+
deprecated: "This plugin no longer uses the Firebase CLI",
103120
env_name: "FIREBASEAPPDISTRO_FIREBASE_CLI_PATH",
104121
description: "The absolute path of the firebase cli command",
105-
default_value: DEFAULT_FIREBASE_CLI_PATH,
106-
default_value_dynamic: true,
107-
optional: false,
108-
type: String,
109-
verify_block: proc do |value|
110-
value.chomp!
111-
if value.to_s == "" || !File.exist?(value)
112-
UI.user_error!("firebase_cli_path: missing path to firebase cli tool. Please install firebase in $PATH or specify path")
113-
end
114-
115-
unless is_firebasecmd_supported?(value)
116-
UI.user_error!("firebase_cli_path: `#{value}` does not support the `#{FIREBASECMD_ACTION}` command. Please download (https://appdistro.page.link/firebase-cli-download) or specify the path to the correct version of firebse")
117-
end
118-
end),
122+
type: String),
119123
FastlaneCore::ConfigItem.new(key: :groups,
120124
env_name: "FIREBASEAPPDISTRO_GROUPS",
121125
description: "The groups used for distribution, separated by commas",
@@ -156,7 +160,11 @@ def self.available_options
156160
description: "Print verbose debug output",
157161
optional: true,
158162
default_value: false,
159-
is_string: false)
163+
is_string: false),
164+
FastlaneCore::ConfigItem.new(key: :service_credentials_file,
165+
description: "Path to Google service account json",
166+
optional: true,
167+
type: String)
160168
]
161169
end
162170

@@ -178,18 +186,6 @@ def self.example_code
178186
CODE
179187
]
180188
end
181-
182-
## TODO: figure out if we can surpress color output.
183-
def self.is_firebasecmd_supported?(cmd)
184-
outerr, status = Open3.capture2e(cmd, "--non-interactive", FIREBASECMD_ACTION, "--help")
185-
return false unless status.success?
186-
187-
if outerr =~ /is not a Firebase command/
188-
return false
189-
end
190-
191-
true
192-
end
193189
end
194190
end
195191
end
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
require 'googleauth'
2+
require 'googleauth/stores/file_token_store'
3+
require "google/apis/people_v1"
4+
require "fileutils"
5+
6+
module Fastlane
7+
module Actions
8+
class FirebaseAppDistributionLoginAction < Action
9+
OOB_URI = "urn:ietf:wg:oauth:2.0:oob"
10+
SCOPE = "https://www.googleapis.com/auth/cloud-platform"
11+
CLIENT_ID = "563584335869-fgrhgmd47bqnekij5i8b5pr03ho849e6.apps.googleusercontent.com"
12+
CLIENT_SECRET = "j9iVZfS8kkCEFUPaAeJV0sAi"
13+
14+
def self.run(params)
15+
client_id = Google::Auth::ClientId.new(CLIENT_ID, CLIENT_SECRET)
16+
authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPE, nil)
17+
url = authorizer.get_authorization_url(base_url: OOB_URI)
18+
19+
UI.message("Open the following address in your browser and sign in with your Google account:")
20+
UI.message(url)
21+
UI.message("")
22+
code = UI.input("Enter the resulting code here: ")
23+
credentials = authorizer.get_credentials_from_code(code: code, base_url: OOB_URI)
24+
UI.message("")
25+
26+
UI.success("Set the refresh token as the FIREBASE_TOKEN environment variable")
27+
UI.success("Refresh Token: #{credentials.refresh_token}")
28+
rescue Signet::AuthorizationError
29+
UI.error("The code you entered is invalid. Copy and paste the code and try again.")
30+
rescue => error
31+
UI.error(error.to_s)
32+
UI.crash!("An error has occured, please login again.")
33+
end
34+
35+
#####################################################
36+
# @!group Documentation
37+
#####################################################
38+
39+
def self.description
40+
"Authenticate with Firebase App Distribution using a Google account."
41+
end
42+
43+
def self.details
44+
"Log in to Firebase App Distribution using a Google account to generate an authentication "\
45+
"token. This token is stored within an environment variable and used to authenticate with your Firebase project. "\
46+
"See https://firebase.google.com/docs/app-distribution/ios/distribute-fastlane for more information."
47+
end
48+
49+
def self.authors
50+
["Manny Jimenez Github: mannyjimenez0810, Alonso Salas Infante Github: alonsosalasinfante"]
51+
end
52+
53+
def self.is_supported?(platform)
54+
[:ios, :android].include?(platform)
55+
end
56+
end
57+
end
58+
end

0 commit comments

Comments
 (0)