Skip to content

Commit 1d99383

Browse files
committed
Refactor the action to auto-extract most of the info
From values provided in the `lane_context` by the `appcenter_upload` action – if it was used to distribute the Prototype build
1 parent e275603 commit 1d99383

File tree

1 file changed

+122
-48
lines changed

1 file changed

+122
-48
lines changed

lib/fastlane/plugin/wpmreleasetoolkit/actions/common/prototype_build_details_comment_action.rb

Lines changed: 122 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,49 @@ module Fastlane
22
module Actions
33
class PrototypeBuildDetailsCommentAction < Action
44
def self.run(params)
5-
# Get Input Parameters
6-
appcenter_org_name = params[:appcenter_org_name]
7-
appcenter_app_name = params[:appcenter_app_name]
8-
appcenter_release_id = params[:appcenter_release_id]
9-
commit = params[:commit] || other_action.last_git_commit[:abbreviated_commit_hash]
10-
11-
metadata = params[:metadata] # e.g. {'Build Config':… , 'Version': …, 'Short Version': …}
12-
direct_link = params[:download_url]
13-
unless direct_link.nil?
14-
metadata['Direct Link'] = "<a href='#{direct_link}'><code>#{File.basename(direct_link)}</code></a>"
15-
end
5+
app_display_name = params[:app_display_name]
166

17-
# Build the comment parts
18-
install_url = "https://install.appcenter.ms/orgs/#{appcenter_org_name}/apps/#{appcenter_app_name}/releases/#{appcenter_release_id}"
19-
qr_code_url = "https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=#{CGI.escape(install_url)}&choe=UTF-8"
20-
metadata_rows = metadata.compact.map do |key, value|
21-
"<tr><td><b>#{key}</b></td><td>#{value}</td></tr>"
7+
app_center_org_name = params[:app_center_org_name]
8+
app_center_info = app_center_org_name.nil? ? {} : lane_context[SharedValues::APPCENTER_BUILD_INFORMATION] || {}
9+
app_center_app_name = params[:app_center_app_name] || app_center_info['app_name']
10+
app_center_app_display_name = app_center_info['app_display_name'] || app_center_app_name
11+
app_center_release_id = params[:app_center_release_id] || app_center_info['id']
12+
13+
# Consolidate the list of Metadata to display with some implicit metadata if available
14+
metadata = params[:metadata] || {}
15+
metadata['Build Number'] ||= app_center_info['version']
16+
metadata['Version'] ||= app_center_info['short_version']
17+
metadata[app_center_info['app_os'] == 'Android' ? 'Application ID' : 'Bundle ID'] = app_center_info['bundle_identifier']
18+
# (Feel free to add more CI-specific env vars in the line below to support other CI providers if you need)
19+
metadata['Commit'] ||= ENV.fetch('BUILDKITE_COMMIT', nil) || other_action.last_git_commit[:abbreviated_commit_hash]
20+
21+
# Installation Link(s) -- either download_url param, or App Center Build link, or both
22+
install_url = nil
23+
if params[:download_url]
24+
install_url = params[:download_url]
25+
metadata['Direct Download'] = "<a href='#{install_url}'><code>#{File.basename(install_url)}</code></a>"
2226
end
27+
if app_center_org_name && app_center_app_name
28+
install_url = "https://install.appcenter.ms/orgs/#{app_center_org_name}/apps/#{app_center_app_name}/releases/#{app_center_release_id}"
29+
metadata['App Center Build'] = "<a href='#{install_url}'>#{app_center_app_display_name} \##{app_center_release_id}</a>"
30+
end
31+
UI.user_error!(NO_INSTALL_URL_ERROR_MESSAGE) if install_url.nil?
32+
qr_code_url = "https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=#{CGI.escape(install_url)}&choe=UTF-8"
2333

24-
intro = "📲 You can test the changes from this Pull Request in <b>#{appcenter_app_name}</b> by scanning the QR code below to install the corresponding build via App Center."
34+
# Build the comment parts
35+
icon_img_tag = img_tag(params[:app_icon] || app_center_info['app_icon_url'], alt: app_display_name)
36+
metadata_rows = metadata.compact.map { |key, value| "<tr><td><b>#{key}</b></td><td>#{value}</td></tr>" }
37+
intro = "#{icon_img_tag}📲 You can test the changes from this Pull Request in <b>#{app_display_name}</b> by scanning the QR code below to install the corresponding build."
38+
footnote = params[:footnote] || (app_center_info.nil? ? '' : '<em>Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.</em>')
2539
body = <<~COMMENT_BODY
2640
<table>
2741
<tr>
28-
<td rowspan='#{metadata.count + 3}'><img src='#{qr_code_url}' width='250' height='250' /></td>
29-
<td width='150px'><b>App Name</b></td><td>#{appcenter_app_name}</td>
42+
<td rowspan='#{metadata.count + 1}' width='260px'><img src='#{qr_code_url}' width='250' height='250' /></td>
43+
<td width='150px'><b>App Name</b></td><td>#{icon_img_tag} #{app_display_name}</td>
3044
</tr>
3145
#{metadata_rows.join("\n")}
32-
<tr><td><b>App Center Build</b></td><td><a href='#{install_url}'>Build \##{appcenter_release_id}</a></td></tr>
33-
<tr><td><b>Commit</b></td><td>#{commit}</td></tr>
3446
</table>
35-
#{params[:footnote]}
47+
#{footnote}
3648
COMMENT_BODY
3749

