@appcircle/codepush-cli 0.0.1 → 0.0.3-alpha.1
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 +0 -55
- package/bin/script/command-executor.js +17 -10
- package/bin/script/command-parser.js +13 -67
- package/bin/script/management-sdk.js +3 -0
- package/bin/script/types/cli.js +22 -26
- package/bin/test/cli.js +0 -62
- package/package.json +1 -1
- package/script/command-executor.ts +21 -15
- package/script/command-parser.ts +15 -80
- package/script/management-sdk.ts +5 -0
- package/script/types/cli.ts +6 -6
- package/script/types/rest-definitions.ts +6 -0
- package/test/cli.ts +0 -77
package/README.md
CHANGED
|
@@ -58,11 +58,6 @@ appcircle-code-push login <optional: server-url> <optional: auth-url>
|
|
|
58
58
|
|
|
59
59
|
This will launch a browser, asking you to authenticate with either your GitHub or Microsoft account. This will generate an access key that you need to copy/paste into the CLI (it will prompt you for it). You are now successfully authenticated and can safely close your browser window.
|
|
60
60
|
|
|
61
|
-
If at any time you want to determine if you're already logged in, you can run the following command to display the e-mail address associated with your current authentication session, which identity providers your account is linked to (e.g. GitHub):
|
|
62
|
-
|
|
63
|
-
```shell
|
|
64
|
-
appcircle-code-push whoami
|
|
65
|
-
```
|
|
66
61
|
|
|
67
62
|
When you login from the CLI, your access key is persisted to disk for the duration of your session so that you don't have to login every time you attempt to access your account. In order to end your session and delete this access key, simply run the following command:
|
|
68
63
|
|
|
@@ -145,56 +140,6 @@ you can run the following command:
|
|
|
145
140
|
appcircle-code-push app ls
|
|
146
141
|
```
|
|
147
142
|
|
|
148
|
-
### App Collaboration
|
|
149
|
-
|
|
150
|
-
If you will be working with other developers on the same CodePush app, you can add them as collaborators using the following command:
|
|
151
|
-
|
|
152
|
-
```shell
|
|
153
|
-
appcircle-code-push collaborator add <appName> <collaboratorEmail>
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
_NOTE: This expects the developer to have already [registered](#account-creation) with CodePush using the specified e-mail address, so ensure that they have done that before attempting to share the app with them._
|
|
157
|
-
|
|
158
|
-
Once added, all collaborators will immediately have the following permissions with regards to the newly shared app:
|
|
159
|
-
|
|
160
|
-
1. View the app, its collaborators, [deployments](#deployment-management) and [release history](#viewing-release-history)
|
|
161
|
-
1. [Release](#releasing-updates) updates to any of the app's deployments
|
|
162
|
-
1. [Promote](#promoting-updates) an update between any of the app's deployments
|
|
163
|
-
1. [Rollback](#rolling-back-undesired-updates) any of the app's deployments
|
|
164
|
-
1. [Patch](#updating-existing-releases) any releases within any of the app's deployments
|
|
165
|
-
|
|
166
|
-
Inversely, that means that an app collaborator cannot do any of the following:
|
|
167
|
-
|
|
168
|
-
1. Rename or delete the app
|
|
169
|
-
1. Transfer ownership of the app
|
|
170
|
-
1. Create, rename or delete new deployments within the app
|
|
171
|
-
1. Clear a deployment's release history
|
|
172
|
-
1. Add or remove collaborators from the app (\*)
|
|
173
|
-
|
|
174
|
-
_NOTE: A developer can remove him/herself as a collaborator from an app that was shared with them._
|
|
175
|
-
|
|
176
|
-
Over time, if someone is no longer working on an app with you, you can remove them as a collaborator using the following command:
|
|
177
|
-
|
|
178
|
-
```shell
|
|
179
|
-
appcircle-code-push collaborator rm <appName> <collaboratorEmail>
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
If at any time you want to list all collaborators that have been added to an app, you can simply run the following command:
|
|
183
|
-
|
|
184
|
-
```shell
|
|
185
|
-
appcircle-code-push collaborator ls <appName>
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
Finally, if at some point, you (as the app owner) will no longer be working on the app, and you want to transfer it to another developer (or a client), you can run the following command:
|
|
189
|
-
|
|
190
|
-
```shell
|
|
191
|
-
appcircle-code-push app transfer <appName> <newOwnerEmail>
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
_NOTE: Just like with the `appcircle-code-push collaborator add` command, this expects that the new owner has already registered with CodePush using the specified e-mail address._
|
|
195
|
-
|
|
196
|
-
Once confirmed, the specified developer becomes the app's owner and immediately receives the permissions associated with that role. Besides the transfer of ownership, nothing else about the app is modified (e.g. deployments, release history, collaborators). This means that you will still be a collaborator of the app, and therefore, if you want to remove yourself, you simply need to run the `appcircle-code-push collaborator rm` command after successfully transferring ownership.
|
|
197
|
-
|
|
198
143
|
### Deployment Management
|
|
199
144
|
|
|
200
145
|
From the CodePush perspective, an app is simply a named grouping for one or more things called "deployments". While the app represents a conceptual "namespace" or "scope" for a platform-specific version of an app (e.g. the iOS port of Foo app), its deployments represent the actual target for releasing updates (for developers) and synchronizing updates (for end-users). Deployments allow you to have multiple "environments" for each app in-flight at any given time, and help model the reality that apps typically move from a dev's personal environment to a testing/QA/staging environment, before finally making their way into production.
|
|
@@ -133,6 +133,11 @@ function appList(command) {
|
|
|
133
133
|
printAppList(command.format, retrievedApps);
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
|
+
function appDeploymentKeyList(command) {
|
|
137
|
+
return exports.sdk.getDeploymentKeys(command.appName).then((retrievedKeys) => {
|
|
138
|
+
printAppDeploymentKeyList(retrievedKeys);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
136
141
|
function appRemove(command) {
|
|
137
142
|
return (0, exports.confirm)("Are you sure you want to remove this app? Note that its deployment keys will be PERMANENTLY unrecoverable.").then((wasConfirmed) => {
|
|
138
143
|
if (wasConfirmed) {
|
|
@@ -368,18 +373,12 @@ function execute(command) {
|
|
|
368
373
|
return appAdd(command);
|
|
369
374
|
case cli.CommandType.appList:
|
|
370
375
|
return appList(command);
|
|
376
|
+
case cli.CommandType.appDeploymentKeyList:
|
|
377
|
+
return appDeploymentKeyList(command);
|
|
371
378
|
case cli.CommandType.appRemove:
|
|
372
379
|
return appRemove(command);
|
|
373
380
|
case cli.CommandType.appRename:
|
|
374
381
|
return appRename(command);
|
|
375
|
-
case cli.CommandType.appTransfer:
|
|
376
|
-
return appTransfer(command);
|
|
377
|
-
case cli.CommandType.collaboratorAdd:
|
|
378
|
-
return addCollaborator(command);
|
|
379
|
-
case cli.CommandType.collaboratorList:
|
|
380
|
-
return listCollaborators(command);
|
|
381
|
-
case cli.CommandType.collaboratorRemove:
|
|
382
|
-
return removeCollaborator(command);
|
|
383
382
|
case cli.CommandType.debug:
|
|
384
383
|
return (0, debug_1.default)(command);
|
|
385
384
|
case cli.CommandType.deploymentAdd:
|
|
@@ -416,8 +415,6 @@ function execute(command) {
|
|
|
416
415
|
return sessionList(command);
|
|
417
416
|
case cli.CommandType.sessionRemove:
|
|
418
417
|
return sessionRemove(command);
|
|
419
|
-
case cli.CommandType.whoami:
|
|
420
|
-
return whoami(command);
|
|
421
418
|
default:
|
|
422
419
|
// We should never see this message as invalid commands should be caught by the argument parser.
|
|
423
420
|
throw new Error("Invalid command: " + JSON.stringify(command));
|
|
@@ -524,6 +521,15 @@ function printAppList(format, apps) {
|
|
|
524
521
|
});
|
|
525
522
|
}
|
|
526
523
|
}
|
|
524
|
+
function printAppDeploymentKeyList(deploymentKeys) {
|
|
525
|
+
const headers = ["Name", "Deployment Key"];
|
|
526
|
+
printTable(headers, (dataSource) => {
|
|
527
|
+
deploymentKeys.forEach((deploymentKey, index) => {
|
|
528
|
+
const row = [deploymentKey.name, wordwrap(50)(deploymentKey.deploymentKey)];
|
|
529
|
+
dataSource.push(row);
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
}
|
|
527
533
|
function getCollaboratorDisplayName(email, collaboratorProperties) {
|
|
528
534
|
return collaboratorProperties.permission === AccountManager.AppPermission.OWNER ? email + chalk.magenta(" (Owner)") : email;
|
|
529
535
|
}
|
|
@@ -1254,6 +1260,7 @@ function throwForInvalidOutputFormat(format) {
|
|
|
1254
1260
|
throw new Error("Invalid format: " + format + ".");
|
|
1255
1261
|
}
|
|
1256
1262
|
}
|
|
1263
|
+
// DEPRECATED
|
|
1257
1264
|
function whoami(command) {
|
|
1258
1265
|
return exports.sdk.getAccountInfo().then((account) => {
|
|
1259
1266
|
const accountInfo = `${account.email} (${account.linkedProviders.join(", ")})`;
|
|
@@ -120,6 +120,14 @@ function appRemove(commandName, yargs) {
|
|
|
120
120
|
.example("app " + commandName + " MyApp", 'Removes app "MyApp"');
|
|
121
121
|
addCommonConfiguration(yargs);
|
|
122
122
|
}
|
|
123
|
+
function appDeploymentKeyList(commandName, yargs) {
|
|
124
|
+
isValidCommand = true;
|
|
125
|
+
yargs
|
|
126
|
+
.usage(USAGE_PREFIX + " app " + commandName + " <appName>")
|
|
127
|
+
.demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
|
|
128
|
+
.example("app " + commandName + " MyApp", 'Lists the deployment keys for app "MyApp" in tabular format');
|
|
129
|
+
addCommonConfiguration(yargs);
|
|
130
|
+
}
|
|
123
131
|
function listCollaborators(commandName, yargs) {
|
|
124
132
|
isValidCommand = true;
|
|
125
133
|
yargs
|
|
@@ -268,6 +276,7 @@ yargs
|
|
|
268
276
|
})
|
|
269
277
|
.command("list", "Lists the apps associated with your account", (yargs) => appList("list", yargs))
|
|
270
278
|
.command("ls", "Lists the apps associated with your account", (yargs) => appList("ls", yargs))
|
|
279
|
+
.command("deployment-keys", "Lists the deployment keys for app", (yargs) => appDeploymentKeyList("deployment-keys", yargs))
|
|
271
280
|
.command("transfer", "Transfer the ownership of an app to another account", (yargs) => {
|
|
272
281
|
isValidCommand = true;
|
|
273
282
|
yargs
|
|
@@ -278,26 +287,6 @@ yargs
|
|
|
278
287
|
})
|
|
279
288
|
.check((argv, aliases) => isValidCommand); // Report unrecognized, non-hyphenated command category.
|
|
280
289
|
addCommonConfiguration(yargs);
|
|
281
|
-
})
|
|
282
|
-
.command("collaborator", "View and manage app collaborators", (yargs) => {
|
|
283
|
-
isValidCommandCategory = true;
|
|
284
|
-
yargs
|
|
285
|
-
.usage(USAGE_PREFIX + " collaborator <command>")
|
|
286
|
-
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments.
|
|
287
|
-
.command("add", "Add a new collaborator to an app", (yargs) => {
|
|
288
|
-
isValidCommand = true;
|
|
289
|
-
yargs
|
|
290
|
-
.usage(USAGE_PREFIX + " collaborator add <appName> <email>")
|
|
291
|
-
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
|
|
292
|
-
.example("collaborator add MyApp foo@bar.com", 'Adds foo@bar.com as a collaborator to app "MyApp"');
|
|
293
|
-
addCommonConfiguration(yargs);
|
|
294
|
-
})
|
|
295
|
-
.command("remove", "Remove a collaborator from an app", (yargs) => removeCollaborator("remove", yargs))
|
|
296
|
-
.command("rm", "Remove a collaborator from an app", (yargs) => removeCollaborator("rm", yargs))
|
|
297
|
-
.command("list", "List the collaborators for an app", (yargs) => listCollaborators("list", yargs))
|
|
298
|
-
.command("ls", "List the collaborators for an app", (yargs) => listCollaborators("ls", yargs))
|
|
299
|
-
.check((argv, aliases) => isValidCommand); // Report unrecognized, non-hyphenated command category.
|
|
300
|
-
addCommonConfiguration(yargs);
|
|
301
290
|
})
|
|
302
291
|
.command("debug", "View the CodePush debug logs for a running app", (yargs) => {
|
|
303
292
|
isValidCommandCategory = true;
|
|
@@ -761,15 +750,6 @@ yargs
|
|
|
761
750
|
.command("ls", "List the current login sessions associated with your account", (yargs) => sessionList("ls", yargs))
|
|
762
751
|
.check((argv, aliases) => isValidCommand); // Report unrecognized, non-hyphenated command category.
|
|
763
752
|
addCommonConfiguration(yargs);
|
|
764
|
-
})
|
|
765
|
-
.command("whoami", "Display the account info for the current login session", (yargs) => {
|
|
766
|
-
isValidCommandCategory = true;
|
|
767
|
-
isValidCommand = true;
|
|
768
|
-
yargs
|
|
769
|
-
.usage(USAGE_PREFIX + " whoami")
|
|
770
|
-
.demand(/*count*/ 0, /*max*/ 0)
|
|
771
|
-
.example("whoami", "Display the account info for the current login session");
|
|
772
|
-
addCommonConfiguration(yargs);
|
|
773
753
|
})
|
|
774
754
|
.alias("v", "version")
|
|
775
755
|
.version(packageJson.version)
|
|
@@ -841,6 +821,10 @@ function createCommand() {
|
|
|
841
821
|
cmd = { type: cli.CommandType.appList };
|
|
842
822
|
cmd.format = argv["format"];
|
|
843
823
|
break;
|
|
824
|
+
case "deployment-keys":
|
|
825
|
+
cmd = { type: cli.CommandType.appDeploymentKeyList };
|
|
826
|
+
cmd.appName = arg2;
|
|
827
|
+
break;
|
|
844
828
|
case "remove":
|
|
845
829
|
case "rm":
|
|
846
830
|
if (arg2) {
|
|
@@ -856,41 +840,6 @@ function createCommand() {
|
|
|
856
840
|
appRenameCommand.newAppName = arg3;
|
|
857
841
|
}
|
|
858
842
|
break;
|
|
859
|
-
case "transfer":
|
|
860
|
-
if (arg2 && arg3) {
|
|
861
|
-
cmd = { type: cli.CommandType.appTransfer };
|
|
862
|
-
const appTransferCommand = cmd;
|
|
863
|
-
appTransferCommand.appName = arg2;
|
|
864
|
-
appTransferCommand.email = arg3;
|
|
865
|
-
}
|
|
866
|
-
break;
|
|
867
|
-
}
|
|
868
|
-
break;
|
|
869
|
-
case "collaborator":
|
|
870
|
-
switch (arg1) {
|
|
871
|
-
case "add":
|
|
872
|
-
if (arg2 && arg3) {
|
|
873
|
-
cmd = { type: cli.CommandType.collaboratorAdd };
|
|
874
|
-
cmd.appName = arg2;
|
|
875
|
-
cmd.email = arg3;
|
|
876
|
-
}
|
|
877
|
-
break;
|
|
878
|
-
case "list":
|
|
879
|
-
case "ls":
|
|
880
|
-
if (arg2) {
|
|
881
|
-
cmd = { type: cli.CommandType.collaboratorList };
|
|
882
|
-
cmd.appName = arg2;
|
|
883
|
-
cmd.format = argv["format"];
|
|
884
|
-
}
|
|
885
|
-
break;
|
|
886
|
-
case "remove":
|
|
887
|
-
case "rm":
|
|
888
|
-
if (arg2 && arg3) {
|
|
889
|
-
cmd = { type: cli.CommandType.collaboratorRemove };
|
|
890
|
-
cmd.appName = arg2;
|
|
891
|
-
cmd.email = arg3;
|
|
892
|
-
}
|
|
893
|
-
break;
|
|
894
843
|
}
|
|
895
844
|
break;
|
|
896
845
|
case "debug":
|
|
@@ -1083,9 +1032,6 @@ function createCommand() {
|
|
|
1083
1032
|
break;
|
|
1084
1033
|
}
|
|
1085
1034
|
break;
|
|
1086
|
-
case "whoami":
|
|
1087
|
-
cmd = { type: cli.CommandType.whoami };
|
|
1088
|
-
break;
|
|
1089
1035
|
}
|
|
1090
1036
|
return cmd;
|
|
1091
1037
|
}
|
|
@@ -190,6 +190,9 @@ class AccountManager {
|
|
|
190
190
|
getApp(appName) {
|
|
191
191
|
return this.get(urlEncode([`/apps/${appName}`])).then((res) => res.body.app);
|
|
192
192
|
}
|
|
193
|
+
getDeploymentKeys(appName) {
|
|
194
|
+
return this.get(urlEncode([`/apps/${appName}/deployment-keys`])).then((res) => res.body);
|
|
195
|
+
}
|
|
193
196
|
addApp(appName) {
|
|
194
197
|
const app = { name: appName };
|
|
195
198
|
return this.post(urlEncode(["/apps"]), JSON.stringify(app), /*expectResponseBody=*/ false).then(() => app);
|
package/bin/script/types/cli.js
CHANGED
|
@@ -11,30 +11,26 @@ var CommandType;
|
|
|
11
11
|
CommandType[CommandType["accessKeyRemove"] = 3] = "accessKeyRemove";
|
|
12
12
|
CommandType[CommandType["appAdd"] = 4] = "appAdd";
|
|
13
13
|
CommandType[CommandType["appList"] = 5] = "appList";
|
|
14
|
-
CommandType[CommandType["
|
|
15
|
-
CommandType[CommandType["
|
|
16
|
-
CommandType[CommandType["
|
|
17
|
-
CommandType[CommandType["
|
|
18
|
-
CommandType[CommandType["
|
|
19
|
-
CommandType[CommandType["
|
|
20
|
-
CommandType[CommandType["
|
|
21
|
-
CommandType[CommandType["
|
|
22
|
-
CommandType[CommandType["
|
|
23
|
-
CommandType[CommandType["
|
|
24
|
-
CommandType[CommandType["
|
|
25
|
-
CommandType[CommandType["
|
|
26
|
-
CommandType[CommandType["
|
|
27
|
-
CommandType[CommandType["
|
|
28
|
-
CommandType[CommandType["
|
|
29
|
-
CommandType[CommandType["
|
|
30
|
-
CommandType[CommandType["
|
|
31
|
-
CommandType[CommandType["
|
|
32
|
-
CommandType[CommandType["
|
|
33
|
-
CommandType[CommandType["
|
|
34
|
-
CommandType[CommandType["
|
|
35
|
-
CommandType[CommandType["
|
|
36
|
-
CommandType[CommandType["rollback"] = 28] = "rollback";
|
|
37
|
-
CommandType[CommandType["sessionList"] = 29] = "sessionList";
|
|
38
|
-
CommandType[CommandType["sessionRemove"] = 30] = "sessionRemove";
|
|
39
|
-
CommandType[CommandType["whoami"] = 31] = "whoami";
|
|
14
|
+
CommandType[CommandType["appDeploymentKeyList"] = 6] = "appDeploymentKeyList";
|
|
15
|
+
CommandType[CommandType["appRemove"] = 7] = "appRemove";
|
|
16
|
+
CommandType[CommandType["appRename"] = 8] = "appRename";
|
|
17
|
+
CommandType[CommandType["debug"] = 9] = "debug";
|
|
18
|
+
CommandType[CommandType["deploymentAdd"] = 10] = "deploymentAdd";
|
|
19
|
+
CommandType[CommandType["deploymentHistory"] = 11] = "deploymentHistory";
|
|
20
|
+
CommandType[CommandType["deploymentHistoryClear"] = 12] = "deploymentHistoryClear";
|
|
21
|
+
CommandType[CommandType["deploymentList"] = 13] = "deploymentList";
|
|
22
|
+
CommandType[CommandType["deploymentMetrics"] = 14] = "deploymentMetrics";
|
|
23
|
+
CommandType[CommandType["deploymentRemove"] = 15] = "deploymentRemove";
|
|
24
|
+
CommandType[CommandType["deploymentRename"] = 16] = "deploymentRename";
|
|
25
|
+
CommandType[CommandType["link"] = 17] = "link";
|
|
26
|
+
CommandType[CommandType["login"] = 18] = "login";
|
|
27
|
+
CommandType[CommandType["logout"] = 19] = "logout";
|
|
28
|
+
CommandType[CommandType["patch"] = 20] = "patch";
|
|
29
|
+
CommandType[CommandType["promote"] = 21] = "promote";
|
|
30
|
+
CommandType[CommandType["register"] = 22] = "register";
|
|
31
|
+
CommandType[CommandType["release"] = 23] = "release";
|
|
32
|
+
CommandType[CommandType["releaseReact"] = 24] = "releaseReact";
|
|
33
|
+
CommandType[CommandType["rollback"] = 25] = "rollback";
|
|
34
|
+
CommandType[CommandType["sessionList"] = 26] = "sessionList";
|
|
35
|
+
CommandType[CommandType["sessionRemove"] = 27] = "sessionRemove";
|
|
40
36
|
})(CommandType || (exports.CommandType = CommandType = {}));
|
package/bin/test/cli.js
CHANGED
|
@@ -482,68 +482,6 @@ describe("CLI", () => {
|
|
|
482
482
|
done();
|
|
483
483
|
});
|
|
484
484
|
});
|
|
485
|
-
it("appTransfer transfers app", (done) => {
|
|
486
|
-
var command = {
|
|
487
|
-
type: cli.CommandType.appTransfer,
|
|
488
|
-
appName: "a",
|
|
489
|
-
email: "b@b.com",
|
|
490
|
-
};
|
|
491
|
-
var transferApp = sandbox.spy(cmdexec.sdk, "transferApp");
|
|
492
|
-
cmdexec.execute(command).done(() => {
|
|
493
|
-
sinon.assert.calledOnce(transferApp);
|
|
494
|
-
sinon.assert.calledOnce(log);
|
|
495
|
-
sinon.assert.calledWithExactly(log, 'Successfully transferred the ownership of app "a" to the account with email "b@b.com".');
|
|
496
|
-
done();
|
|
497
|
-
});
|
|
498
|
-
});
|
|
499
|
-
it("collaboratorAdd adds collaborator", (done) => {
|
|
500
|
-
var command = {
|
|
501
|
-
type: cli.CommandType.collaboratorAdd,
|
|
502
|
-
appName: "a",
|
|
503
|
-
email: "b@b.com",
|
|
504
|
-
};
|
|
505
|
-
var addCollaborator = sandbox.spy(cmdexec.sdk, "addCollaborator");
|
|
506
|
-
cmdexec.execute(command).done(() => {
|
|
507
|
-
sinon.assert.calledOnce(addCollaborator);
|
|
508
|
-
sinon.assert.calledOnce(log);
|
|
509
|
-
sinon.assert.calledWithExactly(log, 'Successfully added "b@b.com" as a collaborator to the app "a".');
|
|
510
|
-
done();
|
|
511
|
-
});
|
|
512
|
-
});
|
|
513
|
-
it("collaboratorList lists collaborators email and properties", (done) => {
|
|
514
|
-
var command = {
|
|
515
|
-
type: cli.CommandType.collaboratorList,
|
|
516
|
-
appName: "a",
|
|
517
|
-
format: "json",
|
|
518
|
-
};
|
|
519
|
-
cmdexec.execute(command).done(() => {
|
|
520
|
-
sinon.assert.calledOnce(log);
|
|
521
|
-
assert.equal(log.args[0].length, 1);
|
|
522
|
-
var actual = log.args[0][0];
|
|
523
|
-
var expected = {
|
|
524
|
-
collaborators: {
|
|
525
|
-
"a@a.com": { permission: "Owner", isCurrentAccount: true },
|
|
526
|
-
"b@b.com": { permission: "Collaborator", isCurrentAccount: false },
|
|
527
|
-
},
|
|
528
|
-
};
|
|
529
|
-
assertJsonDescribesObject(actual, expected);
|
|
530
|
-
done();
|
|
531
|
-
});
|
|
532
|
-
});
|
|
533
|
-
it("collaboratorRemove removes collaborator", (done) => {
|
|
534
|
-
var command = {
|
|
535
|
-
type: cli.CommandType.collaboratorRemove,
|
|
536
|
-
appName: "a",
|
|
537
|
-
email: "b@b.com",
|
|
538
|
-
};
|
|
539
|
-
var removeCollaborator = sandbox.spy(cmdexec.sdk, "removeCollaborator");
|
|
540
|
-
cmdexec.execute(command).done(() => {
|
|
541
|
-
sinon.assert.calledOnce(removeCollaborator);
|
|
542
|
-
sinon.assert.calledOnce(log);
|
|
543
|
-
sinon.assert.calledWithExactly(log, 'Successfully removed "b@b.com" as a collaborator from the app "a".');
|
|
544
|
-
done();
|
|
545
|
-
});
|
|
546
|
-
});
|
|
547
485
|
it("deploymentAdd reports new app name and ID", (done) => {
|
|
548
486
|
var command = {
|
|
549
487
|
type: cli.CommandType.deploymentAdd,
|
package/package.json
CHANGED
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
isBinaryOrZip,
|
|
50
50
|
fileExists
|
|
51
51
|
} from "./utils/file-utils";
|
|
52
|
+
import { DeploymentKey } from "./types/rest-definitions";
|
|
52
53
|
|
|
53
54
|
const configFilePath: string = path.join(process.env.LOCALAPPDATA || process.env.HOME, ".code-push.config");
|
|
54
55
|
const emailValidator = require("email-validator");
|
|
@@ -196,6 +197,12 @@ function appList(command: cli.IAppListCommand): Promise<void> {
|
|
|
196
197
|
});
|
|
197
198
|
}
|
|
198
199
|
|
|
200
|
+
function appDeploymentKeyList(command: cli.IAppDeploymentKeysCommand): Promise<void> {
|
|
201
|
+
return sdk.getDeploymentKeys(command.appName).then((retrievedKeys: DeploymentKey[]): void => {
|
|
202
|
+
printAppDeploymentKeyList(retrievedKeys);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
199
206
|
function appRemove(command: cli.IAppRemoveCommand): Promise<void> {
|
|
200
207
|
return confirm("Are you sure you want to remove this app? Note that its deployment keys will be PERMANENTLY unrecoverable.").then(
|
|
201
208
|
(wasConfirmed: boolean): Promise<void> => {
|
|
@@ -481,6 +488,9 @@ export function execute(command: cli.ICommand) {
|
|
|
481
488
|
|
|
482
489
|
case cli.CommandType.appList:
|
|
483
490
|
return appList(<cli.IAppListCommand>command);
|
|
491
|
+
|
|
492
|
+
case cli.CommandType.appDeploymentKeyList:
|
|
493
|
+
return appDeploymentKeyList(<cli.IAppDeploymentKeysCommand>command);
|
|
484
494
|
|
|
485
495
|
case cli.CommandType.appRemove:
|
|
486
496
|
return appRemove(<cli.IAppRemoveCommand>command);
|
|
@@ -488,18 +498,6 @@ export function execute(command: cli.ICommand) {
|
|
|
488
498
|
case cli.CommandType.appRename:
|
|
489
499
|
return appRename(<cli.IAppRenameCommand>command);
|
|
490
500
|
|
|
491
|
-
case cli.CommandType.appTransfer:
|
|
492
|
-
return appTransfer(<cli.IAppTransferCommand>command);
|
|
493
|
-
|
|
494
|
-
case cli.CommandType.collaboratorAdd:
|
|
495
|
-
return addCollaborator(<cli.ICollaboratorAddCommand>command);
|
|
496
|
-
|
|
497
|
-
case cli.CommandType.collaboratorList:
|
|
498
|
-
return listCollaborators(<cli.ICollaboratorListCommand>command);
|
|
499
|
-
|
|
500
|
-
case cli.CommandType.collaboratorRemove:
|
|
501
|
-
return removeCollaborator(<cli.ICollaboratorRemoveCommand>command);
|
|
502
|
-
|
|
503
501
|
case cli.CommandType.debug:
|
|
504
502
|
return debugCommand(<cli.IDebugCommand>command);
|
|
505
503
|
|
|
@@ -554,9 +552,6 @@ export function execute(command: cli.ICommand) {
|
|
|
554
552
|
case cli.CommandType.sessionRemove:
|
|
555
553
|
return sessionRemove(<cli.ISessionRemoveCommand>command);
|
|
556
554
|
|
|
557
|
-
case cli.CommandType.whoami:
|
|
558
|
-
return whoami(command);
|
|
559
|
-
|
|
560
555
|
default:
|
|
561
556
|
// We should never see this message as invalid commands should be caught by the argument parser.
|
|
562
557
|
throw new Error("Invalid command: " + JSON.stringify(command));
|
|
@@ -671,6 +666,16 @@ function printAppList(format: string, apps: App[]): void {
|
|
|
671
666
|
}
|
|
672
667
|
}
|
|
673
668
|
|
|
669
|
+
function printAppDeploymentKeyList(deploymentKeys: DeploymentKey[]): void {
|
|
670
|
+
const headers = ["Name", "Deployment Key"];
|
|
671
|
+
printTable(headers, (dataSource: any[]): void => {
|
|
672
|
+
deploymentKeys.forEach((deploymentKey: DeploymentKey, index: number): void => {
|
|
673
|
+
const row = [deploymentKey.name, wordwrap(50)(deploymentKey.deploymentKey)];
|
|
674
|
+
dataSource.push(row);
|
|
675
|
+
});
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
|
|
674
679
|
function getCollaboratorDisplayName(email: string, collaboratorProperties: CollaboratorProperties): string {
|
|
675
680
|
return collaboratorProperties.permission === AccountManager.AppPermission.OWNER ? email + chalk.magenta(" (Owner)") : email;
|
|
676
681
|
}
|
|
@@ -1570,6 +1575,7 @@ function throwForInvalidOutputFormat(format: string): void {
|
|
|
1570
1575
|
}
|
|
1571
1576
|
}
|
|
1572
1577
|
|
|
1578
|
+
// DEPRECATED
|
|
1573
1579
|
function whoami(command: cli.ICommand): Promise<void> {
|
|
1574
1580
|
return sdk.getAccountInfo().then((account): void => {
|
|
1575
1581
|
const accountInfo = `${account.email} (${account.linkedProviders.join(", ")})`;
|
package/script/command-parser.ts
CHANGED
|
@@ -146,6 +146,16 @@ function appRemove(commandName: string, yargs: yargs.Argv): void {
|
|
|
146
146
|
addCommonConfiguration(yargs);
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
function appDeploymentKeyList(commandName: string, yargs: yargs.Argv): void {
|
|
150
|
+
isValidCommand = true;
|
|
151
|
+
yargs
|
|
152
|
+
.usage(USAGE_PREFIX + " app " + commandName + " <appName>")
|
|
153
|
+
.demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
|
|
154
|
+
.example("app " + commandName + " MyApp", 'Lists the deployment keys for app "MyApp" in tabular format');
|
|
155
|
+
|
|
156
|
+
addCommonConfiguration(yargs);
|
|
157
|
+
}
|
|
158
|
+
|
|
149
159
|
function listCollaborators(commandName: string, yargs: yargs.Argv): void {
|
|
150
160
|
isValidCommand = true;
|
|
151
161
|
yargs
|
|
@@ -321,6 +331,7 @@ yargs
|
|
|
321
331
|
})
|
|
322
332
|
.command("list", "Lists the apps associated with your account", (yargs: yargs.Argv) => appList("list", yargs))
|
|
323
333
|
.command("ls", "Lists the apps associated with your account", (yargs: yargs.Argv) => appList("ls", yargs))
|
|
334
|
+
.command("deployment-keys","Lists the deployment keys for app", (yargs:yargs.Argv) => appDeploymentKeyList("deployment-keys", yargs))
|
|
324
335
|
.command("transfer", "Transfer the ownership of an app to another account", (yargs: yargs.Argv) => {
|
|
325
336
|
isValidCommand = true;
|
|
326
337
|
yargs
|
|
@@ -334,28 +345,6 @@ yargs
|
|
|
334
345
|
|
|
335
346
|
addCommonConfiguration(yargs);
|
|
336
347
|
})
|
|
337
|
-
.command("collaborator", "View and manage app collaborators", (yargs: yargs.Argv) => {
|
|
338
|
-
isValidCommandCategory = true;
|
|
339
|
-
yargs
|
|
340
|
-
.usage(USAGE_PREFIX + " collaborator <command>")
|
|
341
|
-
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments.
|
|
342
|
-
.command("add", "Add a new collaborator to an app", (yargs: yargs.Argv): void => {
|
|
343
|
-
isValidCommand = true;
|
|
344
|
-
yargs
|
|
345
|
-
.usage(USAGE_PREFIX + " collaborator add <appName> <email>")
|
|
346
|
-
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
|
|
347
|
-
.example("collaborator add MyApp foo@bar.com", 'Adds foo@bar.com as a collaborator to app "MyApp"');
|
|
348
|
-
|
|
349
|
-
addCommonConfiguration(yargs);
|
|
350
|
-
})
|
|
351
|
-
.command("remove", "Remove a collaborator from an app", (yargs: yargs.Argv) => removeCollaborator("remove", yargs))
|
|
352
|
-
.command("rm", "Remove a collaborator from an app", (yargs: yargs.Argv) => removeCollaborator("rm", yargs))
|
|
353
|
-
.command("list", "List the collaborators for an app", (yargs: yargs.Argv) => listCollaborators("list", yargs))
|
|
354
|
-
.command("ls", "List the collaborators for an app", (yargs: yargs.Argv) => listCollaborators("ls", yargs))
|
|
355
|
-
.check((argv: any, aliases: { [aliases: string]: string }): any => isValidCommand); // Report unrecognized, non-hyphenated command category.
|
|
356
|
-
|
|
357
|
-
addCommonConfiguration(yargs);
|
|
358
|
-
})
|
|
359
348
|
.command("debug", "View the CodePush debug logs for a running app", (yargs: yargs.Argv) => {
|
|
360
349
|
isValidCommandCategory = true;
|
|
361
350
|
isValidCommand = true;
|
|
@@ -890,15 +879,6 @@ yargs
|
|
|
890
879
|
|
|
891
880
|
addCommonConfiguration(yargs);
|
|
892
881
|
})
|
|
893
|
-
.command("whoami", "Display the account info for the current login session", (yargs: yargs.Argv) => {
|
|
894
|
-
isValidCommandCategory = true;
|
|
895
|
-
isValidCommand = true;
|
|
896
|
-
yargs
|
|
897
|
-
.usage(USAGE_PREFIX + " whoami")
|
|
898
|
-
.demand(/*count*/ 0, /*max*/ 0)
|
|
899
|
-
.example("whoami", "Display the account info for the current login session");
|
|
900
|
-
addCommonConfiguration(yargs);
|
|
901
|
-
})
|
|
902
882
|
.alias("v", "version")
|
|
903
883
|
.version(packageJson.version)
|
|
904
884
|
.wrap(/*columnLimit*/ null)
|
|
@@ -984,7 +964,10 @@ export function createCommand(): cli.ICommand {
|
|
|
984
964
|
|
|
985
965
|
(<cli.IAppListCommand>cmd).format = argv["format"] as any;
|
|
986
966
|
break;
|
|
987
|
-
|
|
967
|
+
case "deployment-keys":
|
|
968
|
+
cmd = {type : cli.CommandType.appDeploymentKeyList};
|
|
969
|
+
(<cli.IAppDeploymentKeysCommand>cmd).appName = arg2;
|
|
970
|
+
break;
|
|
988
971
|
case "remove":
|
|
989
972
|
case "rm":
|
|
990
973
|
if (arg2) {
|
|
@@ -1004,50 +987,6 @@ export function createCommand(): cli.ICommand {
|
|
|
1004
987
|
appRenameCommand.newAppName = arg3;
|
|
1005
988
|
}
|
|
1006
989
|
break;
|
|
1007
|
-
|
|
1008
|
-
case "transfer":
|
|
1009
|
-
if (arg2 && arg3) {
|
|
1010
|
-
cmd = { type: cli.CommandType.appTransfer };
|
|
1011
|
-
|
|
1012
|
-
const appTransferCommand = <cli.IAppTransferCommand>cmd;
|
|
1013
|
-
|
|
1014
|
-
appTransferCommand.appName = arg2;
|
|
1015
|
-
appTransferCommand.email = arg3;
|
|
1016
|
-
}
|
|
1017
|
-
break;
|
|
1018
|
-
}
|
|
1019
|
-
break;
|
|
1020
|
-
|
|
1021
|
-
case "collaborator":
|
|
1022
|
-
switch (arg1) {
|
|
1023
|
-
case "add":
|
|
1024
|
-
if (arg2 && arg3) {
|
|
1025
|
-
cmd = { type: cli.CommandType.collaboratorAdd };
|
|
1026
|
-
|
|
1027
|
-
(<cli.ICollaboratorAddCommand>cmd).appName = arg2;
|
|
1028
|
-
(<cli.ICollaboratorAddCommand>cmd).email = arg3;
|
|
1029
|
-
}
|
|
1030
|
-
break;
|
|
1031
|
-
|
|
1032
|
-
case "list":
|
|
1033
|
-
case "ls":
|
|
1034
|
-
if (arg2) {
|
|
1035
|
-
cmd = { type: cli.CommandType.collaboratorList };
|
|
1036
|
-
|
|
1037
|
-
(<cli.ICollaboratorListCommand>cmd).appName = arg2;
|
|
1038
|
-
(<cli.ICollaboratorListCommand>cmd).format = argv["format"] as any;
|
|
1039
|
-
}
|
|
1040
|
-
break;
|
|
1041
|
-
|
|
1042
|
-
case "remove":
|
|
1043
|
-
case "rm":
|
|
1044
|
-
if (arg2 && arg3) {
|
|
1045
|
-
cmd = { type: cli.CommandType.collaboratorRemove };
|
|
1046
|
-
|
|
1047
|
-
(<cli.ICollaboratorRemoveCommand>cmd).appName = arg2;
|
|
1048
|
-
(<cli.ICollaboratorAddCommand>cmd).email = arg3;
|
|
1049
|
-
}
|
|
1050
|
-
break;
|
|
1051
990
|
}
|
|
1052
991
|
break;
|
|
1053
992
|
|
|
@@ -1290,10 +1229,6 @@ export function createCommand(): cli.ICommand {
|
|
|
1290
1229
|
break;
|
|
1291
1230
|
}
|
|
1292
1231
|
break;
|
|
1293
|
-
|
|
1294
|
-
case "whoami":
|
|
1295
|
-
cmd = { type: cli.CommandType.whoami };
|
|
1296
|
-
break;
|
|
1297
1232
|
}
|
|
1298
1233
|
|
|
1299
1234
|
return cmd;
|
package/script/management-sdk.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
ServerAccessKey,
|
|
29
29
|
Session,
|
|
30
30
|
} from "./types";
|
|
31
|
+
import { DeploymentKey } from "./types/rest-definitions";
|
|
31
32
|
|
|
32
33
|
const packageJson = require("../../package.json");
|
|
33
34
|
|
|
@@ -268,6 +269,10 @@ class AccountManager {
|
|
|
268
269
|
return this.get(urlEncode([`/apps/${appName}`])).then((res: JsonResponse) => res.body.app);
|
|
269
270
|
}
|
|
270
271
|
|
|
272
|
+
public getDeploymentKeys(appName: string): Promise<DeploymentKey[]> {
|
|
273
|
+
return this.get(urlEncode([`/apps/${appName}/deployment-keys`])).then((res: JsonResponse) => res.body);
|
|
274
|
+
}
|
|
275
|
+
|
|
271
276
|
public addApp(appName: string): Promise<App> {
|
|
272
277
|
const app: App = { name: appName };
|
|
273
278
|
return this.post(urlEncode(["/apps"]), JSON.stringify(app), /*expectResponseBody=*/ false).then(() => app);
|
package/script/types/cli.ts
CHANGED
|
@@ -10,12 +10,9 @@ export enum CommandType {
|
|
|
10
10
|
accessKeyRemove,
|
|
11
11
|
appAdd,
|
|
12
12
|
appList,
|
|
13
|
+
appDeploymentKeyList,
|
|
13
14
|
appRemove,
|
|
14
15
|
appRename,
|
|
15
|
-
appTransfer,
|
|
16
|
-
collaboratorAdd,
|
|
17
|
-
collaboratorList,
|
|
18
|
-
collaboratorRemove,
|
|
19
16
|
debug,
|
|
20
17
|
deploymentAdd,
|
|
21
18
|
deploymentHistory,
|
|
@@ -34,8 +31,7 @@ export enum CommandType {
|
|
|
34
31
|
releaseReact,
|
|
35
32
|
rollback,
|
|
36
33
|
sessionList,
|
|
37
|
-
sessionRemove
|
|
38
|
-
whoami,
|
|
34
|
+
sessionRemove
|
|
39
35
|
}
|
|
40
36
|
|
|
41
37
|
export interface ICommand {
|
|
@@ -75,6 +71,10 @@ export interface IAppRemoveCommand extends ICommand {
|
|
|
75
71
|
appName: string;
|
|
76
72
|
}
|
|
77
73
|
|
|
74
|
+
export interface IAppDeploymentKeysCommand extends ICommand {
|
|
75
|
+
appName: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
78
|
export interface IAppRenameCommand extends ICommand {
|
|
79
79
|
currentAppName: string;
|
|
80
80
|
newAppName: string;
|
|
@@ -126,6 +126,12 @@ export interface Deployment {
|
|
|
126
126
|
/*generated*/ package?: Package;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
/*out*/
|
|
130
|
+
export interface DeploymentKey {
|
|
131
|
+
/*generated key*/ deploymentKey?: string;
|
|
132
|
+
/*key*/ name: string;
|
|
133
|
+
}
|
|
134
|
+
|
|
129
135
|
/*out*/
|
|
130
136
|
export interface BlobInfo {
|
|
131
137
|
size: number;
|
package/test/cli.ts
CHANGED
|
@@ -579,83 +579,6 @@ describe("CLI", () => {
|
|
|
579
579
|
});
|
|
580
580
|
});
|
|
581
581
|
|
|
582
|
-
it("appTransfer transfers app", (done: Mocha.Done): void => {
|
|
583
|
-
var command: cli.IAppTransferCommand = {
|
|
584
|
-
type: cli.CommandType.appTransfer,
|
|
585
|
-
appName: "a",
|
|
586
|
-
email: "b@b.com",
|
|
587
|
-
};
|
|
588
|
-
|
|
589
|
-
var transferApp: sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "transferApp");
|
|
590
|
-
|
|
591
|
-
cmdexec.execute(command).done((): void => {
|
|
592
|
-
sinon.assert.calledOnce(transferApp);
|
|
593
|
-
sinon.assert.calledOnce(log);
|
|
594
|
-
sinon.assert.calledWithExactly(log, 'Successfully transferred the ownership of app "a" to the account with email "b@b.com".');
|
|
595
|
-
|
|
596
|
-
done();
|
|
597
|
-
});
|
|
598
|
-
});
|
|
599
|
-
|
|
600
|
-
it("collaboratorAdd adds collaborator", (done: Mocha.Done): void => {
|
|
601
|
-
var command: cli.ICollaboratorAddCommand = {
|
|
602
|
-
type: cli.CommandType.collaboratorAdd,
|
|
603
|
-
appName: "a",
|
|
604
|
-
email: "b@b.com",
|
|
605
|
-
};
|
|
606
|
-
|
|
607
|
-
var addCollaborator: sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "addCollaborator");
|
|
608
|
-
|
|
609
|
-
cmdexec.execute(command).done((): void => {
|
|
610
|
-
sinon.assert.calledOnce(addCollaborator);
|
|
611
|
-
sinon.assert.calledOnce(log);
|
|
612
|
-
sinon.assert.calledWithExactly(log, 'Successfully added "b@b.com" as a collaborator to the app "a".');
|
|
613
|
-
|
|
614
|
-
done();
|
|
615
|
-
});
|
|
616
|
-
});
|
|
617
|
-
|
|
618
|
-
it("collaboratorList lists collaborators email and properties", (done: Mocha.Done): void => {
|
|
619
|
-
var command: cli.ICollaboratorListCommand = {
|
|
620
|
-
type: cli.CommandType.collaboratorList,
|
|
621
|
-
appName: "a",
|
|
622
|
-
format: "json",
|
|
623
|
-
};
|
|
624
|
-
|
|
625
|
-
cmdexec.execute(command).done((): void => {
|
|
626
|
-
sinon.assert.calledOnce(log);
|
|
627
|
-
assert.equal(log.args[0].length, 1);
|
|
628
|
-
|
|
629
|
-
var actual: string = log.args[0][0];
|
|
630
|
-
var expected = {
|
|
631
|
-
collaborators: {
|
|
632
|
-
"a@a.com": { permission: "Owner", isCurrentAccount: true },
|
|
633
|
-
"b@b.com": { permission: "Collaborator", isCurrentAccount: false },
|
|
634
|
-
},
|
|
635
|
-
};
|
|
636
|
-
|
|
637
|
-
assertJsonDescribesObject(actual, expected);
|
|
638
|
-
done();
|
|
639
|
-
});
|
|
640
|
-
});
|
|
641
|
-
|
|
642
|
-
it("collaboratorRemove removes collaborator", (done: Mocha.Done): void => {
|
|
643
|
-
var command: cli.ICollaboratorRemoveCommand = {
|
|
644
|
-
type: cli.CommandType.collaboratorRemove,
|
|
645
|
-
appName: "a",
|
|
646
|
-
email: "b@b.com",
|
|
647
|
-
};
|
|
648
|
-
|
|
649
|
-
var removeCollaborator: sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "removeCollaborator");
|
|
650
|
-
|
|
651
|
-
cmdexec.execute(command).done((): void => {
|
|
652
|
-
sinon.assert.calledOnce(removeCollaborator);
|
|
653
|
-
sinon.assert.calledOnce(log);
|
|
654
|
-
sinon.assert.calledWithExactly(log, 'Successfully removed "b@b.com" as a collaborator from the app "a".');
|
|
655
|
-
|
|
656
|
-
done();
|
|
657
|
-
});
|
|
658
|
-
});
|
|
659
582
|
|
|
660
583
|
it("deploymentAdd reports new app name and ID", (done: Mocha.Done): void => {
|
|
661
584
|
var command: cli.IDeploymentAddCommand = {
|