UNPKG

@flxbl-io/sfp

Version:

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

217 lines 19.5 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.DeploymentOptions = void 0; const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger")); const kit_1 = require("@salesforce/kit"); const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve"); const fs = __importStar(require("fs-extra")); const path_1 = __importDefault(require("path")); const GetFormattedTime_1 = __importDefault(require("../utils/GetFormattedTime")); const TestOptions_1 = require("../apextest/TestOptions"); const core_1 = require("@salesforce/core"); const source_tracking_1 = require("@salesforce/source-tracking"); class DeploySourceToOrgImpl { constructor(org, projectDir, componentSet, deploymentOptions, logger) { this.org = org; this.projectDir = projectDir; this.componentSet = componentSet; this.deploymentOptions = deploymentOptions; this.logger = logger; } async exec() { let deploySourceResult = {}; if (this.deploymentOptions.apiVersion) this.componentSet.sourceApiVersion = this.deploymentOptions.apiVersion; //Get Deploy ID let result = await this.deploy(this.componentSet); this.writeResultToReport(result); if (this.deploymentOptions.sourceTracking) { await this.handleSourceTracking(this.org, this.logger, this.projectDir, result); } //Handle Responses if (result.response.status == source_deploy_retrieve_1.RequestStatus.Succeeded) { deploySourceResult.message = `Successfully deployed`; deploySourceResult.result = result.response.success; deploySourceResult.deploy_id = result.response.id; } else { if (result.response.status == source_deploy_retrieve_1.RequestStatus.Canceled) { deploySourceResult.message = `The deployment request ${result.response.id} was cancelled by ${result.response.canceledByName}`; } else { deploySourceResult.message = this.handlErrorMesasge(result); } deploySourceResult.response = result.response; deploySourceResult.result = false; deploySourceResult.deploy_id = result.response.id; } return deploySourceResult; } handlErrorMesasge(result) { if (result.response.numberComponentErrors == 0) { //Check for test coverage warnings if (result.response.details.runTestResult.codeCoverageWarnings) { return 'Unable to deploy due to unsatisfactory code coverage and/or test failures'; } else return 'Unable to fetch report, Check your org for details'; } else if (result.response.numberComponentErrors > 0) { return this.constructComponentErrorMessage(result.response.details.componentFailures, this.logger); } else if (result.response.details.runTestResult) { return 'Unable to deploy due to unsatisfactory code coverage and/or test failures'; } else { return 'Unable to fetch report, Check your org for details'; } } constructComponentErrorMessage(componentFailures, logger) { let errorMessage = `Unable to deploy due to failure in some components, check log for details`; if (componentFailures === null || componentFailures === undefined) return; if (componentFailures instanceof Array) { //Search for other scenarios and if background Job is being executed, override the error message for (let failure of componentFailures) { let scenario = classifyErrorScenarios(failure); if (scenario == `BackgroundJob`) { errorMessage = `Unable to deploy due to an ongoing background job from a previous package`; break; } } } else { let failure = componentFailures; let scenario = classifyErrorScenarios(failure); if (scenario == `BackgroundJob`) { errorMessage = `Unable to deploy due to an ongoing background job from a previous package`; } } function classifyErrorScenarios(failure) { let scenario = `Component Error`; //Override if background job is being executed if (failure.problem.includes(`background job is being executed`)) { scenario = `BackgroundJob`; } return scenario; } return errorMessage; } writeResultToReport(result) { let deploymentReports = `.sfpowerscripts/mdapiDeployReports`; fs.mkdirpSync(deploymentReports); fs.writeFileSync(path_1.default.join(deploymentReports, `${result.response.id}.json`), JSON.stringify(this.formatResultAsJSON(result))); } async buildDeploymentOptions(org) { let metdataDeployOptions = { usernameOrConnection: org.getConnection(), apiOptions: {}, }; if (this.deploymentOptions.apiVersion) metdataDeployOptions.apiVersion = this.deploymentOptions.apiVersion; if (this.deploymentOptions.testLevel == TestOptions_1.TestLevel.RunLocalTests) { metdataDeployOptions.apiOptions.testLevel = TestOptions_1.TestLevel.RunLocalTests; } else if (this.deploymentOptions.testLevel == TestOptions_1.TestLevel.RunSpecifiedTests) { metdataDeployOptions.apiOptions.testLevel = TestOptions_1.TestLevel.RunSpecifiedTests; metdataDeployOptions.apiOptions.runTests = this.deploymentOptions.specifiedTests.split(`,`); } else { metdataDeployOptions.apiOptions.testLevel = TestOptions_1.TestLevel.RunNoTests; } if (this.deploymentOptions.ignoreWarnings) { metdataDeployOptions.apiOptions.ignoreWarnings = true; } metdataDeployOptions.apiOptions.rollbackOnError = this.deploymentOptions.rollBackOnError; return metdataDeployOptions; } async deploy(componentSet) { let deploymentOptions = await this.buildDeploymentOptions(this.org); const deploy = await componentSet.deploy(deploymentOptions); let startTime = Date.now(); sfp_logger_1.default.log(`Deploying to ${this.org.getUsername()} with id:${deploy.id}`, sfp_logger_1.LoggerLevel.INFO, this.logger); // Attach a listener to check the deploy status on each poll deploy.onUpdate((response) => { const { status, numberComponentsDeployed, numberComponentsTotal } = response; const progress = `${numberComponentsDeployed}/${numberComponentsTotal}`; const message = `Status: ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(status)} Progress: ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(progress)}`; sfp_logger_1.default.log(message, sfp_logger_1.LoggerLevel.INFO, this.logger); }); deploy.onFinish((response) => { let deploymentDuration = Date.now() - startTime; if (response.response.success) { sfp_logger_1.default.log((0, sfp_logger_1.COLOR_SUCCESS)(`Succesfully Deployed ${(0, sfp_logger_1.COLOR_HEADER)(response.response.numberComponentsDeployed)} components in ${(0, GetFormattedTime_1.default)(deploymentDuration)}`), sfp_logger_1.LoggerLevel.INFO, this.logger); } else sfp_logger_1.default.log((0, sfp_logger_1.COLOR_ERROR)(`Failed to deploy after ${(0, GetFormattedTime_1.default)(deploymentDuration)}`), sfp_logger_1.LoggerLevel.INFO, this.logger); }); // Wait for polling to finish and get the DeployResult object const hoursInWaitTime = Number(this.deploymentOptions.waitTime) / 60; const result = await deploy.pollStatus({ frequency: kit_1.Duration.seconds(30), timeout: kit_1.Duration.hours(hoursInWaitTime), }); return result; } //For compatibility with cli output formatResultAsJSON(result) { const response = result?.response ? result.response : {}; return { result: { ...response, details: { componentSuccesses: response?.details?.componentSuccesses, componentFailures: response?.details?.componentFailures, runTestResult: response?.details?.runTestResult, }, }, }; } async handleSourceTracking(org, logger, projectDir, result) { if (result.response.success) { try { const project = await core_1.SfProject.resolve(this.projectDir); const tracking = await source_tracking_1.SourceTracking.create({ org: org, project: project, }); await tracking.ensureRemoteTracking(); tracking.updateTrackingFromDeploy(result); } catch (error) { sfp_logger_1.default.log(`Unable to update source tracking due to \n ${error}`, sfp_logger_1.LoggerLevel.WARN, logger); } } } } exports.default = DeploySourceToOrgImpl; class DeploymentOptions { } exports.DeploymentOptions = DeploymentOptions; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGVwbG95U291cmNlVG9PcmdJbXBsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvcmUvZGVwbG95ZXJzL0RlcGxveVNvdXJjZVRvT3JnSW1wbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1FQU84QjtBQUU5Qix5Q0FBMkM7QUFFM0MsK0VBTTRDO0FBQzVDLDZDQUErQjtBQUMvQixnREFBd0I7QUFFeEIsaUZBQXlEO0FBQ3pELHlEQUFvRDtBQUNwRCwyQ0FBNkM7QUFDN0MsaUVBQTZEO0FBRTdELE1BQXFCLHFCQUFxQjtJQUN0QyxZQUNZLEdBQVcsRUFDWCxVQUFrQixFQUNsQixZQUEwQixFQUMxQixpQkFBb0MsRUFDcEMsTUFBZTtRQUpmLFFBQUcsR0FBSCxHQUFHLENBQVE7UUFDWCxlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQ2xCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsV0FBTSxHQUFOLE1BQU0sQ0FBUztJQUN4QixDQUFDO0lBRUcsS0FBSyxDQUFDLElBQUk7UUFDYixJQUFJLGtCQUFrQixHQUFHLEVBQXdCLENBQUM7UUFFbEQsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsVUFBVTtZQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQztRQUU5RyxlQUFlO1FBQ2YsSUFBSSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVsRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFNUIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDN0MsTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFD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