@flxbl-io/sfp
Version:
sfp is a CLI tool to help you manage your Salesforce projects in an artifact centric model
227 lines • 25.1 kB
JavaScript
"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 });
const ProjectConfig_1 = __importDefault(require("../../project/ProjectConfig"));
const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger"));
const fs = __importStar(require("fs-extra"));
const Delay_1 = require("../../utils/Delay");
const SfpPackage_1 = require("../SfpPackage");
const CreatePackage_1 = require("./CreatePackage");
const PackageEmptyChecker_1 = __importDefault(require("../validators/PackageEmptyChecker"));
const PackageVersionCoverage_1 = __importDefault(require("../coverage/PackageVersionCoverage"));
const core_1 = require("@salesforce/core");
const SFPStatsSender_1 = __importDefault(require("../../stats/SFPStatsSender"));
const os_1 = require("os");
const SFPOrg_1 = __importDefault(require("../../org/SFPOrg"));
const packaging_1 = require("@salesforce/packaging");
const kit_1 = require("@salesforce/kit");
const PackageDependencyDisplayer_1 = __importDefault(require("../../display/PackageDependencyDisplayer"));
const path = require('path');
class CreateUnlockedPackageImpl extends CreatePackage_1.CreatePackage {
constructor(projectDirectory, sfpPackage, packageCreationParams, logger, params) {
super(projectDirectory, sfpPackage, packageCreationParams, logger, params);
this.projectDirectory = projectDirectory;
this.sfpPackage = sfpPackage;
this.packageCreationParams = packageCreationParams;
this.logger = logger;
this.params = params;
this.isOrgDependentPackage = false;
}
getTypeOfPackage() {
return SfpPackage_1.PackageType.Unlocked;
}
async preCreatePackage(sfpPackage) {
this.devhubOrg = await SFPOrg_1.default.create({ aliasOrUsername: this.packageCreationParams.devHub });
this.connection = this.devhubOrg.getConnection();
let packageId = ProjectConfig_1.default.getPackageId(sfpPackage.projectConfig, this.sfpPackage.packageName);
// Get working directory
this.workingDirectory = sfpPackage.workingDirectory;
//Get the one in working directory, this is always hardcoded to match
this.params.configFilePath = path.join('config', 'project-scratch-def.json');
//Get Type of Package
sfp_logger_1.default.log('Fetching Package Type Info from DevHub', sfp_logger_1.LoggerLevel.INFO, this.logger);
let packageTypeInfos = await this.getPackageTypeInfos();
let packageTypeInfo = packageTypeInfos.find((pkg) => pkg.Id == packageId);
if (packageTypeInfo == null) {
sfp_logger_1.default.log('Unable to find a package info for this particular package, Are you sure you created this package?', sfp_logger_1.LoggerLevel.WARN, this.logger);
throw new Error('Unable to fetch Package Info');
}
if (packageTypeInfo.IsOrgDependent == 'Yes')
this.isOrgDependentPackage = true;
sfp_logger_1.default.log(`Package ${packageTypeInfo.Name}`, sfp_logger_1.LoggerLevel.INFO, this.logger);
sfp_logger_1.default.log(`IsOrgDependent ${packageTypeInfo.IsOrgDependent}`, sfp_logger_1.LoggerLevel.INFO, this.logger);
sfp_logger_1.default.log(`Package Id ${packageTypeInfo.Id}`, sfp_logger_1.LoggerLevel.INFO, this.logger);
sfp_logger_1.default.log('-------------------------', sfp_logger_1.LoggerLevel.INFO, this.logger);
//cleanup sfp constructs in working directory
this.deletesfpAdditionsToProjectConfig(this.workingDirectory);
//Resolve the package dependencies
if (this.isOrgDependentPackage) {
// Store original dependencies to artifact
sfpPackage.dependencies = sfpPackage.packageDescriptor['dependencies'];
}
else if (!this.isOrgDependentPackage && !this.packageCreationParams.isSkipValidation) {
sfpPackage.packageDescriptor = ProjectConfig_1.default.getSFDXPackageDescriptor(this.workingDirectory, this.sfpPackage.packageName);
//Store the resolved dependencies
sfpPackage.dependencies = sfpPackage.packageDescriptor['dependencies'];
}
else {
sfpPackage.dependencies = sfpPackage.packageDescriptor['dependencies'];
}
//Print Dependencies
PackageDependencyDisplayer_1.default.printPackageDependencies(sfpPackage.dependencies, sfpPackage.projectConfig, this.logger);
}
async createPackage(sfpPackage) {
const sfProject = await core_1.SfProject.resolve(this.workingDirectory);
// fix for #1202
// bug packaging lib doesnt support unpackaged metadata from working directory which is not the root
// it keeps on searching for the unpackage in the root folder
// so fix up the path manually
let targetPackageDir = sfProject.getPackageDirectories()[0];
if (targetPackageDir['unpackagedMetadata'])
targetPackageDir['unpackagedMetadata'] = { path: path.join(this.workingDirectory, 'unpackagedMetadata') };
let result = await packaging_1.PackageVersion.create({
connection: this.devhubOrg.getConnection(),
project: sfProject,
installationkey: this.packageCreationParams.installationkey,
installationkeybypass: this.packageCreationParams.installationkeybypass,
tag: sfpPackage.tag,
skipvalidation: this.packageCreationParams.isSkipValidation && !this.isOrgDependentPackage ? true : false,
codecoverage: this.packageCreationParams.isCoverageEnabled && !this.isOrgDependentPackage ? true : false,
versionnumber: sfpPackage.versionNumber,
definitionfile: path.join(this.workingDirectory, this.params.configFilePath),
packageId: this.sfpPackage.packageName,
}, { timeout: kit_1.Duration.minutes(0), frequency: kit_1.Duration.seconds(30) });
sfp_logger_1.default.log(`Package creation for ${this.sfpPackage.packageName} Initiated`, sfp_logger_1.LoggerLevel.INFO, this.logger);
//Poll for package creation every 30 seconds
let currentPackageCreationStatus;
while (true) {
await (0, Delay_1.delay)(30000); //Poll every 30 seconds
currentPackageCreationStatus = await packaging_1.PackageVersion.getCreateStatus(result.Id, this.devhubOrg.getConnection());
//Too Verbose when reading errors.. use only for debug
sfp_logger_1.default.log(`Status: ${(0, sfp_logger_1.COLOR_KEY_MESSAGE)(currentPackageCreationStatus.Status)}, Next Status check in 30 seconds`, sfp_logger_1.LoggerLevel.DEBUG, this.logger);
if (currentPackageCreationStatus.Status === `Success`) {
break;
}
else if (currentPackageCreationStatus.Status === 'Error') {
let errorMessage = '<empty>';
const errors = currentPackageCreationStatus?.Error;
if (errors?.length) {
errorMessage = 'Creation errors: ';
for (let i = 0; i < errors.length; i++) {
errorMessage += `\n${i + 1}) ${errors[i]}`;
}
}
throw new Error(`Unable to create ${this.sfpPackage.packageName} due to \n` + errorMessage);
}
}
sfp_logger_1.default.log(`Package Result:${JSON.stringify(currentPackageCreationStatus)}`, sfp_logger_1.LoggerLevel.TRACE, this.logger);
//Get the full details on the package and throw an error if the result is null, usually when the comamnd is timed out
if (currentPackageCreationStatus.SubscriberPackageVersionId) {
sfpPackage.package_version_id = currentPackageCreationStatus.SubscriberPackageVersionId;
await this.getPackageInfo(sfpPackage);
}
else {
throw new Error(`The build for ${this.sfpPackage.packageName} was not completed in the wait time ${this.packageCreationParams.waitTime} provided.${os_1.EOL}
You might want to increase the wait time or better check the dependencies or convert to different package type ${os_1.EOL}
Read more about it here https://docs.flxbl.io/development-practices/types-of-packaging/unlocked-packages#build-options-with-unlocked-packages`);
}
//Break if coverage is low
if (this.packageCreationParams.isCoverageEnabled && !this.isOrgDependentPackage) {
if (!sfpPackage.has_passed_coverage_check)
throw new Error('This package has not meet the minimum coverage requirement of 75%');
}
}
postCreatePackage(sfpPackage) {
//copy the original config back as existing one would have cleaned up
fs.copyFileSync(path.join(this.workingDirectory, 'sfdx-project-bak.json'), path.join(this.workingDirectory, 'sfdx-project.json'));
fs.unlinkSync(path.join(this.workingDirectory, 'sfdx-project-bak.json'));
if (sfpPackage.isDependencyValidated) {
SFPStatsSender_1.default.logGauge('package.testcoverage', sfpPackage.test_coverage, {
package: sfpPackage.package_name,
from: 'createpackage',
});
}
}
isEmptyPackage(projectDirectory, packageDirectory) {
return PackageEmptyChecker_1.default.isEmptyFolder(projectDirectory, packageDirectory);
}
printAdditionalPackageSpecificHeaders() { }
deletesfpAdditionsToProjectConfig(workingDirectory) {
let projectManifestFromWorkingDirectory = ProjectConfig_1.default.getSFDXProjectConfig(workingDirectory);
let packageDescriptorInWorkingDirectory = ProjectConfig_1.default.getPackageDescriptorFromConfig(this.sfpPackage.packageName, projectManifestFromWorkingDirectory);
fs.writeJsonSync(path.join(workingDirectory, 'sfdx-project-bak.json'), projectManifestFromWorkingDirectory);
//Cleanup sfp constructs
if (this.isOrgDependentPackage)
delete packageDescriptorInWorkingDirectory['dependencies'];
delete packageDescriptorInWorkingDirectory['type'];
delete packageDescriptorInWorkingDirectory['assignPermSetsPreDeployment'];
delete packageDescriptorInWorkingDirectory['assignPermSetsPostDeployment'];
delete packageDescriptorInWorkingDirectory['skipDeployOnOrgs'];
delete packageDescriptorInWorkingDirectory['skipTesting'];
delete packageDescriptorInWorkingDirectory['skipCoverageValidation'];
delete packageDescriptorInWorkingDirectory['ignoreOnStages'];
delete packageDescriptorInWorkingDirectory['ignoreDeploymentErrors'];
delete packageDescriptorInWorkingDirectory['preDeploymentScript'];
delete packageDescriptorInWorkingDirectory['postDeploymentScript'];
delete packageDescriptorInWorkingDirectory['aliasfy'];
delete packageDescriptorInWorkingDirectory['checkpointForPrepare'];
delete packageDescriptorInWorkingDirectory['testSynchronous'];
delete packageDescriptorInWorkingDirectory['tags'];
fs.writeJsonSync(path.join(workingDirectory, 'sfdx-project.json'), projectManifestFromWorkingDirectory);
}
async getPackageInfo(sfpPackage) {
let packageVersionCoverage = new PackageVersionCoverage_1.default(this.connection, this.logger);
let count = 0;
while (count < 10) {
count++;
try {
sfp_logger_1.default.log('Fetching Version Number and Coverage details', sfp_logger_1.LoggerLevel.INFO, this.logger);
let pkgInfoResult = await packageVersionCoverage.getCoverage(sfpPackage.package_version_id);
sfpPackage.isDependencyValidated = !this.packageCreationParams.isSkipValidation;
sfpPackage.package_version_number = pkgInfoResult.packageVersionNumber;
sfpPackage.test_coverage = pkgInfoResult.coverage;
sfpPackage.has_passed_coverage_check = pkgInfoResult.HasPassedCodeCoverageCheck;
break;
}
catch (error) {
sfp_logger_1.default.log(`Unable to fetch package version info due to ${error.message}`, sfp_logger_1.LoggerLevel.INFO, this.logger);
sfp_logger_1.default.log('Retrying...', sfp_logger_1.LoggerLevel.INFO, this.logger);
await (0, Delay_1.delay)(2000);
continue;
}
}
}
async getPackageTypeInfos() {
if (CreateUnlockedPackageImpl.packageTypeInfos == null) {
CreateUnlockedPackageImpl.packageTypeInfos = await this.devhubOrg.listAllPackages();
}
return CreateUnlockedPackageImpl.packageTypeInfos;
}
}
exports.default = CreateUnlockedPackageImpl;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ3JlYXRlVW5sb2NrZWRQYWNrYWdlSW1wbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL3BhY2thZ2UvcGFja2FnZUNyZWF0b3JzL0NyZWF0ZVVubG9ja2VkUGFja2FnZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLGdGQUF3RDtBQUN4RCxtRUFBeUY7QUFDekYsNkNBQStCO0FBQy9CLDZDQUEwQztBQUMxQyw4Q0FBMEU7QUFDMUUsbURBQWdEO0FBQ2hELDRGQUFvRTtBQUNwRSxnR0FBd0U7QUFDeEUsMkNBQXlEO0FBQ3pELGdGQUF3RDtBQUN4RCwyQkFBeUI7QUFDekIsOERBQTJEO0FBRTNELHFEQUEwRjtBQUMxRix5Q0FBMkM7QUFDM0MsMEdBQWtGO0FBQ2xGLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUU3QixNQUFxQix5QkFBMEIsU0FBUSw2QkFBYTtJQU9oRSxZQUNjLGdCQUF3QixFQUN4QixVQUFzQixFQUN0QixxQkFBNEMsRUFDNUMsTUFBZSxFQUNmLE1BQXlCO1FBRW5DLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxVQUFVLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBTmpFLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBUTtRQUN4QixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLDBCQUFxQixHQUFyQixxQkFBcUIsQ0FBdUI7UUFDNUMsV0FBTSxHQUFOLE1BQU0sQ0FBUztRQUNmLFdBQU0sR0FBTixNQUFNLENBQW1CO1FBVi9CLDBCQUFxQixHQUFZLEtBQUssQ0FBQztJQWEvQyxDQUFDO0lBRUQsZ0JBQWdCO1FBQ1osT0FBTyx3QkFBVyxDQUFDLFFBQVEsQ0FBQztJQUNoQyxDQUFDO0lBRUQsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFVBQXNCO1FBQ3pDLElBQUksQ0FBQyxT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