fastlane 0.1.8 → 0.1.9

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.
@@ -1,17 +1,16 @@
1
1
  module Fastlane
2
2
  module Actions
3
3
  module SharedValues
4
-
5
4
  end
6
5
 
7
6
  class FrameitAction
8
7
  def self.run(params)
9
- return if Helper.is_test?
10
-
8
+ return if Helper.test?
9
+
11
10
  require 'frameit'
12
11
 
13
12
  color = Frameit::Editor::Color::BLACK
14
- color = Frameit::Editor::Color::SILVER if [:silver, :white].include?params.first
13
+ color = Frameit::Editor::Color::SILVER if [:silver, :white].include?(params.first)
15
14
 
16
15
  screenshots_folder = Actions.lane_context[SharedValues::SNAPSHOT_SCREENSHOTS_PATH]
17
16
  screenshots_folder ||= FastlaneFolder.path
@@ -22,4 +21,4 @@ module Fastlane
22
21
  end
23
22
  end
24
23
  end
25
- end
24
+ end
@@ -1,7 +1,6 @@
1
1
  module Fastlane
2
2
  module Actions
3
3
  module SharedValues
4
-
5
4
  end
6
5
 
7
6
  class HipchatAction
@@ -14,58 +13,69 @@ module Fastlane
14
13
  require 'net/http'
15
14
  require 'uri'
16
15
 
17
- api_token = ENV["HIPCHAT_API_TOKEN"]
18
- api_version = ENV["HIPCHAT_API_VERSION"]
16
+ api_token = ENV['HIPCHAT_API_TOKEN']
17
+ api_version = ENV['HIPCHAT_API_VERSION']
19
18
 
20
19
  unless api_token
21
20
  Helper.log.fatal "Please add 'ENV[\"HIPCHAT_API_TOKEN\"] = \"your token\"' to your Fastfile's `before_all` section.".red
22
- raise "No HIPCHAT_API_TOKEN given.".red
21
+ raise 'No HIPCHAT_API_TOKEN given.'.red
23
22
  end
24
- if api_version.nil? or ![1,2].include?api_version[0].to_i
23
+ if api_version.nil? || ![1, 2].include?(api_version[0].to_i)
25
24
  Helper.log.fatal "Please add 'ENV[\"HIPCHAT_API_VERSION\"] = \"1 or 2\"' to your Fastfile's `before_all` section.".red
26
- raise "No HIPCHAT_API_VERSION given.".red
25
+ raise 'No HIPCHAT_API_VERSION given.'.red
27
26
  end
28
27
 
29
28
  channel = options[:channel]
30
29
  color = (options[:success] ? 'green' : 'red')
31
- message = "<table><tr><td><img src=\"https://s3-eu-west-1.amazonaws.com/fastlane.tools/fastlane.png\" style=\"width:50px;height:auto\"></td><td>" + options[:message] + "</td></tr></table>"
30
+ message = "<table><tr><td><img src=\"https://s3-eu-west-1.amazonaws.com/fastlane.tools/fastlane.png\" width=\"50\" height=\"50\"></td><td>" + options[:message] + '</td></tr></table>'
32
31
 
33
32
  if api_version.to_i == 1
34
33
  ########## running on V1 ##########
35
- if isUser(channel)
36
- raise "HipChat private message not working with API V1 please use API V2 instead".red
34
+ if user?(channel)
35
+ raise 'HipChat private message not working with API V1 please use API V2 instead'.red
37
36
  else
38
37
  uri = URI.parse('https://api.hipchat.com/v1/rooms/message')
39
- response = Net::HTTP.post_form(uri, {"from" => "fastlane", "auth_token" => api_token, "color" => color, "message_format" => "html", "room_id" => channel, "message" => message})
40
- checkResponseCodeForRoom(response, channel)
38
+ response = Net::HTTP.post_form(uri, { 'from' => 'fastlane',
39
+ 'auth_token' => api_token,
40
+ 'color' => color,
41
+ 'message_format' => 'html',
42
+ 'room_id' => channel,
43
+ 'message' => message })
44
+
45
+ check_response_code(response, channel)
41
46
  end
42
47
  else
43
48
  ########## running on V2 ##########
44
- if isUser(channel)
49
+ if user?(channel)
45
50
  channel.slice!(0)
