UNPKG

@flxbl-io/sfp

Version:

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

272 lines 27.8 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 IsValidSfdxAuthUrl_1 = __importDefault(require("../../core/scratchorg/pool/prequisitecheck/IsValidSfdxAuthUrl")); const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger")); const ArtifactGenerator_1 = __importDefault(require("../../core/artifacts/generators/ArtifactGenerator")); const ProjectConfig_1 = __importDefault(require("../../core/project/ProjectConfig")); const FetchArtifactSelector_1 = __importDefault(require("../artifacts/FetchArtifactSelector")); const BuildImpl_1 = __importDefault(require("../parallelBuilder/BuildImpl")); const PoolCreateImpl_1 = __importDefault(require("../../core/scratchorg/pool/PoolCreateImpl")); const Stage_1 = require("../Stage"); const PrepareOrgJob_1 = __importDefault(require("./PrepareOrgJob")); const rimraf = __importStar(require("rimraf")); const fs = __importStar(require("fs-extra")); const Git_1 = __importDefault(require("../../core/git/Git")); const GitTags_1 = __importDefault(require("../../core/git/GitTags")); const OrgDetailsFetcher_1 = __importDefault(require("../../core/org/OrgDetailsFetcher")); const SFPOrg_1 = __importDefault(require("../../core/org/SFPOrg")); const os_1 = require("os"); const SFPStatsSender_1 = __importDefault(require("../../core/stats/SFPStatsSender")); const ExternalPackage2DependencyResolver_1 = __importDefault(require("../../core/package/dependencies/ExternalPackage2DependencyResolver")); const ExternalDependencyDisplayer_1 = __importDefault(require("../../core/display/ExternalDependencyDisplayer")); const ReleaseDefinitionGenerator_1 = __importDefault(require("../release/ReleaseDefinitionGenerator")); const TableConstants_1 = require("../../ui/TableConstants"); const GroupConsoleLogs_1 = __importDefault(require("../../ui/GroupConsoleLogs")); const ReleaseConfigLoader_1 = __importDefault(require("../release/ReleaseConfigLoader")); const sfp_logger_2 = require("@flxbl-io/sfp-logger"); const Table = require('cli-table'); class PrepareImpl { constructor(hubOrg, pool, logLevel) { this.hubOrg = hubOrg; this.pool = pool; this.logLevel = logLevel; this.artifactFetchedCount = 0; // set defaults if (!this.pool.expiry) this.pool.expiry = 2; if (!this.pool.batchSize) this.pool.batchSize = 5; if (this.pool.succeedOnDeploymentErrors === undefined) this.pool.succeedOnDeploymentErrors = true; if (!this.pool.waitTime) this.pool.waitTime = 6; if (!this.pool.maxRetryCount) this.pool.maxRetryCount = 2; } async exec() { sfp_logger_1.default.log((0, sfp_logger_1.COLOR_KEY_MESSAGE)('Validating Org Authentication Mechanism..'), sfp_logger_1.LoggerLevel.INFO); let orgDisplayResult = await new OrgDetailsFetcher_1.default(this.hubOrg.getUsername()).getOrgDetails(); if (!(orgDisplayResult.sfdxAuthUrl && (0, IsValidSfdxAuthUrl_1.default)(orgDisplayResult.sfdxAuthUrl))) throw new Error(`Pools have to be created using a DevHub authenticated with auth:web or auth:store or auth:accesstoken:store`); return this.poolScratchOrgs(); } async poolScratchOrgs() { //Create Artifact Directory rimraf.sync('artifacts'); fs.mkdirpSync('artifacts'); let restrictedPackages = null; let projectConfig = ProjectConfig_1.default.getSFDXProjectConfig(null); if (this.pool.releaseConfigFile) { restrictedPackages = await getArtifactsByGeneratingReleaseDefinitionFromConfig(this.pool.releaseConfigFile); sfp_logger_1.default.log(`Restricted Packages: ${restrictedPackages}`, sfp_logger_1.LoggerLevel.INFO); projectConfig = ProjectConfig_1.default.cleanupPackagesFromProjectDirectory(null, restrictedPackages); } if (this.pool.installAll) { await this.getPackageArtifacts(restrictedPackages); } let checkpointPackages = this.getcheckPointPackages(projectConfig, new sfp_logger_1.ConsoleLogger()); let externalPackageResolver = new ExternalPackage2DependencyResolver_1.default(this.hubOrg.getConnection(), projectConfig, this.pool.keys); let externalPackage2s = await externalPackageResolver.resolveExternalPackage2DependenciesToVersions(); //Display resolved dependencies let externalDependencyDisplayer = new ExternalDependencyDisplayer_1.default(externalPackage2s, new sfp_logger_1.ConsoleLogger()); externalDependencyDisplayer.display(); let prepareASingleOrgImpl = new PrepareOrgJob_1.default(this.pool, checkpointPackages, externalPackage2s); let createPool = new PoolCreateImpl_1.default(this.hubOrg, this.pool, prepareASingleOrgImpl, this.logLevel); let pool = (await createPool.execute()); if (pool.isOk()) { await this.displayPoolSummary(pool.value); } return pool; async function getArtifactsByGeneratingReleaseDefinitionFromConfig(releaseConfigFile) { let releaseDefinitionGenerator = new ReleaseDefinitionGenerator_1.default(new sfp_logger_1.ConsoleLogger(), 'HEAD', releaseConfigFile, 'prepare', 'test', undefined, undefined, true, false, true); let releaseDefinition = (await releaseDefinitionGenerator.exec()); return Object.keys(releaseDefinition.artifacts); } } //Fetch all checkpoints getcheckPointPackages(projectConfig, logger) { sfp_logger_1.default.log('Fetching checkpoints for prepare if any.....', sfp_logger_1.LoggerLevel.INFO, logger); let checkPointPackages = []; ProjectConfig_1.default.getAllPackageDirectoriesFromConfig(projectConfig).forEach((pkg) => { if (pkg.checkpointForPrepare) checkPointPackages.push(pkg['package']); }); return checkPointPackages; } async displayPoolSummary(pool) { let table = new Table({ head: [ 'Scratch Org Alias Id', 'Scratch Org Username', 'Installed/Requested Count', 'Last Installed Package', ], chars: TableConstants_1.ZERO_BORDER_TABLE }); for (const scratchOrg of pool.scratchOrgs) { try { let scratchOrgAsSFPOrg = await SFPOrg_1.default.create({ aliasOrUsername: scratchOrg.username }); let installedArtifacts = await scratchOrgAsSFPOrg.getInstalledArtifacts(); if (installedArtifacts && installedArtifacts.length >= 1) { let installationCount = installedArtifacts.length; let lastInstalledArifact = installedArtifacts[installedArtifacts.length - 1]; table.push([ scratchOrg.alias, scratchOrg.username, `${installationCount}/${this.artifactFetchedCount}`, lastInstalledArifact.Name, ]); SFPStatsSender_1.default.logGauge(`so.packages.requested`, this.artifactFetchedCount, { pool: this.pool.tag, scratchOrg: scratchOrg.alias, }); SFPStatsSender_1.default.logGauge(`so.packages.installed`, installationCount, { pool: this.pool.tag, scratchOrg: scratchOrg.alias, }); } else { table.push([scratchOrg.alias, scratchOrg.username, `NA`, `NA`]); SFPStatsSender_1.default.logGauge(`so.packages.requested`, 0, { pool: this.pool.tag, scratchOrg: scratchOrg.alias, }); SFPStatsSender_1.default.logGauge(`so.packages.installed`, 0, { pool: this.pool.tag, scratchOrg: scratchOrg.alias, }); } } catch (error) { SFPStatsSender_1.default.logGauge(`so.packages.requested`, 0, { pool: this.pool.tag, scratchOrg: scratchOrg.alias, }); SFPStatsSender_1.default.logGauge(`so.packages.installed`, 0, { pool: this.pool.tag, scratchOrg: scratchOrg.alias, }); table.push([scratchOrg.alias, scratchOrg.username, `Unable to compute`, `Unable to fetch`]); } } if (table.length >= 1) { sfp_logger_1.default.log(os_1.EOL, sfp_logger_1.LoggerLevel.INFO); sfp_logger_1.default.log((0, sfp_logger_1.COLOR_KEY_MESSAGE)('Pool Summary:'), sfp_logger_1.LoggerLevel.INFO); sfp_logger_1.default.log(table.toString(), sfp_logger_1.LoggerLevel.INFO); } } async getPackageArtifacts(restrictedPackages) { //Filter Packages to be ignored from prepare to be fetched let packages = ProjectConfig_1.default.getAllPackageDirectoriesFromDirectory(null).filter((pkg) => { return isPkgToBeInstalled(pkg, restrictedPackages); }); let artifactFetcher; if (this.pool.fetchArtifacts) { let fetchArtifactsLogGroup = new GroupConsoleLogs_1.default(`Fetching Artifacts`); fetchArtifactsLogGroup.begin(); artifactFetcher = new FetchArtifactSelector_1.default(this.pool.fetchArtifacts.artifactFetchScript, this.pool.fetchArtifacts.npm?.scope, this.pool.fetchArtifacts.npm?.npmrcPath).getArtifactFetcher(); const git = await Git_1.default.initiateRepo(); //During Prepare, there could be a race condition where a main is merged with a new package //but the package is not yet available in the validated package list and can cause prepare to fail for (const pkg of packages) { try { let latestGitTagVersion = new GitTags_1.default(git, pkg.package); let version = await latestGitTagVersion.getVersionFromLatestTag(); artifactFetcher.fetchArtifact(pkg.package, 'artifacts', version, true); this.artifactFetchedCount++; } catch (error) { sfp_logger_1.default.log((0, sfp_logger_1.COLOR_WARNING)(`Git Tag for ${pkg.package} missing, This might result in deployment failures`)); } } fetchArtifactsLogGroup.end(); } else { let buildArtifactsLogGroup = new GroupConsoleLogs_1.default(`Building Artifacts`); buildArtifactsLogGroup.begin(); //Build All Artifacts sfp_logger_1.default.log(`${os_1.EOL}`); sfp_logger_1.default.printHeaderLine('WARNING!!!', sfp_logger_1.COLOR_WARNING, sfp_logger_1.LoggerLevel.INFO); sfp_logger_1.default.log('Building packages, as script to fetch artifacts was not provided', sfp_logger_1.LoggerLevel.WARN); sfp_logger_1.default.log('This is not ideal, as the artifacts are built from the current head of the provided branch', sfp_logger_1.LoggerLevel.WARN); sfp_logger_1.default.log('Pools should be prepared with previously validated packages', sfp_logger_1.LoggerLevel.WARN); sfp_logger_1.default.printHeaderLine('', sfp_logger_1.COLOR_WARNING, sfp_logger_1.LoggerLevel.INFO); let buildProps = { configFilePath: this.pool.configFilePath, devhubAlias: this.hubOrg.getUsername(), waitTime: 120, isQuickBuild: true, isDiffCheckEnabled: false, buildNumber: 1, executorcount: 10, isBuildAllAsSourcePackages: this.pool.disableSourcePackageOverride ? false : true, branch: null, currentStage: Stage_1.Stage.PREPARE, }; buildProps = includeOnlyPackagesAsPerReleaseConfig(this.pool.releaseConfigFile, buildProps); let buildImpl = new BuildImpl_1.default(buildProps); let { generatedPackages, failedPackages } = await buildImpl.exec(); if (failedPackages.length > 0) throw new Error('Unable to build packages, Following packages failed to build' + failedPackages); for (let generatedPackage of generatedPackages) { await ArtifactGenerator_1.default.generateArtifact(generatedPackage, process.cwd(), 'artifacts'); this.artifactFetchedCount++; } buildArtifactsLogGroup.end(); } function isPkgToBeInstalled(pkg, restrictedPackages) { let ignoreOnStageFound = pkg.ignoreOnStage?.find((stage) => { stage = stage.toLowerCase(); if (stage === 'prepare') return true; }); //if ignored .. skip if (ignoreOnStageFound) return false; if (restrictedPackages) return restrictedPackages.includes(pkg.package); else return true; } function includeOnlyPackagesAsPerReleaseConfig(releaseConfigFilePath, buildProps, logger) { if (releaseConfigFilePath) { let releaseConfigLoader = new ReleaseConfigLoader_1.default(logger, releaseConfigFilePath); buildProps.includeOnlyPackages = releaseConfigLoader.getPackagesAsPerReleaseConfig(); printIncludeOnlyPackages(buildProps.includeOnlyPackages); } return buildProps; function printIncludeOnlyPackages(includeOnlyPackages) { sfp_logger_1.default.log((0, sfp_logger_1.COLOR_KEY_MESSAGE)(`Build will include the below packages release configs (domain(s))(domain)`), sfp_logger_1.LoggerLevel.INFO); sfp_logger_1.default.log((0, sfp_logger_2.COLOR_KEY_VALUE)(`${includeOnlyPackages.toString()}`), sfp_logger_1.LoggerLevel.INFO); } } } } exports.default = PrepareImpl; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJlcGFyZUltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW1wbC9wcmVwYXJlL1ByZXBhcmVJbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFQSx1SEFBK0Y7QUFDL0YsbUVBQXVIO0FBQ3ZILDBHQUFrRjtBQUNsRixxRkFBNkQ7QUFHN0QsK0ZBQXVFO0FBQ3ZFLDZFQUFxRTtBQUNyRSwrRkFBdUU7QUFFdkUsb0NBQWlDO0FBQ2pDLG9FQUE0QztBQUM1QywrQ0FBaUM7QUFDakMsNkNBQStCO0FBQy9CLDZEQUFxQztBQUNyQyxxRUFBNkM7QUFDN0MseUZBQWlFO0FBQ2pFLG1FQUEyQztBQUMzQywyQkFBeUI7QUFDekIscUZBQTZEO0FBQzdELDRJQUFvSDtBQUNwSCxpSEFBeUY7QUFDekYsdUdBQStFO0FBRS9FLDREQUE0RDtBQUM1RCxpRkFBeUQ7QUFDekQseUZBQWlFO0FBQ2pFLHFEQUF1RDtBQUV2RCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7QUFFbkMsTUFBcUIsV0FBVztJQUc1QixZQUEyQixNQUFjLEVBQVUsSUFBZ0IsRUFBVSxRQUFxQjtRQUF2RSxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQVUsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUFVLGFBQVEsR0FBUixRQUFRLENBQWE7UUFGMUYseUJBQW9CLEdBQVcsQ0FBQyxDQUFDO1FBR3JDLGVBQWU7UUFDZixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBRTVDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVM7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7UUFFbEQsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLHlCQUF5QixLQUFL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