Class: Fastlane::Actions::AppliveryAction

Inherits:
Action
  • Object
show all
Defined in:
lib/fastlane/plugin/applivery/actions/applivery_action.rb

Constant Summary collapse

UPLOAD_PATH =
"/v1/integrations/builds".freeze
DEFAULT_TIMEOUT =

Default timeout for the whole upload request. Big builds on a slow network need way more than the 60 seconds Net::HTTP defaults to.

600

Class Method Summary collapse

Class Method Details

.authorsObject



123
124
125
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 123

def self.authors
  ["Applivery"]
end

.available_optionsObject



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 127

def self.available_options
  [
    FastlaneCore::ConfigItem.new(key: :app_token,
      env_name: "APPLIVERY_APP_TOKEN",
      description: "Your application identifier",
      optional: false,
      sensitive: true,
      type: String),

    FastlaneCore::ConfigItem.new(key: :name,
      env_name: "APPLIVERY_BUILD_NAME",
      description: "Your build name",
      optional: true,
      type: String),

    FastlaneCore::ConfigItem.new(key: :changelog,
      env_name: "APPLIVERY_BUILD_CHANGELOG",
      description: "Your build notes",
      default_value: "Uploaded automatically with fastlane plugin",
      optional: true,
      type: String),

    FastlaneCore::ConfigItem.new(key: :tags,
      env_name: "APPLIVERY_BUILD_TAGS",
      description: "Your build tags",
      optional: true,
      type: String),

    FastlaneCore::ConfigItem.new(key: :build_path,
      env_name: "APPLIVERY_BUILD_PATH",
      description: "Your build path",
      default_value: self.build_path,
      default_value_dynamic: true,
      optional: true,
      type: String),

    FastlaneCore::ConfigItem.new(key: :notify_collaborators,
      env_name: "APPLIVERY_NOTIFY_COLLABORATORS",
      description: "Send an email to your App Collaborators",
      default_value: true,
      optional: true,
      is_string: false),

    FastlaneCore::ConfigItem.new(key: :notify_employees,
      env_name: "APPLIVERY_NOTIFY_EMPLOYEES",
      description: "Send an email to your App Employees",
      default_value: true,
      optional: true,
      is_string: false),

    FastlaneCore::ConfigItem.new(key: :notify_message,
      env_name: "APPLIVERY_NOTIFY_MESSAGE",
      description: "Notification message to be sent along with email notifications",
      default_value: "New version uploaded!",
      optional: true,
      type: String),

    FastlaneCore::ConfigItem.new(key: :filter,
      env_name: "APPLIVERY_FILTER",
      description: "List of groups that will be notified",
      optional: true,
      type: String),

    FastlaneCore::ConfigItem.new(key: :tenant,
      env_name: "APPLIVERY_TENANT",
      description: "Your private tenant name or base domain",
      optional: true,
      type: String),

    FastlaneCore::ConfigItem.new(key: :timeout,
      env_name: "APPLIVERY_TIMEOUT",
      description: "Timeout in seconds for the upload request",
      default_value: DEFAULT_TIMEOUT,
      optional: true,
      type: Integer,
      verify_block: proc do |value|
        UI.user_error!("`timeout` must be greater than 0") unless value.to_i.positive?
      end)
  ]
end

.build_pathObject

Build generated by the previous step of the lane, if any.



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 99

def self.build_path
  platform = Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
  ipa_path = Actions.lane_context[SharedValues::IPA_OUTPUT_PATH]
  aab_path = Actions.lane_context[Actions::SharedValues::GRADLE_AAB_OUTPUT_PATH]
  apk_path = Actions.lane_context[Actions::SharedValues::GRADLE_APK_OUTPUT_PATH]

  return ipa_path if platform == :ios
  return aab_path unless aab_path.nil?
  return apk_path unless apk_path.nil?
  return ipa_path
end

.build_request_body(params, build_path) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 71

def self.build_request_body(params, build_path)
  request_body = {
    changelog: params[:changelog],
    notifyCollaborators: params[:notify_collaborators],
    notifyEmployees: params[:notify_employees],
    notifyMessage: params[:notify_message],
    filter: params[:filter],
    build: Helper::AppliveryHelper.file_part(build_path),
    deployer: {
      name: "fastlane",
      info: {
        buildNumber: Helper::AppliveryHelper.get_integration_number,
        branch: Helper::AppliveryHelper.git_branch,
        commit: Helper::AppliveryHelper.git_commit,
        commitMessage: Helper::AppliveryHelper.git_message,
        repositoryUrl: Helper::AppliveryHelper.add_git_remote,
        tag: Helper::AppliveryHelper.git_tag,
        triggerTimestamp: Time.now.getutc.to_i
      }
    }
  }
  request_body[:versionName] = params[:name] unless params[:name].nil?
  request_body[:tags] = params[:tags] unless params[:tags].nil?

  return request_body
