@revopush/code-push-cli 0.0.1 → 0.0.2
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.
- package/README.md +459 -566
- package/README_MS.md +837 -0
- package/bin/script/cli.js +0 -0
- package/bin/script/command-executor.js +14 -15
- package/bin/script/command-parser.js +42 -27
- package/bin/script/management-sdk.js +5 -4
- package/package.json +7 -3
- package/script/command-executor.ts +28 -36
- package/script/command-parser.ts +51 -32
- package/script/management-sdk.ts +5 -4
- package/script/types/cli.ts +3 -1
- package/.idea/cli.iml +0 -9
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/prettier.xml +0 -6
- package/.idea/vcs.xml +0 -6
package/bin/script/cli.js
CHANGED
|
File without changes
|
|
@@ -27,7 +27,7 @@ const sign_1 = require("./sign");
|
|
|
27
27
|
const xcode = require("xcode");
|
|
28
28
|
const react_native_utils_1 = require("./react-native-utils");
|
|
29
29
|
const file_utils_1 = require("./utils/file-utils");
|
|
30
|
-
const configFilePath = path.join(process.env.LOCALAPPDATA || process.env.HOME, ".
|
|
30
|
+
const configFilePath = path.join(process.env.LOCALAPPDATA || process.env.HOME, ".revopush.config");
|
|
31
31
|
const emailValidator = require("email-validator");
|
|
32
32
|
const packageJson = require("../../package.json");
|
|
33
33
|
const parseXml = Q.denodeify(require("xml2js").parseString);
|
|
@@ -210,7 +210,7 @@ function deleteFolder(folderPath) {
|
|
|
210
210
|
});
|
|
211
211
|
}
|
|
212
212
|
function deploymentAdd(command) {
|
|
213
|
-
return exports.sdk.addDeployment(command.appName, command.deploymentName).then((deployment) => {
|
|
213
|
+
return exports.sdk.addDeployment(command.appName, command.deploymentName, command.key).then((deployment) => {
|
|
214
214
|
(0, exports.log)('Successfully added the "' +
|
|
215
215
|
command.deploymentName +
|
|
216
216
|
'" deployment with key "' +
|
|
@@ -350,7 +350,7 @@ function execute(command) {
|
|
|
350
350
|
if (!!exports.sdk)
|
|
351
351
|
break; // Used by unit tests to skip authentication
|
|
352
352
|
if (!connectionInfo) {
|
|
353
|
-
throw new Error("You are not currently logged in. Run the '
|
|
353
|
+
throw new Error("You are not currently logged in. Run the 'revopush login' command to authenticate with the CodePush server.");
|
|
354
354
|
}
|
|
355
355
|
exports.sdk = getSdk(connectionInfo.accessKey, CLI_HEADERS, connectionInfo.customServerUrl);
|
|
356
356
|
break;
|
|
@@ -433,11 +433,10 @@ function getTotalActiveFromDeploymentMetrics(metrics) {
|
|
|
433
433
|
return totalActive;
|
|
434
434
|
}
|
|
435
435
|
function initiateExternalAuthenticationAsync(action, serverUrl) {
|
|
436
|
-
const message = `A browser is being launched to authenticate your account. Follow the instructions ` +
|
|
437
|
-
`it displays to complete your ${action === "register" ? "registration" : action}.`;
|
|
438
|
-
(0, exports.log)(message);
|
|
439
436
|
const hostname = os.hostname();
|
|
440
|
-
const url = `${serverUrl || AccountManager.
|
|
437
|
+
const url = `${serverUrl || AccountManager.APP_SERVER_URL}/cli-login?hostname=${hostname}`;
|
|
438
|
+
(0, exports.log)("Opening your browser...");
|
|
439
|
+
(0, exports.log)(`Visit ${url} and enter the code`);
|
|
441
440
|
opener(url);
|
|
442
441
|
}
|
|
443
442
|
function link(command) {
|
|
@@ -447,10 +446,10 @@ function link(command) {
|
|
|
447
446
|
function login(command) {
|
|
448
447
|
// Check if one of the flags were provided.
|
|
449
448
|
if (command.accessKey) {
|
|
450
|
-
exports.sdk = getSdk(command.accessKey, CLI_HEADERS, command.
|
|
449
|
+
exports.sdk = getSdk(command.accessKey, CLI_HEADERS, command.apiServerUrl);
|
|
451
450
|
return exports.sdk.isAuthenticated().then((isAuthenticated) => {
|
|
452
451
|
if (isAuthenticated) {
|
|
453
|
-
serializeConnectionInfo(command.accessKey, /*preserveAccessKeyOnLogout*/ true, command.
|
|
452
|
+
serializeConnectionInfo(command.accessKey, /*preserveAccessKeyOnLogout*/ true, command.apiServerUrl);
|
|
454
453
|
}
|
|
455
454
|
else {
|
|
456
455
|
throw new Error("Invalid access key.");
|
|
@@ -458,21 +457,21 @@ function login(command) {
|
|
|
458
457
|
});
|
|
459
458
|
}
|
|
460
459
|
else {
|
|
461
|
-
return loginWithExternalAuthentication("login", command.
|
|
460
|
+
return loginWithExternalAuthentication("login", command.apiServerUrl, command.appServerUrl);
|
|
462
461
|
}
|
|
463
462
|
}
|
|
464
|
-
function loginWithExternalAuthentication(action,
|
|
465
|
-
initiateExternalAuthenticationAsync(action,
|
|
463
|
+
function loginWithExternalAuthentication(action, apiServerUrl, appServerUrl) {
|
|
464
|
+
initiateExternalAuthenticationAsync(action, appServerUrl);
|
|
466
465
|
(0, exports.log)(""); // Insert newline
|
|
467
466
|
return requestAccessKey().then((accessKey) => {
|
|
468
467
|
if (accessKey === null) {
|
|
469
468
|
// The user has aborted the synchronous prompt (e.g.: via [CTRL]+[C]).
|
|
470
469
|
return;
|
|
471
470
|
}
|
|
472
|
-
exports.sdk = getSdk(accessKey, CLI_HEADERS,
|
|
471
|
+
exports.sdk = getSdk(accessKey, CLI_HEADERS, apiServerUrl);
|
|
473
472
|
return exports.sdk.isAuthenticated().then((isAuthenticated) => {
|
|
474
473
|
if (isAuthenticated) {
|
|
475
|
-
serializeConnectionInfo(accessKey, /*preserveAccessKeyOnLogout*/ false,
|
|
474
|
+
serializeConnectionInfo(accessKey, /*preserveAccessKeyOnLogout*/ false, apiServerUrl);
|
|
476
475
|
}
|
|
477
476
|
else {
|
|
478
477
|
throw new Error("Invalid access key.");
|
|
@@ -1212,7 +1211,7 @@ function sessionList(command) {
|
|
|
1212
1211
|
}
|
|
1213
1212
|
function sessionRemove(command) {
|
|
1214
1213
|
if (os.hostname() === command.machineName) {
|
|
1215
|
-
throw new Error("Cannot remove the current login session via this command. Please run '
|
|
1214
|
+
throw new Error("Cannot remove the current login session via this command. Please run 'revopush logout' instead.");
|
|
1216
1215
|
}
|
|
1217
1216
|
else {
|
|
1218
1217
|
return (0, exports.confirm)().then((wasConfirmed) => {
|
|
@@ -10,7 +10,7 @@ const backslash = require("backslash");
|
|
|
10
10
|
const parseDuration = require("parse-duration");
|
|
11
11
|
const packageJson = require("../../package.json");
|
|
12
12
|
const ROLLOUT_PERCENTAGE_REGEX = /^(100|[1-9][0-9]|[1-9])%?$/;
|
|
13
|
-
const USAGE_PREFIX = "Usage:
|
|
13
|
+
const USAGE_PREFIX = "Usage: revopush";
|
|
14
14
|
// Command categories are: access-key, app, release, deployment, deployment-key, login, logout, register
|
|
15
15
|
let isValidCommandCategory = false;
|
|
16
16
|
// Commands are the verb following the command category (e.g.: "add" in "app add").
|
|
@@ -19,13 +19,15 @@ let wasHelpShown = false;
|
|
|
19
19
|
function showHelp(showRootDescription) {
|
|
20
20
|
if (!wasHelpShown) {
|
|
21
21
|
if (showRootDescription) {
|
|
22
|
-
console.log(chalk.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
console.log(chalk.blue(`
|
|
23
|
+
____ ____ _
|
|
24
|
+
| _ \\ _____ _____ | _ \\ _ _ ___| |__
|
|
25
|
+
| |_) / _ \\ \\ / / _ \\| |_) | | | / __| '_ \\
|
|
26
|
+
| _ < __/\\ V / (_) | __/| |_| \\__ \\ | | |
|
|
27
|
+
|_| \\_\\___| \\_/ \\___/|_| \\__,_|___/_| |_| CLI v${packageJson.version}
|
|
28
|
+
============================================`));
|
|
29
|
+
console.log("Revopush is a service that enables you to deploy mobile app updates directly to your users' devices. " +
|
|
30
|
+
"Visit our website https://revopush.org/ \n");
|
|
29
31
|
}
|
|
30
32
|
yargs.showHelp();
|
|
31
33
|
wasHelpShown = true;
|
|
@@ -269,6 +271,7 @@ yargs
|
|
|
269
271
|
.command("list", "Lists the apps associated with your account", (yargs) => appList("list", yargs))
|
|
270
272
|
.command("ls", "Lists the apps associated with your account", (yargs) => appList("ls", yargs))
|
|
271
273
|
.command("transfer", "Transfer the ownership of an app to another account", (yargs) => {
|
|
274
|
+
isValidCommand = true;
|
|
272
275
|
yargs
|
|
273
276
|
.usage(USAGE_PREFIX + " app transfer <appName> <email>")
|
|
274
277
|
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
|
|
@@ -318,7 +321,14 @@ yargs
|
|
|
318
321
|
yargs
|
|
319
322
|
.usage(USAGE_PREFIX + " deployment add <appName> <deploymentName>")
|
|
320
323
|
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
|
|
321
|
-
.example("deployment add MyApp MyDeployment", 'Adds deployment "MyDeployment" to app "MyApp"')
|
|
324
|
+
.example("deployment add MyApp MyDeployment", 'Adds deployment "MyDeployment" to app "MyApp"')
|
|
325
|
+
.example("deployment add MyApp MyDeployment -k abc123", 'Adds deployment key "abc123"')
|
|
326
|
+
.option("key", {
|
|
327
|
+
alias: "k",
|
|
328
|
+
demand: false,
|
|
329
|
+
description: "Specify deployment key",
|
|
330
|
+
type: "string",
|
|
331
|
+
});
|
|
322
332
|
addCommonConfiguration(yargs);
|
|
323
333
|
})
|
|
324
334
|
.command("clear", "Clear the release history associated with a deployment", (yargs) => deploymentHistoryClear("clear", yargs))
|
|
@@ -339,22 +349,23 @@ yargs
|
|
|
339
349
|
.check((argv, aliases) => isValidCommand); // Report unrecognized, non-hyphenated command category.
|
|
340
350
|
addCommonConfiguration(yargs);
|
|
341
351
|
})
|
|
342
|
-
.command("link", "Link an additional authentication provider (e.g. GitHub) to an existing CodePush account", (yargs) => {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
+
/* .command("link", "Link an additional authentication provider (e.g. GitHub) to an existing CodePush account", (yargs: yargs.Argv) => {
|
|
353
|
+
isValidCommandCategory = true;
|
|
354
|
+
isValidCommand = true;
|
|
355
|
+
yargs
|
|
356
|
+
.usage(USAGE_PREFIX + " link")
|
|
357
|
+
.demand(/!*count*!/ 0, /!*max*!/ 1) //set 'max' to one to allow usage of serverUrl undocument parameter for testing
|
|
358
|
+
.example("link", "Links an account on the CodePush server")
|
|
359
|
+
.check((argv: any, aliases: { [aliases: string]: string }): any => isValidCommand); // Report unrecognized, non-hyphenated command category.
|
|
360
|
+
|
|
361
|
+
addCommonConfiguration(yargs);
|
|
362
|
+
})*/
|
|
352
363
|
.command("login", "Authenticate with the CodePush server in order to begin managing your apps", (yargs) => {
|
|
353
364
|
isValidCommandCategory = true;
|
|
354
365
|
isValidCommand = true;
|
|
355
366
|
yargs
|
|
356
367
|
.usage(USAGE_PREFIX + " login [options]")
|
|
357
|
-
.demand(/*count*/ 0, /*max*/
|
|
368
|
+
.demand(/*count*/ 0, /*max*/ 2) //set 'max' to one to allow usage of serverUrl undocument parameter for testing
|
|
358
369
|
.example("login", "Logs in to the CodePush server")
|
|
359
370
|
.example("login --accessKey mykey", 'Logs in on behalf of the user who owns and created the access key "mykey"')
|
|
360
371
|
.option("accessKey", {
|
|
@@ -885,6 +896,9 @@ function createCommand() {
|
|
|
885
896
|
const deploymentAddCommand = cmd;
|
|
886
897
|
deploymentAddCommand.appName = arg2;
|
|
887
898
|
deploymentAddCommand.deploymentName = arg3;
|
|
899
|
+
if (argv["key"]) {
|
|
900
|
+
deploymentAddCommand.key = argv["key"];
|
|
901
|
+
}
|
|
888
902
|
}
|
|
889
903
|
break;
|
|
890
904
|
case "clear":
|
|
@@ -936,16 +950,17 @@ function createCommand() {
|
|
|
936
950
|
break;
|
|
937
951
|
}
|
|
938
952
|
break;
|
|
939
|
-
case "link":
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
953
|
+
/* case "link":
|
|
954
|
+
cmd = <cli.ILinkCommand>{
|
|
955
|
+
type: cli.CommandType.link,
|
|
956
|
+
serverUrl: getServerUrl(arg1),
|
|
957
|
+
};
|
|
958
|
+
break;*/
|
|
945
959
|
case "login":
|
|
946
960
|
cmd = { type: cli.CommandType.login };
|
|
947
961
|
const loginCommand = cmd;
|
|
948
|
-
loginCommand.
|
|
962
|
+
loginCommand.apiServerUrl = getServerUrl(arg1);
|
|
963
|
+
loginCommand.appServerUrl = getServerUrl(arg2);
|
|
949
964
|
loginCommand.accessKey = argv["accessKey"];
|
|
950
965
|
break;
|
|
951
966
|
case "logout":
|
|
@@ -27,7 +27,8 @@ class AccountManager {
|
|
|
27
27
|
OWNER: "Owner",
|
|
28
28
|
COLLABORATOR: "Collaborator",
|
|
29
29
|
};
|
|
30
|
-
static
|
|
30
|
+
static API_SERVER_URL = "https://api.revopush.org";
|
|
31
|
+
static APP_SERVER_URL = "https://app.revopush.org";
|
|
31
32
|
static API_VERSION = 2;
|
|
32
33
|
static ERROR_GATEWAY_TIMEOUT = 504; // Used if there is a network error
|
|
33
34
|
static ERROR_INTERNAL_SERVER = 500;
|
|
@@ -42,7 +43,7 @@ class AccountManager {
|
|
|
42
43
|
throw new Error("An access key must be specified.");
|
|
43
44
|
this._accessKey = accessKey;
|
|
44
45
|
this._customHeaders = customHeaders;
|
|
45
|
-
this._serverUrl = serverUrl || AccountManager.
|
|
46
|
+
this._serverUrl = serverUrl || AccountManager.API_SERVER_URL;
|
|
46
47
|
}
|
|
47
48
|
get accessKey() {
|
|
48
49
|
return this._accessKey;
|
|
@@ -181,8 +182,8 @@ class AccountManager {
|
|
|
181
182
|
return this.del(urlEncode([`/apps/${appName}/collaborators/${email}`])).then(() => null);
|
|
182
183
|
}
|
|
183
184
|
// Deployments
|
|
184
|
-
addDeployment(appName, deploymentName) {
|
|
185
|
-
const deployment = { name: deploymentName };
|
|
185
|
+
addDeployment(appName, deploymentName, deploymentKey) {
|
|
186
|
+
const deployment = { name: deploymentName, key: deploymentKey };
|
|
186
187
|
return this.post(urlEncode([`/apps/${appName}/deployments/`]), JSON.stringify(deployment), /*expectResponseBody=*/ true).then((res) => res.body.deployment);
|
|
187
188
|
}
|
|
188
189
|
clearDeploymentHistory(appName, deploymentName) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revopush/code-push-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Management CLI for the CodePush service",
|
|
5
5
|
"main": "./script/cli.js",
|
|
6
6
|
"scripts": {
|
|
@@ -11,13 +11,17 @@
|
|
|
11
11
|
"lint:fix": "npx eslint ./script/**/*.ts --fix"
|
|
12
12
|
},
|
|
13
13
|
"bin": {
|
|
14
|
-
"
|
|
14
|
+
"revopush": "./bin/script/cli.js"
|
|
15
15
|
},
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
|
-
"url": "https://github.com/
|
|
18
|
+
"url": "https://github.com/revopush/code-push-cli"
|
|
19
19
|
},
|
|
20
20
|
"author": "Microsoft",
|
|
21
|
+
"contributors": [
|
|
22
|
+
"Microsoft",
|
|
23
|
+
"Revopush"
|
|
24
|
+
],
|
|
21
25
|
"dependencies": {
|
|
22
26
|
"backslash": "^0.2.0",
|
|
23
27
|
"chalk": "^4.1.2",
|
|
@@ -2,26 +2,33 @@
|
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
|
|
4
4
|
import AccountManager = require("./management-sdk");
|
|
5
|
+
|
|
5
6
|
const childProcess = require("child_process");
|
|
6
7
|
import debugCommand from "./commands/debug";
|
|
7
8
|
import * as fs from "fs";
|
|
8
9
|
import * as chalk from "chalk";
|
|
10
|
+
|
|
9
11
|
const g2js = require("gradle-to-js/lib/parser");
|
|
10
12
|
import * as moment from "moment";
|
|
13
|
+
|
|
11
14
|
const opener = require("opener");
|
|
12
15
|
import * as os from "os";
|
|
13
16
|
import * as path from "path";
|
|
17
|
+
|
|
14
18
|
const plist = require("plist");
|
|
15
19
|
const progress = require("progress");
|
|
16
20
|
const prompt = require("prompt");
|
|
17
21
|
import * as Q from "q";
|
|
22
|
+
|
|
18
23
|
const rimraf = require("rimraf");
|
|
19
24
|
import * as semver from "semver";
|
|
25
|
+
|
|
20
26
|
const Table = require("cli-table");
|
|
21
27
|
const which = require("which");
|
|
22
28
|
import wordwrap = require("wordwrap");
|
|
23
29
|
import * as cli from "../script/types/cli";
|
|
24
30
|
import sign from "./sign";
|
|
31
|
+
|
|
25
32
|
const xcode = require("xcode");
|
|
26
33
|
import {
|
|
27
34
|
AccessKey,
|
|
@@ -38,23 +45,15 @@ import {
|
|
|
38
45
|
Session,
|
|
39
46
|
UpdateMetrics,
|
|
40
47
|
} from "../script/types";
|
|
41
|
-
import {
|
|
42
|
-
|
|
43
|
-
getiOSHermesEnabled,
|
|
44
|
-
runHermesEmitBinaryCommand,
|
|
45
|
-
isValidVersion
|
|
46
|
-
} from "./react-native-utils";
|
|
47
|
-
import {
|
|
48
|
-
fileDoesNotExistOrIsDirectory,
|
|
49
|
-
isBinaryOrZip,
|
|
50
|
-
fileExists
|
|
51
|
-
} from "./utils/file-utils";
|
|
48
|
+
import { getAndroidHermesEnabled, getiOSHermesEnabled, runHermesEmitBinaryCommand, isValidVersion } from "./react-native-utils";
|
|
49
|
+
import { fileDoesNotExistOrIsDirectory, isBinaryOrZip, fileExists } from "./utils/file-utils";
|
|
52
50
|
|
|
53
|
-
const configFilePath: string = path.join(process.env.LOCALAPPDATA || process.env.HOME, ".
|
|
51
|
+
const configFilePath: string = path.join(process.env.LOCALAPPDATA || process.env.HOME, ".revopush.config");
|
|
54
52
|
const emailValidator = require("email-validator");
|
|
55
53
|
const packageJson = require("../../package.json");
|
|
56
54
|
const parseXml = Q.denodeify(require("xml2js").parseString);
|
|
57
55
|
import Promise = Q.Promise;
|
|
56
|
+
|
|
58
57
|
const properties = require("properties");
|
|
59
58
|
|
|
60
59
|
const CLI_HEADERS: Headers = {
|
|
@@ -290,7 +289,7 @@ function deleteFolder(folderPath: string): Promise<void> {
|
|
|
290
289
|
}
|
|
291
290
|
|
|
292
291
|
function deploymentAdd(command: cli.IDeploymentAddCommand): Promise<void> {
|
|
293
|
-
return sdk.addDeployment(command.appName, command.deploymentName).then((deployment: Deployment): void => {
|
|
292
|
+
return sdk.addDeployment(command.appName, command.deploymentName, command.key).then((deployment: Deployment): void => {
|
|
294
293
|
log(
|
|
295
294
|
'Successfully added the "' +
|
|
296
295
|
command.deploymentName +
|
|
@@ -454,7 +453,7 @@ export function execute(command: cli.ICommand) {
|
|
|
454
453
|
|
|
455
454
|
if (!connectionInfo) {
|
|
456
455
|
throw new Error(
|
|
457
|
-
"You are not currently logged in. Run the '
|
|
456
|
+
"You are not currently logged in. Run the 'revopush login' command to authenticate with the CodePush server."
|
|
458
457
|
);
|
|
459
458
|
}
|
|
460
459
|
|
|
@@ -573,13 +572,10 @@ function getTotalActiveFromDeploymentMetrics(metrics: DeploymentMetrics): number
|
|
|
573
572
|
}
|
|
574
573
|
|
|
575
574
|
function initiateExternalAuthenticationAsync(action: string, serverUrl?: string): void {
|
|
576
|
-
const message: string =
|
|
577
|
-
`A browser is being launched to authenticate your account. Follow the instructions ` +
|
|
578
|
-
`it displays to complete your ${action === "register" ? "registration" : action}.`;
|
|
579
|
-
|
|
580
|
-
log(message);
|
|
581
575
|
const hostname: string = os.hostname();
|
|
582
|
-
const url: string = `${serverUrl || AccountManager.
|
|
576
|
+
const url: string = `${serverUrl || AccountManager.APP_SERVER_URL}/cli-login?hostname=${hostname}`;
|
|
577
|
+
log("Opening your browser...");
|
|
578
|
+
log(`Visit ${url} and enter the code`);
|
|
583
579
|
opener(url);
|
|
584
580
|
}
|
|
585
581
|
|
|
@@ -591,21 +587,21 @@ function link(command: cli.ILinkCommand): Promise<void> {
|
|
|
591
587
|
function login(command: cli.ILoginCommand): Promise<void> {
|
|
592
588
|
// Check if one of the flags were provided.
|
|
593
589
|
if (command.accessKey) {
|
|
594
|
-
sdk = getSdk(command.accessKey, CLI_HEADERS, command.
|
|
590
|
+
sdk = getSdk(command.accessKey, CLI_HEADERS, command.apiServerUrl);
|
|
595
591
|
return sdk.isAuthenticated().then((isAuthenticated: boolean): void => {
|
|
596
592
|
if (isAuthenticated) {
|
|
597
|
-
serializeConnectionInfo(command.accessKey, /*preserveAccessKeyOnLogout*/ true, command.
|
|
593
|
+
serializeConnectionInfo(command.accessKey, /*preserveAccessKeyOnLogout*/ true, command.apiServerUrl);
|
|
598
594
|
} else {
|
|
599
595
|
throw new Error("Invalid access key.");
|
|
600
596
|
}
|
|
601
597
|
});
|
|
602
598
|
} else {
|
|
603
|
-
return loginWithExternalAuthentication("login", command.
|
|
599
|
+
return loginWithExternalAuthentication("login", command.apiServerUrl, command.appServerUrl);
|
|
604
600
|
}
|
|
605
601
|
}
|
|
606
602
|
|
|
607
|
-
function loginWithExternalAuthentication(action: string,
|
|
608
|
-
initiateExternalAuthenticationAsync(action,
|
|
603
|
+
function loginWithExternalAuthentication(action: string, apiServerUrl?: string, appServerUrl?: string): Promise<void> {
|
|
604
|
+
initiateExternalAuthenticationAsync(action, appServerUrl);
|
|
609
605
|
log(""); // Insert newline
|
|
610
606
|
|
|
611
607
|
return requestAccessKey().then((accessKey: string): Promise<void> => {
|
|
@@ -614,11 +610,11 @@ function loginWithExternalAuthentication(action: string, serverUrl?: string): Pr
|
|
|
614
610
|
return;
|
|
615
611
|
}
|
|
616
612
|
|
|
617
|
-
sdk = getSdk(accessKey, CLI_HEADERS,
|
|
613
|
+
sdk = getSdk(accessKey, CLI_HEADERS, apiServerUrl);
|
|
618
614
|
|
|
619
615
|
return sdk.isAuthenticated().then((isAuthenticated: boolean): void => {
|
|
620
616
|
if (isAuthenticated) {
|
|
621
|
-
serializeConnectionInfo(accessKey, /*preserveAccessKeyOnLogout*/ false,
|
|
617
|
+
serializeConnectionInfo(accessKey, /*preserveAccessKeyOnLogout*/ false, apiServerUrl);
|
|
622
618
|
} else {
|
|
623
619
|
throw new Error("Invalid access key.");
|
|
624
620
|
}
|
|
@@ -1081,11 +1077,7 @@ function getAppVersionFromXcodeProject(command: cli.IReleaseReactCommand, projec
|
|
|
1081
1077
|
}
|
|
1082
1078
|
|
|
1083
1079
|
const xcodeProj = xcode.project(resolvedPbxprojFile).parseSync();
|
|
1084
|
-
const marketingVersion = xcodeProj.getBuildProperty(
|
|
1085
|
-
"MARKETING_VERSION",
|
|
1086
|
-
command.buildConfigurationName,
|
|
1087
|
-
command.xcodeTargetName
|
|
1088
|
-
);
|
|
1080
|
+
const marketingVersion = xcodeProj.getBuildProperty("MARKETING_VERSION", command.buildConfigurationName, command.xcodeTargetName);
|
|
1089
1081
|
if (!isValidVersion(marketingVersion)) {
|
|
1090
1082
|
throw new Error(
|
|
1091
1083
|
`The "MARKETING_VERSION" key in the "${resolvedPbxprojFile}" file needs to specify a valid semver string, containing both a major and minor version (e.g. 1.3.2, 1.1).`
|
|
@@ -1353,9 +1345,9 @@ export const releaseReact = (command: cli.IReleaseReactCommand): Promise<void> =
|
|
|
1353
1345
|
)
|
|
1354
1346
|
.then(async () => {
|
|
1355
1347
|
const isHermesEnabled =
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1348
|
+
command.useHermes ||
|
|
1349
|
+
(platform === "android" && (await getAndroidHermesEnabled(command.gradleFile))) || // Check if we have to run hermes to compile JS to Byte Code if Hermes is enabled in build.gradle and we're releasing an Android build
|
|
1350
|
+
(platform === "ios" && (await getiOSHermesEnabled(command.podFile))); // Check if we have to run hermes to compile JS to Byte Code if Hermes is enabled in Podfile and we're releasing an iOS build
|
|
1359
1351
|
|
|
1360
1352
|
if (isHermesEnabled) {
|
|
1361
1353
|
log(chalk.cyan("\nRunning hermes compiler...\n"));
|
|
@@ -1521,7 +1513,7 @@ function sessionList(command: cli.ISessionListCommand): Promise<void> {
|
|
|
1521
1513
|
|
|
1522
1514
|
function sessionRemove(command: cli.ISessionRemoveCommand): Promise<void> {
|
|
1523
1515
|
if (os.hostname() === command.machineName) {
|
|
1524
|
-
throw new Error("Cannot remove the current login session via this command. Please run '
|
|
1516
|
+
throw new Error("Cannot remove the current login session via this command. Please run 'revopush logout' instead.");
|
|
1525
1517
|
} else {
|
|
1526
1518
|
return confirm().then((wasConfirmed: boolean): Promise<void> => {
|
|
1527
1519
|
if (wasConfirmed) {
|
package/script/command-parser.ts
CHANGED
|
@@ -9,7 +9,7 @@ import parseDuration = require("parse-duration");
|
|
|
9
9
|
|
|
10
10
|
const packageJson = require("../../package.json");
|
|
11
11
|
const ROLLOUT_PERCENTAGE_REGEX: RegExp = /^(100|[1-9][0-9]|[1-9])%?$/;
|
|
12
|
-
const USAGE_PREFIX = "Usage:
|
|
12
|
+
const USAGE_PREFIX = "Usage: revopush";
|
|
13
13
|
|
|
14
14
|
// Command categories are: access-key, app, release, deployment, deployment-key, login, logout, register
|
|
15
15
|
let isValidCommandCategory = false;
|
|
@@ -20,13 +20,19 @@ let wasHelpShown = false;
|
|
|
20
20
|
export function showHelp(showRootDescription?: boolean): void {
|
|
21
21
|
if (!wasHelpShown) {
|
|
22
22
|
if (showRootDescription) {
|
|
23
|
-
console.log(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
console.log(
|
|
24
|
+
chalk.blue(`
|
|
25
|
+
____ ____ _
|
|
26
|
+
| _ \\ _____ _____ | _ \\ _ _ ___| |__
|
|
27
|
+
| |_) / _ \\ \\ / / _ \\| |_) | | | / __| '_ \\
|
|
28
|
+
| _ < __/\\ V / (_) | __/| |_| \\__ \\ | | |
|
|
29
|
+
|_| \\_\\___| \\_/ \\___/|_| \\__,_|___/_| |_| CLI v${packageJson.version}
|
|
30
|
+
============================================`)
|
|
31
|
+
);
|
|
32
|
+
console.log(
|
|
33
|
+
"Revopush is a service that enables you to deploy mobile app updates directly to your users' devices. " +
|
|
34
|
+
"Visit our website https://revopush.org/ \n"
|
|
35
|
+
);
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
yargs.showHelp();
|
|
@@ -322,6 +328,7 @@ yargs
|
|
|
322
328
|
.command("list", "Lists the apps associated with your account", (yargs: yargs.Argv) => appList("list", yargs))
|
|
323
329
|
.command("ls", "Lists the apps associated with your account", (yargs: yargs.Argv) => appList("ls", yargs))
|
|
324
330
|
.command("transfer", "Transfer the ownership of an app to another account", (yargs: yargs.Argv) => {
|
|
331
|
+
isValidCommand = true;
|
|
325
332
|
yargs
|
|
326
333
|
.usage(USAGE_PREFIX + " app transfer <appName> <email>")
|
|
327
334
|
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
|
|
@@ -376,7 +383,14 @@ yargs
|
|
|
376
383
|
yargs
|
|
377
384
|
.usage(USAGE_PREFIX + " deployment add <appName> <deploymentName>")
|
|
378
385
|
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
|
|
379
|
-
.example("deployment add MyApp MyDeployment", 'Adds deployment "MyDeployment" to app "MyApp"')
|
|
386
|
+
.example("deployment add MyApp MyDeployment", 'Adds deployment "MyDeployment" to app "MyApp"')
|
|
387
|
+
.example("deployment add MyApp MyDeployment -k abc123", 'Adds deployment key "abc123"')
|
|
388
|
+
.option("key", {
|
|
389
|
+
alias: "k",
|
|
390
|
+
demand: false,
|
|
391
|
+
description: "Specify deployment key",
|
|
392
|
+
type: "string",
|
|
393
|
+
});
|
|
380
394
|
|
|
381
395
|
addCommonConfiguration(yargs);
|
|
382
396
|
})
|
|
@@ -405,23 +419,23 @@ yargs
|
|
|
405
419
|
|
|
406
420
|
addCommonConfiguration(yargs);
|
|
407
421
|
})
|
|
408
|
-
.command("link", "Link an additional authentication provider (e.g. GitHub) to an existing CodePush account", (yargs: yargs.Argv) => {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
422
|
+
/* .command("link", "Link an additional authentication provider (e.g. GitHub) to an existing CodePush account", (yargs: yargs.Argv) => {
|
|
423
|
+
isValidCommandCategory = true;
|
|
424
|
+
isValidCommand = true;
|
|
425
|
+
yargs
|
|
426
|
+
.usage(USAGE_PREFIX + " link")
|
|
427
|
+
.demand(/!*count*!/ 0, /!*max*!/ 1) //set 'max' to one to allow usage of serverUrl undocument parameter for testing
|
|
428
|
+
.example("link", "Links an account on the CodePush server")
|
|
429
|
+
.check((argv: any, aliases: { [aliases: string]: string }): any => isValidCommand); // Report unrecognized, non-hyphenated command category.
|
|
416
430
|
|
|
417
|
-
|
|
418
|
-
|
|
431
|
+
addCommonConfiguration(yargs);
|
|
432
|
+
})*/
|
|
419
433
|
.command("login", "Authenticate with the CodePush server in order to begin managing your apps", (yargs: yargs.Argv) => {
|
|
420
434
|
isValidCommandCategory = true;
|
|
421
435
|
isValidCommand = true;
|
|
422
436
|
yargs
|
|
423
437
|
.usage(USAGE_PREFIX + " login [options]")
|
|
424
|
-
.demand(/*count*/ 0, /*max*/
|
|
438
|
+
.demand(/*count*/ 0, /*max*/ 2) //set 'max' to one to allow usage of serverUrl undocument parameter for testing
|
|
425
439
|
.example("login", "Logs in to the CodePush server")
|
|
426
440
|
.example("login --accessKey mykey", 'Logs in on behalf of the user who owns and created the access key "mykey"')
|
|
427
441
|
.option("accessKey", {
|
|
@@ -786,15 +800,14 @@ yargs
|
|
|
786
800
|
alias: "pod",
|
|
787
801
|
default: null,
|
|
788
802
|
demand: false,
|
|
789
|
-
description:
|
|
803
|
+
description: "Path to the cocopods config file (iOS only).",
|
|
790
804
|
type: "string",
|
|
791
805
|
})
|
|
792
806
|
.option("extraHermesFlags", {
|
|
793
807
|
alias: "hf",
|
|
794
808
|
default: [],
|
|
795
809
|
demand: false,
|
|
796
|
-
description:
|
|
797
|
-
"Flags that get passed to Hermes, JavaScript to bytecode compiler. Can be specified multiple times.",
|
|
810
|
+
description: "Flags that get passed to Hermes, JavaScript to bytecode compiler. Can be specified multiple times.",
|
|
798
811
|
type: "array",
|
|
799
812
|
})
|
|
800
813
|
.option("privateKeyPath", {
|
|
@@ -815,14 +828,16 @@ yargs
|
|
|
815
828
|
alias: "xt",
|
|
816
829
|
default: undefined,
|
|
817
830
|
demand: false,
|
|
818
|
-
description:
|
|
831
|
+
description:
|
|
832
|
+
"Name of target (PBXNativeTarget) which specifies the binary version you want to target this release at (iOS only)",
|
|
819
833
|
type: "string",
|
|
820
834
|
})
|
|
821
835
|
.option("buildConfigurationName", {
|
|
822
836
|
alias: "c",
|
|
823
837
|
default: undefined,
|
|
824
838
|
demand: false,
|
|
825
|
-
description:
|
|
839
|
+
description:
|
|
840
|
+
"Name of build configuration which specifies the binary version you want to target this release at. For example, 'Debug' or 'Release' (iOS only)",
|
|
826
841
|
type: "string",
|
|
827
842
|
})
|
|
828
843
|
.check((argv: any, aliases: { [aliases: string]: string }): any => {
|
|
@@ -1045,6 +1060,9 @@ export function createCommand(): cli.ICommand {
|
|
|
1045
1060
|
|
|
1046
1061
|
deploymentAddCommand.appName = arg2;
|
|
1047
1062
|
deploymentAddCommand.deploymentName = arg3;
|
|
1063
|
+
if (argv["key"]) {
|
|
1064
|
+
deploymentAddCommand.key = argv["key"] as any;
|
|
1065
|
+
}
|
|
1048
1066
|
}
|
|
1049
1067
|
break;
|
|
1050
1068
|
|
|
@@ -1112,19 +1130,20 @@ export function createCommand(): cli.ICommand {
|
|
|
1112
1130
|
}
|
|
1113
1131
|
break;
|
|
1114
1132
|
|
|
1115
|
-
case "link":
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1133
|
+
/* case "link":
|
|
1134
|
+
cmd = <cli.ILinkCommand>{
|
|
1135
|
+
type: cli.CommandType.link,
|
|
1136
|
+
serverUrl: getServerUrl(arg1),
|
|
1137
|
+
};
|
|
1138
|
+
break;*/
|
|
1121
1139
|
|
|
1122
1140
|
case "login":
|
|
1123
1141
|
cmd = { type: cli.CommandType.login };
|
|
1124
1142
|
|
|
1125
1143
|
const loginCommand = <cli.ILoginCommand>cmd;
|
|
1126
1144
|
|
|
1127
|
-
loginCommand.
|
|
1145
|
+
loginCommand.apiServerUrl = getServerUrl(arg1);
|
|
1146
|
+
loginCommand.appServerUrl = getServerUrl(arg2);
|
|
1128
1147
|
loginCommand.accessKey = argv["accessKey"] as any;
|
|
1129
1148
|
break;
|
|
1130
1149
|
|
package/script/management-sdk.ts
CHANGED
|
@@ -58,7 +58,8 @@ class AccountManager {
|
|
|
58
58
|
OWNER: "Owner",
|
|
59
59
|
COLLABORATOR: "Collaborator",
|
|
60
60
|
};
|
|
61
|
-
public static
|
|
61
|
+
public static API_SERVER_URL = "https://api.revopush.org";
|
|
62
|
+
public static APP_SERVER_URL = "https://app.revopush.org";
|
|
62
63
|
|
|
63
64
|
private static API_VERSION: number = 2;
|
|
64
65
|
|
|
@@ -77,7 +78,7 @@ class AccountManager {
|
|
|
77
78
|
|
|
78
79
|
this._accessKey = accessKey;
|
|
79
80
|
this._customHeaders = customHeaders;
|
|
80
|
-
this._serverUrl = serverUrl || AccountManager.
|
|
81
|
+
this._serverUrl = serverUrl || AccountManager.API_SERVER_URL;
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
public get accessKey(): string {
|
|
@@ -253,8 +254,8 @@ class AccountManager {
|
|
|
253
254
|
}
|
|
254
255
|
|
|
255
256
|
// Deployments
|
|
256
|
-
public addDeployment(appName: string, deploymentName: string): Promise<Deployment> {
|
|
257
|
-
const deployment = <Deployment>{ name: deploymentName };
|
|
257
|
+
public addDeployment(appName: string, deploymentName: string, deploymentKey?: string): Promise<Deployment> {
|
|
258
|
+
const deployment = <Deployment>{ name: deploymentName, key: deploymentKey };
|
|
258
259
|
return this.post(urlEncode([`/apps/${appName}/deployments/`]), JSON.stringify(deployment), /*expectResponseBody=*/ true).then(
|
|
259
260
|
(res: JsonResponse) => res.body.deployment
|
|
260
261
|
);
|