3850
if params[:fold]
@@ -42,6 +54,28 @@ def self.run(params)
4254
end
4355
end
4456

57+
#####################################################
58+
# @!group Helpers
59+
#####################################################
60+
61+
NO_INSTALL_URL_ERROR_MESSAGE = <<~NO_URL_ERROR.freeze
62+
No URL provided to download or install the app.
63+
- Either use this action right after using `appcenter_upload` and provide an `app_center_org_name` (so that this action can use the link to the App Center build)
64+
- Or provide an explicit value for the `download_url` parameter
65+
NO_URL_ERROR
66+
67+
def self.img_tag(url_or_emoji, alt: '')
68+
return nil if url_or_emoji.nil?
69+
70+
emoji = url_or_emoji.match(/:(.*):/)&.captures&.first
71+
app_icon_url = if emoji
72+
"https://raw.githubusercontent.com/buildkite/emojis/main/img-buildkite-64/#{emoji}.png"
73+
elsif URI(url_or_emoji)
74+
url_or_emoji
75+
end
76+
app_icon_url ? "<img alt='#{alt}' align='top' src='#{app_icon_url}' width='20px' />" : ''
77+
end
78+
4579
#####################################################
4680
# @!group Documentation
4781
#####################################################
@@ -50,30 +84,75 @@ def self.description
5084
'Generates a string providing all the details of a prototype build, nicely-formatted and ready to be used as a PR comment (e.g. via `comment_on_pr`).'
5185
end
5286

