UNPKG

@flxbl-io/sfp

Version:

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

262 lines 24.2 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 simple_git_1 = require("simple-git"); const fs = __importStar(require("fs-extra")); const ProjectConfig_1 = __importDefault(require("../../core/project/ProjectConfig")); const ajv_1 = __importDefault(require("ajv")); const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger")); const lodash = require("lodash"); const sfp_logger_2 = require("@flxbl-io/sfp-logger"); const Git_1 = __importDefault(require("../../core/git/Git")); const GitTags_1 = __importDefault(require("../../core/git/GitTags")); const retry = require('async-retry'); const yaml = require('js-yaml'); const path = require('path'); class ReleaseDefinitionGenerator { get releaseConfiguration() { // Return clone of releaseDefinition for immutability return lodash.cloneDeep(this._releaseConfiguration); } constructor(logger, gitRef, pathToReleaseDefinition, releaseName, branch, metadata, directory, noPush = false, forcePush = false, inMemoryMode = false) { this.logger = logger; this.gitRef = gitRef; this.releaseName = releaseName; this.branch = branch; this.metadata = metadata; this.directory = directory; this.noPush = noPush; this.forcePush = forcePush; this.inMemoryMode = inMemoryMode; this._releaseConfiguration = yaml.load(fs.readFileSync(pathToReleaseDefinition, 'utf8')); this.validateReleaseDefinitionGeneratorConfig(this._releaseConfiguration); //Attempt to parse metadata flag into JSON if (this.metadata) { try { this.metadata = JSON.parse(this.metadata); } catch (error) { throw new Error(`Invalid JSON for metadata flag: ${error}`); } } // Easy to handle here than with schema if (this._releaseConfiguration.includeOnlyArtifacts && this.releaseConfiguration.excludeArtifacts) { throw new Error('Error: Invalid schema: either use includeArtifacts or excludeArtifacts'); } // Easy to handle here than with schema if (this._releaseConfiguration.includeOnlyPackageDependencies && this.releaseConfiguration.excludePackageDependencies) { throw new Error('Error: Invalid schema: either use includePackageDependencies or excludePackageDependencies'); } // Workaround for jsonschema not supporting validation based on dependency value if (this._releaseConfiguration.releasedefinitionProperties?.baselineOrg && !this._releaseConfiguration.releasedefinitionProperties?.skipIfAlreadyInstalled) throw new Error("Release option 'skipIfAlreadyInstalled' must be true for 'baselineOrg'"); } async exec() { return retry(async (bail, retryNum) => { try { return await this.execHandler(); } catch (err) { if (err instanceof simple_git_1.GitError) { if (!err.message.includes('failed to push some refs')) { // Do not retry for Git errors that are not related to push bail(err); } else { sfp_logger_1.default.log('Failed to push definition', sfp_logger_2.LoggerLevel.WARN, this.logger); sfp_logger_1.default.log(`Retrying...(${retryNum})`, sfp_logger_2.LoggerLevel.WARN, this.logger); throw err; } } else { // Do not retry for non-Git errors bail(err); } } }, { retries: 10, minTimeout: 5, randomize: true, }); } async execHandler() { let repoDir; let git; try { sfp_logger_1.default.log(`Processing Artifacts from reference.. ${this.gitRef}`, sfp_logger_2.LoggerLevel.INFO, this.logger); git = await Git_1.default.initiateRepoAtTempLocation(this.logger); repoDir = git.getRepositoryPath(); let fetchedArtifacts = await this.fetchFromGitRef(git); let releaseDefiniton = await this.generateReleaseDefintion(fetchedArtifacts.artifacts, fetchedArtifacts.packageDependencies, git); return releaseDefiniton; } catch (error) { sfp_logger_1.default.log(error, sfp_logger_2.LoggerLevel.ERROR, this.logger); } finally { git.deleteTempoRepoIfAny(); } } async fetchFromGitRef(git) { let artifacts = {}; let packageDependencies = {}; //Create A copy of repository to a particular commit //If already a duplicate directory switch to the passed git ref //then switch it back let headCommit = await git.getCurrentCommitId(); await git.checkout(this.gitRef, true); let projectConfig = ProjectConfig_1.default.getSFDXProjectConfig(git.getRepositoryPath()); //Read sfdx project json let sfdxPackages = ProjectConfig_1.default.getAllPackagesFromProjectConfig(projectConfig); for (const sfdxPackage of sfdxPackages) { let latestGitTagVersion = new GitTags_1.default(git, sfdxPackage); try { let version = await latestGitTagVersion.getVersionFromLatestTag(); if (this.getArtifactPredicate(sfdxPackage)) { artifacts[sfdxPackage] = version; } } catch (error) { sfp_logger_1.default.log(`Unable to capture version of ${sfdxPackage} due to ${error}`, sfp_logger_2.LoggerLevel.WARN, this.logger); } } if (!this.releaseConfiguration.excludeAllPackageDependencies) { let allExternalPackages = ProjectConfig_1.default.getAllExternalPackages(projectConfig); for (const externalPackage of allExternalPackages) { if (this.getDependencyPredicate(externalPackage.alias) && externalPackage.Package2IdOrSubscriberPackageVersionId.startsWith('04t')) { packageDependencies[externalPackage.alias] = externalPackage.Package2IdOrSubscriberPackageVersionId; } } } return { artifacts, packageDependencies }; } async generateReleaseDefintion(artifacts, packageDependencies, git) { artifacts = Object.keys(artifacts) .sort() .reduce((obj, key) => { obj[key] = artifacts[key]; return obj; }, {}); packageDependencies = Object.keys(packageDependencies) .sort() .reduce((obj, key) => { obj[key] = packageDependencies[key]; return obj; }, {}); let releaseDefinition = { release: this.releaseName, releaseConfigName: this.releaseConfiguration?.releaseName, metadata: this.metadata, skipIfAlreadyInstalled: true, skipArtifactUpdate: false, artifacts: artifacts, }; //Add package dependencies if (Object.keys(packageDependencies).length > 0) releaseDefinition.packageDependencies = packageDependencies; //add promotePackagesBeforeDeploymentToOrg releaseDefinition.promotePackagesBeforeDeploymentToOrg = this.releaseConfiguration.releasedefinitionProperties?.promotePackagesBeforeDeploymentToOrg; //override skip if already installed if (this.releaseConfiguration.releasedefinitionProperties?.skipIfAlreadyInstalled) releaseDefinition.skipIfAlreadyInstalled = this.releaseConfiguration.releasedefinitionProperties?.skipIfAlreadyInstalled; //override skip artifact update if (this.releaseConfiguration.releasedefinitionProperties?.skipArtifactUpdate) releaseDefinition.skipArtifactUpdate = this.releaseConfiguration.releasedefinitionProperties?.skipArtifactUpdate; //Add changelog info releaseDefinition.changelog = this.releaseConfiguration.releasedefinitionProperties?.changelog; if (this.inMemoryMode) return releaseDefinition; let releaseDefinitonYAML = yaml.dump(releaseDefinition, { styles: { '!!null': 'canonical', // dump null as ~ }, sortKeys: false, // sort object keys }); sfp_logger_1.default.log((0, sfp_logger_1.COLOR_HEADER)(`------------Generated Release Definition for ${this.releaseName}----------------`)); sfp_logger_1.default.log(``); sfp_logger_1.default.log((0, sfp_logger_1.COLOR_KEY_MESSAGE)(releaseDefinitonYAML)); let pathToReleaseDefnDirectory = this.createDirectory(this.directory, git.getRepositoryPath()); fs.writeFileSync(path.join(pathToReleaseDefnDirectory, `${this.releaseName}.yml`), releaseDefinitonYAML); if (this.branch) { sfp_logger_1.default.log(`Checking out branch ${this.branch}`); await git.createBranch(this.branch); await git.commitFile([path.join(pathToReleaseDefnDirectory, `${this.releaseName}.yml`)]); if (!this.noPush) await git.pushToRemote(this.branch, this.forcePush); } return { releaseDefinitonYAML, pathToReleaseDefnDirectory }; } createDirectory(directory, repoDir) { if (this.directory) { if (!fs.pathExistsSync(path.join(repoDir, directory))) { fs.mkdirpSync(path.join(repoDir, directory)); } repoDir = path.join(repoDir, this.directory); } return repoDir; } validateReleaseDefinitionGeneratorConfig(releaseDefinitionGeneratorSchema) { let schema = fs.readJSONSync(path.join(__dirname, '..', '..', '..', 'resources', 'schemas', 'release-config.schema.json'), { encoding: 'UTF-8' }); let validator = new ajv_1.default({ allErrors: true }).compile(schema); let validationResult = validator(releaseDefinitionGeneratorSchema); if (!validationResult) { let errorMsg = `Release definition generation config does not meet schema requirements, ` + `found ${validator.errors.length} validation errors:\n`; validator.errors.forEach((error, errorNum) => { errorMsg += `\n${errorNum + 1}: ${error.instancePath}: ${error.message} ${JSON.stringify(error.params, null, 4)}`; }); throw new Error(errorMsg); } } getArtifactPredicate(artifact) { if (this.releaseConfiguration.includeOnlyArtifacts) { return this.releaseConfiguration.includeOnlyArtifacts?.includes(artifact); } else if (this.releaseConfiguration.excludeArtifacts) { return !this.releaseConfiguration.excludeArtifacts?.includes(artifact); } else return true; } getDependencyPredicate(artifact) { if (this.releaseConfiguration.includeOnlyPackageDependencies) { return this.releaseConfiguration.includeOnlyPackageDependencies?.includes(artifact); } else if (this.releaseConfiguration.excludePackageDependencies) { return !this.releaseConfiguration.excludePackageDependencies?.includes(artifact); } else return true; } } exports.default = ReleaseDefinitionGenerator; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVsZWFzZURlZmluaXRpb25HZW5lcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW1wbC9yZWxlYXNlL1JlbGVhc2VEZWZpbml0aW9uR2VuZXJhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBc0M7QUFDdEMsNkNBQStCO0FBRS9CLHFGQUE2RDtBQUM3RCw4Q0FBNkI7QUFDN0IsbUVBQTBGO0FBRTFGLGlDQUFrQztBQUNsQyxxREFBbUQ7QUFDbkQsNkRBQXFDO0FBQ3JDLHFFQUE2QztBQUM3QyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDckMsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ2hDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUU3QixNQUFxQiwwQkFBMEI7SUFHM0MsSUFBSSxvQkFBb0I7UUFDcEIscURBQXFEO1FBQ3JELE9BQU8sTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQsWUFDWSxNQUFjLEVBQ2QsTUFBYyxFQUN0Qix1QkFBK0IsRUFDdkIsV0FBbUIsRUFDbkIsTUFBYyxFQUNkLFFBQWEsRUFDYixTQUFrQixFQUNsQixTQUFrQixLQUFLLEVBQ3ZCLFlBQXFCLEtBQUssRUFDMUIsZUFBdUIsS0FBSztRQVQ1QixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUVkLGdCQUFXLEdBQVgsV0FBVyxDQUFRO1FBQ25CLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxhQUFRLEdBQVIsUUFBUSxDQUFLO1FBQ2IsY0FBUyxHQUFULFNBQVMsQ0FBUztRQUNsQixXQUFNLEdBQU4sTUFBTSxDQUFpQjtRQUN2QixjQUFTLEdBQVQsU0FBUyxDQUFp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