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 +5 -5
- data/LICENSE +2 -2
- data/README.md +134 -43
- data/lib/fastlane/plugin/firebase_test_lab_android.rb +1 -1
- data/lib/fastlane/plugin/firebase_test_lab_android/actions/firebase_test_lab_android_action.rb +111 -54
- data/lib/fastlane/plugin/firebase_test_lab_android/helper/Helper.rb +115 -0
- data/lib/fastlane/plugin/firebase_test_lab_android/helper/github_notifier.rb +87 -0
- data/lib/fastlane/plugin/firebase_test_lab_android/helper/slack_notifier.rb +18 -0
- data/lib/fastlane/plugin/firebase_test_lab_android/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 705bbfe9626de801abd2169fca83b037ae71c7bc9fd5d5300958a08b79c5fff9
|
4
|
+
data.tar.gz: 3009df47e1a59d09685831273daff5bf910cbea7ed106c0c412655b0fa1e56ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
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="
|
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
|
-
```
|
15
|
-
(not yet)
|
54
|
+
```
|
16
55
|
fastlane add_plugin firebase_test_lab_android
|
17
56
|
```
|
18
57
|
|
19
|
-
###
|
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
|
-
|
74
|
+
### Step 4. Import existing Google Cloud Storage buckets to Firebase Storage
|
22
75
|
|
23
|
-
|
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
|
-
|
78
|
+
Import GCS bucket on Firebase console at Storage.
|
27
79
|
|
28
|
-
|
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
|
-
|
83
|
+
#### Step 4-2.
|
33
84
|
|
34
|
-
|
85
|
+
Edit the Firebase Security Rules on Firebase console.
|
35
86
|
|
36
|
-
|
87
|
+
<img src="art/screenshot_firebase_storage_rules.png" width="75%" />
|
37
88
|
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
109
|
+
Using [gcloud tool](https://cloud.google.com/sdk/gcloud/), you can run.
|
45
110
|
|
46
|
-
```
|
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
|
-
|
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
|
-
|
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}
|
6
|
+
Dir[File.expand_path('**/{actions,helper}/**/*.rb', File.dirname(__FILE__))]
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
data/lib/fastlane/plugin/firebase_test_lab_android/actions/firebase_test_lab_android_action.rb
CHANGED
@@ -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
|
-
|
26
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
"
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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: "
|
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: :
|
147
|
-
env_name: "
|
148
|
-
description: "Notify to Slack after finishing of the test.
|
149
|
-
is_string:
|
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:
|
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
|
-
['
|
174
|
-
|
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
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
230
|
+
model: "Nexus6P",
|
231
|
+
version: "23",
|
232
|
+
locale: "ja_JP",
|
233
|
+
orientation: "portrait"
|
183
234
|
},
|
184
235
|
{
|
185
|
-
|
186
|
-
|
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
|
-
|
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
|
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.
|
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-
|
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
|
-
|
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
|