11require "xmlsimple"
22require "json"
33require_relative "find_info_plist_path"
4+ require_relative "bugsnag_cli"
45
56module Fastlane
67 module Actions
78 class SendBuildToBugsnagAction < Action
8-
9- BUILD_TOOL = "bugsnag-fastlane-plugin"
10-
119 def self . run ( params )
12- payload = { buildTool : BUILD_TOOL , sourceControl : { } }
10+ bugsnag_cli_path = BugsnagCli . get_bugsnag_cli_path ( params )
1311
1412 # If a configuration file was found or was specified, load in the options:
13+ config_options = { }
1514 if params [ :config_file ]
1615 UI . message ( "Loading build information from #{ params [ :config_file ] } " )
1716 config_options = load_config_file_options ( params [ :config_file ] )
18-
19- # for each of the config options, if it's not been overriden by any
20- # input to the lane, write it to the payload:
21- payload [ :apiKey ] = params [ :api_key ] || config_options [ :apiKey ]
22- payload [ :appVersion ] = params [ :app_version ] || config_options [ :appVersion ]
23- payload [ :appVersionCode ] = params [ :android_version_code ] || config_options [ :appVersionCode ]
24- payload [ :appBundleVersion ] = params [ :ios_bundle_version ] || config_options [ :appBundleVersion ]
25- payload [ :releaseStage ] = params [ :release_stage ] || config_options [ :releaseStage ] || "production"
26- else
27- # No configuration file was found or specified, use the input parameters:
28- payload [ :apiKey ] = params [ :api_key ]
29- payload [ :appVersion ] = params [ :app_version ]
30- payload [ :appVersionCode ] = params [ :android_version_code ]
31- payload [ :appBundleVersion ] = params [ :ios_bundle_version ]
32- payload [ :releaseStage ] = params [ :release_stage ] || "production"
3317 end
3418
35- # If builder, or source control information has been provided into
36- # Fastlane, apply it to the payload here.
37- payload [ :builderName ] = params [ :builder ] if params [ :builder ]
38- payload [ :sourceControl ] [ :revision ] = params [ :revision ] if params [ :revision ]
39- payload [ :sourceControl ] [ :repository ] = params [ :repository ] if params [ :repository ]
40- payload [ :sourceControl ] [ :provider ] = params [ :provider ] if params [ :provider ]
41-
42- # If provided apply metadata to payload.
43- payload [ :metadata ] = params [ :metadata ]
44-
45- payload . reject! { |k , v | v == nil || ( v . is_a? ( Hash ) && v . empty? ) }
46-
47- if payload [ :apiKey ] . nil? || !payload [ :apiKey ] . is_a? ( String )
19+ api_key = params [ :api_key ] || config_options [ :apiKey ] unless ( params [ :api_key ] . nil? && config_options [ :apiKey ] . nil? )
20+ version_name = params [ :app_version ] || config_options [ :appVersion ] unless ( params [ :app_version ] . nil? && config_options [ :appVersion ] . nil? )
21+ version_code = params [ :android_version_code ] || config_options [ :appVersionCode ] unless ( params [ :android_version_code ] . nil? && config_options [ :appVersionCode ] . nil? )
22+ bundle_version = params [ :ios_bundle_version ] || config_options [ :appBundleVersion ] unless ( params [ :ios_bundle_version ] . nil? && config_options [ :appBundleVersion ] . nil? )
23+ release_stage = params [ :release_stage ] || config_options [ :releaseStage ] || "production" unless ( params [ :release_stage ] . nil? && config_options [ :releaseStage ] . nil? )
24+ builder = params [ :builder ] unless params [ :builder ] . nil?
25+ revision = params [ :revision ] unless params [ :revision ] . nil?
26+ repository = params [ :repository ] unless params [ :repository ] . nil?
27+ provider = params [ :provider ] unless params [ :provider ] . nil?
28+ auto_assign_release = params [ :auto_assign_release ] unless params [ :auto_assign_release ] . nil?
29+ metadata = params [ :metadata ] unless params [ :metadata ] . nil?
30+ retries = params [ :retries ] unless params [ :retries ] . nil?
31+ timeout = params [ :timeout ] unless params [ :timeout ] . nil?
32+ endpoint = params [ :endpoint ] unless params [ :endpoint ] . nil?
33+
34+
35+ if api_key . nil? || !api_key . is_a? ( String )
4836 UI . user_error! missing_api_key_message ( params )
4937 end
50- if payload [ :appVersion ] . nil?
38+ if version_name . nil?
5139 UI . user_error! missing_app_version_message ( params )
5240 end
5341
54- # If verbose flag is enabled (`--verbose`), display the payload debug info
55- UI . verbose ( "Sending build to Bugsnag with payload:" )
56- payload . each do |param |
57- UI . verbose ( " #{ param [ 0 ] . to_s . rjust ( 18 ) } : #{ param [ 1 ] } " )
42+ args = BugsnagCli . create_build_args (
43+ api_key ,
44+ version_name ,
45+ version_code ,
46+ bundle_version ,
47+ release_stage ,
48+ builder ,
49+ revision ,
50+ repository ,
51+ provider ,
52+ auto_assign_release ,
53+ metadata ,
54+ retries ,
55+ timeout ,
56+ endpoint
57+ )
58+ success = BugsnagCli . create_build bugsnag_cli_path , args
59+ if success
60+ UI . success ( "Build successfully sent to Bugsnag" )
61+ else
62+ UI . user_error! ( "Failed to send build to Bugsnag." )
5863 end
59-
60- send_notification ( params [ :endpoint ] , ::JSON . dump ( payload ) )
6164 end
6265
6366 def self . missing_api_key_message ( params )
@@ -146,6 +149,11 @@ def self.available_options
146149 FastlaneCore ::ConfigItem . new ( key : :release_stage ,
147150 description : "Release stage being built, i.e. staging, production" ,
148151 optional : true ) ,
152+ FastlaneCore ::ConfigItem . new ( key : :auto_assign_release ,
153+ description : "Whether to automatically associate this build with any new error events and sessions that are received for" ,
154+ optional : true ,
155+ default_value : false ,
156+ is_string : false ) ,
149157 FastlaneCore ::ConfigItem . new ( key : :builder ,
150158 description : "The name of the entity triggering the build" ,
151159 optional : true ,
@@ -170,13 +178,28 @@ def self.available_options
170178 end ) ,
171179 FastlaneCore ::ConfigItem . new ( key : :endpoint ,
172180 description : "Bugsnag deployment endpoint" ,
173- optional : true ,
174- default_value : "https://build.bugsnag.com" ) ,
181+ default_value : nil ,
182+ optional : true ) ,
175183 FastlaneCore ::ConfigItem . new ( key : :metadata ,
176184 description : "Metadata" ,
177185 optional :true ,
178- type : Object ,
179- default_value : nil )
186+ type : Object ,
187+ default_value : nil ) ,
188+ FastlaneCore ::ConfigItem . new ( key : :retries ,
189+ description : "The number of retry attempts before failing an upload request" ,
190+ optional : true ,
191+ is_string : false ) ,
192+ FastlaneCore ::ConfigItem . new ( key : :timeout ,
193+ description : "The number of seconds to wait before failing an upload request" ,
194+ optional : true ,
195+ is_string : false ) ,
196+ FastlaneCore ::ConfigItem . new ( key : :bugsnag_cli_path ,
197+ env_name : "BUGSNAG_CLI_PATH" ,
198+ description : "Path to your bugsnag-cli" ,
199+ optional : true ,
200+ verify_block : proc do |value |
201+ UI . user_error! "'#{ value } ' is not executable" unless FastlaneCore ::Helper . executable? ( value )
202+ end )
180203 ]
181204 end
182205
@@ -194,7 +217,8 @@ def self.load_git_remote_options
194217 git_options [ :repository ] = origin . url
195218 git_options [ :revision ] = repo . revparse ( "HEAD" )
196219 end
197- rescue
220+ rescue => e
221+ UI . verbose ( "Could not load git options: #{ e . message } " )
198222 end
199223 return git_options
200224 end
@@ -316,45 +340,6 @@ def self.map_meta_data(meta_data)
316340 end
317341 output
318342 end
319-
320- def self . parse_response_body ( response )
321- begin
322- JSON . load ( response . body )
323- rescue
324- nil
325- end
326- end
327-
328- def self . send_notification ( url , body )
329- require "net/http"
330- uri = URI . parse ( url )
331- http = Net ::HTTP . new ( uri . host , uri . port )
332- http . read_timeout = 15
333- http . open_timeout = 15
334-
335- http . use_ssl = uri . scheme == "https"
336-
337- uri . path == "" ? "/" : uri . path
338- request = Net ::HTTP ::Post . new ( uri , { "Content-Type" => "application/json" } )
339- request . body = body
340- begin
341- response = http . request ( request )
342- rescue => e
343- UI . user_error! "Failed to notify Bugsnag of a new build: #{ e } "
344- end
345- if body = parse_response_body ( response )
346- if body . has_key? "errors"
347- errors = body [ "errors" ] . map { |error | "\n * #{ error } " } . join
348- UI . user_error! "The following errors occurred while notifying Bugsnag:#{ errors } .\n \n Please update your lane config and retry."
349- elsif response . code != "200"
350- UI . user_error! "Failed to notify Bugsnag of a new build. Please retry. HTTP status code: #{ response . code } "
351- end
352- if body . has_key? "warnings"
353- warnings = body [ "warnings" ] . map { |warn | "\n * #{ warn } " } . join
354- UI . important "Sending the build to Bugsnag succeeded with the following warnings:#{ warnings } \n \n Please update your lane config."
355- end
356- end
357- end
358343 end
359344 end
360345end
0 commit comments