UNPKG

@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
"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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