46
- params = {'message' => message, 'message_format' => 'html'}
47
- json_headers = {"Content-Type" => "application/json",
48
- "Accept" => "application/json", "Authorization" => "Bearer #{api_token}"}
51
+ params = { 'message' => message, 'message_format' => 'html' }
52
+ json_headers = { 'Content-Type' => 'application/json',
53
+ 'Accept' => 'application/json', 'Authorization' => "Bearer #{api_token}" }
49
54
 
50
55
  uri = URI.parse("https://api.hipchat.com/v2/user/#{channel}/message")
51
56
  http = Net::HTTP.new(uri.host, uri.port)
52
57
  http.use_ssl = true
53
58
 
54
59
  response = http.post(uri.path, params.to_json, json_headers)
55
- checkResponseCode(response, channel)
60
+ check_response_code(response, channel)
56
61
  else
57
62
  uri = URI.parse("https://api.hipchat.com/v2/room/#{channel}/notification")
58
- response = Net::HTTP.post_form(uri, {"from" => "fastlane", "auth_token" => api_token, "color" => color, "message_format" => "html", "message" => message})
59
- checkResponseCode(response, channel)
63
+ response = Net::HTTP.post_form(uri, { 'from' => 'fastlane',
64
+ 'auth_token' => api_token,
65
+ 'color' => color,
66
+ 'message_format' => 'html',
67
+ 'message' => message })
68
+
69
+ check_response_code(response, channel)
60
70
  end
61
71
  end
62
72
  end
63
73
 
64
- def self.isUser(channel)
65
- return channel.to_s.start_with?('@')
74
+ def self.user?(channel)
75
+ channel.to_s.start_with?('@')
66
76
  end
67
77
 
68
- def self.checkResponseCode(response, channel)
78
+ def self.check_response_code(response, channel)
69
79
  case response.code.to_i
70
80
  when 200, 204
71
81
  true
@@ -1,5 +1,5 @@
1
1
  # TODO: Workaround, since hockeyapp.rb from shenzhen includes the code for commander
2
- def command(param)
2
+ def command(_param)
3
3
  end
4
4
 
5
5
  module Fastlane
@@ -13,7 +13,7 @@ module Fastlane
13
13
  def self.run(params)
14
14
  # Available options: http://support.hockeyapp.net/kb/api/api-versions#upload-version
15
15
  options = {
16
- notes: "No changelog given",
16
+ notes: 'No changelog given',
17
17
  status: 2,
18
18
  notify: 1
19
19
  }.merge(params.first)
@@ -26,26 +26,27 @@ module Fastlane
26
26
 
27
27
  raise "No API Token for Hockey given, pass using `api_token: 'token'`".red unless options[:api_token].to_s.length > 0
28
28
  raise "No IPA file given or found, pass using `ipa: 'path.ipa'`".red unless options[:ipa]
29
- raise "IPA file on path '#{File.expand_path(options[:ipa])}' not found".red unless File.exists?(options[:ipa])
29
+ raise "IPA file on path '#{File.expand_path(options[:ipa])}' not found".red unless File.exist?(options[:ipa])
30
30
 
31
31
  if options[:dsym]
32
32
  options[:dsym_filename] = options[:dsym]
33
- else
34
- dsym_path = options[:ipa].gsub("ipa", "app.dSYM.zip")
35
- if File.exists?(dsym_path)
33
+ else
34
+ dsym_path = options[:ipa].gsub('ipa', 'app.dSYM.zip')
35
+ if File.exist?(dsym_path)
36
36
  options[:dsym_filename] = dsym_path
37
37
  else
38
38
  Helper.log.info "Symbols not found on path #{File.expand_path(dsym_path)}. Crashes won't be symbolicated properly".yellow
39
39
  end
40
40
  end
41
41
 
42
- raise "Symbols on path '#{File.expand_path(options[:dsym_filename])}' not found".red if (options[:dsym_filename] && !File.exists?(options[:dsym_filename]))
42
+ raise "Symbols on path '#{File.expand_path(options[:dsym_filename])}' not found".red if (options[:dsym_filename] &&
43
+ !File.exist?(options[:dsym_filename]))
44
+
45
+ Helper.log.info 'Starting with ipa upload to HockeyApp... this could take some time.'.green
43
46
 
