UNPKG

@flxbl-io/sfp

Version:

sfp is a CLI tool to help you manage your Salesforce projects in an artifact centric model

364 lines 39.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.InstallPackage = exports.SfpPackageInstallationOptions = void 0; const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger")); const PackageInstallationResult_1 = require("./PackageInstallationResult"); const ProjectConfig_1 = __importDefault(require("../../project/ProjectConfig")); const SFPStatsSender_1 = __importDefault(require("../../stats/SFPStatsSender")); const AssignPermissionSets_1 = __importDefault(require("../../permsets/AssignPermissionSets")); const ScriptExecutorHelpers_1 = __importDefault(require("../../scriptExecutor/ScriptExecutorHelpers")); const fs = __importStar(require("fs-extra")); const FileSystem_1 = __importDefault(require("../../utils/FileSystem")); const OrgDetailsFetcher_1 = __importDefault(require("../../org/OrgDetailsFetcher")); const path = require("path"); const PermissionSetGroupUpdateAwaiter_1 = __importDefault(require("../../permsets/PermissionSetGroupUpdateAwaiter")); const SfpPackage_1 = require("../SfpPackage"); const DeploymentExecutor_1 = require("../../deployers/DeploymentExecutor"); const GetFormattedTime_1 = __importDefault(require("../../utils/GetFormattedTime")); const TestOptions_1 = require("../../apextest/TestOptions"); const PostDeployersRegistry_1 = require("../deploymentCustomizers/PostDeployersRegistry"); const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve"); const PreDeployersRegistry_1 = require("../deploymentCustomizers/PreDeployersRegistry"); const AnalyzerRegistry_1 = require("../analyser/AnalyzerRegistry"); class SfpPackageInstallationOptions { constructor() { this.apexcompile = 'package'; this.securitytype = 'none'; this.upgradetype = 'mixed-mode'; this.publishWaitTime = 60; this.disableArtifactCommit = false; this.isDryRun = false; } } exports.SfpPackageInstallationOptions = SfpPackageInstallationOptions; class InstallPackage { constructor(sfpPackage, sfpOrg, logger, options) { this.sfpPackage = sfpPackage; this.sfpOrg = sfpOrg; this.logger = logger; this.options = options; this._isArtifactToBeCommittedInOrg = true; } async exec() { let startTime = Date.now(); let elapsedTime; try { this.packageDescriptor = ProjectConfig_1.default.getSFDXPackageDescriptor(this.sfpPackage.sourceDir, this.sfpPackage.packageName); this.connection = this.sfpOrg.getConnection(); if (await this.isPackageToBeInstalled(this.options.skipIfPackageInstalled)) { if (!this.options.isDryRun) { await this.waitTillAllPermissionSetGroupIsUpdated(); await this.assignPermsetsPreDeployment(); await this.executePreDeploymentScripts(); await this.setPackageDirectoryForPackage(); await this.executePreDeployers(); await this.checkPackageDirectoryExists(); await this.install(); await this.assignPermsetsPostDeployment(); await this.executePostDeployers(); await this.executePostDeploymentScript(); await this.commitPackageInstallationStatus(); elapsedTime = Date.now() - startTime; this.sendMetricsWhenSuccessfullyInstalled(elapsedTime); } return { result: PackageInstallationResult_1.PackageInstallationStatus.Succeeded, elapsedTime: elapsedTime }; } else { sfp_logger_1.default.log('Skipping Package Installation', sfp_logger_1.LoggerLevel.INFO, this.logger); return { result: PackageInstallationResult_1.PackageInstallationStatus.Skipped }; } } catch (error) { elapsedTime = Date.now() - startTime; this.sendMetricsWhenFailed(elapsedTime); return { result: PackageInstallationResult_1.PackageInstallationStatus.Failed, message: error.message, elapsedTime: elapsedTime, }; } } checkPackageDirectoryExists() { let absPackageDirectory = path.join(this.sfpPackage.sourceDir, this.packageDirectory); if (!fs.existsSync(absPackageDirectory)) { throw new Error(`Package directory ${absPackageDirectory} does not exist`); } } async waitTillAllPermissionSetGroupIsUpdated() { try { //Package Has Permission Set Group let permissionSetGroupUpdateAwaiter = new PermissionSetGroupUpdateAwaiter_1.default(this.connection, this.logger); await permissionSetGroupUpdateAwaiter.waitTillAllPermissionSetGroupIsUpdated(); } catch (error) { //Ignore error // Lets try proceeding sfp_logger_1.default.log(`Unable to check the status of Permission Set Groups due to ${error}`, sfp_logger_1.LoggerLevel.WARN, this.logger); } } async setPackageDirectoryForPackage() { if (this.packageDescriptor.aliasfy) { const searchDirectory = path.join(this.sfpPackage.sourceDir, this.packageDescriptor.path); const files = FileSystem_1.default.readdirRecursive(searchDirectory, true); let aliasDir; let alias = await this.sfpOrg.getAlias(); aliasDir = files.find((file) => path.basename(file) === alias && fs.lstatSync(path.join(searchDirectory, file)).isDirectory()); sfp_logger_1.default.log(`Using alias directory ${aliasDir ? aliasDir : 'default'}`, sfp_logger_1.LoggerLevel.INFO, this.logger); if (!aliasDir) { const orgDetails = await new OrgDetailsFetcher_1.default(this.sfpOrg.getUsername()).getOrgDetails(); if (orgDetails.isSandbox) { // If the target org is a sandbox, find a 'default' directory to use as package directory aliasDir = files.find((file) => path.basename(file) === 'default' && fs.lstatSync(path.join(searchDirectory, file)).isDirectory()); } } if (!aliasDir) { throw new Error(`Aliasfied package '${this.sfpPackage.packageName}' does not have an alias with '${alias}' or 'default' directory`); } this.packageDirectory = path.join(this.packageDescriptor.path, aliasDir); } else { this.packageDirectory = path.join(this.packageDescriptor['path']); } } sendMetricsWhenFailed(elapsedTime) { sfp_logger_1.default.log(`Package ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(this.sfpPackage.package_name)} installation attempt failed,it took ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)((0, GetFormattedTime_1.default)(elapsedTime))}`); SFPStatsSender_1.default.logCount('package.installation.failure', { package: this.sfpPackage.package_name, type: this.sfpPackage.package_type, target_org: this.sfpOrg.getUsername(), }); } sendMetricsWhenSuccessfullyInstalled(elapsedTime) { sfp_logger_1.default.log(`Package ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(this.sfpPackage.package_name)} installation took ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)((0, GetFormattedTime_1.default)(elapsedTime))}`, sfp_logger_1.LoggerLevel.INFO, this.logger); SFPStatsSender_1.default.logElapsedTime('package.installation.elapsed_time', elapsedTime, { package: this.sfpPackage.package_name, type: this.sfpPackage.package_type, target_org: this.sfpOrg.getUsername(), }); SFPStatsSender_1.default.logCount('package.installation', { package: this.sfpPackage.package_name, type: this.sfpPackage.package_type, target_org: this.sfpOrg.getUsername(), }); } //Set this to disable whethere info about the artifact has to be recorded in the org set isArtifactToBeCommittedInOrg(toCommit) { this._isArtifactToBeCommittedInOrg = toCommit; } async commitPackageInstallationStatus() { if (this._isArtifactToBeCommittedInOrg) { try { await this.sfpOrg.updateArtifactInOrg(this.logger, this.sfpPackage); } catch (error) { sfp_logger_1.default.log('Unable to commit information about the package into org..Check whether prerequisities are installed', sfp_logger_1.LoggerLevel.WARN, this.logger); } } } async isPackageToBeInstalled(skipIfPackageInstalled) { if (skipIfPackageInstalled) { let installationStatus = await this.sfpOrg.isArtifactInstalledInOrg(this.logger, this.sfpPackage); return !installationStatus.isInstalled; } else if (this.sfpPackage.packageType == SfpPackage_1.PackageType.Diff) { // If diff package, check if there are any changes to be deployed, else skip if (!this.sfpPackage.destructiveChanges && this.sfpPackage.metadataCount == 0) { return false; } } return true; // Always install packages if skipIfPackageInstalled is false } async assignPermsetsPreDeployment() { try { if (this.sfpPackage.assignPermSetsPreDeployment) { sfp_logger_1.default.log('Assigning permission sets before deployment:', sfp_logger_1.LoggerLevel.INFO, this.logger); await AssignPermissionSets_1.default.applyPermsets(this.sfpPackage.assignPermSetsPreDeployment, this.connection, this.sfpPackage.sourceDir, this.logger); } } catch (error) { //Proceed ahead not a critical error to break installation sfp_logger_1.default.log(`Unable to assign permsets (Pre Deployment) due to ${error}`, sfp_logger_1.LoggerLevel.WARN, this.logger); } } async executePreDeploymentScripts() { let preDeploymentScript = path.join(this.sfpPackage.sourceDir, `scripts`, `preDeployment`); if (fs.existsSync(preDeploymentScript)) { let alias = await this.sfpOrg.getAlias(); sfp_logger_1.default.log('Executing preDeployment script', sfp_logger_1.LoggerLevel.INFO, this.logger); await ScriptExecutorHelpers_1.default.executeScript(this.logger, preDeploymentScript, this.sfpPackage.packageName, this.sfpOrg.getUsername(), alias ? alias : this.sfpOrg.getUsername(), this.sfpPackage.sourceDir, this.sfpPackage.packageDirectory); } } async assignPermsetsPostDeployment() { try { if (this.sfpPackage.assignPermSetsPostDeployment) { sfp_logger_1.default.log('Assigning permission sets after deployment:', sfp_logger_1.LoggerLevel.INFO, this.logger); await AssignPermissionSets_1.default.applyPermsets(this.sfpPackage.assignPermSetsPostDeployment, this.connection, this.sfpPackage.sourceDir, this.logger); } } catch (error) { //Proceed ahead not a critical error to break installation sfp_logger_1.default.log(`Unable to assign permsets (Post Deployment) due to ${error}`, sfp_logger_1.LoggerLevel.WARN, this.logger); } } async executePostDeploymentScript() { let postDeploymentScript = path.join(this.sfpPackage.sourceDir, `scripts`, `postDeployment`); if (fs.existsSync(postDeploymentScript)) { sfp_logger_1.default.log('Executing postDeployment script', sfp_logger_1.LoggerLevel.INFO, this.logger); let alias = await this.sfpOrg.getAlias(); await ScriptExecutorHelpers_1.default.executeScript(this.logger, postDeploymentScript, this.sfpPackage.packageName, this.sfpOrg.getUsername(), alias ? alias : this.sfpOrg.getUsername(), this.sfpPackage.sourceDir, this.sfpPackage.packageDirectory); } } async executePostDeployers() { sfp_logger_1.default.log(`Executing Post Deployers`, sfp_logger_1.LoggerLevel.INFO, this.logger); //Gather componentSet let componentSet = source_deploy_retrieve_1.ComponentSet.fromSource(path.join(this.sfpPackage.projectDirectory, this.sfpPackage.packageDirectory)); for (const postDeployer of PostDeployersRegistry_1.PostDeployersRegistry.getPostDeployers()) { try { if (await postDeployer.isEnabled(this.sfpPackage, this.connection, this.logger)) { sfp_logger_1.default.log(`Executing Post Deployer ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(postDeployer.getName())}`, sfp_logger_1.LoggerLevel.INFO, this.logger); await postDeployer.execute(this.sfpPackage, componentSet, this.sfpOrg, this.logger, { apiVersion: this.options.apiVersion, waitTime: this.options.waitTime }); } else { sfp_logger_1.default.log(`Post Deployer ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(postDeployer.getName())} skipped or not enabled`, sfp_logger_1.LoggerLevel.INFO, this.logger); } } catch (error) { sfp_logger_1.default.log(`Unable to process post deploy for ${postDeployer.getName()} due to ${error.message}`, sfp_logger_1.LoggerLevel.WARN, this.logger); sfp_logger_1.default.log(`Pre Deployer ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(postDeployer.getName())} skipped due to error`, sfp_logger_1.LoggerLevel.INFO, this.logger); } } } async executePreDeployers() { sfp_logger_1.default.log(`Executing Pre Deployers`, sfp_logger_1.LoggerLevel.INFO, this.logger); //Gather componentSet let componentSet = source_deploy_retrieve_1.ComponentSet.fromSource(path.join(this.sfpPackage.projectDirectory, this.sfpPackage.packageDirectory)); let analyzers = AnalyzerRegistry_1.AnalyzerRegistry.getAnalyzers(); for (const analyzer of analyzers) { if (await analyzer.isEnabled(this.sfpPackage, this.logger)) { sfp_logger_1.default.log(`Executing ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(analyzer.getName())}`, sfp_logger_1.LoggerLevel.INFO, this.logger); this.sfpPackage = await analyzer.analyze(this.sfpPackage, componentSet, this.logger); } else { sfp_logger_1.default.log(`Skipped ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(analyzer.getName())}`, sfp_logger_1.LoggerLevel.INFO, this.logger); } } for (const preDeployer of PreDeployersRegistry_1.PreDeployersRegistry.getPreDeployers()) { try { if (await preDeployer.isEnabled(this.sfpPackage, this.connection, this.logger)) { sfp_logger_1.default.log(`Executing Pre Deployer ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(preDeployer.getName())}`, sfp_logger_1.LoggerLevel.INFO, this.logger); await preDeployer.execute(this.sfpPackage, componentSet, this.sfpOrg, this.logger, { apiVersion: this.options.apiVersion, waitTime: this.options.waitTime }); } else { sfp_logger_1.default.log(`Pre Deployer ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(preDeployer.getName())} skipped or not enabled`, sfp_logger_1.LoggerLevel.INFO, this.logger); } } catch (error) { sfp_logger_1.default.log(`Unable to process pre deploy for ${preDeployer.getName()} due to ${error.message}`, sfp_logger_1.LoggerLevel.WARN, this.logger); sfp_logger_1.default.log(`Pre Deployer ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(preDeployer.getName())} skipped due to error`, sfp_logger_1.LoggerLevel.INFO, this.logger); } } } async generateDeploymentOptions(waitTime, optimizeDeployment, skipTest, target_org, apiVersion) { let deploymentOptions = { ignoreWarnings: true, waitTime: waitTime, }; deploymentOptions.ignoreWarnings = true; deploymentOptions.waitTime = waitTime; deploymentOptions.apiVersion = apiVersion; //Find Org Type let orgDetails; try { orgDetails = await new OrgDetailsFetcher_1.default(target_org).getOrgDetails(); } catch (err) { sfp_logger_1.default.log(`Unable to fetch org details,assuming it is production`, sfp_logger_1.LoggerLevel.WARN, this.logger); orgDetails = { instanceUrl: undefined, isScratchOrg: false, isSandbox: false, organizationType: undefined, sfdxAuthUrl: undefined, status: undefined, }; } if (this.options.deploymentType == DeploymentExecutor_1.DeploymentType.MDAPI_DEPLOY && this.sfpPackage.isApexFound && this.options.isInstallingForValidation == false) { if (orgDetails.isSandbox) { //enforce during selective deployment if (skipTest) { deploymentOptions.testLevel = TestOptions_1.TestLevel.RunNoTests; } else if (this.sfpPackage.apexTestClassses.length > 0 && optimizeDeployment) { deploymentOptions.testLevel = TestOptions_1.TestLevel.RunSpecifiedTests; deploymentOptions.specifiedTests = this.getAStringOfSpecificTestClasses(this.sfpPackage.apexTestClassses); } else { deploymentOptions.testLevel = TestOptions_1.TestLevel.RunLocalTests; } } else { if (this.sfpPackage.apexTestClassses.length > 0 && optimizeDeployment) { deploymentOptions.testLevel = TestOptions_1.TestLevel.RunSpecifiedTests; deploymentOptions.specifiedTests = this.getAStringOfSpecificTestClasses(this.sfpPackage.apexTestClassses); } else { deploymentOptions.testLevel = TestOptions_1.TestLevel.RunLocalTests; } } } // #Issue 1417 // Handle the use-cases of a not optimized source package validating else if (this.sfpPackage.packageType == SfpPackage_1.PackageType.Source && this.sfpPackage.isApexFound && this.options.isInstallingForValidation && !optimizeDeployment) { if (skipTest) { deploymentOptions.testLevel = TestOptions_1.TestLevel.RunNoTests; } else { deploymentOptions.testLevel = TestOptions_1.TestLevel.RunLocalTests; } } else { if (orgDetails.isSandbox) { deploymentOptions.testLevel = TestOptions_1.TestLevel.RunNoTests; } else { deploymentOptions.testLevel = TestOptions_1.TestLevel.RunSpecifiedTests; deploymentOptions.specifiedTests = 'skip'; } } deploymentOptions.rollBackOnError = true; return deploymentOptions; } getAStringOfSpecificTestClasses(apexTestClassses) { let specifedTests = apexTestClassses.join(); return specifedTests; } } exports.InstallPackage = InstallPackage; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5zdGFsbFBhY2thZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29yZS9wYWNrYWdlL3BhY2thZ2VJbnN0YWxsZXJzL0luc3RhbGxQYWNrYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsbUVBQXlGO0FBQ3pGLDJFQUFtRztBQUNuRyxnRkFBd0Q7QUFDeEQsZ0ZBQXdEO0FBQ3hELCtGQUF1RTtBQUN2RSx1R0FBd0U7QUFFeEUsNkNBQStCO0FBQy9CLHdFQUFnRDtBQUNoRCxvRkFBNEU7QUFDNUUsNkJBQThCO0FBQzlCLHFIQUE2RjtBQUU3Riw4Q0FBd0Q7QUFDeEQsMkVBQTRHO0FBRTVHLG9GQUE0RDtBQUM1RCw0REFBdUQ7QUFDdkQsMEZBQXVGO0FBQ3ZGLCtFQUFrRTtBQUdsRSx3RkFBcUY7QUFDckYsbUVBQWdFO0FBRWhFLE1BQWEsNkJBQTZCO0lBQTFDO1FBRUksZ0JBQVcsR0FBWSxTQUFTLENBQUM7UUFDakMsaUJBQVksR0FBWSxNQUFNLENBQUM7UUFDL0IsZ0JBQVcsR0FBWSxZQUFZLENBQUM7UUFHcEMsb0JBQWUsR0FBWSxFQUFFLENBQUM7UUFJOUIsMEJBQXFCLEdBQWEsS0FBSyxDQUFDO1FBR3hDLGFBQVEsR0FBYSxLQUFLLENBQUM7SUFFL0IsQ0FBQztDQUFBO0FBaEJELHNFQWdCQztBQUVELE1BQXNCLGNBQWM7SUFPaEMsWUFDYyxVQUFzQixFQUN0QixNQUFjLEVBQ2QsTUFBYyxFQUNkLE9BQXNDO1FBSHRDLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxZQUFPLEdBQVAsT0FBTyxDQUErQjtRQU41QyxrQ0FBNkIsR0FBWSxJQUFJLENBQUM7SUFPbEQsQ0FBQztJQUVFLEtBQUssQ0FBQyxJQUFJO1FBQ2IsSUFBSSxTQUFTLEdBQUcsSUFBSSxD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