Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Package Push Upgrade List command #853

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
c765915
feat: add package push list feature
btrn11 Dec 12, 2024
1175b46
fix: export required type
btrn11 Dec 12, 2024
137bfdd
feat: add pushupgrade list schema file
btrn11 Dec 12, 2024
38dcf0c
fix: edit pushupgrade list schema file
btrn11 Dec 12, 2024
3947f9a
fix: edit pushupgrade list md file
btrn11 Dec 12, 2024
2d89ac4
fix: change name
btrn11 Dec 12, 2024
5ee2cc3
fix: update push upgrade list md file
btrn11 Dec 13, 2024
1616eaf
feat: add beta state to pu list command
btrn11 Dec 13, 2024
f46cf25
feat: hide pu command
btrn11 Dec 13, 2024
76bcd4b
feat: add package as required flag
btrn11 Dec 13, 2024
cc5b530
fix: add missing type
btrn11 Dec 16, 2024
a90421a
feat: add test for pu request list command
btrn11 Dec 17, 2024
f6d7613
fix: add lint exceptions
btrn11 Dec 30, 2024
ba0ddf6
fix: add lint exceptions
btrn11 Dec 30, 2024
9eda6ab
fix: update list schema
btrn11 Dec 30, 2024
7b114c4
fix: add eslint exception
btrn11 Dec 30, 2024
8b85e14
feat: add num orgs scheduled, succedded and failed + add test for lis…
btrn11 Jan 2, 2025
8752847
feat: add request scheduled time
btrn11 Jan 2, 2025
f0098c2
feat: add schedule last days option
btrn11 Jan 2, 2025
fb6b050
feat: add schedule last days check
btrn11 Jan 2, 2025
3285377
fix: remove verbose flag for list
btrn11 Jan 6, 2025
d5024a5
fix: remove verbose flag for list (update test)
btrn11 Jan 6, 2025
a51573b
fix: update schema and snapshot
btrn11 Jan 6, 2025
0ae3183
feat: display list command correctly
btrn11 Jan 13, 2025
91d38fc
fix: update snapshot
btrn11 Jan 13, 2025
a0c2374
fix: update list schema
btrn11 Jan 13, 2025
e05b38d
fix: update list test
btrn11 Jan 13, 2025
e1315a2
fix: revert gitignore
btrn11 Jan 14, 2025
0fc713a
fix: change summary text
btrn11 Jan 14, 2025
e6ac978
fix: modify field names
btrn11 Jan 14, 2025
61a5a89
fix: change to schedule start time
btrn11 Jan 14, 2025
48d3a2d
fix: add package version number to display
btrn11 Jan 15, 2025
ff32db5
Merge branch 'packagingDistribution/pushUpgradeCLI' into t/packaging-…
btrn11 Jan 15, 2025
84f8954
fix: update push upgrade list md file
btrn11 Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@
"flags": ["api-version", "flags-dir", "json", "loglevel", "target-dev-hub", "verbose"],
"plugin": "@salesforce/plugin-packaging"
},
{
"alias": ["force:package:pushupgrade:list"],
"command": "package:pushupgrade:list",
"flagAliases": ["apiversion", "scheduledlastdays", "target-hub-org", "targetdevhubusername"],
"flagChars": ["l", "p", "s", "v"],
"flags": ["api-version", "flags-dir", "json", "packageid", "scheduled-last-days", "status", "target-dev-hub"],
},
{
"alias": ["force:package:pushupgrade:report"],
"command": "package:pushupgrade:report",
Expand Down
57 changes: 57 additions & 0 deletions messages/package_pushupgrade_list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# summary

Lists the status of push upgrade requests for a given package.

# description

Shows the details of each request to create a push upgrade in the Dev Hub org.

All filter parameters are applied using the AND logical operator (not OR).

To get information about a specific request, run "sf package pushupgrade report" and supply the request ID.

# flags.package-id.summary

Specify the package ID (starts with 033) of the package that you want push upgrade information for.

# flags.scheduled-last-days.summary

Filter the list output to only display push upgrades scheduled in the last few days. For example, if this flag is set to 30, only push upgrade requests scheduled for the last 30 days are listed in the output.

# flags.status.summary

Filter the list output by one of the following statuses: Created, Canceled, Pending, In Progress, Failed, or Succeeded

# flags.verbose.summary

Displays additional information such as number of orgs scheduled for push upgrade, orgs successfully upgraded, etc.

# examples

- List all package push upgrade requests in the specified Dev Hub org:

sf package pushupgrade list --package 033xyz --target-dev-hub myHub

- List all package push upgrade requests in the specified Dev Hub org scheduled in the last 30 days:

sf package pushupgrade list --package 033xyz --scheduled-last-days 30 --target-dev-hub myHub

- List all package push upgrade with a status Succeeded:

sf package pushupgrade list --package 033xyz –-Status=Succeeded

# id

ID

# status

Status

# package-id

Package Id

# packageVersionId

Package Version Id
73 changes: 73 additions & 0 deletions schemas/package-pushupgrade-list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/PackagePushRequestListResultArr",
"definitions": {
"PackagePushRequestListResultArr": {
"type": "array",
"items": {
"$ref": "#/definitions/PackagePushRequestListResult"
}
},
"PackagePushRequestListResult": {
"type": "object",
"properties": {
"Id": {
"type": "string"
},
"PackageVersionId": {
"type": "string"
},
"PackageVersion": {
"type": "object",
"properties": {
"Name": {
"type": "string"
},
"MajorVersion": {
"type": "string"
},
"MinorVersion": {
"type": "string"
}
},
"required": ["Name", "MajorVersion", "MinorVersion"],
"additionalProperties": false
},
"Status": {
"type": "string"
},
"ScheduledStartTime": {
"type": "string"
},
"StartTime": {
"type": "string"
},
"EndTime": {
"type": "string"
},
"OrgsScheduled": {
"type": "number"
},
"OrgsUpgradeSucceeded": {
"type": "number"
},
"OrgsUpgradeFailed": {
"type": "number"
}
},
"required": [
"Id",
"PackageVersionId",
"PackageVersion",
"Status",
"ScheduledStartTime",
"StartTime",
"EndTime",
"OrgsScheduled",
"OrgsUpgradeSucceeded",
"OrgsUpgradeFailed"
],
"additionalProperties": false
}
}
}
109 changes: 109 additions & 0 deletions src/commands/package/pushupgrade/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import { Flags, SfCommand, orgApiVersionFlagWithDeprecations } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
import { PackagePushRequestListResult, PackagePushUpgrade } from '@salesforce/packaging';
import chalk from 'chalk';
import { requiredHubFlag } from '../../../utils/hubFlag.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-packaging', 'package_pushupgrade_list');