44
- Helper.log.info "Starting with ipa upload to HockeyApp... this could take some time.".green
45
-
46
47
  client = Shenzhen::Plugins::HockeyApp::Client.new(options[:api_token])
47
48
 
48
- return if Helper.is_test?
49
+ return if Helper.test?
49
50
 
50
51
  response = client.upload_build(options[:ipa], options)
51
52
  case response.status
@@ -54,14 +55,14 @@ module Fastlane
54
55
 
55
56
  Actions.lane_context[SharedValues::HOCKEY_DOWNLOAD_LINK] = url
56
57
  Actions.lane_context[SharedValues::HOCKEY_BUILD_INFORMATION] = response.body
57
-
58
+
58
59
  Helper.log.info "Public Download URL: #{url}" if url
59
- Helper.log.info "Build successfully uploaded to HockeyApp!".green
60
+ Helper.log.info 'Build successfully uploaded to HockeyApp!'.green
60
61
  else
61
62
  Helper.log.fatal "Error uploading to HockeyApp: #{response.body}"
62
- raise "Error when trying to upload ipa to HockeyApp".red
63
+ raise 'Error when trying to upload ipa to HockeyApp'.red
63
64
  end
64
65
  end
65
66
  end
66
67
  end
67
- end
68
+ end
@@ -6,7 +6,7 @@ module Fastlane
6
6
 
7
7
  class IncrementBuildNumberAction
8
8
  def self.run(params)
9
- # More information about how to set up your project and how it works:
9
+ # More information about how to set up your project and how it works:
10
10
  # https://developer.apple.com/library/ios/qa/qa1827/_index.html
11
11
  # Attention: This is NOT the version number - but the build number
12
12
 
@@ -17,10 +17,10 @@ module Fastlane
17
17
  if custom_number
18
18
  command = "agvtool new-version -all #{custom_number}"
19
19
  else
20
- command = "agvtool next-version -all"
20
+ command = 'agvtool next-version -all'
21
21
  end
22
22
 
23
- if Helper.is_test?
23
+ if Helper.test?
24
24
  Actions.lane_context[SharedValues::BUILD_NUMBER] = command
25
25
  else
26
26
 
@@ -33,10 +33,10 @@ module Fastlane
33
33
 
34
34
  end
35
35
  rescue => ex
36
- Helper.log.error "Make sure to to follow the steps to setup your Xcode project: https://developer.apple.com/library/ios/qa/qa1827/_index.html".yellow
36
+ Helper.log.error 'Make sure to to follow the steps to setup your Xcode project: https://developer.apple.com/library/ios/qa/qa1827/_index.html'.yellow
37
37
  raise ex
38
38
  end
39
39
  end
40
40
  end
41
41
  end
42
- end
42
+ end
@@ -1,9 +1,9 @@
1
1
  module Fastlane
2
2
  module Actions
3
3
  class CocoapodsAction
4
- def self.run(params)
5
- Actions.sh("pod install")
4
+ def self.run(_params)
5
+ Actions.sh('pod install')
6
6
  end
7
7
  end
8
8
  end
9
- end
9
+ end
@@ -1,24 +1,23 @@
1
1
  module Fastlane
2
2
  module Actions
3
-
4
3
  module SharedValues
5
4
  IPA_OUTPUT_PATH = :IPA_OUTPUT_PATH
6
5
  DSYM_OUTPUT_PATH = :DSYM_OUTPUT_PATH
7
6
  end
8
7
 
