fastlane-plugin-firebase_test_lab_android 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8703f0c3e4487ecd05516d8e1104a7d341068f87
4
- data.tar.gz: 2337373ee1df4b4aa368372769e1583489c74c57
2
+ SHA256:
3
+ metadata.gz: 705bbfe9626de801abd2169fca83b037ae71c7bc9fd5d5300958a08b79c5fff9
4
+ data.tar.gz: 3009df47e1a59d09685831273daff5bf910cbea7ed106c0c412655b0fa1e56ba
5
5
  SHA512:
6
- metadata.gz: ff4d07eacfec1045c78398479c1f4cdd90359d92191a481a27fc41fb00d873457e7d1698d6a14ef6f5be25d1e35fc81c74ad00bf70386beec3f868dbf9be63c9
7
- data.tar.gz: d8841242fa07b00aef2e2a5417c5e4a8ec9dc80fd6475c8b51e4f99d6e48e68003d2f0b71cdf7ce9a52c2787623a4dd2db16660bc7b3efe3e40604a769849b9f
6
+ metadata.gz: 655cb13fd7ea93470302b3d085bcbcc843ec092e8843eed59b6588c062321adf07db8193e3100130d985dfd6fb3181c609fd7d5472b7f230c43200537dfc5759
7
+ data.tar.gz: 4338095159fc6dcdf6ba7f7250ae9c676ce2f6f7a1fc354d8dc582988bd82d0c9865a289ff1f95cf0a461e9eb9edf5c032426749fcd538131efe1c573ccf7e2f
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018 Pink Room
3
+ Copyright (c) 2019 CyberAgent, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Firebase Test Lab plugin for fastlane
2
2
 
3
3
  <p align="center">
4
- <img src="./art/firebase-test-lab.jpg" width="600" />
4
+ <img src="art/screenshot_github.png" width="75%" />
5
5
  </p>
6
6
 