type Status = 'Created' | 'Cancelled' | 'Pending' | 'In Progress' | 'Failed' | 'Succeeded';

export type PackagePushRequestListResultArr = PackagePushRequestListResult[];

export class PackagePushRequestListCommand extends SfCommand<PackagePushRequestListResultArr> {
public static readonly summary = messages.getMessage('summary');
public static readonly description = messages.getMessage('description');
public static readonly examples = messages.getMessages('examples');
public static readonly hidden = true;
public static state = 'beta';
public static readonly aliases = ['force:package:pushupgrade:list'];
public static readonly flags = {
'target-dev-hub': requiredHubFlag,
'api-version': orgApiVersionFlagWithDeprecations,
packageid: Flags.string({
char: 'p',
summary: messages.getMessage('flags.package-id.summary'),
required: true,
}),
'scheduled-last-days': Flags.integer({
char: 'l',
deprecateAliases: true,
aliases: ['scheduledlastdays'],
summary: messages.getMessage('flags.scheduled-last-days.summary'),
}),
status: Flags.custom<Status>({
options: ['Created', 'Cancelled', 'Pending', 'In Progress', 'Failed', 'Succeeded'],
})({
char: 's',
summary: messages.getMessage('flags.status.summary'),
}),
};

public async run(): Promise<PackagePushRequestListResultArr> {
const { flags } = await this.parse(PackagePushRequestListCommand);
const connection = flags['target-dev-hub'].getConnection(flags['api-version']);
const scheduledLastDays = flags['scheduled-last-days'];

// Check if scheduledLastDays is valid
if (flags['scheduled-last-days'] !== undefined) {
if (isNaN(scheduledLastDays!) || scheduledLastDays! <= 0) {
throw new Error('Invalid value for --scheduled-last-days. It must be a positive integer.');
}
}

// Get results of query here
// Use const since we will add verbose later
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
const results: PackagePushRequestListResult[] = await PackagePushUpgrade.list(connection, {
packageId: flags.packageid,
status: flags.status,
scheduledLastDays,
});

if (results.length === 0) {
this.warn('No results found');
} else {
const data = await Promise.all(
results.map(async (record: PackagePushRequestListResult) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const packagePushRequestOptions = { packagePushRequestId: record?.Id };
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const totalNumOrgs = await PackagePushUpgrade.getTotalJobs(connection, packagePushRequestOptions);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const numOrgsUpgradedFail = await PackagePushUpgrade.getFailedJobs(connection, packagePushRequestOptions);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const numOrgsUpgradedSuccess = await PackagePushUpgrade.getSucceededJobs(
connection,
packagePushRequestOptions
);

return {
Id: record?.Id,
PackageVersionId: record?.PackageVersionId,
PackageVersionName: record?.PackageVersion?.Name,
PackageVersionNumber: record?.PackageVersion?.MajorVersion + '.' + record?.PackageVersion?.MinorVersion,
Status: record?.Status,
ScheduledStartTime: record?.ScheduledStartTime,
StartTime: record?.StartTime,
EndTime: record?.EndTime,
NumOrgsScheduled: totalNumOrgs,
NumOrgsUpgradedFail: numOrgsUpgradedFail,
NumOrgsUpgradedSuccess: numOrgsUpgradedSuccess,
};
})
);

this.table({ data, overflow: 'wrap', title: chalk.blue(`Push Upgrade Request List: [${results.length}]`) });
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return results;
}
}
81 changes: 81 additions & 0 deletions test/commands/package/packagePushUpgradeList.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { MockTestOrgData, TestContext } from '@salesforce/core/testSetup';
import { Config } from '@oclif/core';
import { expect } from 'chai';
import { PackagePushRequestListResult, PackagePushUpgrade } from '@salesforce/packaging';
import { env } from '@salesforce/kit';
import { PackagePushRequestListCommand } from '../../../src/commands/package/pushupgrade/list.js';