9
- # -w, --workspace WORKSPACE Workspace (.xcworkspace) file to use to build app (automatically detected in current directory)
10
- # -p, --project PROJECT Project (.xcodeproj) file to use to build app (automatically detected in current directory, overridden by --workspace option, if passed)
11
- # -c, --configuration CONFIGURATION Configuration used to build
12
- # -s, --scheme SCHEME Scheme used to build app
13
- # --xcconfig XCCONFIG use an extra XCCONFIG file to build the app
14
- # --xcargs XCARGS pass additional arguments to xcodebuild when building the app. Be sure to quote multiple args.
15
- # --[no-]clean Clean project before building
16
- # --[no-]archive Archive project after building
17
- # -d, --destination DESTINATION Destination. Defaults to current directory
18
- # -m, --embed PROVISION Sign .ipa file with .mobileprovision
19
- # -i, --identity IDENTITY Identity to be used along with --embed
20
- # --sdk SDK use SDK as the name or path of the base SDK when building the project
21
- # --ipa IPA specify the name of the .ipa file to generate (including file extension)
8
+ # -w, --workspace WORKSPACE Workspace (.xcworkspace) file to use to build app (automatically detected in current directory)
9
+ # -p, --project PROJECT Project (.xcodeproj) file to use to build app (automatically detected in current directory, overridden by --workspace option, if passed)
10
+ # -c, --configuration CONFIGURATION Configuration used to build
11
+ # -s, --scheme SCHEME Scheme used to build app
12
+ # --xcconfig XCCONFIG use an extra XCCONFIG file to build the app
13
+ # --xcargs XCARGS pass additional arguments to xcodebuild when building the app. Be sure to quote multiple args.
14
+ # --[no-]clean Clean project before building
15
+ # --[no-]archive Archive project after building
16
+ # -d, --destination DESTINATION Destination. Defaults to current directory
17
+ # -m, --embed PROVISION Sign .ipa file with .mobileprovision
18
+ # -i, --identity IDENTITY Identity to be used along with --embed
19
+ # --sdk SDK use SDK as the name or path of the base SDK when building the project
20
+ # --ipa IPA specify the name of the .ipa file to generate (including file extension)
22
21
 
23
22
  ARGS_MAP = {
24
23
  workspace: '-w',
@@ -36,7 +35,6 @@ module Fastlane
36
35
 
37
36
  class IpaAction
38
37
  def self.run(params)
39
-
40
38
  # The args we will build with
41
39
  build_args = nil
42
40
 
@@ -61,10 +59,10 @@ module Fastlane
61
59
  # If no dest directory given, default to current directory
62
60
  absolute_dest_directory ||= Dir.pwd
63
61
 
64
- if Helper.is_test?
65
- Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] = File.join(absolute_dest_directory, "test.ipa")
66
- Actions.lane_context[SharedValues::DSYM_OUTPUT_PATH] = File.join(absolute_dest_directory, "test.app.dSYM.zip")
67
- return build_args
62
+ if Helper.test?
63
+ Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] = File.join(absolute_dest_directory, 'test.ipa')
64
+ Actions.lane_context[SharedValues::DSYM_OUTPUT_PATH] = File.join(absolute_dest_directory, 'test.app.dSYM.zip')
65
+ return build_args
68
66
  end
69
67
 
70
68
  # Joins args into space delimited string
@@ -73,7 +71,7 @@ module Fastlane
73
71
  command = "ipa build #{build_args}"
74
72
  Helper.log.debug command
75
73
  Actions.sh command
76
-
74
+
77
75
  # Finds absolute path of IPA and dSYM
78
76
  absolute_ipa_path = find_ipa_file(absolute_dest_directory)
79
77
  absolute_dsym_path = find_dsym_file(absolute_dest_directory)
@@ -87,13 +85,13 @@ module Fastlane
87
85
 
88
86
  def self.params_to_build_args(params)
89
87
  # Remove nil value params unless :clean or :archive
90
- params = params.delete_if { |k, v| (k != :clean && k != :archive ) && v.nil? }
88
+ params = params.delete_if { |k, v| (k != :clean && k != :archive) && v.nil? }
91
89
 
92
90
  # Maps nice developer param names to Shenzhen's `ipa build` arguments
93
- params.collect do |k,v|
91
+ params.collect do |k, v|
94
92
  v ||= ''
95
93
  if args = ARGS_MAP[k]
96
- value = (v.to_s.length > 0 ? "\"#{v}\"" : "")
94
+ value = (v.to_s.length > 0 ? "\"#{v}\"" : '')
97
95
  "#{ARGS_MAP[k]} #{value}".strip
98
96
  end
99
97
  end.compact
@@ -101,15 +99,13 @@ module Fastlane
101
99
 
102
100
  def self.find_ipa_file(dir)
103
101
  # Finds last modified .ipa in the destination directory
104
- Dir[File.join(dir, "*.ipa")].sort { |a,b| File.mtime(b) <=> File.mtime(a) }.first
102
+ Dir[File.join(dir, '*.ipa')].sort { |a, b| File.mtime(b) <=> File.mtime(a) }.first
105
103
  end