87+
def self.details
88+
<<~DESC
89+
Generates a string providing all the details of a prototype build, nicely-formatted as HTML.
90+
The returned string will typically be subsequently used by the `comment_on_pr` action to post that HTML as comment on a PR.
91+
92+
If you used the `appcenter_upload` lane (to upload the Prototype build to App Center) before calling this action, and pass
93+
a value to the `app_center_org_name` parameter, then many of the parameters and metadata will be automatically extracted
94+
from the `lane_context` provided by `appcenter_upload`, including:
95+
96+
- The `app_center_app_name`, `app_center_release_id` and installation URL to use for the QR code to point to that release in App Center
97+
- The `app_icon`
98+
- The app's Build Number / versionCode
99+
- The app's Version / versionName
100+
- The app's Bundle ID / Application ID
101+
- A `footnote` mentioning the MC tool for Automatticians to add themselves to App Center
102+
103+
This means that if you are using App Center to distribute your Prototype Build, the only parameters you *have* to provide
104+
to this action are `app_display_name` and `app_center_org_name`; plus, for `metadata` most of the interesting values will already be pre-filled.
105+
106+
Any of those implicit default values/metadata can of course be overridden by passing an explicit value to the appropriate parameter(s).
107+
DESC
108+
end
109+
53110
def self.available_options
111+
app_center_auto = '(will be automatically extracted from `lane_context if you used `appcenter_upload` to distribute your Prototype build)'
54112
[
55113
FastlaneCore::ConfigItem.new(
56-
key: :appcenter_org_name,
57-
env_name: 'APPCENTER_OWNER_NAME', # Same as the one used by the `appcenter_upload` action
58-
description: 'The name of the organization in App Center',
114+
key: :app_display_name,
115+
env_name: 'FL_PROTOTYPE_BUILD_DETAILS_COMMENT_APP_DISPLAY_NAME',
116+
description: 'The display name to use for the app in the comment message',
117+
optional: false,
59118
type: String
60119
),
61120
FastlaneCore::ConfigItem.new(
62-
key: :appcenter_app_name,
63-
env_name: 'APPCENTER_APP_NAME', # Same as the one used by the `appcenter_upload` action
64-
description: 'The name of the app in App Center',
65-
type: String
121+
key: :app_center_org_name,
122+
env_name: 'APPCENTER_OWNER_NAME', # Intentionally the same as the one used by the `appcenter_upload` action
123+
description: 'The name of the organization in App Center (if you used `appcenter_upload` to distribute your Prototype build)',
124+
type: String,
125+
optional: true
126+
),
127+
FastlaneCore::ConfigItem.new(
128+
key: :app_center_app_name,
129+
env_name: 'APPCENTER_APP_NAME', # Intentionally the same as the one used by the `appcenter_upload` action
130+
description: "The name of the app in App Center #{app_center_auto}",
131+
type: String,
132+
optional: true,
133+
default_value_dynamic: true # As it will be extracted from the `lane_context`` if you used `appcenter_upload``
66134
),
67135
FastlaneCore::ConfigItem.new(
68-
key: :appcenter_release_id,
69-
env_name: 'FL_PROTOTYPE_BUILD_APPCENTER_RELEASE_ID',
70-
description: "The release ID/Number in App Center; can be obtained using `lane_context[SharedValues::APPCENTER_BUILD_INFORMATION]['id']`",
71-
type: Integer
136+
key: :app_center_release_id,
137+
env_name: 'APPCENTER_RELEASE_ID',
138+
description: "The release ID/Number in App Center #{app_center_auto}",
139+
type: String,
140+
optional: true,
141+
default_value_dynamic: true # As it will be extracted from the `lane_context`` if you used `appcenter_upload``
142+
),
143+
FastlaneCore::ConfigItem.new(
144+
key: :app_icon,
145+
env_name: 'FL_PROTOTYPE_BUILD_DETAILS_COMMENT_APP_ICON',
146+
description: "An `:emojicode:` or URL to use for the icon of the app in the message. #{app_center_auto}",
147+
type: String,
148+
optional: true,
149+
default_value_dynamic: true # As it will be extracted from the `lane_context`` if you used `appcenter_upload``
72150
),
73151
FastlaneCore::ConfigItem.new(
74152
key: :download_url,
75-
env_name: 'FL_PROTOTYPE_BUILD_DOWNLOAD_URL',
76-
description: 'The URL to download the build directly; e.g. a public link to the `.apk` file; you might use `lane_context[SharedValues::APPCENTER_DOWNLOAD_LINK]` for this for example',
153+
env_name: 'FL_PROTOTYPE_BUILD_DETAILS_COMMENT_DOWNLOAD_URL',
154+
description: 'The URL to download the build as a direct download. ' \
155+
+ 'If you uploaded the build to App Center, we recommend leaving this nil (the comment will use the URL to the App Center build for the QR code)',
77156
type: String,
78157
optional: true,
79158
default_value: nil
@@ -88,25 +167,20 @@ def self.available_options
88167
FastlaneCore::ConfigItem.new(
89168
key: :metadata,
90169
env_name: 'FL_PROTOTYPE_BUILD_DETAILS_COMMENT_METADATA',
91-
description: 'All additional metadata (as key/value pairs) you want to include in the HTML table of the comment',
170+
description: 'All additional metadata (as key/value pairs) you want to include in the HTML table of the comment. ' \
171+
+ 'If you are running this action after `appcenter_upload`, some metadata will automatically be added to this list too',
92172
type: Hash,
93173
optional: true,
94-
default_value: {}
174+
default_value_dynamic: true # As some metadata will be auto-filled if you used `appcenter_upload`
95175
),
96176
FastlaneCore::ConfigItem.new(
97177
key: :footnote,
98178
env_name: 'FL_PROTOTYPE_BUILD_DETAILS_COMMENT_FOOTNOTE',
99-
description: 'Optional footnote to add below the HTML table of the comment',
179+
description: 'Optional footnote to add below the HTML table of the comment. ' \
180+
+ 'If you are running this action after `appcenter_upload`, a default footnote for Automatticians will be used unless you provide an explicit value',
100181
type: String,
101-
default_value: '<em>Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.</em>'
102-
),
103-
FastlaneCore::ConfigItem.new(
104-
key: :commit,
105-
# Buildkite ENV var: https://buildkite.com/docs/pipelines/environment-variables#BUILDKITE_COMMIT
106-
env_names: ['BUILDKITE_COMMIT'], # Feel free to add more CI-specific env vars for other CI providers
107-
description: 'The commit this prototype build was build from; usually not passed explicitly, but derived from the environment variable instead',
108-
type: String,
109-
optional: true
182+
optional: true,
183+
default_value_dynamic: true # We have a default footnote for the case when you used App Center
110184
),
111185
]
112186
end
@@ -116,7 +190,7 @@ def self.return_type
116190
end
117191

118192
def self.return_value
119-
'The HTML comment containing all the relevant info about a Prototype build published to App Center'
193+
'The HTML comment containing all the relevant info about a Prototype build and links to install it'
120194
end
121195

122196
def self.authors

0 commit comments

Comments
 (0)