7
7
  Inspired by [Firebase test lab plugin for ios](https://github.com/fastlane/fastlane-plugin-firebase_test_lab)
@@ -9,41 +9,106 @@ Inspired by [Firebase test lab plugin for ios](https://github.com/fastlane/fastl
9
9
 
10
10
  ## Getting Started
11
11
 
12
+ [![License](https://img.shields.io/github/license/cats-oss/fastlane-plugin-firebase_test_lab_android.svg)](https://github.com/cats-oss/fastlane-plugin-firebase_test_lab_android/blob/master/LICENSE)
13
+ [![Gem](https://img.shields.io/gem/v/fastlane-plugin-firebase_test_lab_android.svg?style=flat)](https://rubygems.org/gems/fastlane-plugin-firebase_test_lab_android)
14
+ [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-firebase_test_lab_android)
15
+
16
+ ### Step 1. First of all, get started with Firebase Test Lab from the gcloud Command Line
17
+
18
+ Please check [Firebase documents](https://firebase.google.com/docs/test-lab/android/command-line)
19
+
20
+ Using with Google Cloud SDK.
21
+ ```
22
+ # gcloud firebase test android run \
23
+ --type robo \
24
+ --app app-debug-unaligned.apk \
25
+ --device model=Nexus6,version=24,locale=en,orientation=portrait \
26
+ --timeout 90s
27
+
28
+ Have questions, feedback, or issues? Get support by visiting:
29
+ https://firebase.google.com/support/
30
+
31
+ API [toolresults.googleapis.com] not enabled on project
32
+ [************]. Would you like to enable and retry (this will take a
33
+ few minutes)? (y/N)? y
34
+
35
+ Enabling service [toolresults.googleapis.com] on project [************]...
36
+ Operation "operations/acf.********-****-****-****-************" finished successfully.
37
+ ...
38
+ ...
39
+ ...
40
+
41
+ Robo testing complete.
42
+
43
+ More details are available at [https://console.firebase.google.com/project/*******/testlab/histories/**********/matrices/********].
44
+ ┌─────────┬───────────────────────┬──────────────┐
45
+ │ OUTCOME │ TEST_AXIS_VALUE │ TEST_DETAILS │
46
+ ├─────────┼───────────────────────┼──────────────┤
47
+ │ Passed │ Nexus6-24-en-portrait │ -- │
48
+ └─────────┴───────────────────────┴──────────────┘
49
+ ```
50
+
51
+ ### Step 2. Add to your project
12
52
  This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-firebase_test_lab_android`, add it to your project by running:
13
53
 
14
- ```bash
15
- (not yet)
54
+ ```
16
55
  fastlane add_plugin firebase_test_lab_android
17
56
  ```
18
57
 
19
- ### If you are not current user of Firebase
58
+ ### Step 3. Create a GCS bucket
59
+
60
+ [Creating storage buckets](https://cloud.google.com/storage/docs/creating-buckets)
61
+
62
+ You will need the bucket name later in the Fastfile.
63
+
64
+ If you using the `gsutil`.
65
+ ```s
66
+ gsutil mb gs://[BUCKET_NAME]/
67
+ ```
68
+ ```
69
+ # gsutil mb gs://firebase_cats_test_bucket
70
+ Creating gs://firebase_cats_test_bucket/...
71
+ ```
72
+
20
73
 
21
- You need to set up Firebase first. These only needs to be done once for an organization.
74
+ ### Step 4. Import existing Google Cloud Storage buckets to Firebase Storage
22
75
 
23
- - If you have not used Google Cloud before, you need to [create a new Google Cloud project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#Creating%20a%20Project) first.
24
- - Go to the [Firebase Console](https://console.firebase.google.com/). Add Firebase into your Google Cloud project by clicking on "Add project" and then choose your just-created project.
76
+ https://firebase.google.com/docs/storage
25
77
 
26
- ### Configure Google credentials through service accounts
78
+ Import GCS bucket on Firebase console at Storage.
27
79
 
28
- To authenticate, Google Cloud credentials will need to be set for any machine where _fastlane_ and this plugin runs on.
80
+ <img src="art/screenshot_firebase_storage_setup_bucket.png" width="75%" />
29
81
 
30
- If you are running this plugin on Google Cloud [Compute Engine](https://cloud.google.com/compute), [Kubernetes Engine](https://cloud.google.com/kubernetes-engine) or [App Engine flexible environment](https://cloud.google.com/appengine/docs/flexible/), a default service account is automatically provisioned. You will not need to create a service account. See [this](https://cloud.google.com/compute/docs/access/service-accounts#compute_engine_default_service_account) for more details.
31
82
 
32
- In all other cases, you need to configure the service account manually. You can follow [this guide](https://cloud.google.com/docs/authentication/getting-started) on how to create a new service account and create a key for it. You will need to set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable pointing to the service account key file according to the document.
83
+ #### Step 4-2.
33
84
 
34
- No matter if you are a using an automatically provisioned service account or a manually created one, the service account must be configured to have the project editor role.
85
+ Edit the Firebase Security Rules on Firebase console.
35
86
 
36
- ### Enable relevant Google APIs
87
+ <img src="art/screenshot_firebase_storage_rules.png" width="75%" />
37
88
 
38
- - You need to enable the following APIs on your [Google Cloud API library](https://console.cloud.google.com/apis/library) (see [this](https://support.google.com/cloud/answer/6158841) for instructions how):
39
- 1. Cloud Testing API
40
- 2. Cloud Tool Results API
89
+ This plugin need some match rules it `images` and `logcat` file for hyperlinks.
90
+ ```
91
+ rules_version = '2';
92
+ service firebase.storage {
93
+ match /b/{bucket}/o {
94
+ match /{result_dir}/{device}/artifacts/{image} {
95
+ allow read: if image.matches(".*(jpeg|jpg|png)$")
96
+ }
97
+ match /{result_dir}/{device}/{file} {
98
+ allow read: if file.matches("logcat")
99
+ }
100
+ match /{allPaths=**} {
101
+ allow read, write: if request.auth != null;
102
+ }
103
+ }
104
+ }
105
+ ```
41
106
 
42
- ### Find the devices you want to test on
107
+ ### Step 5. Find the devices you want to test on
43
108
 
44
- If you have [gcloud tool](https://cloud.google.com/sdk/gcloud/), you can run
109
+ Using [gcloud tool](https://cloud.google.com/sdk/gcloud/), you can run.
45
110
 
46
- ```no-highlight
111
+ ```
47
112
  gcloud beta firebase test android models list
48
113
  ```
49
114
 
@@ -52,39 +117,65 @@ to get a list of supported devices and their identifiers.
52
117
  Alternatively all available devices can also be seen [here](https://firebase.google.com/docs/test-lab/ios/available-testing-devices).
53
118
 
54
119
 
55
- ## Actions
120
+ ### Step 6. Add settings to your Fastfile
56
121
 
57
122
  Test your app with Firebase Test Lab with ease using fastlane.
58
123
  Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin.
59
124
 
60
125
  ```ruby
61
126
  before_all do
62
- ENV["SLACK_URL"] = "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"
127
+ ENV["SLACK_URL"] = "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"
128
+ end
129
+
130
+ lane :test do
131
+
132
+ # Get Pull request number from CI
133
+ pr_number = ENV["CI_PULL_REQUEST"] != nil ? ENV["CI_PULL_REQUEST"][/(?<=https:\/\/github.com\/cats-oss\/android\/pull\/)(.*)/] : nil
134
+
135
+ # Upload to Firebase Test Lab
136
+ firebase_test_lab_android(
137
+ project_id: "cats-firebase", # Your Firebase project name.
138
+ gcloud_service_key_file: "fastlane/client-secret.json", # File path containing the gcloud auth key.
139
+ type: "robo", # Optional: Test type (robo/instrumentation).
140
+ devices: [ # Devices
141
+ {
142
+ model: "Nexus6P",
143
+ version: "23",
144
+ locale: "ja_JP",
145
+ orientation: "portrait"
146
+ },
147
+ {
148
+ model: "Pixel2",
149
+ version: "28"
150
+ }
151
+ ],
152
+ app_apk: "app-debug.apk", # The path for your android app apk.
153
+ # app_test_apk: "app-test.apk", # The path for your android test apk.
154
+ console_log_file_name: "fastlane/console_output.log",
155
+ timeout: "3m",
156
+ firebase_test_lab_results_bucket: "firebase_cats_test_bucket", #
157
+ slack_url: ENV["SLACK_URL"], # IF you want notify to Slack.
158
+
159
+ # If you want notify to Github pull requests.
160
+ github_owner: "******", # Owner name.
161
+ github_repository: "************", # Repository name.
162
+ github_pr_number: pr_number, # If you using run on CI that need pull request number for auto comment.
163
+ github_api_token: ENV["GITHUB_API_TOKEN"] # https://github.com/settings/tokens
164
+ )
63
165
  end
64
-
65
- firebase_test_lab_android(
66
- project_id: "cats-firebase",
67
- gcloud_service_key_file: "fastlane/client-secret.json",
68
- type: "robo",
69
- devices: [
70
- {
71
- model: "hammerhead",
72
- version: "21",
73
- locale: "ja_JP",
74
- orientation: "portrait"
75
- },
76
- {
77
- model: "Pixel2",
78
- version: "28"
79
- }
80
- ],
81
- app_apk: "test.apk",
82
- console_log_file_name: "fastlane/console_output.log",
83
- timeout: "1m",
84
- notify_to_slack: true
85
- )
86
166
  ```
87
167
 
168
+ ### Finish. Check your slack or Github PR
169
+
170
+ **If you set `slack_url: ENV["SLACK_URL"]` to Fastfile.**
171
+
172
+ <img src="art/screenshot_slack.png" width="75%" />
173
+
174
+ **If you set `github_owner, github_repository, github_pr_number, github_api_token` to Fastfile.**
175
+
176
+ <img src="art/screenshot_github.png" width="75%" />
177
+
178
+
88
179
  ## Issues and Feedback
89
180
 
90
181
  For any other issues and feedback about this plugin, please submit it to this repository.
@@ -3,7 +3,7 @@ require 'fastlane/plugin/firebase_test_lab_android/version'
3
3
  module Fastlane
4
4
  module FirebaseTestLabAndroid
5
5
  def self.all_classes
6
- Dir[File.expand_path('**/{actions}/*.rb', File.dirname(__FILE__))]
6
+ Dir[File.expand_path('**/{actions,helper}/**/*.rb', File.dirname(__FILE__))]
7
7
  end
8
8
  end
9
9
  end
@@ -1,57 +1,67 @@
1
1
  require 'fastlane/action'
2
+ require 'json'
2
3
 
3
4
  module Fastlane
4
- module Commands
5
- def self.config
6
- "gcloud config set project"
7
- end
8
-
9
- def self.auth
10
- "gcloud auth activate-service-account"
11
- end
12
-
13
- def self.run_tests
14
- "gcloud firebase test android run"
15
- end
16
- end
17
-
18
5
  module Actions
19
6
  class FirebaseTestLabAndroidAction < Action
20
- PIPE = "testlab-pipe"
21
7
 
22
8
  def self.run(params)
23
9
  UI.message("Starting...")
24
10
 
25
- UI.message("Set Google Cloud target project.")
26
- Action.sh("#{Commands.config} #{params[:project_id]}")
11
+ results_bucket = params[:firebase_test_lab_results_bucket] == nil ? "#{params[:project_id]}_test_results" : params[:firebase_test_lab_results_bucket]
12
+ results_dir = "firebase_test_result_#{DateTime.now.strftime('%Y-%m-%d-%H:%M:%S')}"
27
13
 
28
- UI.message("Authenticate with Google Cloud.")
29
- Action.sh("#{Commands.auth} --key-file #{params[:gcloud_service_key_file]}")
30
-
31
- UI.message("Running...")
32
- Action.sh("rm #{PIPE}") if File.exist?(PIPE)
33
- Action.sh("mkfifo #{PIPE}")
34
- Action.sh("set +e;"\
35
- "tee #{params[:console_log_file_name]} < #{PIPE} & "\
36
- "#{Commands.run_tests} "\
37
- "--type #{params[:type]} "\
14
+ # Set target project
15
+ Helper.config(params[:project_id])
16
+ # Activate service account
17
+ Helper.authenticate(params[:gcloud_service_key_file])
18
+ # Run Firebase Test Lab
19
+ Helper.run_tests("--type #{params[:type]} "\
20
+ "#{"--use-orchestrator " if params[:type] == "instrumentation"}"\
38
21
  "--app #{params[:app_apk]} "\
39
22
  "#{"--test #{params[:app_test_apk]} " unless params[:app_test_apk].nil?}"\
40
23
  "#{params[:devices].map { |d| "--device model=#{d[:model]},version=#{d[:version]},locale=#{d[:locale]},orientation=#{d[:orientation]} " }.join}"\
41
24
  "--timeout #{params[:timeout]} "\
25
+ "--results-bucket #{results_bucket} "\
26
+ "--results-dir #{results_dir} "\
42
27
  "#{params[:extra_options]} "\
43
- "> #{PIPE} 2>&1;"\
44
- "set -e")
45
- Action.sh("rm #{PIPE}") if File.exist?(PIPE)
46
-
47
- if params[:notify_to_slack]
48
- output = File.read(params[:console_log_file_name])
49
- failed = output.include?("Failed") || output.include?("Inconclusive")
50
- other_action.slack(message: output,
51
- success: !failed,
52
- use_webhook_configured_username_and_icon: true,
53
- default_payloads: [:git_branch, :git_author, :last_git_commit])
28
+ "--format=json 1>#{params[:console_log_file_name]}"
29
+ )
30
+
31
+ # Sample data
32
+ # [
33
+ # {
34
+ # "axis_value": "Nexus6P-23-ja_JP-portrait",
35
+ # "outcome": "Passed",
36
+ # "test_details": "--"
37
+ # },
38
+ # {
39
+ # "axis_value": "Pixel2-28-en_US-portrait",
40
+ # "outcome": "Passed",
41
+ # "test_details": "--"
42
+ # }
43
+ # ]
44
+ json = JSON.parse(File.read(params[:console_log_file_name]))
45
+
46
+ # Notify to Slack
47
+ if params[:slack_url] != nil
48
+ success, body = Helper.make_slack_text(json)
49
+ SlackNotifier.notify(params[:slack_url], body, success)
50
+ end
51
+
52
+ # Notify to Github
53
+ owner = params[:github_owner]
54
+ repository = params[:github_repository]
55
+ pr_number = params[:github_pr_number]
56
+ api_token = params[:github_api_token]
57
+ unless owner.nil? || repository.nil? || pr_number.nil? || api_token.nil?
58
+ prefix, comment = Helper.make_github_text(json, params[:project_id], results_bucket, results_dir)
59
+ # Delete past comments
60
+ GitHubNotifier.delete_comments(owner, repository, pr_number, prefix, api_token)
61
+ GitHubNotifier.put_comment(owner, repository, pr_number, comment, api_token)
54
62
  end
63
+
64
+ UI.message("Finishing...")
55
65
  end
56
66
 
57
67
  def self.description
@@ -119,7 +129,7 @@ module Fastlane
119
129
  description: "The max time this test execution can run before it is cancelled. Default: 5m (this value must be greater than or equal to 1m)",
120
130
  is_string: true,
121
131
  optional: true,
122
- default_value: "5m"),
132
+ default_value: "3m"),
123
133
  FastlaneCore::ConfigItem.new(key: :app_apk,
124
134
  env_name: "APP_APK",
125
135
  description: "The path for your android app apk",
@@ -143,12 +153,43 @@ module Fastlane
143
153
  is_string: true,
144
154
  optional: true,
145
155
  default_value: ""),
146
- FastlaneCore::ConfigItem.new(key: :notify_to_slack,
147
- env_name: "NOTIFY_TO_SLACK",
148
- description: "Notify to Slack after finishing of the test. Default: false",
149
- is_string: false,
156
+ FastlaneCore::ConfigItem.new(key: :slack_url,
157
+ env_name: "SLACK_URL",
158
+ description: "If Notify to Slack after finishing of the test. Set your slack incoming webhook url",
159
+ is_string: true,
150
160
  optional: true,
151
- default_value: false)]
161
+ default_value: nil),
162
+ FastlaneCore::ConfigItem.new(key: :firebase_test_lab_results_bucket,
163
+ env_name: "FIREBASE_TEST_LAB_RESULTS_BUCKET",
164
+ description: "Name of Firebase Test Lab results bucket",
165
+ type: String,
166
+ optional: true,
167
+ default_value: nil),
168
+ FastlaneCore::ConfigItem.new(key: :github_owner,
169
+ env_name: "GITHUB_OWNER",
170
+ description: "Owner name",
171
+ type: String,
172
+ optional: true,
173
+ default_value: nil),
174
+ FastlaneCore::ConfigItem.new(key: :github_repository,
175
+ env_name: "GITHUB_REPOSITORY",
176
+ description: "Repository name",
177
+ type: String,
178
+ optional: true,
179
+ default_value: nil),
180
+ FastlaneCore::ConfigItem.new(key: :github_pr_number,
181
+ env_name: "GITHUB_PR_NUMBER",
182
+ description: "Pull request number",
183
+ type: String,
184
+ optional: true,
185
+ default_value: nil),
186
+ FastlaneCore::ConfigItem.new(key: :github_api_token,
187
+ env_name: "GITHUB_API_TOKEN",
188
+ description: "GitHub API Token",
189
+ type: String,
190
+ optional: true,
191
+ default_value: nil)
192
+ ]
152
193
  end
153
194
 
154
195
  def self.check_has_property(hash_obj, property)
@@ -170,27 +211,43 @@ module Fastlane
170
211
  end
171
212
 
172
213
  def self.example_code
173
- ['firebase_test_lab_android(
174
- project_id: "winticket-firebase",
214
+ ['before_all do
215
+ ENV["SLACK_URL"] = "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"
216
+ end
217
+
218
+ lane :test do
219
+
220
+ # Get Pull request number
221
+ pr_number = ENV["CI_PULL_REQUEST"] != nil ? ENV["CI_PULL_REQUEST"][/(?<=https:\/\/github.com\/cats-oss\/android\/pull\/)(.*)/] : nil
222
+
223
+ # Upload to Firebase Test Lab
224
+ firebase_test_lab_android(
225
+ project_id: "cats-firebase",
175
226
  gcloud_service_key_file: "fastlane/client-secret.json",
176
227
  type: "robo",
177
228
  devices: [
178
229
  {
179
- model: "hammerhead",
180
- version: "21",
181
- locale: "ja_JP",
182
- orientation: "portrait"
230
+ model: "Nexus6P",
231
+ version: "23",
232
+ locale: "ja_JP",
233
+ orientation: "portrait"
183
234
  },
184
235
  {
185
- model: "Pixel2",
186
- version: "28"
236
+ model: "Pixel2",
237
+ version: "28"
187
238
  }
188
239
  ],
189
240
  app_apk: "test.apk",
190
241
  console_log_file_name: "fastlane/console_output.log",
191
242
  timeout: "3m",
192
- notify_to_slack: true
193
- )']
243
+ firebase_test_lab_results_bucket: "firebase_cats_test_bucket",
244
+ slack_url: ENV["SLACK_URL"],
245
+ github_owner: "cats-oss",
246
+ github_repository: "fastlane-plugin-firebase_test_lab_android",
247
+ github_pr_number: pr_number,
248
+ github_api_token: ENV["DANGER_GITHUB_API_TOKEN"]
249
+ )
250
+ end']
194
251
  end
195
252
  end
196
253
  end
@@ -0,0 +1,115 @@
1
+ require 'fastlane_core/ui/ui'
2
+
3
+ module Fastlane
4
+
5
+ # Outcome
6
+ PASSED = 'Passed'
7
+ FAILED = 'Failed'
8
+ SKIPPED = 'Skipped'
9
+ INCONCLUSIVE = 'Inconclusive'
10
+
11
+ module Helper
12
+
13
+ def self.gcs_result_bucket_url(bucket, dir)
14
+ "https://console.developers.google.com/storage/browser/#{bucket}/#{CGI.escape(dir)}"
15
+ end
16
+
17
+ def self.firebase_object_url(bucket, path)
18
+ "https://firebasestorage.googleapis.com/v0/b/#{bucket}/o/#{CGI.escape(path)}?alt=media"
19
+ end
20
+
21
+ def self.firebase_test_lab_histories_url(project_id)
22
+ "https://console.firebase.google.com/u/0/project/#{project_id}/testlab/histories/"
23
+ end
24
+
25
+ def self.config(project_id)
26
+ UI.message "Set Google Cloud target project"
27
+ Action.sh("gcloud config set project #{project_id}")
28
+ end
29
+
30
+ def self.authenticate(gcloud_key_file)
31
+ UI.message "Authenticate with GCP"
32
+ Action.sh("gcloud auth activate-service-account --key-file #{gcloud_key_file}")
33
+ end
34
+
35
+ def self.run_tests(arguments)
36
+ UI.message("Test running...")
37
+ Action.sh("gcloud firebase test android run #{arguments}")
38
+ end
39
+
40
+ def self.is_failure(outcome)
41
+ outcome == FAILED || outcome == INCONCLUSIVE
42
+ end
43
+
44
+ def self.format_device_name(axis_value)
45
+ # Sample Nexus6P-23-ja_JP-portrait
46
+ array = axis_value.split("-")
47
+ "#{array[0]} (API #{array[1]})"
48
+ end
49
+
50
+ def self.emoji_status(outcome)
51
+ # Github emoji list
52
+ # https://github.com/ikatyang/emoji-cheat-sheet
53
+ return case outcome
54
+ when PASSED
55
+ ":tada:"
56
+ when FAILED
57
+ ":fire:"
58
+ when INCONCLUSIVE
59
+ ":warning:"
60
+ when SKIPPED
61
+ ":expressionless:"
62
+ else
63
+ ":question:"
64
+ end
65
+ end
66
+
67
+ def self.random_emoji_cat
68
+ # Github emoji list
69
+ # https://github.com/ikatyang/emoji-cheat-sheet#cat-face
70
+ %w(:smiley_cat: :smile_cat: :joy_cat: :heart_eyes_cat: :smirk_cat: :kissing_cat:).sample
71
+ end
72
+
73
+ def self.make_slack_text(json)
74
+ success = true
75
+ json.each do |status|
76
+ success = !is_failure(status["outcome"])
77
+ break unless success
78
+ end
79
+
80
+ body = json.map { |status|
81
+ outcome = status["outcome"]
82
+ emoji = emoji_status(outcome)
83
+ device = format_device_name(status["axis_value"])
84
+ "#{device}: #{emoji} #{outcome}\n"
85
+ }.inject(&:+)
86
+ return success, body
87
+ end
88
+
89
+ def self.make_github_text(json, project_id, bucket, dir)
90
+ prefix = "<img src=\"https://github.com/cats-oss/fastlane-plugin-firebase_test_lab_android/blob/master/art/firebase_test_lab_logo.png?raw=true\" width=\"65%\" loading=\"lazy\" />"
91
+ cells = json.map { |data|
92
+ axis = data["axis_value"]
93
+ device = format_device_name(axis)
94
+ outcome = data["outcome"]
95
+ status = "#{emoji_status(outcome)} #{outcome}"
96
+ message = data["test_details"]
97
+ logcat = "<a href=\"#{firebase_object_url(bucket, "#{dir}/#{axis}/logcat")}\" target=\"_blank\" >#{random_emoji_cat}</a>"
98
+ sitemp = "<img src=\"#{firebase_object_url(bucket, "#{dir}/#{axis}/artifacts/sitemap.png")}\" height=\"64px\" loading=\"lazy\" target=\"_blank\" />"
99
+ "| **#{device}** | #{status} | #{message} | #{logcat} | #{sitemp} |\n"
100
+ }.inject(&:+)
101
+ comment = <<~EOS
102
+ #{prefix}
103
+
104
+ ### Results
105
+ Firebase console: [#{project_id}](#{Helper.firebase_test_lab_histories_url(project_id)})
106
+ Test results: [#{dir}](#{Helper.gcs_result_bucket_url(bucket, dir)})
107
+
108
+ | :iphone: Device | :thermometer: Status | :memo: Message | :eyes: Logcat | :japan: Sitemap |
109
+ | --- | :---: | --- | :---: | :---: |
110
+ #{cells}
111
+ EOS
112
+ return prefix, comment
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,87 @@
1
+ require 'fastlane_core/ui/ui'
2
+ require 'json'
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ module Fastlane
7
+ module GitHubNotifier
8
+ def self.fold_comments(github_owner, github_repository, github_pr_number, comment_prefix, summary, github_api_token)
9
+ res = get_comments(github_owner, github_repository, github_pr_number, github_api_token)
10
+ JSON.parse(res.body)
11
+ .select {|comment| comment["body"].start_with?(comment_prefix)}
12
+ .each {|comment|
13
+ body = "<details><summary>#{summary}</summary>\n\n#{comment["body"]}\n\n</details>\n"
14
+ patch_comment(github_owner, github_repository, comment["id"], body, github_api_token)
15
+ }
16
+ end
17
+
18
+ def self.delete_comments(github_owner, github_repository, github_pr_number, comment_prefix, github_api_token)
19
+ res = get_comments(github_owner, github_repository, github_pr_number, github_api_token)
20
+ JSON.parse(res.body)
21
+ .select {|comment| comment["body"].start_with?(comment_prefix)}
22
+ .each {|comment| delete_comment(github_owner, github_repository, comment["id"], github_api_token)}
23
+ end
24
+
25
+ def self.get_comments(github_owner, github_repository, github_pr_number, github_api_token)
26
+ api_url = "https://api.github.com/repos/#{github_owner}/#{github_repository}/issues/#{github_pr_number}/comments"
27
+ UI.message "get comments #{api_url}"
28
+
29
+ uri = URI.parse(api_url)
30
+ req = Net::HTTP::Get.new(uri)
31
+ req["Content-Type"] = "application/json"
32
+ req["Authorization"] = "token #{github_api_token}"
33
+
34
+ res = Net::HTTP.start(uri.hostname, uri.port, {use_ssl: uri.scheme = "https"}) {|http| http.request(req)}
35
+ UI.message "#{res.code}\n#{res.body}"
36
+
37
+ res
38
+ end
39
+
40
+ def self.put_comment(github_owner, github_repository, github_pr_number, body, github_api_token)
41
+ api_url = "https://api.github.com/repos/#{github_owner}/#{github_repository}/issues/#{github_pr_number}/comments"
42
+ UI.message "put comment #{api_url}"
43
+
44
+ uri = URI.parse(api_url)
45
+ req = Net::HTTP::Post.new(uri)
46
+ req["Content-Type"] = "application/json"
47
+ req["Authorization"] = "token #{github_api_token}"
48
+ req.body = {:body => body}.to_json
49
+
50
+ res = Net::HTTP.start(uri.hostname, uri.port, {use_ssl: uri.scheme = "https"}) {|http| http.request(req)}
51
+ UI.message "#{res.code}\n#{res.body}"
52
+
53
+ res
54
+ end
55
+
56
+ def self.patch_comment(github_owner, github_repository, comment_id, body, github_api_token)
57
+ api_url = "https://api.github.com/repos/#{github_owner}/#{github_repository}/issues/comments/#{comment_id}"
58
+ UI.message "patch comment #{api_url}"
59
+
60
+ uri = URI.parse(api_url)
61
+ req = Net::HTTP::Patch.new(uri)
62
+ req["Content-Type"] = "application/json"
63
+ req["Authorization"] = "token #{github_api_token}"
64
+ req.body = {:body => body}.to_json
65
+
66
+ res = Net::HTTP.start(uri.hostname, uri.port, {use_ssl: uri.scheme = "https"}) {|http| http.request(req)}
67
+ UI.message "#{res.code}\n#{res.body}"
68
+
69
+ res
70
+ end
71
+
72
+ def self.delete_comment(github_owner, github_repository, comment_id, github_api_token)
73
+ api_url = "https://api.github.com/repos/#{github_owner}/#{github_repository}/issues/comments/#{comment_id}"
74
+ UI.message "delete comment #{api_url}"
75
+
76
+ uri = URI.parse(api_url)
77
+ req = Net::HTTP::Delete.new(uri)
78
+ req["Content-Type"] = "application/json"
79
+ req["Authorization"] = "token #{github_api_token}"
80
+
81
+ res = Net::HTTP.start(uri.hostname, uri.port, {use_ssl: uri.scheme = "https"}) {|http| http.request(req)}
82
+ UI.message "#{res.code}\n#{res.body}"
83
+
84
+ res
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,18 @@
1
+ require 'fastlane/action'
2
+ require 'fastlane_core/ui/ui'
3
+ require 'json'
4
+
5
+ module Fastlane
6
+ module SlackNotifier
7
+ def self.notify(slack_url, message, success)
8
+ slackArgs = Fastlane::ConfigurationHelper.parse(Fastlane::Actions::SlackAction, {
9
+ slack_url: slack_url,
10
+ message: message,
11
+ success: success,
12
+ use_webhook_configured_username_and_icon: true,
13
+ default_payloads: [:git_branch, :git_author, :last_git_commit]
14
+ })
15
+ Fastlane::Actions::SlackAction.run(slackArgs)
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module FirebaseTestLabAndroid
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-firebase_test_lab_android
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - wasabeef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-01 00:00:00.000000000 Z
11
+ date: 2019-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -146,6 +146,9 @@ files:
146
146
  - README.md
147
147
  - lib/fastlane/plugin/firebase_test_lab_android.rb
148
148
  - lib/fastlane/plugin/firebase_test_lab_android/actions/firebase_test_lab_android_action.rb
149
+ - lib/fastlane/plugin/firebase_test_lab_android/helper/Helper.rb
150
+ - lib/fastlane/plugin/firebase_test_lab_android/helper/github_notifier.rb
151
+ - lib/fastlane/plugin/firebase_test_lab_android/helper/slack_notifier.rb
149
152
  - lib/fastlane/plugin/firebase_test_lab_android/version.rb
150
153
  homepage: https://github.com/cats-oss/fastlane-plugin-firebase_test_lab_android
151
154
  licenses:
@@ -166,8 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
169
  - !ruby/object:Gem::Version
167
170
  version: '0'
168
171
  requirements: []
169
- rubyforge_project:
170
- rubygems_version: 2.5.2.3
172
+ rubygems_version: 3.0.3
171
173
  signing_key:
172
174
  specification_version: 4
173
175
  summary: Test your app with Firebase Test Lab with ease using fastlane