diff --git a/command-snapshot.json b/command-snapshot.json index b54a46dc..76ff621d 100644 --- a/command-snapshot.json +++ b/command-snapshot.json @@ -179,6 +179,14 @@ "flags": ["api-version", "flags-dir", "json", "loglevel", "target-dev-hub", "verbose"], "plugin": "@salesforce/plugin-packaging" }, + { + "alias": ["force:package:pushupgrade:report"], + "command": "package:pushupgrade:report", + "flagAliases": ["apiversion", "packagepushrequestid", "target-hub-org", "targetdevhubusername"], + "flagChars": ["i", "v"], + "flags": ["api-version", "flags-dir", "json", "loglevel", "package-push-request-id", "target-dev-hub"], + "plugin": "@salesforce/plugin-packaging" + }, { "alias": ["force:package:uninstall"], "command": "package:uninstall", @@ -229,7 +237,6 @@ "releasenotesurl", "skipancestorcheck", "skipvalidation", - "asyncvalidation", "target-hub-org", "targetdevhubusername", "uninstallscript", @@ -241,6 +248,7 @@ "flagChars": ["a", "b", "c", "d", "e", "f", "j", "k", "n", "p", "r", "s", "t", "v", "w", "x"], "flags": [ "api-version", + "async-validation", "branch", "build-instance", "code-coverage", @@ -259,7 +267,6 @@ "releasenotes-url", "skip-ancestor-check", "skip-validation", - "async-validation", "tag", "target-dev-hub", "uninstall-script", diff --git a/messages/package_pushupgrade_report.md b/messages/package_pushupgrade_report.md new file mode 100644 index 00000000..457381c9 --- /dev/null +++ b/messages/package_pushupgrade_report.md @@ -0,0 +1,27 @@ +# summary + +Retrieve details about a package push request. + +# description + +Specify the request ID for which you want to view details. If applicable, the command displays errors related to the request. + +To show all requests in the org, run "<%= config.bin %> package pushupgrade list". + +# examples + +- Retrieve details about the package push request with the specified ID; uses your default Dev Hub org: + + <%= config.bin %> <%= command.id %> --package-push-request-id 0DV... + +- Retrieve details about the specified package push request in the Dev Hub org with username devhub@example.com: + + <%= config.bin %> <%= command.id %> --package-push-request-id 0DV... --target-dev-hub devhub@example.com + +# flags.package-push-request-id.summary + +ID (starts with 0DV) of the package push request you want to display. + +# truncatedErrors + +To see all errors, run: %s data query -t -q "SELECT Message FROM Package2VersionCreateRequestError WHERE ParentRequest.Id='%s'" -o %s diff --git a/schemas/package-pushupgrade-report.json b/schemas/package-pushupgrade-report.json new file mode 100644 index 00000000..801d05b7 --- /dev/null +++ b/schemas/package-pushupgrade-report.json @@ -0,0 +1,82 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/ReportCommandResult", + "definitions": { + "ReportCommandResult": { + "anyOf": [ + { + "type": "null" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/PackagePushRequestReportResult" + } + } + ] + }, + "PackagePushRequestReportResult": { + "type": "object", + "properties": { + "PackageVersion": { + "type": "object", + "properties": { + "MetadataPackage": { + "type": "object", + "properties": { + "Name": { + "type": "string" + }, + "NamespacePrefix": { + "type": "string" + } + }, + "required": ["Name", "NamespacePrefix"], + "additionalProperties": false + }, + "MetadataPackageId": { + "type": "string" + }, + "Name": { + "type": "string" + } + }, + "required": ["MetadataPackage", "MetadataPackageId", "Name"], + "additionalProperties": false + }, + "Id": { + "type": "string" + }, + "PackageVersionId": { + "type": "string" + }, + "Status": { + "type": "string" + }, + "ScheduledStartTime": { + "type": ["string", "null"] + }, + "StartTime": { + "type": ["string", "null"] + }, + "EndTime": { + "type": ["string", "null"] + }, + "DurationSeconds": { + "type": ["number", "null"] + } + }, + "required": [ + "PackageVersion", + "Id", + "PackageVersionId", + "Status", + "ScheduledStartTime", + "StartTime", + "EndTime", + "DurationSeconds" + ], + "additionalProperties": false + } + } +} diff --git a/src/commands/package/pushupgrade/report.ts b/src/commands/package/pushupgrade/report.ts new file mode 100644 index 00000000..18d2e085 --- /dev/null +++ b/src/commands/package/pushupgrade/report.ts @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2025, 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, loglevel, orgApiVersionFlagWithDeprecations, SfCommand } from '@salesforce/sf-plugins-core'; +// import { Messages, Org } from '@salesforce/core'; +import { Messages } from '@salesforce/core'; + +// import pkgUtils, { PackagePushRequestResult } from '@salesforce/packaging'; +import { PackagePushUpgrade, PackagePushRequestReportResult } from '@salesforce/packaging'; +// import chalk from 'chalk'; +// import { camelCaseToTitleCase } from '@salesforce/kit'; +import chalk from 'chalk'; +import { requiredHubFlag } from '../../../utils/hubFlag.js'; + +Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); +const messages = Messages.loadMessages('@salesforce/plugin-packaging', 'package_pushupgrade_report'); +// const pvclMessages = Messages.loadMessages('@salesforce/plugin-packaging', 'package_version_create_list'); +// const pvlMessages = Messages.loadMessages('@salesforce/plugin-packaging', 'package_version_list'); +// const plMessages = Messages.loadMessages('@salesforce/plugin-packaging', 'package_list'); +// const ERROR_LIMIT = 12; + +export type PackagePushRequestReportDetails = { + PackageName: string; + NamespacePrefix: string; + PackageId: string; + PackageVersionId: string; + PackageVersionName: string; + PackagePushRequestId: string; + Status: string; + ScheduledStartTime: string; + InstallUrl: string; + AncestorVersion: string; + Alias: string; + IsOrgDependent: 'N/A' | 'Yes' | 'No'; + CreatedBy: string; + ValidatedAsync?: boolean; +}; + +export type ReportCommandResult = null | PackagePushRequestReportResult[]; + +export class PackagePushUpgradeReportCommand extends SfCommand { + public static readonly summary = messages.getMessage('summary'); + public static readonly description = messages.getMessage('description'); + public static readonly examples = messages.getMessages('examples'); + public static readonly deprecateAliases = true; + public static readonly aliases = ['force:package:pushupgrade:report']; + public static readonly flags = { + loglevel, + 'target-dev-hub': requiredHubFlag, + 'api-version': orgApiVersionFlagWithDeprecations, + // eslint-disable-next-line sf-plugin/id-flag-suggestions + 'package-push-request-id': Flags.salesforceId({ + length: 'both', + deprecateAliases: true, + aliases: ['packagepushrequestid'], + char: 'i', + summary: messages.getMessage('flags.package-push-request-id.summary'), + required: true, + }), + }; + + public async run(): Promise { + const { flags } = await this.parse(PackagePushUpgradeReportCommand); + const connection = flags['target-dev-hub'].getConnection(flags['api-version']); + + const packagePushRequestOptions = { packagePushRequestId: flags['package-push-request-id'] }; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + const records = await PackagePushUpgrade.report(connection, packagePushRequestOptions); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (records?.length === 1) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access + const record = records[0]; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + const totalJobs = await PackagePushUpgrade.getTotalJobs(connection, packagePushRequestOptions); + + let failedJobs; + let succeededJobs; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (record?.Status === 'Succeeded' || record?.Status === 'Failed') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + failedJobs = await PackagePushUpgrade.getFailedJobs(connection, packagePushRequestOptions); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + succeededJobs = await PackagePushUpgrade.getSucceededJobs(connection, packagePushRequestOptions); + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument + this.display(records[0], totalJobs, succeededJobs, failedJobs); + } + return null; + } + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + private display( + record: PackagePushRequestReportResult, + totalJobs: number, + succeededJobs?: number, + failedJobs?: number + ): void { + const data = [ + // { + // name: 'PackageName', + // // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + // value: record.PackageVersion.MetadataPackage.Name + // }, + // { + // name: 'Namespace', + // // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + // value: record.PackageVersion.MetadataPackage.NamespacePrefix, + // }, + // { + // name: 'PackageId', + // // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + // value: record.PackageVersion.MetadataPackageId, + // }, + // { + // name: 'PackageVersionId', + // // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + // value: record.PackageVersionId, + // }, + // { + // name: 'PackageVersionName', + // // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + // value: record.PackageVersion.Name, + // }, + { + name: 'PackagePushRequestId', + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + value: record.Id, + }, + { + name: 'Status', + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + value: record.Status, + }, + { + name: 'ScheduledStartTime', + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + value: record.ScheduledStartTime, + }, + { + name: 'StartTime', + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + value: record.StartTime, + }, + { + name: 'EndTime', + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + value: record.EndTime, + }, + { + name: 'TotalJobs', + value: totalJobs, + }, + { + name: 'SucceededJobs', + value: succeededJobs, + }, + { + name: 'FailedJobs', + value: failedJobs, + }, + // { + // name: 'DurationMinutes', + // // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + // value: record.DurationSeconds / 60, + // }, + ]; + + this.table({ data, title: chalk.blue('Package Push Request') }); + + // if (record.Error?.length > 0) { + // this.log(''); + // const errors: string[] = []; + // record.Error.slice(0, ERROR_LIMIT).forEach((error: string) => { + // errors.push(`(${errors.length + 1}) ${error}`); + // }); + // this.styledHeader(chalk.red('Errors')); + // this.warn(errors.join('\n')); + + // // Check if errors were truncated. If so, inform the user with + // // instructions on how to retrieve the remaining errors. + // if (record.Error.length > ERROR_LIMIT) { + // this.warn(messages.getMessage('truncatedErrors', [this.config.bin, requestId, devOrg.getUsername() as string])); + // } + // } + } +}