Skip to content

Commit 7b9e5ab

Browse files
authored
Merge pull request #870 from salesforcecli/t/packaging-distribution/W-17409066/pushUpgrade-abort
feat: adds pushupgrade abort command support
2 parents e150a14 + b6a1c5c commit 7b9e5ab

File tree

5 files changed

+211
-0
lines changed

5 files changed

+211
-0
lines changed

command-snapshot.json

+8
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,14 @@
210210
"target-dev-hub"
211211
],
212212
"plugin": "@salesforce/plugin-packaging"
213+
}
214+
{
215+
"alias": ["force:package:pushupgrade:abort"],
216+
"command": "package:pushupgrade:abort",
217+
"flagAliases": [],
218+
"flagChars": ["i", "v"],
219+
"flags": ["api-version", "flags-dir", "json", "push-request-id", "target-dev-hub"],
220+
"plugin": "@salesforce/plugin-packaging"
213221
},
214222
{
215223
"alias": ["force:package:uninstall"],

messages/package_pushupgrade_abort.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# summary
2+
3+
Aborts a package push upgrade that has been scheduled. Only push upgrade requests with a Status of Created or Pending can be aborted.
4+
5+
# description
6+
7+
Specify the request ID for which you want abort the request. If applicable, the command displays errors related to the request. Only package push requests in Created or Pending statuses can be aborted.
8+
9+
To show all requests in the org, run "<%= config.bin %> package pushupgrade list --package 033...".
10+
11+
# examples
12+
13+
- Cancel the specified package push upgrade request with the specified ID; uses your default Dev Hub org:
14+
15+
<%= config.bin %> <%= command.id %> --push-request-id 0DV...
16+
17+
- Cancel the specified package push upgrade request in the Dev Hub org with username devhub@example.com:
18+
19+
<%= config.bin %> <%= command.id %> --push-request-id 0DV... --target-dev-hub devhub@example.com
20+
21+
# flags.push-request-id.summary
22+
23+
The ID of the package push request (starts with 0DV). This ID is returned after the package pushupgrade schedule command is run.
24+
25+
# flags.target-dev-hub.summary
26+
27+
Username or alias of the Dev Hub org.
28+
29+
# flags.target-dev-hub.description
30+
31+
Overrides the value of the target-dev-hub configuration variable, if set.
32+
33+
# error.invalid-push-request-id-owner
34+
35+
--push-request-id 0DV... is not owned by the org from where the CLI command is run.
36+
37+
# error.invalid-push-request-id
38+
39+
Package push upgrade request id is invalid. Please use valid ID (starts with 0DV).
40+
41+
# error.invalid-push-request-status
42+
43+
The status of the push request is one of the following: In Progress, Succeeded, Failed, Canceled. Only push requests in Created or Pending statuses can be aborted.
44+
45+
# status
46+
47+
Status
48+
49+
# output
50+
51+
Scheduled push upgrade ID [%s] was cancelled.
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$ref": "#/definitions/PackagePushUpgradeAbortResult",
4+
"definitions": {
5+
"PackagePushUpgradeAbortResult": {
6+
"type": "object",
7+
"properties": {
8+
"PushRequestId": {
9+
"type": "string"
10+
},
11+
"Status": {
12+
"type": "string"
13+
}
14+
},
15+
"required": ["PushRequestId", "Status"],
16+
"additionalProperties": false
17+
}
18+
}
19+
}
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2024, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
8+
import { Messages } from '@salesforce/core';
9+
import { PackagePushUpgrade } from '@salesforce/packaging';
10+
11+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
12+
const messages = Messages.loadMessages('@salesforce/plugin-packaging', 'package_pushupgrade_abort');
13+
14+
export class PackagePushUpgradeAbortCommand extends SfCommand<boolean> {
15+
public static readonly summary = messages.getMessage('summary');
16+
public static readonly description = messages.getMessage('description');
17+
public static readonly examples = messages.getMessages('examples');
18+
public static readonly hidden = true;
19+
public static state = 'beta';
20+
public static readonly flags = {
21+
'target-dev-hub': Flags.requiredHub(),
22+
'api-version': Flags.orgApiVersion(),
23+
// eslint-disable-next-line sf-plugin/id-flag-suggestions
24+
'push-request-id': Flags.salesforceId({
25+
length: 'both',
26+
char: 'i',
27+
summary: messages.getMessage('flags.push-request-id.summary'),
28+
required: true,
29+
startsWith: '0DV',
30+
}),
31+
};
32+
33+
public async run(): Promise<boolean> {
34+
const { flags } = await this.parse(PackagePushUpgradeAbortCommand);
35+
const connection = flags['target-dev-hub'].getConnection(flags['api-version']);
36+
37+
const packagePushRequestOptions = { packagePushRequestId: flags['push-request-id'] };
38+
39+
// Schedule the push upgrade
40+
const result = await PackagePushUpgrade.abort(connection, packagePushRequestOptions);
41+
42+
if (result) {
43+
this.log(messages.getMessage('output', [flags['push-request-id']]));
44+
}
45+
46+
return result;
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2024, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
8+
import { MockTestOrgData, TestContext } from '@salesforce/core/testSetup';
9+
import { SfCommand } from '@salesforce/sf-plugins-core';
10+
import { Config } from '@oclif/core';
11+
import { expect } from 'chai';
12+
import sinon from 'sinon';
13+
import { PackagePushUpgrade } from '@salesforce/packaging';
14+
import { PackagePushUpgradeAbortCommand } from '../../../src/commands/package/pushupgrade/abort.js';
15+
16+
describe('PackagePushUpgradeAbortCommand', () => {
17+
const $$ = new TestContext();
18+
const testOrg = new MockTestOrgData();
19+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
20+
const abortStub = $$.SANDBOX.stub(PackagePushUpgrade, 'abort');
21+
const config = new Config({ root: import.meta.url });
22+
23+
// stubs
24+
let logStub: sinon.SinonStub;
25+
26+
const stubSpinner = (cmd: PackagePushUpgradeAbortCommand) => {
27+
$$.SANDBOX.stub(cmd.spinner, 'start');
28+
$$.SANDBOX.stub(cmd.spinner, 'stop');
29+
};
30+
31+
before(async () => {
32+
await $$.stubAuths(testOrg);
33+
await config.load();
34+
});
35+
36+
beforeEach(async () => {
37+
logStub = $$.SANDBOX.stub(SfCommand.prototype, 'log');
38+
});
39+
40+
afterEach(() => {
41+
$$.restore();
42+
});
43+
44+
it('should successfully abort a push request', async () => {
45+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
46+
const cmd = new PackagePushUpgradeAbortCommand(['-i', '0DVxx0000004CCG', '-v', 'test@hub.org'], config);
47+
stubSpinner(cmd);
48+
const res = await cmd.run();
49+
50+
expect(res).to.be.true;
51+
expect(abortStub.calledOnce).to.be.true;
52+
expect(logStub.callCount).to.equal(1);
53+
expect(logStub.args[0]).to.deep.equal(['Scheduled push upgrade ID 0DVxx0000004CCG was canceled.']);
54+
});
55+
56+
it('should throw an error if push-request-id is missing', async () => {
57+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
58+
const cmd = new PackagePushUpgradeAbortCommand(['-v', 'test@hub.org'], config);
59+
stubSpinner(cmd);
60+
61+
try {
62+
await cmd.run();
63+
} catch (err) {
64+
const error = err as Error;
65+
expect(error.name).to.equal('Error');
66+
expect(error.message).to.include('Missing required flag push-request-id');
67+
}
68+
});
69+
70+
it('should throw an error if push-request status is not "Created" or "Pending" or is missing', async () => {
71+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
72+
abortStub.rejects(new Error('Abortion is only allowed for "Created" or "Pending" statuses.'));
73+
const cmd = new PackagePushUpgradeAbortCommand(['-i', '0DVxx0000004CCG', '-v', 'test@hub.org'], config);
74+
stubSpinner(cmd);
75+
76+
try {
77+
await cmd.run();
78+
} catch (err) {
79+
const error = err as Error;
80+
const msg = 'Abortion is only allowed for "Created" or "Pending" statuses.';
81+
expect(error.name).to.equal('Error');
82+
expect(error.message).to.include(msg);
83+
}
84+
});
85+
});

0 commit comments

Comments
 (0)