fastlane-plugin-roku_app_util 0.1.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +113 -0
- data/lib/fastlane/plugin/roku_app_util/actions/roku_app_install_action.rb +66 -0
- data/lib/fastlane/plugin/roku_app_util/actions/roku_app_package_action.rb +89 -0
- data/lib/fastlane/plugin/roku_app_util/actions/roku_app_uninstall_action.rb +58 -0
- data/lib/fastlane/plugin/roku_app_util/actions/roku_dev_server_check_action.rb +47 -0
- data/lib/fastlane/plugin/roku_app_util/helper/roku_app_util_helper.rb +206 -0
- data/lib/fastlane/plugin/roku_app_util/version.rb +5 -0
- data/lib/fastlane/plugin/roku_app_util.rb +16 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: caca31eb4fd3efe39646aca1255a3f195ba1365de0e27e6ceb135962647d20c8
|
4
|
+
data.tar.gz: c9252326f8a583f38c216d80ef793e39d7265ad9d97848d7cf426d2edb62c886
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5328c864cf08113bfbefab27ef8527821383b05493218915e67ec2036af6eb95710ce77c9949e6ee0fd419ecc2277d294e578f920ef57b2965ff29dd8ca1174b
|
7
|
+
data.tar.gz: b2b3d89924298efb7b12943562b941a25e7f6f6cff774ed37e82cb6378e272e317eeeca20d9b68cb4e901ae43cfb6ee9b6acad9b32b6e0ca429ef90390bbf966
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) Warner Media, LLC. All other rights reserved.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# Fastlane roku_app_util plugin
|
2
|
+
|
3
|
+
[](https://github.com/WarnerMedia/fastlane-plugin-roku_app_util/actions/workflows/test.yml)
|
4
|
+
<!-- [](https://rubygems.org/gems/fastlane-plugin-roku_app_util) -->
|
5
|
+
|
6
|
+
## Getting Started
|
7
|
+
|
8
|
+
This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-roku_app_util`, add it to your project by running:
|
9
|
+
|
10
|
+
1. `bundle exec fastlane add_plugin roku_app_util`
|
11
|
+
2. When prompted enter option `1` for providing a **Git URL**
|
12
|
+
3. Enter the URL for this repo: `https://github.com/WarnerMedia/fastlane-plugin-roku_app_util`
|
13
|
+
|
14
|
+
## About roku_app_util
|
15
|
+
|
16
|
+
Fastlane plugin for Roku app automation. All actions require a Roku dev server on the same network as the machine running the following Fastlane actions.
|
17
|
+
|
18
|
+
### Available actions
|
19
|
+
* [`roku_dev_server_check`](#action-roku_dev_server_check) : Checks Roku dev server
|
20
|
+
* [`roku_app_install`](#action-roku_app_install) : Installs the app as a dev channel on a Roku target device
|
21
|
+
* [`roku_app_uninstall`](#action-roku_app_uninstall) : Uninstalls any apps/dev channels on a Roku target device
|
22
|
+
* [`roku_app_package`](#action-roku_app_package) : Creates Roku package from application sources
|
23
|
+
|
24
|
+
#### Action: `roku_dev_server_check`
|
25
|
+
|
26
|
+
##### Description: Checks Roku dev server
|
27
|
+
|
28
|
+
##### Parameters:
|
29
|
+
|
30
|
+
Key | Environment Variable Equivalent | Description | Required?
|
31
|
+
------------- | ------------- | ------------- | -------------
|
32
|
+
`dev_target` | `ROKUAPPUTIL_DEV_TARGET` | The IP of the Roku dev target | YES
|
33
|
+
|
34
|
+
#### Action: `roku_app_install`
|
35
|
+
|
36
|
+
##### Description: Installs the app as a dev channel on a Roku target device
|
37
|
+
|
38
|
+
##### Parameters:
|
39
|
+
|
40
|
+
Key | Environment Variable Equivalent | Description | Required?
|
41
|
+
------------- | ------------- | ------------- | -------------
|
42
|
+
`dev_target` | `ROKUAPPUTIL_DEV_TARGET` | The IP of the Roku dev target | YES
|
43
|
+
`dev_user` | `ROKUAPPUTIL_DEV_USER` | Roku development username | NO - Default value: `rokudev`
|
44
|
+
`dev_pass` | `ROKUAPPUTIL_DEV_PASS` | Roku development password | YES
|
45
|
+
`zip_path` | `ROKUAPPUTIL_ZIP_PATH` | Roku application ZIP file path | YES
|
46
|
+
|
47
|
+
#### Action: `roku_app_uninstall`
|
48
|
+
|
49
|
+
##### Description: Uninstalls any apps/dev channels on a Roku target device
|
50
|
+
|
51
|
+
##### Parameters:
|
52
|
+
|
53
|
+
Key | Environment Variable Equivalent | Description | Required?
|
54
|
+
------------- | ------------- | ------------- | -------------
|
55
|
+
`dev_target` | `ROKUAPPUTIL_DEV_TARGET` | The IP of the Roku dev target | YES
|
56
|
+
`dev_user` | `ROKUAPPUTIL_DEV_USER` | Roku development username | NO - Default value: `rokudev`
|
57
|
+
`dev_pass` | `ROKUAPPUTIL_DEV_PASS` | Roku development password | YES
|
58
|
+
|
59
|
+
#### Action: `roku_app_package`
|
60
|
+
|
61
|
+
##### Description: Creates Roku package from application sources
|
62
|
+
|
63
|
+
##### Parameters:
|
64
|
+
|
65
|
+
Key | Environment Variable Equivalent | Description | Required?
|
66
|
+
------------- | ------------- | ------------- | -------------
|
67
|
+
`dev_target` | `ROKUAPPUTIL_DEV_TARGET` | The IP of the Roku dev target | YES
|
68
|
+
`dev_user` | `ROKUAPPUTIL_DEV_USER` | Roku development username | NO - Default value: `rokudev`
|
69
|
+
`dev_pass` | `ROKUAPPUTIL_DEV_PASS` | Roku development password | YES
|
70
|
+
`zip_path` | `ROKUAPPUTIL_ZIP_PATH` | Roku application ZIP file path | YES
|
71
|
+
`sign_key` | `ROKUAPPUTIL_SIGN_KEY` | Roku signing key | YES
|
72
|
+
`app_name` | `ROKUAPPUTIL_APP_NAME` | Roku application name | YES
|
73
|
+
`app_version` | `ROKUAPPUTIL_APP_VERSION`| Roku application version | YES
|
74
|
+
`pkg_output_path` | `ROKUAPPUTIL_PKG_OUTPUT_PATH`| Roku application PKG path | NO - Default value: `./`
|
75
|
+
|
76
|
+
## Example
|
77
|
+
|
78
|
+
Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin. Try it by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane test`.
|
79
|
+
|
80
|
+
**Note to author:** Please set up a sample project to make it easy for users to explore what your plugin does. Provide everything that is necessary to try out the plugin in this project (including a sample Xcode/Android project if necessary)
|
81
|
+
|
82
|
+
## Run tests for this plugin
|
83
|
+
|
84
|
+
To run both the tests, and code style validation, run
|
85
|
+
|
86
|
+
```
|
87
|
+
bundle exec rake
|
88
|
+
```
|
89
|
+
|
90
|
+
To automatically fix many of the styling issues, use
|
91
|
+
```
|
92
|
+
bundle exec rubocop -a
|
93
|
+
```
|
94
|
+
|
95
|
+
## Issues and Feedback
|
96
|
+
|
97
|
+
For any other issues and feedback about this plugin, please submit it to this repository.
|
98
|
+
|
99
|
+
## Troubleshooting
|
100
|
+
|
101
|
+
If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
|
102
|
+
|
103
|
+
## Using _fastlane_ Plugins
|
104
|
+
|
105
|
+
For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
|
106
|
+
|
107
|
+
## About _fastlane_
|
108
|
+
|
109
|
+
_fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
|
110
|
+
|
111
|
+
## License
|
112
|
+
|
113
|
+
This repository is released under [the MIT license](https://en.wikipedia.org/wiki/MIT_License). View the [local license file](./LICENSE).
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require 'fastlane_core/configuration/config_item'
|
3
|
+
require_relative '../helper/roku_app_util_helper'
|
4
|
+
|
5
|
+
module Fastlane
|
6
|
+
module Actions
|
7
|
+
class RokuAppInstallAction < Action
|
8
|
+
def self.run(params)
|
9
|
+
Helper::RokuAppUtilHelper.roku_app_install(params)
|
10
|
+
# If we've gotten this far the Roku app has been installed
|
11
|
+
UI.success("Roku app installed")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.description
|
15
|
+
"Installs the app as a dev channel on a Roku target device"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.authors
|
19
|
+
["Onyx Mueller"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.return_value
|
23
|
+
# If your method provides a return value, you can describe here what it does
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.details
|
27
|
+
# Optional:
|
28
|
+
""
|
29
|
+
end
|
30
|
+
|
31
|
+
# For each option, optional is set to true to prevent forcing Fastlane to be interactive and prompting for input
|
32
|
+
def self.available_options
|
33
|
+
[
|
34
|
+
FastlaneCore::ConfigItem.new(key: :dev_target,
|
35
|
+
env_name: "ROKUAPPUTIL_DEV_TARGET",
|
36
|
+
description: "IP of the Roku development device",
|
37
|
+
optional: true,
|
38
|
+
type: String),
|
39
|
+
FastlaneCore::ConfigItem.new(key: :dev_user,
|
40
|
+
env_name: "ROKUAPPUTIL_DEV_USER",
|
41
|
+
description: "Roku development username",
|
42
|
+
optional: true,
|
43
|
+
type: String,
|
44
|
+
default_value: "rokudev"),
|
45
|
+
FastlaneCore::ConfigItem.new(key: :dev_pass,
|
46
|
+
env_name: "ROKUAPPUTIL_DEV_PASS",
|
47
|
+
description: "Roku development password",
|
48
|
+
optional: true,
|
49
|
+
type: String),
|
50
|
+
FastlaneCore::ConfigItem.new(key: :zip_path,
|
51
|
+
env_name: "ROKUAPPUTIL_ZIP_PATH",
|
52
|
+
description: "Roku application ZIP file path",
|
53
|
+
optional: true,
|
54
|
+
type: String,
|
55
|
+
verify_block: proc do |value|
|
56
|
+
UI.user_error!("Could not find ZIP file") unless File.exist?(value)
|
57
|
+
end)
|
58
|
+
]
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.is_supported?(platform)
|
62
|
+
[:roku].include?(platform)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require 'fastlane_core/configuration/config_item'
|
3
|
+
require_relative '../helper/roku_app_util_helper'
|
4
|
+
|
5
|
+
module Fastlane
|
6
|
+
module Actions
|
7
|
+
class RokuAppPackageAction < Action
|
8
|
+
def self.run(params)
|
9
|
+
package_file_path = Helper::RokuAppUtilHelper.roku_app_package(params)
|
10
|
+
# If we've gotten this far the Roku app has been packaged
|
11
|
+
UI.success("Package file path: #{package_file_path}")
|
12
|
+
|
13
|
+
return package_file_path
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.description
|
17
|
+
"Creates Roku package from application sources"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.authors
|
21
|
+
["Onyx Mueller"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.return_value
|
25
|
+
# If your method provides a return value, you can describe here what it does
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.details
|
29
|
+
# Optional:
|
30
|
+
""
|
31
|
+
end
|
32
|
+
|
33
|
+
# For each option, optional is set to true to prevent forcing Fastlane to be interactive and prompting for input
|
34
|
+
def self.available_options
|
35
|
+
[
|
36
|
+
FastlaneCore::ConfigItem.new(key: :dev_target,
|
37
|
+
env_name: "ROKUAPPUTIL_DEV_TARGET",
|
38
|
+
description: "IP of the Roku development device",
|
39
|
+
optional: true,
|
40
|
+
type: String),
|
41
|
+
FastlaneCore::ConfigItem.new(key: :dev_user,
|
42
|
+
env_name: "ROKUAPPUTIL_DEV_USER",
|
43
|
+
description: "Roku development username",
|
44
|
+
optional: true,
|
45
|
+
type: String,
|
46
|
+
default_value: "rokudev"),
|
47
|
+
FastlaneCore::ConfigItem.new(key: :dev_pass,
|
48
|
+
env_name: "ROKUAPPUTIL_DEV_PASS",
|
49
|
+
description: "Roku development password",
|
50
|
+
optional: true,
|
51
|
+
type: String),
|
52
|
+
FastlaneCore::ConfigItem.new(key: :zip_path,
|
53
|
+
env_name: "ROKUAPPUTIL_ZIP_PATH",
|
54
|
+
description: "Roku application ZIP file path",
|
55
|
+
optional: true,
|
56
|
+
type: String,
|
57
|
+
verify_block: proc do |value|
|
58
|
+
UI.user_error!("Could not find ZIP file") unless File.exist?(value)
|
59
|
+
end),
|
60
|
+
FastlaneCore::ConfigItem.new(key: :sign_key,
|
61
|
+
env_name: "ROKUAPPUTIL_SIGN_KEY",
|
62
|
+
description: "Roku signing key",
|
63
|
+
optional: true,
|
64
|
+
type: String),
|
65
|
+
FastlaneCore::ConfigItem.new(key: :app_name,
|
66
|
+
env_name: "ROKUAPPUTIL_APP_NAME",
|
67
|
+
description: "Roku application name",
|
68
|
+
optional: true,
|
69
|
+
type: String),
|
70
|
+
FastlaneCore::ConfigItem.new(key: :app_version,
|
71
|
+
env_name: "ROKUAPPUTIL_APP_VERSION",
|
72
|
+
description: "Roku application version",
|
73
|
+
optional: true,
|
74
|
+
type: String),
|
75
|
+
FastlaneCore::ConfigItem.new(key: :pkg_output_path,
|
76
|
+
env_name: "ROKUAPPUTIL_PKG_OUTPUT_PATH",
|
77
|
+
description: "Output path for pkg",
|
78
|
+
optional: true,
|
79
|
+
type: String,
|
80
|
+
default_value: "./")
|
81
|
+
]
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.is_supported?(platform)
|
85
|
+
[:roku].include?(platform)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require 'fastlane_core/configuration/config_item'
|
3
|
+
require_relative '../helper/roku_app_util_helper'
|
4
|
+
|
5
|
+
module Fastlane
|
6
|
+
module Actions
|
7
|
+
class RokuAppUninstallAction < Action
|
8
|
+
def self.run(params)
|
9
|
+
Helper::RokuAppUtilHelper.roku_app_uninstall(params)
|
10
|
+
# If we've gotten this far the Roku apps has been uninstalled
|
11
|
+
UI.success("Roku apps uninstalled")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.description
|
15
|
+
"Uninstalls any apps/dev channels on a Roku target device"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.authors
|
19
|
+
["Onyx Mueller"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.return_value
|
23
|
+
# If your method provides a return value, you can describe here what it does
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.details
|
27
|
+
# Optional:
|
28
|
+
""
|
29
|
+
end
|
30
|
+
|
31
|
+
# For each option, optional is set to true to prevent forcing Fastlane to be interactive and prompting for input
|
32
|
+
def self.available_options
|
33
|
+
[
|
34
|
+
FastlaneCore::ConfigItem.new(key: :dev_target,
|
35
|
+
env_name: "ROKUAPPUTIL_DEV_TARGET",
|
36
|
+
description: "IP of the Roku development device",
|
37
|
+
optional: true,
|
38
|
+
type: String),
|
39
|
+
FastlaneCore::ConfigItem.new(key: :dev_user,
|
40
|
+
env_name: "ROKUAPPUTIL_DEV_USER",
|
41
|
+
description: "Roku development username",
|
42
|
+
optional: true,
|
43
|
+
type: String,
|
44
|
+
default_value: "rokudev"),
|
45
|
+
FastlaneCore::ConfigItem.new(key: :dev_pass,
|
46
|
+
env_name: "ROKUAPPUTIL_DEV_PASS",
|
47
|
+
description: "Roku development password",
|
48
|
+
optional: true,
|
49
|
+
type: String)
|
50
|
+
]
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.is_supported?(platform)
|
54
|
+
[:roku].include?(platform)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require 'fastlane_core/configuration/config_item'
|
3
|
+
require_relative '../helper/roku_app_util_helper'
|
4
|
+
|
5
|
+
module Fastlane
|
6
|
+
module Actions
|
7
|
+
class RokuDevServerCheckAction < Action
|
8
|
+
def self.run(params)
|
9
|
+
Helper::RokuAppUtilHelper.roku_dev_server_check(params)
|
10
|
+
# If we've gotten this far the Roku dev server checks out
|
11
|
+
UI.success("Roku dev server is ready")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.description
|
15
|
+
"Checks Roku dev server"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.authors
|
19
|
+
["Onyx Mueller"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.return_value
|
23
|
+
# If your method provides a return value, you can describe here what it does
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.details
|
27
|
+
# Optional:
|
28
|
+
""
|
29
|
+
end
|
30
|
+
|
31
|
+
# For each option, optional is set to true to prevent forcing Fastlane to be interactive and prompting for input
|
32
|
+
def self.available_options
|
33
|
+
[
|
34
|
+
FastlaneCore::ConfigItem.new(key: :dev_target,
|
35
|
+
env_name: "ROKUAPPUTIL_DEV_TARGET",
|
36
|
+
description: "The IP of the Roku dev target",
|
37
|
+
optional: true,
|
38
|
+
type: String)
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.is_supported?(platform)
|
43
|
+
[:roku].include?(platform)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'fastlane_core/ui/ui'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
UI = FastlaneCore::UI unless Fastlane.const_defined?(:UI)
|
5
|
+
|
6
|
+
module Helper
|
7
|
+
class RokuAppUtilHelper
|
8
|
+
def self.roku_dev_server_check(params)
|
9
|
+
validate_params(params, [:dev_target])
|
10
|
+
|
11
|
+
target = params[:dev_target]
|
12
|
+
|
13
|
+
# Check if device is on the network and responding with a quick ping
|
14
|
+
ping_args = ''
|
15
|
+
if FastlaneCore::Helper.linux?
|
16
|
+
ping_args = '-c 1 -w 1'
|
17
|
+
elsif FastlaneCore::Helper.mac?
|
18
|
+
ping_args = '-c 1 -W 1'
|
19
|
+
else
|
20
|
+
ping_args = '-c 1'
|
21
|
+
end
|
22
|
+
|
23
|
+
`ping #{ping_args} #{target}`
|
24
|
+
if $?.exitstatus != 0
|
25
|
+
UI.shell_error!('Device is not responding to ping')
|
26
|
+
end
|
27
|
+
|
28
|
+
# Check ECP, to verify we are talking to a Roku
|
29
|
+
check_device_response = `curl --connect-timeout 2 --silent http://#{target}:8060`
|
30
|
+
if $?.exitstatus != 0
|
31
|
+
UI.shell_error!('Device is not responding to ECP - is it a Roku?')
|
32
|
+
end
|
33
|
+
|
34
|
+
parsed_device_names = validate_response_match(check_device_response, %r{<friendlyName>(.*?)</friendlyName>}m)
|
35
|
+
# Message the device friendly name
|
36
|
+
UI.message("Device reports as #{parsed_device_names[0]}")
|
37
|
+
|
38
|
+
# Check the dev web server - check to see if the developer mode is enable
|
39
|
+
`curl --connect-timeout 2 --silent http://#{target}`
|
40
|
+
|
41
|
+
if $?.exitstatus != 0
|
42
|
+
UI.shell_error!('Device server is not responding - is the developer mode enabled?')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.roku_app_install(params)
|
47
|
+
roku_dev_server_check(params)
|
48
|
+
|
49
|
+
validate_params(params, [:dev_user, :dev_pass, :zip_path])
|
50
|
+
|
51
|
+
# Variables
|
52
|
+
# roku username when enable the developer mode
|
53
|
+
user = params[:dev_user]
|
54
|
+
# roku password when enable the developer mode
|
55
|
+
pass = params[:dev_pass]
|
56
|
+
# roku device ip
|
57
|
+
target = params[:dev_target]
|
58
|
+
# Complete path where the zip lives
|
59
|
+
zip_path = params[:zip_path]
|
60
|
+
# curl timeout value
|
61
|
+
timeout = 10
|
62
|
+
user_pass = "#{user}:#{pass}"
|
63
|
+
|
64
|
+
output = `curl --user #{user_pass} --digest --silent --show-error --connect-timeout #{timeout} -F \"mysubmit=Install\" -F \"archive=@#{zip_path}\" http://#{target}/plugin_install`
|
65
|
+
|
66
|
+
# Check exit code
|
67
|
+
if $?.exitstatus != 0
|
68
|
+
UI.shell_error!("Curl exit code #{$?.exitstatus}. See URL for meaning: https://everything.curl.dev/usingcurl/returns#available-exit-codes")
|
69
|
+
end
|
70
|
+
|
71
|
+
parsed_responses = validate_response_match(output, %r{<font color="red">(.*?)</font>}m)
|
72
|
+
result = parsed_responses[0]
|
73
|
+
# Dev server installation output will display 'Application Received' if app is installed successfully (or already is)
|
74
|
+
unless result.include?("Application Received")
|
75
|
+
UI.shell_error!("Error from Roku: #{result}")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.roku_app_uninstall(params)
|
80
|
+
roku_dev_server_check(params)
|
81
|
+
|
82
|
+
validate_params(params, [:dev_user, :dev_pass])
|
83
|
+
|
84
|
+
# Variables
|
85
|
+
# roku username when enable the developer mode
|
86
|
+
user = params[:dev_user]
|
87
|
+
# roku password when enable the developer mode
|
88
|
+
pass = params[:dev_pass]
|
89
|
+
# roku device ip
|
90
|
+
target = params[:dev_target]
|
91
|
+
user_pass = "#{user}:#{pass}"
|
92
|
+
|
93
|
+
http_status = `curl --user #{user_pass} --digest --silent --show-error -F \"mysubmit=Delete\" -F \"archive=\" --write-out \"%{http_code}\" http://#{target}/plugin_install`
|
94
|
+
|
95
|
+
# Check exit code
|
96
|
+
if $?.exitstatus != 0
|
97
|
+
UI.shell_error!("Curl exit code #{$?.exitstatus}. See URL for meaning: https://everything.curl.dev/usingcurl/returns#available-exit-codes")
|
98
|
+
end
|
99
|
+
parsed_responses = validate_response_match(http_status, %r{<font color="red">(.*?)</font>}m)
|
100
|
+
result = parsed_responses[0]
|
101
|
+
|
102
|
+
# Dev server uninstall build will display 'Delete Succeeded' result if app is uninstalled successfully
|
103
|
+
unless result.include?("Delete Succeeded.")
|
104
|
+
UI.message("Uninstall failed - was the app installed? Result from Roku: #{result}")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.roku_app_package(params)
|
109
|
+
roku_app_install(params)
|
110
|
+
|
111
|
+
validate_params(params, [:sign_key, :app_name, :app_version])
|
112
|
+
|
113
|
+
# Variables
|
114
|
+
# roku username when enable the developer mode
|
115
|
+
user = params[:dev_user]
|
116
|
+
# roku password when enable the developer mode
|
117
|
+
pass = params[:dev_pass]
|
118
|
+
# roku device ip
|
119
|
+
target = params[:dev_target]
|
120
|
+
# developer's signing key (from genkey)
|
121
|
+
sign_key = params[:sign_key]
|
122
|
+
# application name
|
123
|
+
app_name = params[:app_name]
|
124
|
+
# application version
|
125
|
+
app_version = params[:app_version]
|
126
|
+
# pkg_output_path: default to current folder
|
127
|
+
pkg_output_path = params[:pkg_output_path]
|
128
|
+
|
129
|
+
user_pass = "#{user}:#{pass}"
|
130
|
+
app_name_version = "#{app_name}/#{app_version}"
|
131
|
+
current_time = Time.now.strftime('%s')
|
132
|
+
|
133
|
+
# Package POST to roku device
|
134
|
+
package_output = `curl --user #{user_pass} --digest --silent --show-error -F \"mysubmit=Package\" -F \"app_name=#{app_name_version}\" -F \"passwd=#{sign_key}\" -F \"pkg_time=#{current_time}\" http://#{target}/plugin_package`
|
135
|
+
# Check exit code
|
136
|
+
if $?.exitstatus != 0
|
137
|
+
UI.shell_error!("Curl exit code #{$?.exitstatus}. See URL for meaning: https://everything.curl.dev/usingcurl/returns#available-exit-codes")
|
138
|
+
end
|
139
|
+
|
140
|
+
parsed_responses = validate_response_match(package_output, %r{<font color="red">(.*?)</font>}m)
|
141
|
+
result = parsed_responses[0]
|
142
|
+
# Dev server installation output will display 'Success' if app is packaged successfully
|
143
|
+
unless result.include?("Success")
|
144
|
+
UI.shell_error!("Error from Roku: #{result}")
|
145
|
+
end
|
146
|
+
|
147
|
+
UI.success("Roku app signed")
|
148
|
+
UI.message("Starting the package download")
|
149
|
+
|
150
|
+
# If there isn't error you should find the zip url inside a '<a>' tag
|
151
|
+
package_output_matched = validate_response_match(package_output, %r{<a href="pkgs//(.*?)"})
|
152
|
+
# Set the name of the file should be the first match
|
153
|
+
package_name = package_output_matched[0]
|
154
|
+
|
155
|
+
# Use a combination of the app name & version for the output package file name
|
156
|
+
output_package_file = "#{app_name}_#{app_version}.pkg".gsub(' ', '_')
|
157
|
+
# download and rename package to pkg_output_path
|
158
|
+
Dir.chdir(pkg_output_path) do
|
159
|
+
`curl --user #{user_pass} --digest --silent --show-error --output #{output_package_file} http://#{target}/pkgs/#{package_name}`
|
160
|
+
# Check exit code
|
161
|
+
if $?.exitstatus != 0
|
162
|
+
UI.shell_error!("Curl exit code #{$?.exitstatus}. See URL for meaning: https://everything.curl.dev/usingcurl/returns#available-exit-codes")
|
163
|
+
end
|
164
|
+
|
165
|
+
# Check if file exists
|
166
|
+
unless File.file?(output_package_file.to_s)
|
167
|
+
UI.shell_error!("Unable to download package")
|
168
|
+
end
|
169
|
+
end
|
170
|
+
# Return the full path to the output package file
|
171
|
+
return File.expand_path(output_package_file)
|
172
|
+
end
|
173
|
+
|
174
|
+
# A helper method to check if all the necessary parameters are set
|
175
|
+
# params: An array containing all the parameters to check
|
176
|
+
# keys: An array of keys to use in params
|
177
|
+
def self.validate_params(params, keys)
|
178
|
+
# Check if required parameter is defined, if not throw the error
|
179
|
+
keys.each do |key|
|
180
|
+
value = params[key]
|
181
|
+
if value.nil? || (value.size == 0)
|
182
|
+
UI.user_error!("#{key} parameter is not set")
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Helper to check if a response from a curl match the desired regex
|
188
|
+
# response: All the response from the curl
|
189
|
+
# regex: Regular expression/pattern to be search in the response
|
190
|
+
def self.validate_response_match(response, regex)
|
191
|
+
if response.nil? || (response.size == 0)
|
192
|
+
UI.shell_error!("Device returned no output")
|
193
|
+
end
|
194
|
+
output_matched = response.match(regex)
|
195
|
+
if output_matched.nil? || (output_matched.size == 0)
|
196
|
+
UI.shell_error!("Unexpected output")
|
197
|
+
end
|
198
|
+
possible_matches = output_matched.captures
|
199
|
+
if possible_matches.nil? || (possible_matches.size == 0)
|
200
|
+
UI.shell_error!("Couldn't parse results")
|
201
|
+
end
|
202
|
+
return possible_matches
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'fastlane/plugin/roku_app_util/version'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module RokuAppUtil
|
5
|
+
# Return all .rb files inside the "actions" and "helper" directory
|
6
|
+
def self.all_classes
|
7
|
+
Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# By default we want to import all available actions and helpers
|
13
|
+
# A plugin can contain any number of actions and plugins
|
14
|
+
Fastlane::RokuAppUtil.all_classes.each do |current|
|
15
|
+
require current
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fastlane-plugin-roku_app_util
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Onyx Mueller
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-09-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fastlane
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.199.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.199.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec_junit_formatter
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.12.1
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.12.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop-performance
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-require_tools
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: simplecov
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description:
|
154
|
+
email: onyx.mueller@warnermedia.com
|
155
|
+
executables: []
|
156
|
+
extensions: []
|
157
|
+
extra_rdoc_files: []
|
158
|
+
files:
|
159
|
+
- LICENSE
|
160
|
+
- README.md
|
161
|
+
- lib/fastlane/plugin/roku_app_util.rb
|
162
|
+
- lib/fastlane/plugin/roku_app_util/actions/roku_app_install_action.rb
|
163
|
+
- lib/fastlane/plugin/roku_app_util/actions/roku_app_package_action.rb
|
164
|
+
- lib/fastlane/plugin/roku_app_util/actions/roku_app_uninstall_action.rb
|
165
|
+
- lib/fastlane/plugin/roku_app_util/actions/roku_dev_server_check_action.rb
|
166
|
+
- lib/fastlane/plugin/roku_app_util/helper/roku_app_util_helper.rb
|
167
|
+
- lib/fastlane/plugin/roku_app_util/version.rb
|
168
|
+
homepage: https://github.com/WarnerMedia/fastlane-plugin-roku_app_util
|
169
|
+
licenses:
|
170
|
+
- MIT
|
171
|
+
metadata: {}
|
172
|
+
post_install_message:
|
173
|
+
rdoc_options: []
|
174
|
+
require_paths:
|
175
|
+
- lib
|
176
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '2.5'
|
181
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - ">="
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0'
|
186
|
+
requirements: []
|
187
|
+
rubygems_version: 3.1.2
|
188
|
+
signing_key:
|
189
|
+
specification_version: 4
|
190
|
+
summary: Fastlane plugin for Roku app utility.
|
191
|
+
test_files: []
|