106
104
 
107
105
  def self.find_dsym_file(dir)
108
106
  # Finds last modified .dSYM.zip in the destination directory
109
- Dir[File.join(dir, "*.dSYM.zip")].sort { |a,b| File.mtime(b) <=> File.mtime(a) }.first
107
+ Dir[File.join(dir, '*.dSYM.zip')].sort { |a, b| File.mtime(b) <=> File.mtime(a) }.first
110
108
  end
111
-
112
109
  end
113
-
114
110
  end
115
- end
111
+ end
@@ -7,29 +7,28 @@ module Fastlane
7
7
  class ProduceAction
8
8
  def self.run(params)
9
9
  require 'produce'
10
-
10
+
11
11
  hash = params.first || {}
12
- raise "Parameter of produce must be a hash".red unless hash.kind_of?Hash
12
+ raise 'Parameter of produce must be a hash'.red unless hash.is_a?(Hash)
13
13
 
14
14
  hash.each do |key, value|
15
15
  ENV[key.to_s.upcase] = value.to_s
16
16
  end
17
17
 
18
- return if Helper.is_test?
18
+ return if Helper.test?
19
19
 
20
20
  Dir.chdir(FastlaneFolder.path || Dir.pwd) do
21
21
  # This should be executed in the fastlane folder
22
-
22
+
23
23
  CredentialsManager::PasswordManager.shared_manager(ENV['PRODUCE_USERNAME']) if ENV['PRODUCE_USERNAME']
24
24
  Produce::Config.shared_config # to ask for missing information right in the beginning
25
-
26
- apple_id = Produce::Manager.start_producing.to_s
27
25
 
26
+ apple_id = Produce::Manager.start_producing.to_s
28
27
 
29
28
  Actions.lane_context[SharedValues::PRODUCE_APPLE_ID] = apple_id
30
- ENV["PRODUCE_APPLE_ID"] = apple_id
29
+ ENV['PRODUCE_APPLE_ID'] = apple_id
31
30
  end
32
31
  end
33
32
  end
34
33
  end
35
- end
34
+ end
@@ -7,4 +7,4 @@ module Fastlane
7
7
  end
8
8
  end
9
9
  end
10
- end
10
+ end
@@ -9,16 +9,16 @@ module Fastlane
9
9
  require 'sigh'
10
10
  require 'credentials_manager/appfile_config'
11
11
 
12
- type = Sigh::DeveloperCenter::APPSTORE
13
- type = Sigh::DeveloperCenter::ADHOC if params.include? :adhoc
14
- type = Sigh::DeveloperCenter::DEVELOPMENT if params.include? :development
15
-
16
- return type if Helper.is_test?
12
+ type = FastlaneCore::DeveloperCenter::APPSTORE
13
+ type = FastlaneCore::DeveloperCenter::ADHOC if params.include? :adhoc
14
+ type = FastlaneCore::DeveloperCenter::DEVELOPMENT if params.include? :development
15
+
16
+ return type if Helper.test?
17
17
 
18
18
  app = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
19
- raise "No app_identifier definied in `./fastlane/Appfile`".red unless app
19
+ raise 'No app_identifier definied in `./fastlane/Appfile`'.red unless app
20
20
 
21
- path = Sigh::DeveloperCenter.new.run(app, type)
21
+ path = FastlaneCore::DeveloperCenter.new.run(app, type)
22
22
  output_path = File.expand_path(File.join('.', File.basename(path)))
23
23
  FileUtils.mv(path, output_path)
24
24
  Helper.log.info "Exported provisioning profile to '#{output_path}'".green
@@ -1,7 +1,6 @@
1
1
  module Fastlane
2
2
  module Actions
3
3
  module SharedValues
4
-
5
4
  end
6
5
 
7
6
  class SlackAction
@@ -9,7 +8,7 @@ module Fastlane
9
8
  return ENV['GIT_BRANCH'] if ENV['GIT_BRANCH'].to_s.length > 0 # set by Jenkins
10
9
  s = `git rev-parse --abbrev-ref HEAD`
11
10
  return s if s.to_s.length > 0
12
- return nil
11
+ nil
13
12
  end
14
13
 
15
14
  def self.git_author