end

.categoryObject



224
225
226
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 224

def self.category
  :beta
end

.descriptionObject



111
112
113
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 111

def self.description
  "Upload new iOS or Android build to Applivery"
end

.detailsObject



115
116
117
118
119
120
121
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 115

def self.details
  [
    "Uploads an IPA, APK or AAB file to Applivery and attaches the information of the current build:",
    "build number, git branch, commit, commit message, tag and repository URL.",
    "By default it takes the build generated by `gym` or `gradle` in the same lane."
  ].join(" ")
end

.example_codeObject



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 228

def self.example_code
  [
    'applivery(app_token: "YOUR_APP_TOKEN")',
    'applivery(
      app_token: "YOUR_APP_TOKEN",
      build_path: "./app/build/outputs/bundle/release/app-release.aab",
      name: "RC 1.0",
      changelog: "Bug fixing",
      tags: "RC1, QA",
      notify_collaborators: true,
      notify_employees: false,
      notify_message: "Enjoy the new version!",
      filter: "group1,group2|group3"
    )',
    'applivery(
      app_token: "YOUR_APP_TOKEN",
      tenant: "mycompany"
    )'
  ]
end

.handle_response(response) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 42

def self.handle_response(response)
  body = Helper::AppliveryHelper.parse_response_body(response)
  UI.verbose("Response Body: #{body}")

  if body["status"]
    UI.success("Build uploaded successfully! 💪")
    build_id = (body["data"] || {})["id"]
    Actions.lane_context[SharedValues::APPLIVERY_BUILD_ID] = build_id
    return build_id
  else
    UI.error("Oops! Something went wrong.... 🔥")
    Helper::AppliveryHelper.parse_error(body["error"], response.status)
  end
end

.is_supported?(platform) ⇒ Boolean

Returns:

  • (Boolean)


218
219
220
221
222
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 218

def self.is_supported?(platform)
  # The action uploads any IPA, APK or AAB file, so it also works when the
  # lane has no platform defined (for example with `fastlane run applivery`)
  true
end

.outputObject



208
209
210
211
212
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 208

def self.output
  [
    ['APPLIVERY_BUILD_ID', 'The id for the new build generated. You can open your build in https://dashboard.applivery.io/apps/apps/<YOUR_APP_SLUG>/builds?id=${APPLIVERY_BUILD_ID}']
  ]
end

.return_valueObject



214
215
216
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 214

def self.return_value
  "The id of the build created in Applivery"
end

.run(params) ⇒ Object



16
17
18
19
20
21
22
23
24
25
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 16

def self.run(params)
  build_path = validated_build_path(params[:build_path])
  request_body = build_request_body(params, build_path)
  connection = Helper::AppliveryHelper.upload_connection(params[:tenant], params[:timeout])

  UI.message("Uploading to Applivery... 🛫")
  response = upload(connection, request_body, params)

  handle_response(response)
end

.upload(connection, request_body, params) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 27

def self.upload(connection, request_body, params)
  connection.post do |req|
    req.url(UPLOAD_PATH)
    req.headers['Content-Type'] = 'multipart/form-data'
    req.headers['Accept'] = 'application/json'
    req.headers['Authorization'] = "bearer #{params[:app_token]}"
    req.body = request_body
    UI.verbose("Request Body: #{req.body}")
  end
rescue Faraday::TimeoutError
  UI.user_error!("Timed out while uploading the build to Applivery. You can increase the `timeout` option (currently #{params[:timeout] || DEFAULT_TIMEOUT} seconds) and try again")
rescue Faraday::ConnectionFailed => e
  UI.user_error!("Could not connect to Applivery: #{e.message}. Please check your network connection#{params[:tenant] ? " and the `tenant` option (#{params[:tenant]})" : ''}")
end

.validated_build_path(build_path) ⇒ Object

Fails early with an actionable message instead of uploading an empty request and letting the API reject it.



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/fastlane/plugin/applivery/actions/applivery_action.rb', line 59

def self.validated_build_path(build_path)
  build_path = build_path.to_s.strip
  if build_path.empty?
    UI.user_error!("No build to upload. Please set the `build_path` option (or the APPLIVERY_BUILD_PATH environment variable) with the path to your IPA, APK or AAB file")
  end
  unless File.file?(build_path)
    UI.user_error!("Build not found at '#{build_path}'. Please double-check the `build_path` option")
  end

  return build_path
end