Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
efc3e66
Add `prototype_build_details_comment` action
AliSoftware Feb 1, 2023
13116a9
Add CHANGELOG entry
AliSoftware Feb 1, 2023
0af1b8f
Don't wrap arbitrary metadata in `<tt>` tags
AliSoftware Feb 1, 2023
57d2e44
Add ability to hide the table behind `<details>`
AliSoftware Feb 1, 2023
9946b4a
Add ability to provide a direct download link
AliSoftware Feb 1, 2023
11a277a
Fix `<details>` block rendering/syntax
AliSoftware Feb 1, 2023
c7ed840
Shake up some tests to vary tested cases more
AliSoftware Feb 1, 2023
9a54428
Refine table key names
AliSoftware Feb 1, 2023
935b1e0
Shorten Intro text
AliSoftware Feb 1, 2023
ff25e36
Provide additional doc for appcenter_release_id
AliSoftware Feb 1, 2023
2d5d7fd
Improve wording on action description
AliSoftware Feb 3, 2023
d214c33
Typo on spec name
AliSoftware Feb 3, 2023
4204a45
s/<strong>/<b>/
AliSoftware Feb 3, 2023
911d71b
s/<tt>/<code>/
AliSoftware Feb 3, 2023
854098f
Add comment on the Buildkite-specificity of env var used by the `:com…
AliSoftware Feb 3, 2023
e275603
Remove <code> around app name and commit
AliSoftware Feb 7, 2023
1d99383
Refactor the action to auto-extract most of the info
AliSoftware Feb 7, 2023
6e4b3d7
Fix existing tests
AliSoftware Feb 8, 2023
0940a6b
Improving tests, pass 1
AliSoftware Feb 8, 2023
2c3c4b0
Improving tests, pass 2
AliSoftware Feb 9, 2023
9255053
Split code in helpers to reduce complexity
AliSoftware Feb 9, 2023
3f28db7
Refactoring to split code in more separate methods
AliSoftware Feb 9, 2023
f1f93ca
Improve description for `app_icon` parameter
AliSoftware Feb 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

- Add new `buildkite_annotate` action to add/remove annotations from the current build. [#442]
- Add new `buildkite_metadata` action to set/get metadata from the current build. [#442]
- Add new `prototype_build_details_comment` action to make it easier to generate the HTML comment about Prototype Builds in PRs. [#449]

### Bug Fixes

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
module Fastlane
module Actions
class PrototypeBuildDetailsCommentAction < Action
def self.run(params)
# Get Input Parameters
appcenter_org_name = params[:appcenter_org_name]
appcenter_app_name = params[:appcenter_app_name]
appcenter_release_id = params[:appcenter_release_id]
commit = params[:commit] || other_action.last_git_commit[:abbreviated_commit_hash]

metadata = params[:metadata] # e.g. {'Build Config':… , 'Version': …, 'Short Version': …}
direct_link = params[:download_url]
unless direct_link.nil?
metadata['Direct Link'] = "<a href='#{direct_link}'><tt>#{File.basename(direct_link)}</tt></a>"
end

# Build the comment parts
install_url = "https://install.appcenter.ms/orgs/#{appcenter_org_name}/apps/#{appcenter_app_name}/releases/#{appcenter_release_id}"
qr_code_url = "https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=#{CGI.escape(install_url)}&choe=UTF-8"
metadata_rows = metadata.compact.map do |key, value|
"<tr><td><b>#{key}</b></td><td>#{value}</td></tr>"
end

intro = "📲 You can test the changes from this Pull Request in <strong>#{appcenter_app_name}</strong> by scanning the QR code below to install the corresponding build via App Center."
body = <<~COMMENT_BODY
<table>
<tr>
<td rowspan='#{metadata.count + 3}'><img src='#{qr_code_url}' width='250' height='250' /></td>
<td width='150px'><b>App Name</b></td><td><tt>#{appcenter_app_name}</tt></td>
</tr>
#{metadata_rows.join("\n")}
<tr><td><b>App Center Build</b></td><td><a href='#{install_url}'>Build \##{appcenter_release_id}</a></td></tr>
<tr><td><b>Commit</b></td><td><tt>#{commit}</tt></td></tr>
</table>
#{params[:footnote]}
COMMENT_BODY

if params[:fold]
"<details><summary>#{intro}</summary>\n#{body}</details>\n"
else
"<p>#{intro}</p>\n#{body}"
end
end

#####################################################
# @!group Documentation
#####################################################

def self.description
'Generates the nicely-formatted string providing all the details of a prototype build, ready to be used as a PR comment (e.g. via `comment_on_pr`).'
end

def self.available_options
[
FastlaneCore::ConfigItem.new(
key: :appcenter_org_name,
env_name: 'APPCENTER_OWNER_NAME', # Same as the one used by the `appcenter_upload` action
description: 'The name of the organization in App Center',
type: String
),
FastlaneCore::ConfigItem.new(
key: :appcenter_app_name,
env_name: 'APPCENTER_APP_NAME', # Same as the one used by the `appcenter_upload` action
description: 'The name of the app in App Center',
type: String
),
FastlaneCore::ConfigItem.new(
key: :appcenter_release_id,
env_name: 'FL_PROTOTYPE_BUILD_APPCENTER_RELEASE_ID',
description: "The release ID/Number in App Center; can be obtained using `lane_context[SharedValues::APPCENTER_BUILD_INFORMATION]['id']`",
type: Integer
),
FastlaneCore::ConfigItem.new(
key: :download_url,
env_name: 'FL_PROTOTYPE_BUILD_DOWNLOAD_URL',
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',
type: String,
optional: true,
default_value: nil
),
FastlaneCore::ConfigItem.new(
key: :fold,
env_name: 'FL_PROTOTYPE_BUILD_DETAILS_COMMENT_FOLD',
description: 'If true, will wrap the HTML table inside a <details> block (hidden by default)',
type: Boolean,
default_value: false
),
FastlaneCore::ConfigItem.new(
key: :metadata,
env_name: 'FL_PROTOTYPE_BUILD_DETAILS_COMMENT_METADATA',
description: 'All additional metadata (as key/value pairs) you want to include in the HTML table of the comment',
type: Hash,
optional: true,
default_value: {}
),
FastlaneCore::ConfigItem.new(
key: :footnote,
env_name: 'FL_PROTOTYPE_BUILD_DETAILS_COMMENT_FOOTNOTE',
description: 'Optional footnote to add below the HTML table of the comment',
type: String,
default_value: '<em>Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.</em>'
),
FastlaneCore::ConfigItem.new(
key: :commit,
env_name: 'BUILDKITE_COMMIT',
description: 'The commit this prototype build was build from; usually not passed explicitly, but derived from the environment variable instead',
type: String,
optional: true
),
]
end

def self.return_type
:string
end

def self.return_value
'The HTML comment containing all the relevant info about a Prototype build published to App Center'
end

def self.authors
['Automattic']
end

def self.is_supported?(platform)
true
end
end
end
end
173 changes: 173 additions & 0 deletions spec/prototype_build_details_comment_action_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
require_relative './spec_helper'

describe Fastlane::Actions::PrototypeBuildDetailsCommentAction do
before do
ENV['APPCENTER_OWNER_NAME'] = 'My-Org'
ENV['BUILDKITE_COMMIT'] = 'a1b2c3f'
end

describe 'expected info is included' do
it 'generates the proper AppCenter link and QR code given an org, app name and release ID' do
comment = run_described_fastlane_action(
appcenter_app_name: 'MyApp',
appcenter_release_id: 1337
)
expect(comment).to include "<a href='https://install.appcenter.ms/orgs/My-Org/apps/MyApp/releases/1337'>Build #1337</a>"
expect(comment).to include 'https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=https%3A%2F%2Finstall.appcenter.ms%2Forgs%2FMy-Org%2Fapps%2FMyApp%2Freleases%2F1337&choe=UTF-8'
end

it 'includes the commit as part of the default rows' do
comment = run_described_fastlane_action(
appcenter_app_name: 'MyApp',
appcenter_release_id: 1337
)
expect(comment).to include '<td><b>Commit</b></td><td><tt>a1b2c3f</tt></td>'
end

it 'correctly includes additional metadata when some are provided' do
metadata = {
'Version:Short': '28.1',
'Version:Long': '281003',
'Build Config': 'Prototype'
}
comment = run_described_fastlane_action(
appcenter_app_name: 'MyApp',
appcenter_release_id: 1337,
metadata: metadata
)
expect(comment).to include "<td rowspan='6'>"
expect(comment).to include '<td><b>Version:Short</b></td><td>28.1</td>'
expect(comment).to include '<td><b>Version:Long</b></td><td>281003</td>'
expect(comment).to include '<td><b>Build Config</b></td><td>Prototype</td>'
end

it 'includes the direct link if one is provided' do
comment = run_described_fastlane_action(
appcenter_app_name: 'MyApp',
appcenter_release_id: 1337,
download_url: 'https://foo.cloudfront.net/someuuid/myapp-prototype-build-pr1337-a1b2c3f.apk'
)
expect(comment).to include "<td rowspan='4'>"
expect(comment).to include "<td><b>Direct Link</b></td><td><a href='https://foo.cloudfront.net/someuuid/myapp-prototype-build-pr1337-a1b2c3f.apk'><tt>myapp-prototype-build-pr1337-a1b2c3f.apk</tt></a></td>"
end

it 'includes the default footnote by default' do
comment = run_described_fastlane_action(
appcenter_org_name: 'BestOrg',
appcenter_app_name: 'MyApp',
appcenter_release_id: 1337
)
expect(comment).to include '<em>Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.</em>'
end

it 'includes the provided footnote if any' do
comment = run_described_fastlane_action(
appcenter_app_name: 'MyApp',
appcenter_release_id: 1337,
footnote: '<em>Note that Google Sign-In in not available in those builds</em>'
)
expect(comment).to include '<em>Note that Google Sign-In in not available in those builds</em>'
end
end

describe 'full comment' do
it 'generates a standard HTML table comment by default, with all the information provided' do
metadata = {
'Version:Short': '28.2',
'Version:Long': '28.2.0.108',
Flavor: 'Celray'
}

comment = run_described_fastlane_action(
appcenter_org_name: 'BestOrg',
appcenter_app_name: 'BestApp',
appcenter_release_id: 8888,
metadata: metadata,
footnote: '<em>Note: Google Sign-In in not available in those builds</em>'
)

expect(comment).to eq <<~EXPECTED_COMMENT
<p>📲 You can test the changes from this Pull Request in <strong>BestApp</strong> by scanning the QR code below to install the corresponding build via App Center.</p>
<table>
<tr>
<td rowspan='6'><img src='https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=https%3A%2F%2Finstall.appcenter.ms%2Forgs%2FBestOrg%2Fapps%2FBestApp%2Freleases%2F8888&choe=UTF-8' width='250' height='250' /></td>
<td width='150px'><b>App Name</b></td><td><tt>BestApp</tt></td>
</tr>
<tr><td><b>Version:Short</b></td><td>28.2</td></tr>
<tr><td><b>Version:Long</b></td><td>28.2.0.108</td></tr>
<tr><td><b>Flavor</b></td><td>Celray</td></tr>
<tr><td><b>App Center Build</b></td><td><a href='https://install.appcenter.ms/orgs/BestOrg/apps/BestApp/releases/8888'>Build \#8888</a></td></tr>
<tr><td><b>Commit</b></td><td><tt>a1b2c3f</tt></td></tr>
</table>
<em>Note: Google Sign-In in not available in those builds</em>
EXPECTED_COMMENT
end

it 'generates a HTML table comment including the direct link if provided' do
metadata = {
'Version:Short': '28.2',
'Version:Long': '28.2.0.108'
}

comment = run_described_fastlane_action(
appcenter_org_name: 'BestOrg',
appcenter_app_name: 'BestApp',
appcenter_release_id: 8888,
download_url: 'https://bestfront.cloudfront.net/feed42/bestapp-pr1357-a1b2c3f.apk',
metadata: metadata
)

expect(comment).to eq <<~EXPECTED_COMMENT
<p>📲 You can test the changes from this Pull Request in <strong>BestApp</strong> by scanning the QR code below to install the corresponding build via App Center.</p>
<table>
<tr>
<td rowspan='6'><img src='https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=https%3A%2F%2Finstall.appcenter.ms%2Forgs%2FBestOrg%2Fapps%2FBestApp%2Freleases%2F8888&choe=UTF-8' width='250' height='250' /></td>
<td width='150px'><b>App Name</b></td><td><tt>BestApp</tt></td>
</tr>
<tr><td><b>Version:Short</b></td><td>28.2</td></tr>
<tr><td><b>Version:Long</b></td><td>28.2.0.108</td></tr>
<tr><td><b>Direct Link</b></td><td><a href='https://bestfront.cloudfront.net/feed42/bestapp-pr1357-a1b2c3f.apk'><tt>bestapp-pr1357-a1b2c3f.apk</tt></a></td></tr>
<tr><td><b>App Center Build</b></td><td><a href='https://install.appcenter.ms/orgs/BestOrg/apps/BestApp/releases/8888'>Build \#8888</a></td></tr>
<tr><td><b>Commit</b></td><td><tt>a1b2c3f</tt></td></tr>
</table>
<em>Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.</em>
EXPECTED_COMMENT
end

it 'generates a HTML table in a spoiler block if fold is true' do
metadata = {
'Version:Short': '28.2',
'Version:Long': '28.2.0.108',
Flavor: 'Celray',
Configuration: 'Debug'
}

comment = run_described_fastlane_action(
appcenter_org_name: 'BestOrg',
appcenter_app_name: 'BestApp',
appcenter_release_id: 1234,
fold: true,
metadata: metadata,
footnote: '<em>Note: Google Sign-In in not available in those builds</em>'
)

expect(comment).to eq <<~EXPECTED_COMMENT
<details><summary>📲 You can test the changes from this Pull Request in <strong>BestApp</strong> by scanning the QR code below to install the corresponding build via App Center.</summary>
<table>
<tr>
<td rowspan='7'><img src='https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=https%3A%2F%2Finstall.appcenter.ms%2Forgs%2FBestOrg%2Fapps%2FBestApp%2Freleases%2F1234&choe=UTF-8' width='250' height='250' /></td>
<td width='150px'><b>App Name</b></td><td><tt>BestApp</tt></td>
</tr>
<tr><td><b>Version:Short</b></td><td>28.2</td></tr>
<tr><td><b>Version:Long</b></td><td>28.2.0.108</td></tr>
<tr><td><b>Flavor</b></td><td>Celray</td></tr>
<tr><td><b>Configuration</b></td><td>Debug</td></tr>
<tr><td><b>App Center Build</b></td><td><a href='https://install.appcenter.ms/orgs/BestOrg/apps/BestApp/releases/1234'>Build \#1234</a></td></tr>
<tr><td><b>Commit</b></td><td><tt>a1b2c3f</tt></td></tr>
</table>
<em>Note: Google Sign-In in not available in those builds</em>
</details>
EXPECTED_COMMENT
end
end
end