@jsnyder147/sandbox-deploy
Version:
Handles Sandbox deploy from repo
169 lines (150 loc) • 6.17 kB
JavaScript
#!/usr/bin/env node
const chalk = require('chalk');
const clear = require('clear');
const CLI = require('clui');
const cmd = require('node-cmd');
const figlet = require('figlet');
const sfdx = require('sfdx-node');
const Spinner = CLI.Spinner;
const minimist = require('minimist');
//DIRECTORY CONSTANTS
const sfdxProjectDirectory = 'sfdx-project.json';
const deployListDirectory = 'deployList.json';
const artifactDirectory = 'deploy-artifact';
const mdapiDirectory = 'mdapiDeploy';
// List of Metadata Types that require a second file (file-meta.xml)
const requireXML = ['aura', 'certs', 'classes', 'components', 'contentassets', 'email', 'lwc', 'networkBranding', 'objects', 'pages', 'siteDotComSites', 'staticresources', 'triggers'];
// Utility
const utility = require('./lib/utility');
// // Clear Terminal
// clear();
// // Display Title
// console.log(chalk.cyan.bold(figlet.textSync('---------\n Sandbox \n Deploy \n---------', { font:'Trek', horizontalLayout: 'default' })));
//Check if sfdx-project.json exists
utility.checkDirectory(sfdxProjectDirectory, sfdxProjectDirectory + ' does not exist');
// Check if sfdx-project.json has package directories
const packageDirectories = utility.getJSON(sfdxProjectDirectory).packageDirectories;
if(!packageDirectories || packageDirectories.length == 0) {
utility.showError('packageDirectories in ' + sfdxProjectDirectory + ' is empty or does not exist');
}
// Check if package directory path exists
const packageDirectoryPath = packageDirectories[0].path;
utility.checkDirectory(packageDirectoryPath, packageDirectoryPath + ' does not exist.');
// Check if deploy list JSON exists
utility.checkDirectory(deployListDirectory, deployListDirectory + ' file with metadata list does not exist');
// Check if deploy list metadata array is empty
const deployListMetadata = utility.getJSON(deployListDirectory).metadata;
if (!deployListMetadata || deployListMetadata.length == 0) {
utility.showError('metadata array in ' + deployListDirectory + ' is empty or does not exist')
}
// Get Org Info
const status = new Spinner('Verifying Org..');
const args = minimist(process.argv.slice(2), {
boolean: 'checkonly', // --checkonly
string: 'deploydir', // --deploydir
string: 'testlevel', // --testlevel
string: 'targetusername', // --targetusername
string: 'wait', // --wait
alias: { c: 'checkonly', d: 'deploydir', l: 'testlevel', u: 'targetusername', w: 'wait'},
default: {checkonly:false, deploydir:artifactDirectory, testlevel: 'NoTestRun'}
})
// If targetusername arg provided
if(args['targetusername']) {
getOrgConfig(args['targetusername'])
}
else {
utility.getUsername().then((response) => {
getOrgConfig(response.username);
});
}
// Check for org Configuration
function getOrgConfig(username) {
status.start();
sfdx.org.display({targetusername:username})
.then((orgData)=> {
status.stop();
if(orgData){
createArtifact();
convertToMdapi(orgData);
}
else{
utility.showError('No org configuration found for name ' + username);
}
});
}
// Create Source Deploy Artifact
function createArtifact(){
status.message('Creating Deploy Artifact..');
status.start();
// Create Source Artifact Directory
cmd.get(('mkdir ' + args['deploydir']));
// Loop through metadata in deployList JSON file
deployListMetadata.forEach(metadata => {
var metaSplit = metadata.split('default/');
metaSplit = metaSplit[1].split('/');
var metadataTypeDirectory = '';
var metadataType;
var metaItem = metaSplit.pop();
if(metaSplit && metaSplit.length > 0) {
metadataType = metaSplit[0];
//Loop through each directory until metaItem
metaSplit.forEach(path => {
metadataTypeDirectory += ('/' +path);
// Check if MetaDataType Directory needs to be created (ex classes, aura, lwc, etc.)
if(!utility.directoryExists(args['deploydir'] + '/' + metadataTypeDirectory)) {
cmd.get(('mkdir ' + args['deploydir'] + '/' + metadataTypeDirectory));
}
});
}
// Copy Metadata to deploy artifact directory
cmd.run(('cp ' + metadata + ' ' + args['deploydir'] + '/' + metadataTypeDirectory + '/' + metaItem));
// Copy -meta.xml file to artifact directory if necessary
if(requireXML.includes(metadataType) && !deployListMetadata.includes(metaItem + '-meta.xml')) {
cmd.run(('cp ' + metadata + '-meta.xml ' + args['deploydir'] + '/' + metadataTypeDirectory));
}
});
status.stop();
}
// Convert Source Format Artifact Directory to MDAPI format
function convertToMdapi(orgData){
status.message('Converting to Metadata API Format..');
status.start();
cmd.get(('sfdx force:source:convert -r ' + args['deploydir'] + ' -d ' + mdapiDirectory ), function(err, data, stderr) {
if(err) {
status.stop();
console.log(chalk.red(stderr));
process.exit();
}
else {
status.stop();
// Delete Source Format Artifact Directory
utility.deleteDirectory(artifactDirectory);
deployToOrg(orgData);
}
});
}
// Deploy Metadat API to org
function deployToOrg(orgData) {
var name;
if(orgData.alias) {
name = orgData.alias;
}
else {
name = orgData.username;
}
utility.confirmDeploy(name).then((response) => {
status.message('Deploying to ' + name + '..');
status.start();
cmd.get(('sfdx force:mdapi:deploy -d ' + mdapiDirectory + ' -l ' + args['testlevel'] + ' -w -1' ), function(err, data, stderr) {
if(err) {
status.stop();
console.log(chalk.red(stderr));
process.exit();
}
else {
status.stop();
console.log(chalk.green('Metadata deployed to ' + name));
}
});
});
}