fastlane-plugin-firebase_test_lab_android 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
[](https://github.com/cats-oss/fastlane-plugin-firebase_test_lab_android/blob/master/LICENSE)
|
13
|
+
[](https://rubygems.org/gems/fastlane-plugin-firebase_test_lab_android)
|
14
|
+
[](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
|