From 46a592a11011b7ec5c98cf3ff5682724a798abb5 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Mon, 7 Mar 2016 23:11:08 -0800 Subject: [PATCH 1/4] clear deployment --- cli/definitions/cli.ts | 6 +++++ cli/script/command-executor.ts | 17 +++++++++++++ cli/script/command-parser.ts | 21 ++++++++++++++++ cli/test/cli.ts | 45 ++++++++++++++++++++++++++++++++++ sdk/script/management-sdk.ts | 5 ++++ 5 files changed, 94 insertions(+) diff --git a/cli/definitions/cli.ts b/cli/definitions/cli.ts index 9636a1a9..ad1577c0 100644 --- a/cli/definitions/cli.ts +++ b/cli/definitions/cli.ts @@ -11,6 +11,7 @@ collaboratorList, collaboratorRemove, deploymentAdd, + deploymentClear, deploymentHistory, deploymentList, deploymentMetrics, @@ -83,6 +84,11 @@ export interface IDeploymentAddCommand extends ICommand { deploymentName: string; } +export interface IDeploymentClearCommand extends ICommand { + appName: string; + deploymentName: string; +} + export interface IDeploymentHistoryCommand extends ICommand { appName: string; deploymentName: string; diff --git a/cli/script/command-executor.ts b/cli/script/command-executor.ts index 13282b51..91c66c71 100644 --- a/cli/script/command-executor.ts +++ b/cli/script/command-executor.ts @@ -275,6 +275,20 @@ function deploymentAdd(command: cli.IDeploymentAddCommand): Promise { }); } +function deploymentClear(command: cli.IDeploymentAddCommand): Promise { + return confirm() + .then((wasConfirmed: boolean): Promise => { + if (wasConfirmed) { + return sdk.clearDeployment(command.appName, command.deploymentName) + .then((): void => { + log("Successfully cleared all the updates associated with the \"" + command.deploymentName + "\" deployment from the \"" + command.appName + "\" app."); + }) + } + + log("Clear deployment cancelled."); + }); +} + export var deploymentList = (command: cli.IDeploymentListCommand, showPackage: boolean = true): Promise => { throwForInvalidOutputFormat(command.format); var deployments: Deployment[]; @@ -436,6 +450,9 @@ export function execute(command: cli.ICommand): Promise { case cli.CommandType.deploymentAdd: return deploymentAdd(command); + case cli.CommandType.deploymentClear: + return deploymentClear(command); + case cli.CommandType.deploymentHistory: return deploymentHistory(command); diff --git a/cli/script/command-parser.ts b/cli/script/command-parser.ts index 9d8276de..db1a243a 100644 --- a/cli/script/command-parser.ts +++ b/cli/script/command-parser.ts @@ -113,6 +113,15 @@ function removeCollaborator(commandName: string, yargs: yargs.Argv): void { addCommonConfiguration(yargs); } +function deploymentClear(commandName: string, yargs: yargs.Argv): void { + isValidCommand = true; + yargs.usage(USAGE_PREFIX + " deployment " + commandName + " ") + .demand(/*count*/ 4, /*max*/ 4) // Require exactly four non-option arguments. + .example("deployment " + commandName + " MyApp MyDeployment", "Clears away all the updates associated with deployment \"MyDeployment\" from app \"MyApp\""); + + addCommonConfiguration(yargs); +} + function deploymentList(commandName: string, yargs: yargs.Argv): void { isValidCommand = true; yargs.usage(USAGE_PREFIX + " deployment " + commandName + " [--format ] [--displayKeys]") @@ -227,6 +236,7 @@ var argv = yargs.usage(USAGE_PREFIX + " ") addCommonConfiguration(yargs); }) + .command("clear", "Clears away all the updates associated with a deployment", (yargs: yargs.Argv) => deploymentClear("clear", yargs)) .command("remove", "Remove a deployment from an app", (yargs: yargs.Argv) => deploymentRemove("remove", yargs)) .command("rm", "Remove a deployment from an app", (yargs: yargs.Argv) => deploymentRemove("rm", yargs)) .command("rename", "Rename an existing deployment", (yargs: yargs.Argv) => { @@ -461,6 +471,17 @@ function createCommand(): cli.ICommand { } break; + case "clear": + if (arg2 && arg3) { + cmd = { type: cli.CommandType.deploymentClear }; + + var deploymentClearCommand = cmd; + + deploymentClearCommand.appName = arg2; + deploymentClearCommand.deploymentName = arg3; + } + break; + case "list": case "ls": if (arg2) { diff --git a/cli/test/cli.ts b/cli/test/cli.ts index b44b1a96..7c0d4d34 100644 --- a/cli/test/cli.ts +++ b/cli/test/cli.ts @@ -52,6 +52,10 @@ export class SdkStub { }); } + public clearDeployment(appId: string, deployment: string): Promise { + return Q(null); + } + public getAccessKeys(): Promise { return Q([{ name: "8", @@ -516,6 +520,47 @@ describe("CLI", () => { }); }); + it("deploymentClear clears deployment", (done: MochaDone): void => { + var command: cli.IDeploymentClearCommand = { + type: cli.CommandType.deploymentClear, + appName: "a", + deploymentName: "Staging" + }; + + var clearDeployment: Sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "clearDeployment"); + + cmdexec.execute(command) + .done((): void => { + sinon.assert.calledOnce(clearDeployment); + sinon.assert.calledWithExactly(clearDeployment, "a", "Staging"); + sinon.assert.calledOnce(log); + sinon.assert.calledWithExactly(log, "Successfully cleared all the updates associated with the \"Staging\" deployment from the \"a\" app."); + + done(); + }); + }); + + it("deploymentClear does not clear deployment if cancelled", (done: MochaDone): void => { + var command: cli.IDeploymentClearCommand = { + type: cli.CommandType.deploymentClear, + appName: "a", + deploymentName: "Staging" + }; + + var clearDeployment: Sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "clearDeployment"); + + wasConfirmed = false; + + cmdexec.execute(command) + .done((): void => { + sinon.assert.notCalled(clearDeployment); + sinon.assert.calledOnce(log); + sinon.assert.calledWithExactly(log, "Clear deployment cancelled."); + + done(); + }); + }); + it("deploymentList lists deployment names, deployment keys, and package information", (done: MochaDone): void => { var command: cli.IDeploymentListCommand = { type: cli.CommandType.deploymentList, diff --git a/sdk/script/management-sdk.ts b/sdk/script/management-sdk.ts index eef46748..d5e6d0db 100644 --- a/sdk/script/management-sdk.ts +++ b/sdk/script/management-sdk.ts @@ -169,6 +169,11 @@ class AccountManager { return this.post(urlEncode `/apps/${appName}/deployments/`, JSON.stringify(deployment), /*expectResponseBody=*/ true) .then((res: JsonResponse) => res.body.deployment); } + + public clearDeployment(appName: string, deploymentName: string): Promise { + return this.del(urlEncode `/apps/${appName}/deployments/${deploymentName}/history`) + .then(() => null); + } public getDeployments(appName: string): Promise { return this.get(urlEncode `/apps/${appName}/deployments/`) From 54d7ad803e052b229e657c3c169d9739fb943abe Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Tue, 8 Mar 2016 11:22:20 -0800 Subject: [PATCH 2/4] review feedback --- cli/README.md | 12 +++++++++++- cli/definitions/cli.ts | 4 ++-- cli/script/command-executor.ts | 10 +++++----- cli/script/command-parser.ts | 14 +++++++------- cli/test/cli.ts | 20 ++++++++++---------- sdk/script/management-sdk.ts | 2 +- 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/cli/README.md b/cli/README.md index b797c4d3..8c673899 100644 --- a/cli/README.md +++ b/cli/README.md @@ -172,8 +172,8 @@ code-push deployment add Just like with apps, you can remove and rename deployments as well, using the following commands respectively: ``` -code-push deployment rename code-push deployment rm +code-push deployment rename ``` If at any time you'd like to view the list of deployments that a specific app includes, you can simply run the following command: @@ -425,3 +425,13 @@ Additionally, the history displays the install metrics for each release. You can By default, the history doesn't display the author of each release, but if you are collaborating on an app with other developers, and want to view who released each update, you can pass the additional `--displayAuthor` (or `-a`) flag to the history command. *NOTE: The history command can also be run using the "h" alias* + +## Clearing release history + +You can clear the release history associated with a deployment using the following command: + +``` +code-push deployment history +``` + +After running this command, client devices configured to receive updates from this deployment using its associated deployment key will no longer be able to receive the updates that have been cleared. This command is irreversible, and therefore should not be used in a production deployment. diff --git a/cli/definitions/cli.ts b/cli/definitions/cli.ts index ad1577c0..ccaebd70 100644 --- a/cli/definitions/cli.ts +++ b/cli/definitions/cli.ts @@ -11,8 +11,8 @@ collaboratorList, collaboratorRemove, deploymentAdd, - deploymentClear, deploymentHistory, + deploymentHistoryClear, deploymentList, deploymentMetrics, deploymentRemove, @@ -84,7 +84,7 @@ export interface IDeploymentAddCommand extends ICommand { deploymentName: string; } -export interface IDeploymentClearCommand extends ICommand { +export interface IDeploymentHistoryClearCommand extends ICommand { appName: string; deploymentName: string; } diff --git a/cli/script/command-executor.ts b/cli/script/command-executor.ts index 91c66c71..752acdf6 100644 --- a/cli/script/command-executor.ts +++ b/cli/script/command-executor.ts @@ -275,13 +275,13 @@ function deploymentAdd(command: cli.IDeploymentAddCommand): Promise { }); } -function deploymentClear(command: cli.IDeploymentAddCommand): Promise { +function deploymentHistoryClear(command: cli.IDeploymentHistoryClearCommand): Promise { return confirm() .then((wasConfirmed: boolean): Promise => { if (wasConfirmed) { - return sdk.clearDeployment(command.appName, command.deploymentName) + return sdk.clearDeploymentHistory(command.appName, command.deploymentName) .then((): void => { - log("Successfully cleared all the updates associated with the \"" + command.deploymentName + "\" deployment from the \"" + command.appName + "\" app."); + log("Successfully cleared the release history associated with the \"" + command.deploymentName + "\" deployment from the \"" + command.appName + "\" app."); }) } @@ -450,8 +450,8 @@ export function execute(command: cli.ICommand): Promise { case cli.CommandType.deploymentAdd: return deploymentAdd(command); - case cli.CommandType.deploymentClear: - return deploymentClear(command); + case cli.CommandType.deploymentHistoryClear: + return deploymentHistoryClear(command); case cli.CommandType.deploymentHistory: return deploymentHistory(command); diff --git a/cli/script/command-parser.ts b/cli/script/command-parser.ts index db1a243a..c91c1ec9 100644 --- a/cli/script/command-parser.ts +++ b/cli/script/command-parser.ts @@ -113,11 +113,11 @@ function removeCollaborator(commandName: string, yargs: yargs.Argv): void { addCommonConfiguration(yargs); } -function deploymentClear(commandName: string, yargs: yargs.Argv): void { +function deploymentHistoryClear(commandName: string, yargs: yargs.Argv): void { isValidCommand = true; yargs.usage(USAGE_PREFIX + " deployment " + commandName + " ") .demand(/*count*/ 4, /*max*/ 4) // Require exactly four non-option arguments. - .example("deployment " + commandName + " MyApp MyDeployment", "Clears away all the updates associated with deployment \"MyDeployment\" from app \"MyApp\""); + .example("deployment " + commandName + " MyApp MyDeployment", "Clears the release history associated with deployment \"MyDeployment\" from app \"MyApp\""); addCommonConfiguration(yargs); } @@ -236,7 +236,7 @@ var argv = yargs.usage(USAGE_PREFIX + " ") addCommonConfiguration(yargs); }) - .command("clear", "Clears away all the updates associated with a deployment", (yargs: yargs.Argv) => deploymentClear("clear", yargs)) + .command("clear", "Clears the release history associated with a deployment", (yargs: yargs.Argv) => deploymentHistoryClear("clear", yargs)) .command("remove", "Remove a deployment from an app", (yargs: yargs.Argv) => deploymentRemove("remove", yargs)) .command("rm", "Remove a deployment from an app", (yargs: yargs.Argv) => deploymentRemove("rm", yargs)) .command("rename", "Rename an existing deployment", (yargs: yargs.Argv) => { @@ -473,12 +473,12 @@ function createCommand(): cli.ICommand { case "clear": if (arg2 && arg3) { - cmd = { type: cli.CommandType.deploymentClear }; + cmd = { type: cli.CommandType.deploymentHistoryClear }; - var deploymentClearCommand = cmd; + var deploymentHistoryClearCommand = cmd; - deploymentClearCommand.appName = arg2; - deploymentClearCommand.deploymentName = arg3; + deploymentHistoryClearCommand.appName = arg2; + deploymentHistoryClearCommand.deploymentName = arg3; } break; diff --git a/cli/test/cli.ts b/cli/test/cli.ts index 7c0d4d34..6b12712c 100644 --- a/cli/test/cli.ts +++ b/cli/test/cli.ts @@ -52,7 +52,7 @@ export class SdkStub { }); } - public clearDeployment(appId: string, deployment: string): Promise { + public clearDeploymentHistory(appId: string, deployment: string): Promise { return Q(null); } @@ -520,34 +520,34 @@ describe("CLI", () => { }); }); - it("deploymentClear clears deployment", (done: MochaDone): void => { - var command: cli.IDeploymentClearCommand = { - type: cli.CommandType.deploymentClear, + it("deploymentHistoryClear clears deployment", (done: MochaDone): void => { + var command: cli.IDeploymentHistoryClearCommand = { + type: cli.CommandType.deploymentHistoryClear, appName: "a", deploymentName: "Staging" }; - var clearDeployment: Sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "clearDeployment"); + var clearDeployment: Sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "clearDeploymentHistory"); cmdexec.execute(command) .done((): void => { sinon.assert.calledOnce(clearDeployment); sinon.assert.calledWithExactly(clearDeployment, "a", "Staging"); sinon.assert.calledOnce(log); - sinon.assert.calledWithExactly(log, "Successfully cleared all the updates associated with the \"Staging\" deployment from the \"a\" app."); + sinon.assert.calledWithExactly(log, "Successfully cleared the release history associated with the \"Staging\" deployment from the \"a\" app."); done(); }); }); - it("deploymentClear does not clear deployment if cancelled", (done: MochaDone): void => { - var command: cli.IDeploymentClearCommand = { - type: cli.CommandType.deploymentClear, + it("deploymentHistoryClear does not clear deployment if cancelled", (done: MochaDone): void => { + var command: cli.IDeploymentHistoryClearCommand = { + type: cli.CommandType.deploymentHistoryClear, appName: "a", deploymentName: "Staging" }; - var clearDeployment: Sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "clearDeployment"); + var clearDeployment: Sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "clearDeploymentHistory"); wasConfirmed = false; diff --git a/sdk/script/management-sdk.ts b/sdk/script/management-sdk.ts index d5e6d0db..39b28689 100644 --- a/sdk/script/management-sdk.ts +++ b/sdk/script/management-sdk.ts @@ -170,7 +170,7 @@ class AccountManager { .then((res: JsonResponse) => res.body.deployment); } - public clearDeployment(appName: string, deploymentName: string): Promise { + public clearDeploymentHistory(appName: string, deploymentName: string): Promise { return this.del(urlEncode `/apps/${appName}/deployments/${deploymentName}/history`) .then(() => null); } From 3506ac3f2047f33fdd104d82a54453db93443e26 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Tue, 8 Mar 2016 11:23:56 -0800 Subject: [PATCH 3/4] doc tweak --- cli/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/README.md b/cli/README.md index 8c673899..cb68566c 100644 --- a/cli/README.md +++ b/cli/README.md @@ -434,4 +434,4 @@ You can clear the release history associated with a deployment using the followi code-push deployment history ``` -After running this command, client devices configured to receive updates from this deployment using its associated deployment key will no longer be able to receive the updates that have been cleared. This command is irreversible, and therefore should not be used in a production deployment. +After running this command, client devices configured to receive updates from this deployment using its associated deployment key will no longer receive those updates that have been cleared. This command is irreversible, and therefore should not be used in a production deployment. From 5abc4b563d82394e33432363581c22ed70b14d80 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Tue, 8 Mar 2016 11:27:08 -0800 Subject: [PATCH 4/4] doc tweak --- cli/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/README.md b/cli/README.md index cb68566c..161490d9 100644 --- a/cli/README.md +++ b/cli/README.md @@ -431,7 +431,7 @@ By default, the history doesn't display the author of each release, but if you a You can clear the release history associated with a deployment using the following command: ``` -code-push deployment history +code-push deployment clear ``` After running this command, client devices configured to receive updates from this deployment using its associated deployment key will no longer receive those updates that have been cleared. This command is irreversible, and therefore should not be used in a production deployment.