fastlane-plugin-firebase_management 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6df846eaf1aad7840c15967396f8be9e0b5d7d54e8743621506c71c451e47ad8
4
+ data.tar.gz: 4cad671ea2d90da2cd663017cfd0c287d61e38498850630ad4fc62bcc4feaf23
5
+ SHA512:
6
+ metadata.gz: b29e743396ab24b68b03b1cdc9d59a6718768f40be3ef894241a8e3249d97f62a4a947afb4587d84312fd970abe50bc3c98180e4e18c7c0003ba138e7238da26
7
+ data.tar.gz: ed5b0d1e4a7669e310f958fe8711e8e560ddb6976d7e48c8bae40dbe7ccaf24eebf1e2a505f27130d840344ef08270a4b53a00e0f98707a0298517a0fc964474
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Tomas Kohout <email@tomaskohout.cz>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # firebase_management `fastlane` Plugin
2
+
3
+ [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-firebase_management)
4
+
5
+ ## Getting Started
6
+
7
+ This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-firebase_management`, add it to your project by running:
8
+
9
+ ```bash
10
+ fastlane add_plugin firebase_management
11
+ ```
12
+
13
+ ## About firebase_management
14
+
15
+ An unofficial tool to access Firebase project settings. It allows you to create new apps and download config files (GoogleInfo.plist for ios and google-services.json for android).
16
+
17
+ Plugin uses new official Firebase Management API introduced on Firebase Summit 10/2018. It's based on [tkohout/fastlane-firebase-plugin](https://github.com/tkohout/fastlane-firebase-plugin), which uses web scraping instead of official API to manage Firebase apps.
18
+
19
+ **This very first version was developed using alpha version of the API in a very short time, so it's not well tested and may contain bugs or mistakes. Issues and PRs are very welcome! 🤗**
20
+
21
+ ### Actions
22
+
23
+ List all projects and apps
24
+
25
+ ```
26
+ firebase_list
27
+ ```
28
+
29
+
30
+ Add app to a project and download config file
31
+
32
+ ```
33
+ firebase_add_app
34
+ ```
35
+
36
+ Download config file for a client
37
+
38
+ ```
39
+ firebase_download_config
40
+ ```
41
+
42
+ ## Example
43
+
44
+ Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin. Try it by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane test`.
45
+
46
+
47
+ ## Run tests for this plugin
48
+
49
+ To run both the tests, and code style validation, run
50
+
51
+ ```
52
+ rake
53
+ ```
54
+
55
+ To automatically fix many of the styling issues, use
56
+ ```
57
+ rubocop -a
58
+ ```
59
+
60
+ ## Issues and Feedback
61
+
62
+ For any other issues and feedback about this plugin, please submit it to this repository.
63
+
64
+ ## Troubleshooting
65
+
66
+ If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
67
+
68
+ ## Using _fastlane_ Plugins
69
+
70
+ For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
71
+
72
+ ## About _fastlane_
73
+
74
+ _fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
75
+
76
+ ## Warning
77
+
78
+ DISCLAIMER OF WARRANTIES AND LIMITATION OF LIABILITY.
79
+
80
+ UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
81
+
82
+ TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
83
+
84
+ THE DISCLAIMER OF WARRANTIES AND LIMITATION OF LIABILITY PROVIDED ABOVE SHALL BE INTERPRETED IN A MANNER THAT, TO THE EXTENT POSSIBLE, MOST CLOSELY APPROXIMATES AN ABSOLUTE DISCLAIMER AND WAIVER OF ALL LIABILITY.
@@ -0,0 +1,16 @@
1
+ require 'fastlane/plugin/firebase_management/version'
2
+
3
+ module Fastlane
4
+ module FirebaseManagement
5
+ # Return all .rb files inside the "actions" and "helper" directory
6
+ def self.all_classes
7
+ Dir[File.expand_path('**/{actions,helper,lib}/*.rb', File.dirname(__FILE__))]
8
+ end
9
+ end
10
+ end
11
+
12
+ # By default we want to import all available actions and helpers
13
+ # A plugin can contain any number of actions and plugins
14
+ Fastlane::FirebaseManagement.all_classes.each do |current|
15
+ require current
16
+ end
@@ -0,0 +1,148 @@
1
+ module Fastlane
2
+ module Actions
3
+ class FirebaseManagementAddAppAction < Action
4
+
5
+ def self.run(params)
6
+ manager = FirebaseManagement::Manager.new
7
+
8
+ # login
9
+ api = manager.login(params[:service_account_json_path])
10
+
11
+ # select project
12
+ project_id = params[:project_id] || manager.select_project(nil)["projectId"]
13
+
14
+ # select type
15
+ type = params[:type].to_sym
16
+
17
+ bundle_id = params[:bundle_id]
18
+
19
+ display_name = params[:display_name]
20
+
21
+ case type
22
+ when :ios
23
+ # create new ios app on Firebase
24
+ api.add_ios_app(project_id, bundle_id, display_name)
25
+
26
+ # App creation is a long-running operation.
27
+ # Creation endpoint returns operation ID which should be used to check
28
+ # the result of the operation. This requires another Google API to be
29
+ # enabled and other stuff to do so just wait for 3 seconds here, fetch
30
+ # apps from Firebase and check whether the new app is there.
31
+ sleep 3
32
+
33
+ # download apps for project
34
+ apps = api.ios_app_list(project_id)
35
+
36
+ # search for newly created app
37
+ app = apps.detect {|app| app["bundleId"] == bundle_id }
38
+
39
+ when :android
40
+ # create new android app on Firebase
41
+ api.add_android_app(project_id, bundle_id, display_name)
42
+
43
+ # see reason described above
44
+ sleep 3
45
+
46
+ # download apps for project
47
+ apps = api.android_app_list(project_id)
48
+
49
+ # search for newly created app
50
+ app = apps.detect {|app| app["packageName"] == bundle_id }
51
+ end
52
+
53
+ # present result to user
54
+ if app != nil then
55
+ UI.success "New app with id: #{app["appId"]} successfully created"
56
+ else
57
+ UI.crash! "Unable to create new app"
58
+ end
59
+
60
+ if params[:download_config] then
61
+ #Download config
62
+ Actions::FirebaseManagementDownloadConfigAction.run(
63
+ service_account_json_path: params[:service_account_json_path],
64
+ project_id: project_id,
65
+ app_id: app["appId"],
66
+ type: type,
67
+ output_path: params[:output_path]
68
+ )
69
+ end
70
+ end
71
+
72
+ def self.description
73
+ "Add new app to Firebase project"
74
+ end
75
+
76
+ def self.authors
77
+ ["Ackee, s.r.o."]
78
+ end
79
+
80
+ def self.return_value
81
+ # If your method provides a return value, you can describe here what it does
82
+ end
83
+
84
+ def self.details
85
+ # Optional:
86
+ "Firebase plugin helps you list your projects, create applications and download configuration files."
87
+ end
88
+
89
+ def self.available_options
90
+ [
91
+ FastlaneCore::ConfigItem.new(key: :service_account_json_path,
92
+ env_name: "FIREBASE_SERVICE_ACCOUNT_JSON_PATH",
93
+ description: "Path to service account json key",
94
+ optional: false),
95
+
96
+ FastlaneCore::ConfigItem.new(key: :project_id,
97
+ env_name: "FIREBASE_PROJECT_ID",
98
+ description: "Project id",
99
+ optional: true),
100
+
101
+ FastlaneCore::ConfigItem.new(key: :download_config,
102
+ env_name: "FIREBASE_DOWNLOAD_CONFIG",
103
+ description: "Should download config for created client",
104
+ optional: false,
105
+ is_string: false,
106
+ default_value: false),
107
+
108
+ FastlaneCore::ConfigItem.new(key: :type,
109
+ env_name: "FIREBASE_TYPE",
110
+ description: "Type of client (ios, android)",
111
+ verify_block: proc do |value|
112
+ types = [:ios, :android]
113
+ UI.user_error!("Type must be in #{types}") unless types.include?(value.to_sym)
114
+ end
115
+ ),
116
+ FastlaneCore::ConfigItem.new(key: :bundle_id,
117
+ env_name: "FIREBASE_BUNDLE_ID",
118
+ description: "Bundle ID (package name)",
119
+ optional: false),
120
+
121
+ FastlaneCore::ConfigItem.new(key: :display_name,
122
+ env_name: "FIREBASE_DISPLAY_NAME",
123
+ description: "Display name",
124
+ optional: true),
125
+
126
+ FastlaneCore::ConfigItem.new(key: :output_path,
127
+ env_name: "FIREBASE_OUTPUT_PATH",
128
+ description: "Path for the downloaded config",
129
+ optional: false,
130
+ default_value: "./"),
131
+
132
+ FastlaneCore::ConfigItem.new(key: :output_name,
133
+ env_name: "FIREBASE_OUTPUT_NAME",
134
+ description: "Name of the downloaded file",
135
+ optional: true)
136
+ ]
137
+ end
138
+
139
+ def self.is_supported?(platform)
140
+ # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
141
+ # See: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Platforms.md
142
+ #
143
+ # [:ios, :mac, :android].include?(platform)
144
+ true
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,100 @@
1
+ module Fastlane
2
+ module Actions
3
+ class FirebaseManagementDownloadConfigAction < Action
4
+
5
+ def self.run(params)
6
+ manager = FirebaseManagement::Manager.new
7
+
8
+ # login
9
+ api = manager.login(params[:service_account_json_path])
10
+
11
+ # select project
12
+ project_id = params[:project_id] || manager.select_project(nil)["projectId"]
13
+
14
+ # select type
15
+ type = params[:type].to_sym
16
+
17
+ # select app
18
+ app_id = params[:app_id] || manager.select_app(project_id, nil, type)["appId"]
19
+
20
+ # download
21
+ case type
22
+ when :ios
23
+ config = api.download_ios_config_file(project_id, app_id)
24
+ when :android
25
+ config = api.download_android_config_file(project_id, app_id)
26
+ end
27
+
28
+ path = File.join(params[:output_path], params[:output_name] || config["configFilename"])
29
+
30
+ decode_base64_content = Base64.decode64(config["configFileContents"])
31
+ File.open(path, "wb") do |f|
32
+ f.write(decode_base64_content)
33
+ end
34
+
35
+ UI.success "Successfuly saved config at #{path}"
36
+
37
+ return nil
38
+ end
39
+
40
+ def self.description
41
+ "Download configuration file for Firebase app"
42
+ end
43
+
44
+ def self.authors
45
+ ["Ackee, s.r.o."]
46
+ end
47
+
48
+ def self.return_value
49
+ # If your method provides a return value, you can describe here what it does
50
+ end
51
+
52
+ def self.details
53
+ # Optional:
54
+ "Firebase plugin helps you list your projects, create applications and download configuration files."
55
+ end
56
+
57
+ def self.available_options
58
+ [
59
+ FastlaneCore::ConfigItem.new(key: :service_account_json_path,
60
+ env_name: "FIREBASE_SERVICE_ACCOUNT_JSON_PATH",
61
+ description: "Path to service account json key",
62
+ optional: false),
63
+ FastlaneCore::ConfigItem.new(key: :project_id,
64
+ env_name: "FIREBASE_PROJECT_ID",
65
+ description: "Project id",
66
+ optional: true),
67
+ FastlaneCore::ConfigItem.new(key: :app_id,
68
+ env_name: "FIREBASE_APP_ID",
69
+ description: "Project app id",
70
+ optional: true),
71
+ FastlaneCore::ConfigItem.new(key: :type,
72
+ env_name: "FIREBASE_TYPE",
73
+ description: "Type of client (ios, android)",
74
+ verify_block: proc do |value|
75
+ types = [:ios, :android]
76
+ UI.user_error!("Type must be in #{types}") unless types.include?(value.to_sym)
77
+ end
78
+ ),
79
+ FastlaneCore::ConfigItem.new(key: :output_path,
80
+ env_name: "FIREBASE_OUTPUT_PATH",
81
+ description: "Path for the downloaded config",
82
+ optional: false,
83
+ default_value: "./"),
84
+ FastlaneCore::ConfigItem.new(key: :output_name,
85
+ env_name: "FIREBASE_OUTPUT_NAME",
86
+ description: "Name of the downloaded file",
87
+ optional: true)
88
+ ]
89
+ end
90
+
91
+ def self.is_supported?(platform)
92
+ # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
93
+ # See: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Platforms.md
94
+ #
95
+ # [:ios, :mac, :android].include?(platform)
96
+ true
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,81 @@
1
+ module Fastlane
2
+ module Actions
3
+ class FirebaseManagementListAction < Action
4
+
5
+ def self.run(params)
6
+ manager = FirebaseManagement::Manager.new
7
+
8
+ # login
9
+ api = manager.login(params[:service_account_json_path])
10
+
11
+ # download list of projects
12
+ projects = api.project_list()
13
+
14
+ # download list of apps for each project
15
+ projects.map! { |project|
16
+ project["iosApps"] = api.ios_app_list(project["projectId"])
17
+ project["androidApps"] = api.android_app_list(project["projectId"])
18
+ project
19
+ }
20
+
21
+ # create formatted output
22
+ projects.each_with_index { |p, i|
23
+ UI.message "#{i+1}. #{p["displayName"]} (#{p["projectId"]})"
24
+
25
+ ios_apps = p["iosApps"] || []
26
+ if !ios_apps.empty? then
27
+ UI.message " iOS"
28
+ ios_apps.sort {|left, right| left["appId"] <=> right["appId"] }.each_with_index { |app, j|
29
+ UI.message " - #{app["displayName"] || app["bundleId"]} (#{app["appId"]})"
30
+ }
31
+ end
32
+
33
+ android_apps = p["androidApps"] || []
34
+ if !android_apps.empty? then
35
+ UI.message " Android"
36
+ android_apps.sort {|left, right| left["appId"] <=> right["appId"] }.each_with_index { |app, j|
37
+ UI.message " - #{app["displayName"] || app["packageName"]} (#{app["appId"]})"
38
+ }
39
+ end
40
+ }
41
+
42
+ return nil
43
+ end
44
+
45
+ def self.description
46
+ "List all Firebase projects and their apps"
47
+ end
48
+
49
+ def self.authors
50
+ ["Ackee, s.r.o."]
51
+ end
52
+
53
+ def self.return_value
54
+ # If your method provides a return value, you can describe here what it does
55
+ end
56
+
57
+ def self.details
58
+ # Optional:
59
+ "Firebase plugin helps you list your projects, create applications and download configuration files."
60
+ end
61
+
62
+ def self.available_options
63
+ [
64
+ FastlaneCore::ConfigItem.new(key: :service_account_json_path,
65
+ env_name: "FIREBASE_SERVICE_ACCOUNT_JSON_PATH",
66
+ description: "Path to service account json key",
67
+ optional: false
68
+ )
69
+ ]
70
+ end
71
+
72
+ def self.is_supported?(platform)
73
+ # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
74
+ # See: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Platforms.md
75
+ #
76
+ # [:ios, :mac, :android].include?(platform)
77
+ true
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,16 @@
1
+ require 'fastlane_core/ui/ui'
2
+
3
+ module Fastlane
4
+ UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
5
+
6
+ module Helper
7
+ class FirebaseManagementHelper
8
+ # class methods that you define here become available in your action
9
+ # as `Helper::FirebaseManagementHelper.your_method`
10
+ #
11
+ def self.show_message
12
+ UI.message("Hello from the firebase_management plugin helper!")
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,129 @@
1
+ module Fastlane
2
+ module FirebaseManagement
3
+ class Api
4
+ class LoginError < StandardError
5
+ end
6
+
7
+ class BadRequestError < StandardError
8
+ attr_reader :code
9
+
10
+ def initialize(msg, code)
11
+ @code = code
12
+ super(msg)
13
+ end
14
+ end
15
+
16
+ require 'googleauth'
17
+ require 'httparty'
18
+
19
+ def initialize(jsonPath)
20
+ @base_url = "https://firebase.googleapis.com"
21
+
22
+ scope = 'https://www.googleapis.com/auth/firebase https://www.googleapis.com/auth/cloud-platform'
23
+
24
+ authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
25
+ json_key_io: File.open(jsonPath),
26
+ scope: scope
27
+ )
28
+
29
+ access_token = authorizer.fetch_access_token!["access_token"]
30
+ @authorization_headers = {
31
+ 'Authorization' => 'Bearer ' + access_token
32
+ }
33
+ end
34
+
35
+ def request_json(path, method = :get, parameters = Hash.new, headers = Hash.new)
36
+ begin
37
+ if method == :get then
38
+ response = HTTParty.get("#{@base_url}/#{path}", headers: headers.merge(@authorization_headers), format: :plain)
39
+ elsif method == :post then
40
+ headers['Content-Type'] = 'application/json'
41
+ response = HTTParty.post("#{@base_url}/#{path}", headers: headers.merge(@authorization_headers), body: parameters.to_json, format: :plain)
42
+ end
43
+
44
+ case response.code
45
+ when 400...600
46
+ UI.crash! response
47
+ else
48
+ JSON.parse(response)
49
+ end
50
+
51
+ rescue HTTParty::Error => e
52
+ UI.crash! e.response.body
53
+ rescue StandardError => e
54
+ UI.crash! e
55
+ end
56
+ end
57
+
58
+ def project_list
59
+ UI.verbose "Retrieving project list"
60
+ json = request_json("v1beta1/projects")
61
+ projects = json["results"] || []
62
+ UI.verbose "Found #{projects.count} projects"
63
+ projects
64
+ end
65
+
66
+ def ios_app_list(project_id)
67
+ UI.verbose "Retrieving app list for project #{project_id}"
68
+ json = request_json("v1beta1/projects/#{project_id}/iosApps")
69
+ apps = json["apps"] || []
70
+ UI.verbose "Found #{apps.count} apps"
71
+ apps
72
+ end
73
+
74
+ def android_app_list(project_id)
75
+ UI.verbose "Retrieving app list for project #{project_id}"
76
+ json = request_json("v1beta1/projects/#{project_id}/androidApps")
77
+ apps = json["apps"] || []
78
+ UI.verbose "Found #{apps.count} apps"
79
+ apps
80
+ end
81
+
82
+ def add_ios_app(project_id, bundle_id, app_name)
83
+ parameters = {
84
+ "bundleId" => bundle_id,
85
+ "displayName" => app_name || ""
86
+ }
87
+
88
+ request_json("v1beta1/projects/#{project_id}/iosApps", :post, parameters)
89
+ end
90
+
91
+ def add_android_app(project_id, package_name, app_name)
92
+ parameters = {
93
+ "packageName" => package_name,
94
+ "displayName" => app_name || ""
95
+ }
96
+
97
+ request_json("v1beta1/projects/#{project_id}/androidApps", :post, parameters)
98
+ end
99
+
100
+ def upload_certificate(project_number, client_id, type, certificate_value, certificate_password)
101
+
102
+ prefix = type == :development ? "debug" : "prod"
103
+
104
+ parameters = {
105
+ "#{prefix}ApnsCertificate" => {
106
+ "certificateValue" => certificate_value,
107
+ "apnsPassword" => certificate_password
108
+ }
109
+ }
110
+
111
+ json = request_json("v1/projects/#{project_number}/clients/#{client_id}:setApnsCertificate", :post, parameters)
112
+ end
113
+
114
+ def download_ios_config_file(project_id, app_id)
115
+ UI.verbose "Downloading config file"
116
+ json = request_json("v1beta1/projects/#{project_id}/iosApps/#{app_id}/config")
117
+ UI.verbose "Successfuly downloaded #{json["configFilename"]}"
118
+ json
119
+ end
120
+
121
+ def download_android_config_file(project_id, app_id)
122
+ UI.verbose "Downloading config file"
123
+ json = request_json("v1beta1/projects/#{project_id}/androidApps/#{app_id}/config")
124
+ UI.verbose "Successfuly downloaded #{json["configFilename"]}"
125
+ json
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,41 @@
1
+ require 'commander'
2
+ require 'fastlane/version'
3
+
4
+
5
+ module FirebaseManagement
6
+ class CommandsGenerator
7
+ include Commander::Methods
8
+
9
+ def self.start
10
+ self.new.run
11
+ end
12
+
13
+ def run
14
+ program :name, 'firebase'
15
+ program :version, Fastlane::VERSION
16
+ program :description, 'CLI for \'PEM\' - Automatically generate and renew your push notification profiles'
17
+ program :help, 'Author', 'Felix Krause <pem@krausefx.com>'
18
+ program :help, 'Website', 'https://fastlane.tools'
19
+ program :help, 'GitHub', 'https://github.com/fastlane/PEM'
20
+ program :help_formatter, :compact
21
+
22
+ global_option('--verbose') { FastlaneCore::Globals.verbose = true }
23
+
24
+ command :list do |c|
25
+ c.syntax = 'fastlane firebase list'
26
+ c.description = 'Lists all projects in your firebase'
27
+
28
+ FastlaneCore::CommanderGenerator.new.generate(Firebase::Options.available_options, command: c)
29
+
30
+ c.action do |args, options|
31
+ Firebase.config = FastlaneCore::Configuration.create(Firebase::Options.available_options, options.__hash__)
32
+ #Firebase::Manager.start
33
+ end
34
+ end
35
+
36
+ default_command :list
37
+
38
+ run!
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,64 @@
1
+ module Fastlane
2
+ module FirebaseManagement
3
+ class Manager
4
+
5
+ def login(jsonPath)
6
+ begin
7
+ #Api instance
8
+ @api = FirebaseManagement::Api.new(jsonPath)
9
+ @api
10
+ rescue StandardError => e
11
+ UI.crash! e
12
+ end
13
+ end
14
+
15
+ def select_project(project_id)
16
+
17
+ projects = @api.project_list()
18
+
19
+ if projects.count == 0 then
20
+ UI.user_error! "No projects exist under the account"
21
+ return
22
+ end
23
+
24
+ if project = projects.select {|p| p["projectId"] == project_id }.first then
25
+ project
26
+ else
27
+ options = projects.map { |p| "#{p["displayName"]} (#{p["projectId"]})" }
28
+ index = select_index("Select project:", options)
29
+ projects[index]
30
+ end
31
+ end
32
+
33
+ def select_app(project_id, app_id, type)
34
+
35
+ case type
36
+ when :ios
37
+ apps = @api.ios_app_list(project_id)
38
+ when :android
39
+ apps = @api.android_app_list(project_id)
40
+ end
41
+
42
+ if apps.empty? then
43
+ UI.user_error! "Project has no #{type} apps"
44
+ return
45
+ end
46
+
47
+ apps = apps.sort {|left, right| left["appId"] <=> right["appId"] }
48
+
49
+ if app = apps.select {|a| a["appId"] == app_id }.first then
50
+ app
51
+ else
52
+ options = apps.map { |a| "#{a["displayName"] || a["bundleId"] || a["packageName"]} (#{a["appId"]})" }
53
+ index = select_index("Select app:", options)
54
+ apps[index]
55
+ end
56
+ end
57
+
58
+ def select_index(text, options)
59
+ selected = UI.select(text, options)
60
+ return options.index(selected)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,16 @@
1
+ require 'fastlane_core'
2
+ require 'credentials_manager'
3
+
4
+ module FirebaseManagement
5
+ class Options
6
+ def self.available_options
7
+ [
8
+ FastlaneCore::ConfigItem.new(
9
+ key: :username,
10
+ env_name: "FIREBASE_USERNAME",
11
+ description: "Username for the google account"
12
+ )
13
+ ]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ module Fastlane
2
+ module FirebaseManagement
3
+ VERSION = "1.0.1"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,209 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fastlane-plugin-firebase_management
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ackee
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec_junit_formatter
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.49.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 0.49.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-require_tools
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: fastlane
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: 2.108.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: 2.108.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: googleauth
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: httparty
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ description:
168
+ email: jan.misar@ackee.cz
169
+ executables: []
170
+ extensions: []
171
+ extra_rdoc_files: []
172
+ files:
173
+ - LICENSE
174
+ - README.md
175
+ - lib/fastlane/plugin/firebase_management.rb
176
+ - lib/fastlane/plugin/firebase_management/actions/firebase_add_app_action.rb
177
+ - lib/fastlane/plugin/firebase_management/actions/firebase_download_config_action.rb
178
+ - lib/fastlane/plugin/firebase_management/actions/firebase_list_action.rb
179
+ - lib/fastlane/plugin/firebase_management/helper/firebase_management_helper.rb
180
+ - lib/fastlane/plugin/firebase_management/lib/api.rb
181
+ - lib/fastlane/plugin/firebase_management/lib/commands_generator.rb
182
+ - lib/fastlane/plugin/firebase_management/lib/manager.rb
183
+ - lib/fastlane/plugin/firebase_management/lib/options.rb
184
+ - lib/fastlane/plugin/firebase_management/version.rb
185
+ homepage: https://github.com/AckeeCZ/fastlane-plugin-firebase_management
186
+ licenses:
187
+ - MIT
188
+ metadata: {}
189
+ post_install_message:
190
+ rdoc_options: []
191
+ require_paths:
192
+ - lib
193
+ required_ruby_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ required_rubygems_version: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ requirements: []
204
+ rubyforge_project:
205
+ rubygems_version: 2.7.8
206
+ signing_key:
207
+ specification_version: 4
208
+ summary: Unofficial tool to access Firebase project settings
209
+ test_files: []