const pushUpgradeListSuccess: PackagePushRequestListResult[] = [
{
Id: '0Af0M000000AxuqSAC',
PackageVersionId: '04t0M000000AxuqSAC',
PackageVersion: {
Name: 'VersionName',
MajorVersion: '1',
MinorVersion: '1',
},
Status: 'Success',
ScheduledStartTime: '2024-01-02T00:00:00.000Z',
StartTime: '2024-01-02T00:01:00.000Z',
EndTime: '2024-01-02T00:10:00.000Z',
OrgsScheduled: 2,
OrgsUpgradeFailed: 0,
OrgsUpgradeSucceeded: 2,
},
];

describe('package:pushupgrade:list - tests', () => {
const $$ = new TestContext();
const testOrg = new MockTestOrgData();
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const createStub = $$.SANDBOX.stub(PackagePushUpgrade, 'list');
const config = new Config({ root: import.meta.url });

const stubSpinner = (cmd: PackagePushRequestListCommand) => {
$$.SANDBOX.stub(cmd.spinner, 'start');
$$.SANDBOX.stub(cmd.spinner, 'stop');
};

before(async () => {
await $$.stubAuths(testOrg);
await config.load();
});

afterEach(() => {
$$.restore();
});

it('should list push upgrade requests', async () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
createStub.resolves(pushUpgradeListSuccess);
const envSpy = $$.SANDBOX.spy(env, 'setBoolean').withArgs('SF_APPLY_REPLACEMENTS_ON_CONVERT', true);

const cmd = new PackagePushRequestListCommand(['-p', '033xi000000Gmj6XXX', '-v', '[email protected]'], config);
stubSpinner(cmd);
const res = await cmd.run();
expect(envSpy.calledOnce).to.equal(false);
expect(res).to.eql(pushUpgradeListSuccess);
});

it('should fail to list push upgrade requests', async () => {
createStub.rejects(new Error('Failed to list push upgrade requests'));
const envSpy = $$.SANDBOX.spy(env, 'setBoolean').withArgs('SF_APPLY_REPLACEMENTS_ON_CONVERT', true);

const cmd = new PackagePushRequestListCommand(['-p', '033xi000000Gmj6XXX', '-v', '[email protected]'], config);
stubSpinner(cmd);

try {
await cmd.run();
throw new Error('Failed to list push upgrade requests');
} catch (error) {
expect((error as Error).message).to.equal('Failed to list push upgrade requests');
expect(envSpy.calledOnce).to.equal(false);
}
});
});
Loading