@@ -24,7 +23,7 @@ module Fastlane
24
23
  def self.last_git_commit
25
24
  s = `git log -1 --pretty=%B`.strip
26
25
  return s if s.to_s.length > 0
27
- return nil
26
+ nil
28
27
  end
29
28
 
30
29
  def self.run(params)
@@ -38,18 +37,18 @@ module Fastlane
38
37
  color = (options[:success] ? 'good' : 'danger')
39
38
  options[:message] = Slack::Notifier::LinkFormatter.format(options[:message])
40
39
 
41
- url = ENV["SLACK_URL"]
40
+ url = ENV['SLACK_URL']
42
41
  unless url
43
42
  Helper.log.fatal "Please add 'ENV[\"SLACK_URL\"] = \"https://hooks.slack.com/services/...\"' to your Fastfile's `before_all` section.".red
44
- raise "No SLACK_URL given.".red
43
+ raise 'No SLACK_URL given.'.red
45
44
  end
46
45
 
47
46
  notifier = Slack::Notifier.new url
48
47
 
49
48
  notifier.username = 'fastlane'
50
49
  if options[:channel].to_s.length > 0
51
- notifier.channel = options[:channel]
52
- notifier.channel = ('#' + notifier.channel) unless ["#", "@"].include?notifier.channel[0] # send message to channel by default
50
+ notifier.channel = options[:channel]
51
+ notifier.channel = ('#' + notifier.channel) unless ['#', '@'].include?(notifier.channel[0]) # send message to channel by default
53
52
  end
54
53
 
55
54
  test_result = {
@@ -58,13 +57,13 @@ module Fastlane
58
57
  color: color,
59
58
  fields: [
60
59
  {
61
- title: "Lane",
60
+ title: 'Lane',
62
61
  value: Actions.lane_context[Actions::SharedValues::LANE_NAME],
63
62
  short: true
64
63
  },
65
64
  {
66
- title: "Test Result",
67
- value: (options[:success] ? "Success" : "Error"),
65
+ title: 'Test Result',
66
+ value: (options[:success] ? 'Success' : 'Error'),
68
67
  short: true
69
68
  }
70
69
  ]
@@ -72,18 +71,18 @@ module Fastlane
72
71
 
73
72
  if git_branch
74
73
  test_result[:fields] << {
75
- title: "Git Branch",
74
+ title: 'Git Branch',
76
75
  value: git_branch,
77
76
  short: true
78
77
  }
79
78
  end
80
79
 
81
80
  if git_author
82
- if ENV["FASTLANE_SLACK_HIDE_AUTHOR_ON_SUCCESS"] and success
81
+ if ENV['FASTLANE_SLACK_HIDE_AUTHOR_ON_SUCCESS'] && success
83
82
  # We only show the git author if the build failed
84
83
  else
85
84
  test_result[:fields] << {
86
- title: "Git Author",
85
+ title: 'Git Author',
87
86
  value: git_author,
88
87
  short: true
89
88
  }
@@ -92,21 +91,21 @@ module Fastlane
92
91
 
93
92
  if last_git_commit
94
93
  test_result[:fields] << {
95
- title: "Git Commit",
94
+ title: 'Git Commit',
96
95
  value: last_git_commit,
97
96
  short: false
98
97
  }
99
98
  end
100
99
 
101
- result = notifier.ping "",
102
- icon_url: 'https://s3-eu-west-1.amazonaws.com/fastlane.tools/fastlane.png',
103
- attachments: [test_result]
100
+ result = notifier.ping '',
101
+ icon_url: 'https://s3-eu-west-1.amazonaws.com/fastlane.tools/fastlane.png',
102
+ attachments: [test_result]
104
103
 
105
104
  unless result.code.to_i == 200
106
105
  Helper.log.debug result
107
- raise "Error pushing Slack message, maybe the integration has no permission to post on this channel? Try removing the channel parameter in your Fastfile.".red
106
+ raise 'Error pushing Slack message, maybe the integration has no permission to post on this channel? Try removing the channel parameter in your Fastfile.'.red
108
107
  else
109
- Helper.log.info "Successfully sent Slack notification".green
108
+ Helper.log.info 'Successfully sent Slack notification'.green
110
109
  end
111
110
  end
112
111
  end