@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
JavaScript
;
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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