@shm-open/code-push-cli
Version:
Management CLI for the CodePush service
1,077 lines (1,075 loc) • 60.5 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.command = exports.showHelp = void 0;
var yargs_1 = __importDefault(require("yargs"));
var cli = __importStar(require("./definitions/cli"));
var chalk_1 = __importDefault(require("chalk"));
var update_notifier_1 = __importDefault(require("update-notifier"));
var parse_duration_1 = __importDefault(require("parse-duration"));
var backslash = require("backslash");
var packageJson = require('../package.json');
var ROLLOUT_PERCENTAGE_REGEX = /^(100|[1-9][0-9]|[1-9])%?$/;
var USAGE_PREFIX = 'Usage: code-push';
// Command categories are: access-key, app, release, deployment, deployment-key, login, logout, register
var isValidCommandCategory = false;
// Commands are the verb following the command category (e.g.: "add" in "app add").
var isValidCommand = false;
var wasHelpShown = false;
function showHelp(showRootDescription) {
if (!wasHelpShown) {
if (showRootDescription) {
console.log(chalk_1.default.cyan(' _____ __ ' + chalk_1.default.green(' ___ __ ')));
console.log(chalk_1.default.cyan(' / ___/__ ___/ /__' + chalk_1.default.green(' / _ \\__ _____ / / ')));
console.log(chalk_1.default.cyan('/ /__/ _ \\/ _ / -_)' + chalk_1.default.green(' ___/ // (_-</ _ \\')));
console.log(chalk_1.default.cyan('\\___/\\___/\\_,_/\\__/' + chalk_1.default.green('_/ \\_,_/___/_//_/')) +
' CLI v' +
packageJson.version);
console.log(chalk_1.default.cyan('======================================'));
console.log('');
console.log("Mobile Center CodePush is a service that enables you to deploy mobile app updates directly to your users' devices.\n");
updateCheck();
}
yargs_1.default.showHelp();
wasHelpShown = true;
}
}
exports.showHelp = showHelp;
function updateCheck() {
var notifier = (0, update_notifier_1.default)({ pkg: packageJson });
if (notifier.update) {
notifier.notify();
}
}
function accessKeyAdd(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' access-key ' + commandName + ' <accessKeyName>')
.demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
.example('access-key ' + commandName + ' "VSTS Integration"', 'Creates a new access key with the name "VSTS Integration"');
//.example("access-key " + commandName + " \"One time key\" --ttl 5m", "Creates a new access key with the name \"One time key\", which expires in 5 minutes")
//.option("ttl", { default: "60d", demand: false, description: "Duration string which specifies the amount of time that the access key should remain valid for (e.g 5m, 60d, 1y)", type: "string" });
addCommonConfiguration(yargs);
}
function accessKeyPatch(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' access-key ' + commandName + ' <accessKeyName>')
.demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
.example('access-key ' + commandName + ' "Key for build server" --name "Key for CI machine"', 'Renames the access key named "Key for build server" to "Key for CI machine"')
.example('access-key ' + commandName + ' "Key for build server" --ttl 7d', 'Updates the access key named "Key for build server" to expire in 7 days')
.option('name', {
default: null,
demand: false,
description: 'Display name for the access key',
type: 'string',
})
.option('ttl', {
default: null,
demand: false,
description: 'Duration string which specifies the amount of time that the access key should remain valid for (e.g 5m, 60d, 1y)',
type: 'string',
});
addCommonConfiguration(yargs);
}
function accessKeyList(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' access-key ' + commandName + ' [options]')
.demand(/*count*/ 0, /*max*/ 0)
.example('access-key ' + commandName, 'Lists your access keys in tabular format')
.example('access-key ' + commandName + ' --format json', 'Lists your access keys in JSON format')
.option('format', {
default: 'table',
demand: false,
description: 'Output format to display your access keys with ("json" or "table")',
type: 'string',
});
addCommonConfiguration(yargs);
}
function accessKeyRemove(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' access-key ' + commandName + ' <accessKeyName>')
.demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
.example('access-key ' + commandName + ' "VSTS Integration"', 'Removes the "VSTS Integration" access key');
addCommonConfiguration(yargs);
}
function addCommonConfiguration(yargs) {
yargs
.wrap(/*columnLimit*/ null)
.string('_') // Interpret non-hyphenated arguments as strings (e.g. an app version of '1.10').
// TODO: fix this
// .strict() // Validate hyphenated (named) arguments.
.fail(function (msg) { return showHelp(); }); // Suppress the default error message.
}
function appList(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' app ' + commandName + ' [options]')
.demand(/*count*/ 0, /*max*/ 0)
.example('app ' + commandName, 'List your apps in tabular format')
.example('app ' + commandName + ' --format json', 'List your apps in JSON format')
.option('format', {
default: 'table',
demand: false,
description: 'Output format to display your apps with ("json" or "table")',
type: 'string',
});
addCommonConfiguration(yargs);
}
function appRemove(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' app ' + commandName + ' <appName>')
.demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
.example('app ' + commandName + ' MyApp', 'Removes app "MyApp"');
addCommonConfiguration(yargs);
}
function listCollaborators(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' collaborator ' + commandName + ' <appName> [options]')
.demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
.example('collaborator ' + commandName + ' MyApp', 'Lists the collaborators for app "MyApp" in tabular format')
.example('collaborator ' + commandName + ' MyApp --format json', 'Lists the collaborators for app "MyApp" in JSON format')
.option('format', {
default: 'table',
demand: false,
description: 'Output format to display collaborators with ("json" or "table")',
type: 'string',
});
addCommonConfiguration(yargs);
}
function removeCollaborator(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' collaborator ' + commandName + ' <appName> <email>')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
.example('collaborator ' + commandName + ' MyApp foo@bar.com', 'Removes foo@bar.com as a collaborator from app "MyApp"');
addCommonConfiguration(yargs);
}
function deploymentHistoryClear(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' deployment ' + commandName + ' <appName> <deploymentName>')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
.example('deployment ' + commandName + ' MyApp MyDeployment', 'Clears the release history associated with deployment "MyDeployment" from app "MyApp"');
addCommonConfiguration(yargs);
}
function deploymentList(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' deployment ' + commandName + ' <appName> [options]')
.demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
.example('deployment ' + commandName + ' MyApp', 'Lists the deployments for app "MyApp" in tabular format')
.example('deployment ' + commandName + ' MyApp --format json', 'Lists the deployments for app "MyApp" in JSON format')
.option('format', {
default: 'table',
demand: false,
description: 'Output format to display your deployments with ("json" or "table")',
type: 'string',
})
.option('displayKeys', {
alias: 'k',
default: false,
demand: false,
description: 'Specifies whether to display the deployment keys',
type: 'boolean',
});
addCommonConfiguration(yargs);
}
function deploymentRemove(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' deployment ' + commandName + ' <appName> <deploymentName>')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
.example('deployment ' + commandName + ' MyApp MyDeployment', 'Removes deployment "MyDeployment" from app "MyApp"');
addCommonConfiguration(yargs);
}
function deploymentHistory(commandName, yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' deployment ' + commandName + ' <appName> <deploymentName> [options]')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
.example('deployment ' + commandName + ' MyApp MyDeployment', 'Displays the release history for deployment "MyDeployment" from app "MyApp" in tabular format')
.example('deployment ' + commandName + ' MyApp MyDeployment --format json', 'Displays the release history for deployment "MyDeployment" from app "MyApp" in JSON format')
.option('format', {
default: 'table',
demand: false,
description: 'Output format to display the release history with ("json" or "table")',
type: 'string',
})
.option('displayAuthor', {
alias: 'a',
default: false,
demand: false,
description: 'Specifies whether to display the release author',
type: 'boolean',
});
addCommonConfiguration(yargs);
}
var argv = yargs_1.default
.usage(USAGE_PREFIX + ' <command>')
.demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option argument.
.command('access-key', 'View and manage the access keys associated with your account', function (yargs) {
isValidCommandCategory = true;
yargs
.usage(USAGE_PREFIX + ' access-key <command>')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments.
.command('add', 'Create a new access key associated with your account', function (yargs) { return accessKeyAdd('add', yargs); })
// Mobile Center doesn't support renaming access keys or changing their TTL (which never expire), so we no longer support patch
/*
.command("patch", "Update the name and/or TTL of an existing access key", (yargs: yargs.Argv) => accessKeyPatch("patch", yargs))
*/
.command('remove', 'Remove an existing access key', function (yargs) {
return accessKeyRemove('remove', yargs);
})
.command('rm', 'Remove an existing access key', function (yargs) {
return accessKeyRemove('rm', yargs);
})
.command('list', 'List the access keys associated with your account', function (yargs) { return accessKeyList('list', yargs); })
.command('ls', 'List the access keys associated with your account', function (yargs) { return accessKeyList('ls', yargs); })
.check(function (argv, aliases) { return isValidCommand; }); // Report unrecognized, non-hyphenated command category.
addCommonConfiguration(yargs);
})
.command('app', 'View and manage your CodePush apps', function (yargs) {
isValidCommandCategory = true;
yargs
.usage(USAGE_PREFIX + ' app <command>')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments.
.command('add', 'Add a new app to your account', function (yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' app add <appName> <os> <platform>')
.demand(/*count*/ 3, /*max*/ 3) // Require exactly three non-option arguments
.example('app add MyApp ios react-native', 'Adds app "MyApp", indicating that it\'s an iOS React Native app')
.example('app add MyApp windows react-native', 'Adds app "MyApp", indicating that it\'s a Windows React Native app')
.example('app add MyApp android cordova', 'Adds app "MyApp", indicating that it\'s an Android Cordova app');
addCommonConfiguration(yargs);
})
.command('remove', 'Remove an app from your account', function (yargs) {
return appRemove('remove', yargs);
})
.command('rm', 'Remove an app from your account', function (yargs) {
return appRemove('rm', yargs);
})
.command('rename', 'Rename an existing app', function (yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' app rename <currentAppName> <newAppName>')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
.example('app rename CurrentName NewName', 'Renames app "CurrentName" to "NewName"');
addCommonConfiguration(yargs);
})
.command('list', 'Lists the apps associated with your account', function (yargs) {
return appList('list', yargs);
})
.command('ls', 'Lists the apps associated with your account', function (yargs) {
return appList('ls', yargs);
})
/*
.command("transfer", "Transfer the ownership of an app to another account", (yargs: yargs.Argv) => {
yargs.usage(USAGE_PREFIX + " app transfer <appName> <email>")
.demand(2, 2) // Require exactly two non-option arguments
.example("app transfer MyApp foo@bar.com", "Transfers the ownership of app \"MyApp\" to an account with email \"foo@bar.com\"");
addCommonConfiguration(yargs);
})
*/
.check(function (argv, aliases) { return isValidCommand; }); // Report unrecognized, non-hyphenated command category.
addCommonConfiguration(yargs);
})
.command('collaborator', 'View and manage app collaborators', function (yargs) {
isValidCommandCategory = true;
yargs
.usage(USAGE_PREFIX + ' collaborator <command>')
.demand(2, 2) // Require exactly two non-option arguments.
.command('add', 'Add a new collaborator to an app', function (yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' collaborator add <appName> <email>')
.demand(2, 2) // Require exactly two non-option arguments
.example('collaborator add MyApp foo@bar.com', 'Adds foo@bar.com as a collaborator to app "MyApp"');
addCommonConfiguration(yargs);
})
.command('remove', 'Remove a collaborator from an app', function (yargs) {
return removeCollaborator('remove', yargs);
})
.command('rm', 'Remove a collaborator from an app', function (yargs) {
return removeCollaborator('rm', yargs);
})
.command('list', 'List the collaborators for an app', function (yargs) {
return listCollaborators('list', yargs);
})
.command('ls', 'List the collaborators for an app', function (yargs) {
return listCollaborators('ls', yargs);
})
.check(function (argv, aliases) { return isValidCommand; }); // Report unrecognized, non-hyphenated command category.
addCommonConfiguration(yargs);
})
.command('debug', 'View the CodePush debug logs for a running app', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' debug <platform>')
.demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
.example('debug android', 'View the CodePush debug logs for an Android emulator or device')
.example('debug ios', 'View the CodePush debug logs for the iOS simulator');
addCommonConfiguration(yargs);
})
.command('deployment', 'View and manage your app deployments', function (yargs) {
isValidCommandCategory = true;
yargs
.usage(USAGE_PREFIX + ' deployment <command>')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments.
.command('add', 'Add a new deployment to an app', function (yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' deployment add <appName> [deploymentName]')
.demand(/*count*/ 1, /*max*/ 2) // Require the app name, with deploymentName optional (either deploymentName or --default needs to be specified)
.option('default', {
alias: 'd',
demand: false,
description: 'Add the default "Staging" and "Production" deployments',
type: 'boolean',
})
.example('deployment add MyApp --default', 'Adds default "Staging" and "Production" deployments to app "MyApp"')
.example('deployment add MyApp MyDeployment', 'Adds deployment "MyDeployment" to app "MyApp"');
addCommonConfiguration(yargs);
})
.command('clear', 'Clear the release history associated with a deployment', function (yargs) { return deploymentHistoryClear('clear', yargs); })
.command('remove', 'Remove a deployment from an app', function (yargs) {
return deploymentRemove('remove', yargs);
})
.command('rm', 'Remove a deployment from an app', function (yargs) {
return deploymentRemove('rm', yargs);
})
.command('rename', 'Rename an existing deployment', function (yargs) {
isValidCommand = true;
yargs
.usage(USAGE_PREFIX +
' deployment rename <appName> <currentDeploymentName> <newDeploymentName>')
.demand(/*count*/ 3, /*max*/ 3) // Require exactly three non-option arguments
.example('deployment rename MyApp CurrentDeploymentName NewDeploymentName', 'Renames deployment "CurrentDeploymentName" to "NewDeploymentName"');
addCommonConfiguration(yargs);
})
.command('list', 'List the deployments associated with an app', function (yargs) {
return deploymentList('list', yargs);
})
.command('ls', 'List the deployments associated with an app', function (yargs) {
return deploymentList('ls', yargs);
})
.command('history', 'Display the release history for a deployment', function (yargs) { return deploymentHistory('history', yargs); })
.command('h', 'Display the release history for a deployment', function (yargs) {
return deploymentHistory('h', yargs);
})
.check(function (argv, aliases) { return isValidCommand; }); // Report unrecognized, non-hyphenated command category.
addCommonConfiguration(yargs);
})
.command('link', 'Link an additional authentication provider (e.g. GitHub) to an existing Mobile Center account', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' link')
.demand(/*count*/ 0, /*max*/ 1) //set 'max' to one to allow usage of serverUrl undocument parameter for testing
.example('link', 'Links an account on the Mobile Center server')
.check(function (argv, aliases) { return isValidCommand; }); // Report unrecognized, non-hyphenated command category.
addCommonConfiguration(yargs);
})
.command('login', 'Authenticate in order to begin managing your apps', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' login <serverUrl> [options]')
.demand(/*count*/ 1, /*max*/ 1)
.example('login', 'Logs in to the Mobile Center server')
.example('login https://codepushserver --accessKey mykey', 'Logs in on behalf of the user who owns and created the access key "mykey"')
.example('login https://codepushserver --proxy http://someproxy.com:455', 'Logs in with the specified proxy url')
.option('accessKey', {
alias: 'key',
default: null,
demand: false,
description: 'Access key to authenticate against the Mobile Center server with, instead of providing your username and password credentials',
type: 'string',
})
.option('proxy', {
default: null,
demand: false,
description: 'URL of the proxy server to use',
type: 'string',
})
.option('noProxy', {
default: false,
demand: false,
description: 'Bypass the system-wide proxy settings',
type: 'boolean',
})
.check(function (argv, aliases) { return isValidCommand; }); // Report unrecognized, non-hyphenated command category.
addCommonConfiguration(yargs);
})
.command('logout', 'Log out of the current session', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' logout')
.demand(/*count*/ 0, /*max*/ 0)
.example('logout', 'Logs out and ends your current session');
addCommonConfiguration(yargs);
})
.command('patch', 'Update the metadata for an existing release', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' patch <appName> <deploymentName> [options]')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
.example('patch MyApp Production --des "Updated description" -r 50%', 'Updates the description of the latest release for "MyApp" app\'s "Production" deployment and updates the rollout value to 50%')
.example('patch MyApp Production -l v3 --des "Updated description for v3"', 'Updates the description of the release with label v3 for "MyApp" app\'s "Production" deployment')
.option('label', {
alias: 'l',
default: null,
demand: false,
description: 'Label of the release to update. Defaults to the latest release within the specified deployment',
type: 'string',
})
.option('description', {
alias: 'des',
default: null,
demand: false,
description: 'Description of the changes made to the app with this release',
type: 'string',
})
.option('disabled', {
alias: 'x',
default: null,
demand: false,
description: 'Specifies whether this release should be immediately downloadable',
type: 'boolean',
})
.option('mandatory', {
alias: 'm',
default: null,
demand: false,
description: 'Specifies whether this release should be considered mandatory',
type: 'boolean',
})
.option('rollout', {
alias: 'r',
default: null,
demand: false,
description: 'Percentage of users this release should be immediately available to. This attribute can only be increased from the current value.',
type: 'string',
})
.option('targetBinaryVersion', {
alias: 't',
default: null,
demand: false,
description: 'Semver expression that specifies the binary app version(s) this release is targeting (e.g. 1.1.0, ~1.2.3).',
type: 'string',
})
.check(function (argv, aliases) {
return isValidRollout(argv);
});
addCommonConfiguration(yargs);
})
.command('promote', 'Promote the latest release from one app deployment to another', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX +
' promote <appName> <sourceDeploymentName> <destDeploymentName> [options]')
.demand(/*count*/ 3, /*max*/ 3) // Require exactly three non-option arguments
.example('promote MyApp Staging Production', 'Promotes the latest release within the "Staging" deployment of "MyApp" to "Production"')
.example('promote MyApp Staging Production --des "Production rollout" -r 25', 'Promotes the latest release within the "Staging" deployment of "MyApp" to "Production", with an updated description, and targeting only 25% of the users')
.option('description', {
alias: 'des',
default: null,
demand: false,
description: 'Description of the changes made to the app with this release. If omitted, the description from the release being promoted will be used.',
type: 'string',
})
.option('label', {
alias: 'l',
default: null,
demand: false,
description: 'Label of the source release that will be taken. If omitted, the latest release being promoted will be used.',
type: 'string',
})
.option('disabled', {
alias: 'x',
default: null,
demand: false,
description: 'Specifies whether this release should be immediately downloadable. If omitted, the disabled attribute from the release being promoted will be used.',
type: 'boolean',
})
.option('mandatory', {
alias: 'm',
default: null,
demand: false,
description: 'Specifies whether this release should be considered mandatory. If omitted, the mandatory property from the release being promoted will be used.',
type: 'boolean',
})
.option('noDuplicateReleaseError', {
default: false,
demand: false,
description: 'When this flag is set, promoting a package that is identical to the latest release on the target deployment will produce a warning instead of an error',
type: 'boolean',
})
.option('rollout', {
alias: 'r',
default: '100%',
demand: false,
description: 'Percentage of users this update should be immediately available to',
type: 'string',
})
.option('targetBinaryVersion', {
alias: 't',
default: null,
demand: false,
description: 'Semver expression that specifies the binary app version(s) this release is targeting (e.g. 1.1.0, ~1.2.3). If omitted, the target binary version property from the release being promoted will be used.',
type: 'string',
})
.check(function (argv, aliases) {
return isValidRollout(argv);
});
addCommonConfiguration(yargs);
})
.command('register', 'Register a new Mobile Center account', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' register <serverUrl>')
.demand(/*count*/ 1, /*max*/ 1)
.example('register', 'Registers a new Mobile Center account')
.example('register https://codepushserver --proxy http://someproxy.com:455', 'Registers with the specified proxy url')
.option('proxy', {
default: null,
demand: false,
description: 'URL of the proxy server to use',
type: 'string',
})
.option('noProxy', {
default: false,
demand: false,
description: 'Bypass the system-wide proxy settings',
type: 'boolean',
})
.check(function (argv, aliases) { return isValidCommand; }); // Report unrecognized, non-hyphenated command category.
addCommonConfiguration(yargs);
})
.command('release', 'Release an update to an app deployment', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX +
' release <appName> <updateContentsPath> <targetBinaryVersion> [options]')
.demand(/*count*/ 3, /*max*/ 3) // Require exactly three non-option arguments.
.example('release MyApp app.js "*"', 'Releases the "app.js" file to the "MyApp" app\'s "Staging" deployment, targeting any binary version using the "*" wildcard range syntax.')
.example('release MyApp ./platforms/ios/www 1.0.3 -d Production -k ~/.ssh/codepush_rsa', 'Releases the "./platforms/ios/www" folder and all its contents to the "MyApp" app\'s "Production" deployment, targeting only the 1.0.3 binary version and signed with the "codepush_rsa" private key')
.example('release MyApp ./platforms/ios/www 1.0.3 -d Production -r 20', 'Releases the "./platforms/ios/www" folder and all its contents to the "MyApp" app\'s "Production" deployment, targeting the 1.0.3 binary version and rolling out to about 20% of the users')
.option('deploymentName', {
alias: 'd',
default: 'Staging',
demand: false,
description: 'Deployment to release the update to',
type: 'string',
})
.option('description', {
alias: 'des',
default: null,
demand: false,
description: 'Description of the changes made to the app in this release',
type: 'string',
})
.option('disabled', {
alias: 'x',
default: false,
demand: false,
description: 'Specifies whether this release should be immediately downloadable',
type: 'boolean',
})
.option('mandatory', {
alias: 'm',
default: false,
demand: false,
description: 'Specifies whether this release should be considered mandatory',
type: 'boolean',
})
.option('privateKeyPath', {
alias: 'k',
default: false,
demand: false,
description: 'Specifies the location of a RSA private key to sign the release with',
type: 'string',
})
.option('noDuplicateReleaseError', {
default: false,
demand: false,
description: 'When this flag is set, releasing a package that is identical to the latest release will produce a warning instead of an error',
type: 'boolean',
})
.option('rollout', {
alias: 'r',
default: '100%',
demand: false,
description: 'Percentage of users this release should be available to',
type: 'string',
})
.check(function (argv, aliases) {
return checkValidReleaseOptions(argv);
});
addCommonConfiguration(yargs);
})
.command('release-cordova', 'Release a Cordova update to an app deployment', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' release-cordova <appName> <platform> [options]')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
.example('release-cordova MyApp ios', 'Releases the Cordova iOS project in the current working directory to the "MyApp" app\'s "Staging" deployment')
.example('release-cordova MyApp android -d Production', 'Releases the Cordova Android project in the current working directory to the "MyApp" app\'s "Production" deployment')
.option('build', {
alias: 'b',
default: false,
demand: false,
description: 'Invoke "cordova build" instead of "cordova prepare"',
type: 'boolean',
})
.option('isReleaseBuildType', {
alias: 'rb',
default: false,
demand: false,
description: 'If "build" option is true specifies whether perform a release build',
type: 'boolean',
})
.option('deploymentName', {
alias: 'd',
default: 'Staging',
demand: false,
description: 'Deployment to release the update to',
type: 'string',
})
.option('description', {
alias: 'des',
default: null,
demand: false,
description: 'Description of the changes made to the app in this release',
type: 'string',
})
.option('disabled', {
alias: 'x',
default: false,
demand: false,
description: 'Specifies whether this release should be immediately downloadable',
type: 'boolean',
})
.option('mandatory', {
alias: 'm',
default: false,
demand: false,
description: 'Specifies whether this release should be considered mandatory',
type: 'boolean',
})
.option('privateKeyPath', {
alias: 'k',
default: false,
demand: false,
description: 'Specifies the location of a RSA private key to sign the release with',
type: 'string',
})
.option('noDuplicateReleaseError', {
default: false,
demand: false,
description: 'When this flag is set, releasing a package that is identical to the latest release will produce a warning instead of an error',
type: 'boolean',
})
.option('rollout', {
alias: 'r',
default: '100%',
demand: false,
description: 'Percentage of users this release should be immediately available to',
type: 'string',
})
.option('targetBinaryVersion', {
alias: 't',
default: null,
demand: false,
description: 'Semver expression that specifies the binary app version(s) this release is targeting (e.g. 1.1.0, ~1.2.3). If omitted, the release will target the exact version specified in the config.xml file.',
type: 'string',
})
.check(function (argv, aliases) {
return checkValidReleaseOptions(argv);
});
addCommonConfiguration(yargs);
})
.command('release-react', 'Release a React Native update to an app deployment', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' release-react <appName> <platform> [options]')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
.example('release-react MyApp ios', 'Releases the React Native iOS project in the current working directory to the "MyApp" app\'s "Staging" deployment')
.example('release-react MyApp android -d Production -k ~/.ssh/codepush_rsa', 'Releases the React Native Android project in the current working directory to the "MyApp" app\'s "Production" deployment, signed with the "codepush_rsa" private key')
.example('release-react MyApp windows --dev', 'Releases the development bundle of the React Native Windows project in the current working directory to the "MyApp" app\'s "Staging" deployment')
.option('bundleName', {
alias: 'b',
default: null,
demand: false,
description: 'Name of the generated JS bundle file. If unspecified, the standard bundle name will be used, depending on the specified platform: "main.jsbundle" (iOS), "index.android.bundle" (Android) or "index.windows.bundle" (Windows)',
type: 'string',
})
.option('deploymentName', {
alias: 'd',
default: 'Staging',
demand: false,
description: 'Deployment to release the update to',
type: 'string',
})
.option('description', {
alias: 'des',
default: null,
demand: false,
description: 'Description of the changes made to the app with this release',
type: 'string',
})
.option('development', {
alias: 'dev',
default: false,
demand: false,
description: 'Specifies whether to generate a dev or release build',
type: 'boolean',
})
.option('disabled', {
alias: 'x',
default: false,
demand: false,
description: 'Specifies whether this release should be immediately downloadable',
type: 'boolean',
})
.option('entryFile', {
alias: 'e',
default: null,
demand: false,
description: 'Path to the app\'s entry Javascript file. If omitted, "index.<platform>.js" and then "index.js" will be used (if they exist)',
type: 'string',
})
.option('gradleFile', {
alias: 'g',
default: null,
demand: false,
description: 'Path to the gradle file which specifies the binary version you want to target this release at (android only).',
})
.option('podFile', {
alias: 'pf',
default: null,
demand: false,
description: 'Path to the cocopods config file (iOS only).',
})
.option('mandatory', {
alias: 'm',
default: false,
demand: false,
description: 'Specifies whether this release should be considered mandatory',
type: 'boolean',
})
.option('noDuplicateReleaseError', {
default: false,
demand: false,
description: 'When this flag is set, releasing a package that is identical to the latest release will produce a warning instead of an error',
type: 'boolean',
})
.option('plistFile', {
alias: 'p',
default: null,
demand: false,
description: 'Path to the plist file which specifies the binary version you want to target this release at (iOS only).',
})
.option('plistFilePrefix', {
alias: 'pre',
default: null,
demand: false,
description: "Prefix to append to the file name when attempting to find your app's Info.plist file (iOS only).",
})
.option('rollout', {
alias: 'r',
default: '100%',
demand: false,
description: 'Percentage of users this release should be immediately available to',
type: 'string',
})
.option('privateKeyPath', {
alias: 'k',
default: false,
demand: false,
description: 'Specifies the location of a RSA private key to sign the release with',
type: 'string',
})
.option('sourcemapOutput', {
alias: 's',
default: null,
demand: false,
description: 'Path to where the sourcemap for the resulting bundle should be written. If omitted, a sourcemap will not be generated.',
type: 'string',
})
.option('sourcemapOutputDir', {
default: null,
demand: false,
description: 'Path to folder where the sourcemap for the resulting bundle should be written. Name of sourcemap file will be generated automatically. This argument will be ignored if "sourcemap-output" argument is provided. If omitted, a sourcemap will not be generated.',
type: 'string',
})
.option('targetBinaryVersion', {
alias: 't',
default: null,
demand: false,
description: 'Semver expression that specifies the binary app version(s) this release is targeting (e.g. 1.1.0, ~1.2.3). If omitted, the release will target the exact version specified in the "Info.plist" (iOS), "build.gradle" (Android) or "Package.appxmanifest" (Windows) files.',
type: 'string',
})
.option('outputDir', {
alias: 'o',
default: null,
demand: false,
description: 'Path to where the bundle and sourcemap should be written. If omitted, a bundle and sourcemap will not be written.',
type: 'string',
})
.option('config', {
alias: 'c',
default: null,
demand: false,
description: 'Path to the React Native CLI configuration file',
type: 'string',
})
.option('extraBundlerOptions', {
default: [],
demand: false,
description: 'Option that gets passed to react-native bundler. Can be specified multiple times',
type: 'array',
})
.option('extraHermesFlags', {
default: [],
demand: false,
description: 'Flag that gets passed to Hermes, JavaScript to bytecode compiler. Can be specified multiple times',
type: 'array',
})
.check(function (argv, aliases) {
return checkValidReleaseOptions(argv);
});
addCommonConfiguration(yargs);
})
.command('rollback', 'Rollback the latest release for an app deployment', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' rollback <appName> <deploymentName> [options]')
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
.example('rollback MyApp Production', 'Performs a rollback on the "Production" deployment of "MyApp"')
.example('rollback MyApp Production --targetRelease v4', 'Performs a rollback on the "Production" deployment of "MyApp" to the v4 release')
.option('targetRelease', {
alias: 'r',
default: null,
demand: false,
description: 'Label of the release to roll the specified deployment back to (e.g. v4). If omitted, the deployment will roll back to the previous release.',
type: 'string',
});
addCommonConfiguration(yargs);
})
.command('whoami', 'Display the account info for the current login session', function (yargs) {
isValidCommandCategory = true;
isValidCommand = true;
yargs
.usage(USAGE_PREFIX + ' whoami')
.demand(/*count*/ 0, /*max*/ 0)
.example('whoami', 'Display the account info for the current login session');
addCommonConfiguration(yargs);
})
.alias('v', 'version')
.version(packageJson.version)
.wrap(/*columnLimit*/ null)
// TODO: fix this
// .strict() // Validate hyphenated (named) arguments.
.check(function (argv, aliases) { return isValidCommandCategory; }) // Report unrecognized, non-hyphenated command category.
.fail(function (msg) { return showHelp(/*showRootDescription*/ true); })
.parseSync(); // Suppress the default error message.
function createCommand() {
var cmd;
if (!wasHelpShown && argv._ && argv._.length > 0) {
// Create a command object
var arg0 = argv._[0];
var arg1 = argv._[1];
var arg2 = argv._[2];
var arg3 = argv._[3];
var arg4 = argv._[4];
switch (arg0) {
case 'access-key':
switch (arg1) {
case 'add':
if (arg2) {
cmd = { type: cli.CommandType.accessKeyAdd };
var accessKeyAddCmd = cmd;
accessKeyAddCmd.name = arg2;
/*
var ttlOption: string = argv["ttl"];
if (isDefined(ttlOption)) {
accessKeyAddCmd.ttl = parseDurationMilliseconds(ttlOption);
}
*/
// Mobile Center access keys never expire, so this setting doesn't matter (it just needs to be something)
accessKeyAddCmd.ttl = parseDurationMilliseconds('60d');
}
break;
case 'patch':
if (arg2) {
cmd = { type: cli.CommandType.accessKeyPatch };
var accessKeyPatchCmd = cmd;
accessKeyPatchCmd.oldName = arg2;
var newNameOption = argv['name'];
var ttlOption = argv['ttl'];
if (isDefined(newNameOption)) {
accessKeyPatchCmd.newName = newNameOption;
}
if (isDefined(ttlOption)) {
accessKeyPatchCmd.ttl = parseDurationMilliseconds(ttlOption);
}
}
break;
case 'list':
case 'ls':
cmd = { type: cli.CommandType.accessKeyList };
cmd.format = argv['format'];
break;
case 'remove':
case 'rm':
if (arg2) {
cmd = { type: cli.CommandType.accessKeyRemove };
cmd.accessKey = arg2;
}
break;
}
break;
case 'app':
switch (arg1) {
case 'add':
if (arg2) {
cmd = { type: cli.CommandType.appAdd };
var appAddCommand = cmd;
appAddCommand.appName = arg2;
appAddCommand.os = arg3;
appAddCommand.platform = arg4;
}
break;
case 'list':
case 'ls':
cmd = { type: cli.CommandType.appList };
cmd.format = argv['format'];
break;
case 'remove':
case 'rm':
if (arg2) {
cmd = { type: cli.CommandType.appRemove };
cmd.appName = arg2;
}
break;
case 'rename':
if (arg2 && arg3) {
cmd = { type: cli.CommandType.appRename };
var appRenameCommand = cmd;
appRenameCommand.currentAppName = arg2;
appRenameCommand.newAppName = arg3;
}
break;
case 'transfer':
if (arg2 && arg3) {
cmd = { type: cli.CommandType.appTransfer };
var appTransferCommand = cmd;
appTransferCommand.appName = arg2;
appTransferCommand.email = arg3;
}
break;
}
break;
case 'collaborator':
switch (arg1) {
case 'add':
if (arg2 && arg3) {
cmd = { type: cli.CommandType.collaboratorAdd };
cmd.appName = arg2;
cmd.email = arg3;
}
break;
case 'list':
case 'ls':
if (arg2) {
cmd = { type: cli.CommandType.collaboratorList };
cmd.appName = arg2;
cmd.format = argv['format'];
}
break;
case 'remove':
case 'rm':
if (arg2 && arg3) {
cmd = { type: cli.CommandType.collaboratorRemove };
cmd.appName = arg2;
cmd.email = arg3;
}
break;
}
break;
case 'debug':
cmd = {
type: cli.CommandType.debug,
platform: arg1,
};
break;
case 'deployment':
switch (arg1) {
case 'add':
if (arg2 && (arg3 || argv['default'])) {
cmd = { type: cli.CommandType.deploymentAdd };
var deploymentAddCommand = cmd;
deploymentAddCommand.appName = arg2;
deploymentAddCommand.deploymentName = arg3;
deploymentAddCommand.default = argv['default'];
}
break;
case 'clear':
if (arg2 && arg3) {
cmd = {
type: cli.CommandType.deploymentHistoryClear,
};
var deploymentHistoryClearCommand = cmd;
deploymentHistoryClearCommand.appName = arg2;
deploymentHistoryClearCommand.deploymentName = arg3;
}
break;
case 'list':
case 'ls':
if (arg2) {
cmd = { type: cli.CommandType.deploymentList };
var deploymentListCommand = cmd;
deploymentListCommand.appName = arg2;
deploymentListCommand.format = argv['format'];
deploymentListCommand.displayKeys = argv['displayKeys'];
}