rokucommunity / roku-deploy Goto Github PK
View Code? Open in Web Editor NEWAn npm module for zipping and deploying to Roku devices.
License: MIT License
An npm module for zipping and deploying to Roku devices.
License: MIT License
Error: TypeError: rokuDeploy is not a function
Code:
const rokuDeploy = require('roku-deploy');
const configs = require('../rokudeploy.json');
rokuDeploy(configs)
.then(() => console.log('deployed'))
.catch((e) => console.log(e));
Note that npm run deploy
runs with no errors with package.json:
"scripts": {
"deploy": "roku-deploy"
}
I would expect these two patterns to be equivalent:
"components/*",
{ src: "components/*" }
According to the documentation, for {src;dest;}
objects, when dest
is omitted, the root of the output folder is assumed
. However, the current implementation (v3.5.3) does not work that way.
Consider the file components/CustomButton.brs
.
"components/*"
results in pkg:/components/CustomButton.brs
. (as expected){src: "components/*" }
results in pkg:/CustomButton.brs
(unexpected)This should be corrected so that the src;dest
pattern works the same as the raw string approach. However, this would be a breaking change, so we need to consider that.
Allow options (perhaps in bsconfig.json) to specify args passed when launching, things like mediaType
and contentId
To allow launching with deep link data directly.
It would be nice that brighterscript require('brighterscript').ProgramBuilder
can take these launch arguments and pass them to the app on Roku.
Just wanted to add an option to not delete the previously installed channel upon publishing as sometimes it proves to be unneccesary and delete local storage files associated with the channel and can slow down iteration time.
I get ESOCKETTIMEDOUT error at every attempt via roku-deploy for a simple project, but uploading roku-deploy.zip
via Roku web server works
Log:
npm run deploy
> [email protected] deploy
> roku-deploy
Error: ESOCKETTIMEDOUT
at ClientRequest.<anonymous> (C:\Users\DeKaN\IdeaProjects\roku-sdk\composer\node_modules\request\request.js:816:19)
at Object.onceWrapper (node:events:509:28)
at ClientRequest.emit (node:events:390:28)
at Socket.emitRequestTimeout (node:_http_client:763:9)
at Object.onceWrapper (node:events:509:28)
at Socket.emit (node:events:402:35)
at Socket._onTimeout (node:net:486:8)
at listOnTimeout (node:internal/timers:557:17)
at processTimers (node:internal/timers:500:7) {
code: 'ESOCKETTIMEDOUT',
connect: false
}
package.json's scripts:
"scripts": {
"build": "bsc",
"deploy": "roku-deploy",
"lint": "bslint --project ./bsconfig.json",
"package": "bsc --create-package",
"validate": "bsc --create-package=false --copy-to-staging=false"
}
rokudeploy.json:
{
"rootDir": "dist",
"remoteDebug": true,
"logLevel": "debug",
"host": "192.168.1.22",
"password": "123456"
}
bsconfig.json:
// https://github.com/rokucommunity/brighterscript brighterscript config
{
"rootDir": "src",
"files": [
"manifest",
"source/**/*.*",
"components/**/*.*",
"images/**/*.*"
],
"plugins": ["@rokucommunity/bslint"],
"stagingFolderPath": "dist",
"retainStagingFolder": true,
"autoImportComponentScript": true,
"sourceMap": true,
"debug": {
"enableDebugProtocol": true
}
}
The default value for the files
array was created a long time ago, and there are a few enhancements I think we should make.
Here's my proposal for the updated files array.
{
"files": [
//current files array
"source/**/*.*",
"components/**/*.*",
"images/**/*.*:",
"manifest",
//new entries
"locale/**/*",
"fonts/**/*",
//exclude root-level node_modules folder
"!node_modules",
//exclude markdown files, mac and windows fs database files
"!**/*.{md,DS_Store,db}",
]
}
Is there anything else I'm missing?
Roku recommends doing squashfs conversion now and should be added in
Could we have better error messages for certain types of invalid src;dest
objects? For example:
`` { src: "../manifest", dest: "./"}``` This one should be easy to detect. We could run
src` through the `glob.hasMagic` method, and if it's not a magic string, check for `fsExtra.isFile` or `fsExtra.isDir`. Then, we know for sure that the path on the right needs to be a path to a file, or if referencing a dir, throw an error saying directories can't be referenced directly.
The two use cases that justify this request:
Throw better errors / or successes with better details. Use cases where we don’t return a value (We should be able to return the actual response (and everything else) for external code to process)
This is probably a breaking change.
Example rekeying function in js:
module.exports.rekey = function(target, devPass, pkgPass, rekeyPath, timeout, callback) {
var url = `http://${target}/plugin_inspect`;
var auth = {
user: 'rokudev',
pass: devPass,
sendImmediately: false
};
var data = {
mysubmit: 'Rekey',
passwd: pkgPass,
archive: fs.createReadStream(rekeyPath)
};
console.log()
console.log(`Rekeying ${target} from ${rekeyPath}`);
console.log()
request.post({url: url, auth: auth, formData: data, timeout: timeout}, (err, response, body) => {
if (checkNetworkError(err, response) === false) {
if (body.match(/<font color="red">Success.<\/font>/) === null) {
/* If some other failure, such as out of space, report it here */
let errorMessages = body.match(/<font color="red">([^<]*)/);
if (errorMessages !== null) {
errorMessages.shift()
errorMessages.forEach((message) => {
console.log(`Device install error: ${message}`);
});
}
else {
console.log("Rekey failed");
}
}
else {
console.log("Rekey succeeded");
}
callback();
}
else {
callback(err);
}
});
}
Currently the files
array only supports files found within rootDir
. It would be useful to support files found outside of the root dir, whether it be via an absolute file path or a relative path that uses ..
to walk backwards. So something like this:
"files": [
"manifest",
"source/**/*.*",
"C:/projects/common/lib.brs"
]
Would copy lib.brs
to the root of the outDir
.
You could also do this:
"files": [
"manifest",
"source/**/*.*",
{
"src": "C:/projects/common/lib.brs",
"dest": "common"
}
}
Would copy lib.brs
to outDir/common/lib.brs
.
You could also do this:
"files": [
"manifest",
"source/**/*.*",
{
"src": "../common/lib.brs",
"dest": "common"
}
}
Would copy lib.brs
to outDir/common/lib.brs
.
When running roku deploy the following things happen
I can repeat this for the samples project https://github.com/rokudev/samples/tree/master/getting%20started/SceneGraphTutorial
Simply add in the required information and either create a node script or create a file calling these methods. Both result in the same issue when running deploy.
rokudeploy.json
"host": "192.168.1.14", // your device IP
"password": "test" // your device password
Is there anything I'm missing?
Output message after successful deployment:
{
message: 'Successful deploy',
results: {
response: IncomingMessage {
_readableState: [ReadableState],
readable: false,
_events: [Object: null prototype],
_eventsCount: 4,
_maxListeners: undefined,
socket: [Socket],
connection: [Socket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 200,
statusMessage: 'OK',
client: [Socket],
_consuming: true,
_dumped: false,
req: [ClientRequest],
request: [Request],
toJSON: [Function: responseToJSON],
caseless: [Caseless],
body: '<html>\n' +
'<head>\n' +
' <meta charset="utf-8">\n' +
' <meta name="HandheldFriendly" content="True">\n' +
' <title> Roku Development Kit </title>\n' +
'\n' +
' <link rel="stylesheet" type="text/css" media="screen" href="css/global.css" />\n' +
'</head>\n' +
'<body>\n' +
' <div id="root" style="background: #fff">\n' +
' \n' +
' \n' +
' </div>\n' +
'\n' +
' <!-- Keep it, so old scripts can continue to work -->\n' +
' <div style="display:none">\n' +
' <font color="red">Application Received: 794759 bytes stored.\n' +
'</font>\n' +
' <font color="red">Install Success.</font>\n' +
' <p><font face="Courier">16af54a339fa3051f2b248c15d3d4d09 <br /> zip file in internal memory (794759 bytes)</font></p>\n' +
' </div>\n' +
'\n' +
' <script type="text/javascript" src="css/global.js"></script>\n' +
' <script type="text/javascript">\n' +
' \n' +
' // Include core components and resounce bundle (needed)\n' +
' Shell.resource.set(null, {\n' +
' endpoints: {} \n' +
' });\n' +
" Shell.create('Roku.Event.Key');\n" +
" Shell.create('Roku.Events.Resize');\n" +
" Shell.create('Roku.Events.Scroll'); \n" +
'\n' +
' // Create global navigation and render it\n' +
" var nav = Shell.create('Roku.Nav')\n" +
" .trigger('Enable standalone and utility mode - hide user menu, shopping cart, and etc.')\n" +
" .trigger('Use compact footer')\n" +
" .trigger('Hide footer')\n" +
" .trigger('Render', document.getElementById('root'))\n" +
' // Create custom links\n' +
" .trigger('Remove all feature links from header')\n" +
" .trigger('Add feature link in header', {\n" +
" text: 'Installer',\n" +
" url: 'plugin_install'\n" +
' })\n' +
" .trigger('Add feature link in header', {\n" +
" text: 'Utilities',\n" +
" url: 'plugin_inspect'\n" +
' })\n' +
' \n' +
" .trigger('Add feature link in header', { text: 'Packager (no dev key)' });\n" +
'\n' +
' // Retrieve main content body node\n' +
" var node = nav.invoke('Get main body section mounting node');\n" +
' \n' +
' // Create page container and page header\n' +
" var container = Shell.create('Roku.Nav.Page.Standard').trigger('Render', node);\n" +
" node = container.invoke('Get main body node');\n" +
" container.invoke('Get headline node').innerHTML = 'Development Application Installer';\n" +
'\n' +
` node.innerHTML = '<p>Currently Installed Application:</p><p><font face="Courier">16af54a339fa3051f2b248c15d3d4d09 <br /> zip file in internal memory (794759 bytes)</font></p>';\n` +
'\n' +
' // Set up form in main body content area\n' +
" form = Shell.create('Roku.Form')\n" +
" .trigger('Set form action URL', 'plugin_install')\n" +
" .trigger('Set form encryption type to multi-part')\n" +
' .trigger("Add file upload button", { \n' +
' name: "archive",\n' +
' label: "File:" \n' +
' })\n' +
' .trigger("Add hidden input field", {\n' +
' name: "mysubmit"\n' +
' });\n' +
'\n' +
' // Render some buttons\n' +
" var Delete = document.createElement('BUTTON');\n" +
" Delete.className = 'roku-button';\n" +
" Delete.innerHTML = 'Delete';\n" +
' Delete.onclick = function() {\n' +
" form.trigger('Update input field value', { name: 'mysubmit', value: 'Delete'})\n" +
" form.trigger('Force submit'); \n" +
' };\n' +
' node.appendChild(Delete);\n' +
' \n' +
' if (true)\n' +
' {\n' +
' // Render some buttons\n' +
" var convert = document.createElement('BUTTON');\n" +
" convert.className = 'roku-button';\n" +
" convert.innerHTML = 'Convert to cramfs';\n" +
' convert.onclick = function() {\n' +
" form.trigger('Update input field value', { name: 'mysubmit', value: 'Convert to cramfs'})\n" +
" form.trigger('Force submit'); \n" +
' };\n' +
' node.appendChild(convert);\n' +
'\n' +
" var convert2 = document.createElement('BUTTON');\n" +
" convert2.className = 'roku-button';\n" +
" convert2.innerHTML = 'Convert to squashfs';\n" +
' convert2.onclick = function() {\n' +
" form.trigger('Update input field value', { name: 'mysubmit', value: 'Convert to squashfs'})\n" +
" form.trigger('Force submit'); \n" +
' };\n' +
' node.appendChild(convert2);\n' +
' }\n' +
' \n' +
" var hrDiv = document.createElement('div');\n" +
" hrDiv.innerHTML = '<hr />';\n" +
' node.appendChild(hrDiv);\n' +
'\n' +
" form.trigger('Render', node);\n" +
'\n' +
' // Render some buttons\n' +
" var submit = document.createElement('BUTTON');\n" +
" submit.className = 'roku-button';\n" +
" submit.innerHTML = 'Replace';\n" +
' submit.onclick = function() {\n' +
" form.trigger('Update input field value', { name: 'mysubmit', value: 'replace'})\n" +
" if(form.invoke('Validate and get input values').valid === true) {\n" +
" form.trigger('Force submit'); \n" +
' }\n' +
' };\n' +
' node.appendChild(submit);\n' +
'\n' +
" var d = document.createElement('div');\n" +
" d.innerHTML = '<br />';\n" +
' node.appendChild(d);\n' +
'\n' +
' // Reder messages (info, error, and success)\n' +
" Shell.create('Roku.Message').trigger('Set message type', 'success').trigger('Set message content', 'Application Received: 794759 bytes stored.').trigger('Render', node);\n" +
' \n' +
" Shell.create('Roku.Message').trigger('Set message type', 'success').trigger('Set message content', 'Install Success.').trigger('Render', node);\n" +
'\n' +
' </script>\n' +
'\n' +
'</body>\n' +
'</html>\n',
[Symbol(kCapture)]: false
},
body: '<html>\n' +
'<head>\n' +
' <meta charset="utf-8">\n' +
' <meta name="HandheldFriendly" content="True">\n' +
' <title> Roku Development Kit </title>\n' +
'\n' +
' <link rel="stylesheet" type="text/css" media="screen" href="css/global.css" />\n' +
'</head>\n' +
'<body>\n' +
' <div id="root" style="background: #fff">\n' +
' \n' +
' \n' +
' </div>\n' +
'\n' +
' <!-- Keep it, so old scripts can continue to work -->\n' +
' <div style="display:none">\n' +
' <font color="red">Application Received: 794759 bytes stored.\n' +
'</font>\n' +
' <font color="red">Install Success.</font>\n' +
' <p><font face="Courier">16af54a339fa3051f2b248c15d3d4d09 <br /> zip file in internal memory (794759 bytes)</font></p>\n' +
' </div>\n' +
'\n' +
' <script type="text/javascript" src="css/global.js"></script>\n' +
' <script type="text/javascript">\n' +
' \n' +
' // Include core components and resounce bundle (needed)\n' +
' Shell.resource.set(null, {\n' +
' endpoints: {} \n' +
' });\n' +
" Shell.create('Roku.Event.Key');\n" +
" Shell.create('Roku.Events.Resize');\n" +
" Shell.create('Roku.Events.Scroll'); \n" +
'\n' +
' // Create global navigation and render it\n' +
" var nav = Shell.create('Roku.Nav')\n" +
" .trigger('Enable standalone and utility mode - hide user menu, shopping cart, and etc.')\n" +
" .trigger('Use compact footer')\n" +
" .trigger('Hide footer')\n" +
" .trigger('Render', document.getElementById('root'))\n" +
' // Create custom links\n' +
" .trigger('Remove all feature links from header')\n" +
" .trigger('Add feature link in header', {\n" +
" text: 'Installer',\n" +
" url: 'plugin_install'\n" +
' })\n' +
" .trigger('Add feature link in header', {\n" +
" text: 'Utilities',\n" +
" url: 'plugin_inspect'\n" +
' })\n' +
' \n' +
" .trigger('Add feature link in header', { text: 'Packager (no dev key)' });\n" +
'\n' +
' // Retrieve main content body node\n' +
" var node = nav.invoke('Get main body section mounting node');\n" +
' \n' +
' // Create page container and page header\n' +
" var container = Shell.create('Roku.Nav.Page.Standard').trigger('Render', node);\n" +
" node = container.invoke('Get main body node');\n" +
" container.invoke('Get headline node').innerHTML = 'Development Application Installer';\n" +
'\n' +
` node.innerHTML = '<p>Currently Installed Application:</p><p><font face="Courier">16af54a339fa3051f2b248c15d3d4d09 <br /> zip file in internal memory (794759 bytes)</font></p>';\n` +
'\n' +
' // Set up form in main body content area\n' +
" form = Shell.create('Roku.Form')\n" +
" .trigger('Set form action URL', 'plugin_install')\n" +
" .trigger('Set form encryption type to multi-part')\n" +
' .trigger("Add file upload button", { \n' +
' name: "archive",\n' +
' label: "File:" \n' +
' })\n' +
' .trigger("Add hidden input field", {\n' +
' name: "mysubmit"\n' +
' });\n' +
'\n' +
' // Render some buttons\n' +
" var Delete = document.createElement('BUTTON');\n" +
" Delete.className = 'roku-button';\n" +
" Delete.innerHTML = 'Delete';\n" +
' Delete.onclick = function() {\n' +
" form.trigger('Update input field value', { name: 'mysubmit', value: 'Delete'})\n" +
" form.trigger('Force submit'); \n" +
' };\n' +
' node.appendChild(Delete);\n' +
' \n' +
' if (true)\n' +
' {\n' +
' // Render some buttons\n' +
" var convert = document.createElement('BUTTON');\n" +
" convert.className = 'roku-button';\n" +
" convert.innerHTML = 'Convert to cramfs';\n" +
' convert.onclick = function() {\n' +
" form.trigger('Update input field value', { name: 'mysubmit', value: 'Convert to cramfs'})\n" +
" form.trigger('Force submit'); \n" +
' };\n' +
' node.appendChild(convert);\n' +
'\n' +
" var convert2 = document.createElement('BUTTON');\n" +
" convert2.className = 'roku-button';\n" +
" convert2.innerHTML = 'Convert to squashfs';\n" +
' convert2.onclick = function() {\n' +
" form.trigger('Update input field value', { name: 'mysubmit', value: 'Convert to squashfs'})\n" +
" form.trigger('Force submit'); \n" +
' };\n' +
' node.appendChild(convert2);\n' +
' }\n' +
' \n' +
" var hrDiv = document.createElement('div');\n" +
" hrDiv.innerHTML = '<hr />';\n" +
' node.appendChild(hrDiv);\n' +
'\n' +
" form.trigger('Render', node);\n" +
'\n' +
' // Render some buttons\n' +
" var submit = document.createElement('BUTTON');\n" +
" submit.className = 'roku-button';\n" +
" submit.innerHTML = 'Replace';\n" +
' submit.onclick = function() {\n' +
" form.trigger('Update input field value', { name: 'mysubmit', value: 'replace'})\n" +
" if(form.invoke('Validate and get input values').valid === true) {\n" +
" form.trigger('Force submit'); \n" +
' }\n' +
' };\n' +
' node.appendChild(submit);\n' +
'\n' +
" var d = document.createElement('div');\n" +
" d.innerHTML = '<br />';\n" +
' node.appendChild(d);\n' +
'\n' +
' // Reder messages (info, error, and success)\n' +
" Shell.create('Roku.Message').trigger('Set message type', 'success').trigger('Set message content', 'Application Received: 794759 bytes stored.').trigger('Render', node);\n" +
' \n' +
" Shell.create('Roku.Message').trigger('Set message type', 'success').trigger('Set message content', 'Install Success.').trigger('Render', node);\n" +
'\n' +
' </script>\n' +
'\n' +
'</body>\n' +
'</html>\n'
}
}
const signedPackage = await signExistingPackage(options);
const retrievedPackage = await retrieveSignedPackage(signedPackage, options);
// file hasn't finished downloading at this point
Roku-deploy uses the "request" package - a deprecated NPM package
There is a security vulnerability with the current version that roku-deploy uses (v2.88.0). We should update the package to the latest version(v2.88.2) or replace with a better maintained NPM package
It would be nice to have multiple levels of logging in roku-deploy
to help debug issues when they arise. Here are the following tasks necessary to complete this:
add new option to RokuDeployOptions
called logLevel
with the following signature:
logLevel: 'error' | 'warn' | 'log' | 'info' | 'debug' | 'trace'
logLevel
should be supported in the following scenarios:
--log-level
from the command line (see this section in brighterscript for how to parse from the command line).options: RokuDeployOptions
anywhere in roku-deploy
roku-deploy.json
bsconfig.json
use @rokucommunity/logger package in this project, and make it an instance variable on the RokuDeploy
class so it can be mocked or swapped out during tests or other situations.
convert any current console.*
calls in roku-deploy
to use this.logger.*
.
add additional logging calls as needed
We need proper documentation for:
Sometimes roku-deploy just returns a string as the response from doing something. That's not overly helpful .We should do a much better job return a structured response/status object so the callers can make more informed decisions about this stuff.
Problems to solve:
info
, warn
, error
stuff. we're not logging those. we should. So if we're gonna throw, we should log better reasons why.We might need to append rokuMessages to every error.
interface RokuDeployError {
message: string;
stack: any;
rokuMessages: RokuMessages;
}
As of node 19 the form post requests all fail with a ECONNRESET. This does not happen on 18.
To simplify logic (globs, string replacements, etc...) we should force all incoming paths to use forward slashes. Then, only on the way out would we replace them with the os-specific path separator. This would help slightly with performance, and also simplify our internal logic.
My bsconfig.json looks like this
{
"extends": "config/bsconfig.base.json",
...
}
But roku deploy does not seem to read from config/bsconfig.base.json
Making this fails (because it's looking in the wrong staging folder)
rokuDeploy.zipPackage({
outDir: '.',
outFile: zip_name
}).then(function(){
console.log(`${zip_name} created`)
}, function(error) {
console.error(error);
});
Fix #104 by using a different http library. I think Axios would be a good library to use.
We need to replace all usage of the request
module with axios
, and update the corresponding code in the RokuDeploy logic to work with axios
.
Make sure to run the device tests to make sure these all work.
npm run test:device
for automated build systems, like some clients have, it'd be great to be able to get support for generating dev keys, as per https://developer.roku.com/docs/developer-program/publishing/packaging-channels.md
suggestion
credentials = rokuDeploy.generateDeveloperKeys(options);
where credentials would resolve to
{
password: foo
dev_id: bar
}
Pressing home should no longer be needed. We should try removing it to speed up deployments and if needed making an option if it causes issues in some specific cases.
In order to leverage the Brightscript profiler:
https://developer.roku.com/en-gb/docs/developer-program/dev-tools/brightscript-profiler.md
It would be convenient, if the following values are set in the manifest:
bsprof_enable=1
bsprof_data_dest=network
that roku-deploy
would automatically pipe the profiling output from host:8080 into a profile-<timestamp>.bsprof
.
Additionally there could be a --profile
flag for roku-deploy
to automatically set the aformentioned flags.
When using roku-deploy in a typescript file, the jsdoc information doesn't show up when using the roku-deploy imports. I believe this is because the index.ts
creates local variables and then exports those. We should investigate how to fix this, as the typescript experience is lacking without full documentation info.
Currently roku-deploy doesn't handle anything other than doing a regular deployment to the device while developing. In order to help make this the base for a more formalized CI/CD script we need to at minimum be able to make a signed package file for upload to Roku as well. Being able to switch Dev ID would be nice as well but is not required.
We should allow negated top-level strings that point outside of rootDir.
{
"files": [
//currently unsupported, will throw error saying "don't use top level strings to reference files outside of rootDir"
"!../someExternalDir/**/*",
//this works.
{ "src": "!../someExternalDir/**/*"}
]
}
Modify roku-deploy so that both examples above will work
I would like to modify some files before zipping the project. I know the possibility of using the incrementBuildNumber parameter but it doesn't work for me because I need to change the version number in several files and I also need to remove one line from another file when build a release. I have modified the file that calls rokudeploy to receive the version as parameter, but now I don't know how to modify those files. Is it possible?
Adding this issue to help track this bug. We are implementing a temporary work around but ultimately want to fix the underlying cause.
When the outFile
configuration value in RokuDeployOptions
gets too long the package fails to download.
This is the error output after a ~3 minute timeout:
Error: ESOCKETTIMEDOUT
at ClientRequest.<anonymous> (/Users/christianholbrook/work/rokukor/node_modules/postman-request/request.js:1138:19)
at Object.onceWrapper (node:events:627:28)
at ClientRequest.emit (node:events:513:28)
at ClientRequest.emit (node:domain:489:12)
at Socket.emitRequestTimeout (node:_http_client:839:9)
at Object.onceWrapper (node:events:627:28)
at Socket.emit (node:events:525:35)
at Socket.emit (node:domain:489:12)
at Socket._onTimeout (node:net:550:8)
at listOnTimeout (node:internal/timers:559:17)
at processTimers (node:internal/timers:502:7)
A followup to #72
Remove all the exported functions from src/index.ts, users must import { rokuDeploy } from 'roku-deploy';
I'm working on a project where I'm using BrighterScript. Maybe I'm missing something here but I'm trying to use roku-deploy to create my signed production package. During my development workflow, I use BrighterScript either by using a vscode build task to call bsc
directly to build and deploy it or, if I need to debug, I use the vscode extension process here.
When it comes time to create a signed package, I'd like to simply use deployAndSignPackage
but that doesn't do the bsc
transpiling. I know I can manually do a bsc
build and THEN call zipPackage
, publish
, and then signExistingPackage
but is there a better way?
EDIT: I think even the method I laid out above wouldn't work for me. As part of my release I would like to increment the manifest build number but it looks like that's only called from createPackage
but that will do a full build with BS untranspiled code. :(
aside form other issues I get when using bsc, I can no longer install, either..
installing on device with args { host: '192.168.8.204',
username: 'rokudev',
password: 'aaaa',
files: [ '', '**/', '!.zip', '!**/.zip' ],
app_name: 'Smithsonian Channel/5.11',
rootDir: 'build',
rekeySignedPackage: null,
outDir: 'out',
outFile: 'roku-deploy',
signingPassword: null,
retainStagingFolder: true }
deploying to device
There was a problem while instlaling on the device SyntaxError: Unexpected token / in JSON at position 664
[12:06:53] 'deploy' errored after 8.87 ms
[12:06:53] SyntaxError: Unexpected token / in JSON at position 664
at JSON.parse ()
at RokuDeploy.getOptions (/home/george/hope/smc/pot-smithsonian-channel-roku-xm/node_modules/roku-deploy/src/RokuDeploy.ts:711:36)
at RokuDeploy. (/home/george/hope/smc/pot-smithsonian-channel-roku-xm/node_modules/roku-deploy/src/RokuDeploy.ts:653:24)
at step (/home/george/hope/smc/pot-smithsonian-channel-roku-xm/node_modules/roku-deploy/dist/RokuDeploy.js:44:23)
at Object.next (/home/george/hope/smc/pot-smithsonian-channel-roku-xm/node_modules/roku-deploy/dist/RokuDeploy.js:25:53)
at /home/george/hope/smc/pot-smithsonian-channel-roku-xm/node_modules/roku-deploy/dist/RokuDeploy.js:19:71
at new Promise ()
at __awaiter (/home/george/hope/smc/pot-smithsonian-channel-roku-xm/node_modules/roku-deploy/dist/RokuDeploy.js:15:12)
at RokuDeploy.deploy (/home/george/hope/smc/pot-smithsonian-channel-roku-xm/node_modules/roku-deploy/dist/RokuDeploy.js:856:16)
at /home/george/hope/smc/pot-smithsonian-channel-roku-xm/gulpfile.ts:176:22
It's not possible to sign a package without pointing to a staging folder in order for the script to read the manifest and get the app name and version.
It would be nice to be able to provide something like signAppNameVersion
in the options so the module doesn't need to read the manifest.
Was getting the following error on my Roku:
Error_Could not retrieve Dev ID
Invalid response code: 400
And realized it was because I didn't have a zip file loaded on the device. The Packager tab is where we get the devID is not available until a zip file has been loaded. Not sure the best solution. Could either let the user know, try to get devID a different way, upload a temporary zip file, or just ignore this check in that case.
If prepublishToStaging copies 0 files, there's probably something wrong. Add some checks into the code to dig around the file system a little bit and recommend a different rootDirectory if possible.
It would be nice to be able to use the nice features of roku-deploy using a pre-packaged app, like:
roku-deploy -infile bin/app.zip -host 1.2.3.4 -password abc
Even using the internal JS API it isn't easy to achieve.
Add command to capture screenshot from remote roku device.
Command: screenshot-and-save (specify location in user settings or roku-deploy.json)
Command: screenshot-to-clipboard
.map files are required to facilitate debugging brighterscript files.
They should not be included in zips however, so we can exlclude them in vscode, using the files glob in the launch config.
However:
Can we please have a means of exlcuding .map files (or perhaps any glob of files) from the zip; while maintaining them in the staging folder?
There's a bug on the Roku devices that sometimes causes issues when sideloading a zip file when there's already a sideloaded app. In this situation, it would be helpful to have roku-deploy
delete any existing sideloaded app before publishing a new one.
Hi, so I use submodules that exist outside the channel directory that I need a couple files brought in from. Personally I feel like symlinks would be easiest to use however currently Roku-Deploy zips the actual symlink instead of following it.
Would it be easy to change this?
How i can modify ManifestData before deploying? i already know how to deal with rokudeploy.json but where i can modify manifest data ? As example i want to change the title of the app
Many of the roku-deploy public functions take the RokuDeployOptions interface. That's very confusing because it's huge and has many options that many of the functions don't actually need. We should do the following:
providing devId on bash, or zsh on ubuntu 18.04 results in error, even when dev id is valid.
Currently in normalizeFilesArray
, we run the src
string through util.standardizePath()
. However, this could break glob escapes. All glob paths must use forward slash for directory separators.
This is a breaking change, so it should be handled in v4.
We currently allow the global roku-deploy options to just be passed around everywhere, which makes all the functions much more confusing because most of the time they don't need most of those options.
We need to create separate objects/interfaces for each function call, so it's clear how to use each one.
Support using top-level patterns to external directories as long as there's at least 1 globstar. Example:
Consider this pattern:
"../thirdPartySDK/**/*"
For this path: ../thirdPartySDK/source/sdk.brs
, its final path would be: ./source/sdk.brs
because the globstar indicates the start of the relative path portion.
If there are multiple globstars, the first globstar is where the relative pattern will begin.
Could this tool or maybe the vscode plugin help with updating the manifest on each deployment?
My idea is to set the build version to the current repository commit hash. But I guess only in the deploy, the source manifest should be untouched of course.
We should be able to do everything in roku-deploy from the command-line. Things like move-to-stage, create zip from a folder, etc.
Here's a good example of a cli file that this feature can be modelled after.
https://github.com/rokucommunity/ropm/blob/master/src/cli.ts
We want to expose most of the public functions on the RokuDeploy class.
So tasks for this:
Here are a few examples of how we'd use it (args and names might need to be changed, but this gets the point across):
npx roku-deploy copy-to-staging --stagingDir ./staging
npx roku-deploy create-zip --stagingDir ./staging --file app.zip
npx roku-deploy deploy --host 192.168.1.123 --password --file app.zip
If no app is currently side-loaded, then we get:
Error: Delete Failed: No such file or directory.
at new FailedDeviceResponseError (node_modules/roku-deploy/dist/Errors.js:52:28)
at RokuDeploy.checkRequest (node_modules/roku-deploy/dist/RokuDeploy.js:873:19)
at RokuDeploy.<anonymous> (node_modules/roku-deploy/dist/RokuDeploy.js:830:34)
at step (node_modules/roku-deploy/dist/RokuDeploy.js:44:23)
at Object.next (node_modules/roku-deploy/dist/RokuDeploy.js:25:53)
at fulfilled (node_modules/roku-deploy/dist/RokuDeploy.js:16:58)
at processTicksAndRejections (node:internal/process/task_queues:94:5)
this is coz the HTTP delete fails - that error should be ignored.
If I get a mo, I'll put a pr up; but it's unlikely
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.