UNPKG

sfdx-hardis

Version:

Swiss-army-knife Toolbox for Salesforce. Allows you to define a complete CD/CD Pipeline. Orchestrate base commands and assist users with interactive wizards

136 lines (129 loc) 7.34 kB
/* jscpd:ignore-start */ import { SfCommand, Flags, requiredHubFlagWithDeprecations } from '@salesforce/sf-plugins-core'; import { Messages } from '@salesforce/core'; import c from 'chalk'; import { execSfdxJson, uxLog } from '../../../../common/utils/index.js'; import { prompts } from '../../../../common/utils/prompts.js'; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('sfdx-hardis', 'org'); export default class PackageVersionPromote extends SfCommand { static title = 'Promote new versions of package(s)'; static description = ` ## Command Behavior **Promotes a Salesforce package version from beta to released status in your Dev Hub.** This command is a critical step in the package development lifecycle, marking a package version as stable and ready for production use. Once promoted, a package version can be installed in production organizations. Key functionalities: - **Package Version Selection:** Allows you to select a specific package version to promote. If the \`--auto\` flag is used, it automatically identifies package versions that are not yet released and promotes them. - **Automated Promotion:** When \`--auto\` is enabled, it queries for all unreleased package versions and promotes them without further user interaction. - **Dev Hub Integration:** Interacts with your connected Dev Hub to change the status of the package version. <details markdown="1"> <summary>Technical explanations</summary> The command's technical implementation involves: - **Package Alias Retrieval:** It retrieves package aliases from your \`sfdx-project.json\` to identify available packages. - **Automated Promotion Logic:** If \`--auto\` is used, it executes \`sf package version list --released\` to get a list of already released packages and then filters the available package aliases to find those that are not yet released. - **Interactive Prompts:** If not in auto mode, it uses the \`prompts\` library to allow the user to select a package version to promote. - **Salesforce CLI Integration:** It constructs and executes the \`sf package version promote\` command, passing the package version ID. - **\`execSfdxJson\`:** This utility is used to execute the Salesforce CLI command and capture its JSON output. - **Error Handling:** It handles cases where a package version might already be promoted or if other errors occur during the promotion process. </details> `; static examples = ['$ sf hardis:package:version:promote', '$ sf hardis:package:version:promote --auto']; // public static args = [{name: 'file'}]; static flags = { auto: Flags.boolean({ char: 'f', default: false, description: 'Auto-detect which versions of which packages need to be promoted', }), debug: Flags.boolean({ char: 'd', default: false, description: messages.getMessage('debugMode'), }), websocket: Flags.string({ description: messages.getMessage('websocket'), }), skipauth: Flags.boolean({ description: 'Skip authentication check when a default username is required', }), 'target-dev-hub': requiredHubFlagWithDeprecations, }; // Set this to true if your command requires a project workspace; 'requiresProject' is false by default static requiresProject = true; /* jscpd:ignore-end */ async run() { const { flags } = await this.parse(PackageVersionPromote); const debugMode = flags.debug || false; const auto = flags.auto || false; // List project packages const sfdxProjectJson = this.project?.getSfProjectJson(false) || {}; const packageAliases = sfdxProjectJson.get('packageAliases') || []; const availablePackageAliases = {}; for (const packageAlias of Object.keys(packageAliases) .sort() .filter((pckgAlias) => pckgAlias.includes('@'))) { const packageName = packageAlias.split('@')[0]; availablePackageAliases[packageName] = packageAlias; } // Select packages to promote const packagesToPromote = []; if (auto) { // Promote only packages not promoted yet const packageListRes = await execSfdxJson('sf package version list --released', this, { output: true, fail: true, }); const filteredPackagesToPromote = Object.values(availablePackageAliases).filter((packageAlias) => { return (packageListRes.result.filter((releasedPackage) => { return releasedPackage.Alias === packageAlias && !(releasedPackage.IsReleased === true); }).length === 0); }); packagesToPromote.push(...filteredPackagesToPromote); } else { // Prompt user if not auto const packageResponse = await prompts([ { type: 'select', name: 'packageSelected', message: c.cyanBright(`Please select a package (this is not a drill, it will create an official new version !)`), description: 'Choose which package to promote - this will create a new official version that cannot be undone', placeholder: 'Select a package', choices: Object.values(availablePackageAliases).map((packageAlias) => { return { title: packageAlias, value: packageAlias }; }), }, ]); // Manage user response packagesToPromote.push(packageResponse.packageSelected); } const promotedPackageVersions = []; const errorPromotedVersions = []; // Promote packages for (const packageToPromote of packagesToPromote) { uxLog("action", this, c.cyan(`Promoting version of package ${c.green(packageToPromote)}`)); const promoteCommand = 'sf package version promote' + ` --package "${packageToPromote}"` + ' --no-prompt'; const promoteResult = await execSfdxJson(promoteCommand, this, { fail: false, output: false, debug: debugMode, }); if (promoteResult.status === 0) { uxLog("action", this, c.cyan(`Promoted package version ${c.green(packageToPromote)} with id ${c.green(promoteResult.result.id)}. It is now installable on production orgs`)); promotedPackageVersions.push({ package: packageToPromote, result: promoteResult }); } else { uxLog("warning", this, c.yellow(`Error promoting package version ${c.red(packageToPromote)} (probably already promoted so it can be ok)`)); errorPromotedVersions.push({ package: packageToPromote, result: promoteResult }); } } process.exitCode = errorPromotedVersions.length === 0 ? 0 : 1; // Return an object to be displayed with --json return { outputString: 'Promoted packages', promotedPackageVersions: promotedPackageVersions, errorPromotedVersions: errorPromotedVersions, }; } } //# sourceMappingURL=promote.js.map