Node module optimizations: re-use Heroku CLI node_modules for force.js and release and test innvocations; fix node cache re-use; log clean-up
This commit is contained in:
Родитель
5749bb588f
Коммит
fb5959545f
155
bin/compile
155
bin/compile
|
@ -40,26 +40,11 @@ elif [ -f $1/config.json ]; then
|
|||
export SALESFORCE_WORKSPACE=true
|
||||
fi
|
||||
|
||||
### Compile
|
||||
|
||||
### E X P O R T C O N F I G V A R S
|
||||
log "Exporting config vars to environment..."
|
||||
export_env_dir
|
||||
|
||||
mkdir -p $SALESFORCE_DIR
|
||||
export SALESFORCE_DIR=$SALESFORCE_DIR
|
||||
|
||||
# REVIEWME: probably can remove if we use nodejs buildpack
|
||||
install_nodejs $SALESFORCE_CACHE_DIR
|
||||
# Put node in build dir since the cache is not available at time of deploy
|
||||
cp -a $SALESFORCE_CACHE_DIR/node $SALESFORCE_DIR/node
|
||||
export PATH="$SALESFORCE_DIR/node/bin":$PATH
|
||||
|
||||
cp -R $BP_DIR/lib/* $SALESFORCE_DIR/
|
||||
cp $BP_DIR/package.json $SALESFORCE_DIR/package.json
|
||||
|
||||
status "Installing node modules..."
|
||||
cd $SALESFORCE_DIR
|
||||
npm install --prefix $SALESFORCE_DIR | indent
|
||||
|
||||
# set defaults for optional config vars
|
||||
if [[ ! -v SALESFORCE_BYOO ]]; then
|
||||
export SALESFORCE_BYOO="false"
|
||||
|
@ -69,20 +54,81 @@ if [[ ! -v SALESFORCE_BUILDPACK_VERBOSE ]]; then
|
|||
export SALESFORCE_BUILDPACK_VERBOSE="false"
|
||||
fi
|
||||
|
||||
# FIXME: workaround for HEROKU_APP_NAME not provided by staging app
|
||||
if [[ ! -v HEROKU_APP_NAME ]]; then
|
||||
export HEROKU_APP_NAME="App Name Unknown"
|
||||
if [[ ! -v SALESFORCE_BUILDPACK_DEBUG ]]; then
|
||||
export SALESFORCE_BUILDPACK_DEBUG="false"
|
||||
fi
|
||||
|
||||
mkdir -p $SALESFORCE_DIR
|
||||
export SALESFORCE_DIR=$SALESFORCE_DIR
|
||||
|
||||
|
||||
### H E R O K U C L I
|
||||
status "Installing Heroku CLI and Salesforce plugins"
|
||||
|
||||
# vendor directories
|
||||
VENDORED_HEROKU_CLI="vendor/heroku-cli"
|
||||
|
||||
# download and extract the client tarball
|
||||
rm -rf "$BUILD_DIR/$VENDORED_HEROKU_CLI"
|
||||
mkdir -p "$BUILD_DIR/$VENDORED_HEROKU_CLI"
|
||||
cd "$BUILD_DIR/$VENDORED_HEROKU_CLI"
|
||||
|
||||
#: ${HEROKU_CLI_URL:="https://cli-assets.heroku.com/branches/stable/5.2.40-09fa7ac/heroku-v5.2.40-09fa7ac-linux-amd64.tar.xz"}
|
||||
: ${HEROKU_CLI_URL:="https://cli-assets.heroku.com/branches/stable/5.4.1-ae9db27/heroku-v5.4.1-ae9db27-linux-amd64.tar.xz"}
|
||||
if [[ -z "$(which wget)" ]]; then
|
||||
curl -s $HEROKU_CLI_URL | tar xJf -
|
||||
else
|
||||
wget -qO- $HEROKU_CLI_URL | tar xJf -
|
||||
fi
|
||||
|
||||
export PATH="$PATH:$BUILD_DIR/$VENDORED_HEROKU_CLI/heroku/bin"
|
||||
export XDG_DATA_HOME="$BUILD_DIR/.local"
|
||||
export XDG_CACHE_HOME="$BUILD_DIR/.cache"
|
||||
|
||||
# touch autoupdate file to prevent 'heroku update' (which breaks
|
||||
# tar as 'heroku update' alters what is being tar'd)
|
||||
mkdir -p $XDG_CACHE_HOME/heroku
|
||||
touch $XDG_CACHE_HOME/heroku/autoupdate
|
||||
|
||||
# install plugins
|
||||
: ${SALESFORCE_APPCLOUD_TOOLBET_DIST_TAG:="latest"}
|
||||
: ${SALESFORCE_FORCE_COM_CLI_DIST_TAG:="latest"}
|
||||
heroku plugins:install salesforce-alm-buildpack-dev@$SALESFORCE_APPCLOUD_TOOLBET_DIST_TAG
|
||||
heroku plugins:install force-cli-dev@$SALESFORCE_FORCE_COM_CLI_DIST_TAG
|
||||
heroku plugins
|
||||
|
||||
status "Heroku CLI and Salesforce plugins installation complete"
|
||||
|
||||
|
||||
### N O D E
|
||||
# install node, if not already present
|
||||
install_nodejs $SALESFORCE_CACHE_DIR
|
||||
# Put node in build dir since the cache is not available at time of deploy
|
||||
cp -a $SALESFORCE_CACHE_DIR/node $SALESFORCE_DIR/node
|
||||
export PATH="$SALESFORCE_DIR/node/bin":$PATH
|
||||
|
||||
# re-use node modules installed w/ plugins
|
||||
export NODE_PATH=$XDG_DATA_HOME/heroku/plugins/node_modules
|
||||
|
||||
status "Installing node modules..."
|
||||
cp -R $BP_DIR/lib/* $SALESFORCE_DIR/
|
||||
cp $BP_DIR/package.json $XDG_DATA_HOME/heroku/plugins/package.json
|
||||
cd $XDG_DATA_HOME/heroku/plugins
|
||||
npm install --only=production | indent
|
||||
|
||||
# double-check that node is installed
|
||||
if [ ! -f $SALESFORCE_DIR/node/bin/node ]; then
|
||||
error "! Node not found at $SALESFORCE_DIR/node/bin/node"
|
||||
error "Node not found at $SALESFORCE_DIR/node/bin/node"
|
||||
fi
|
||||
|
||||
# install secret tool used by appcloud
|
||||
# FIXME: disabled until we enable encryption on toolbelt
|
||||
#install_libsecret
|
||||
|
||||
|
||||
### C O M P I L E
|
||||
# disable process.exit calls
|
||||
export APPCLOUD_SOFT_EXIT=true;
|
||||
# delegate actual source deployment to node script
|
||||
: ${SALESFORCE_BYPASS_COMPILE:="false"}
|
||||
export SALESFORCE_DEPLOY_DIR="$SALESFORCE_DIR"
|
||||
|
@ -94,43 +140,8 @@ else
|
|||
status "Bypassing compile phase."
|
||||
fi
|
||||
|
||||
status "Installing Heroku CLI and AppCloud and Force CLI Plugins"
|
||||
|
||||
# vendor directories
|
||||
VENDORED_HEROKU_CLI="vendor/heroku-cli"
|
||||
|
||||
# download and extract the client tarball
|
||||
rm -rf "$BUILD_DIR/$VENDORED_HEROKU_CLI"
|
||||
mkdir -p "$BUILD_DIR/$VENDORED_HEROKU_CLI"
|
||||
cd "$BUILD_DIR/$VENDORED_HEROKU_CLI"
|
||||
|
||||
HEROKU_CLIENT_URL="https://cli-assets.heroku.com/branches/stable/5.2.40-09fa7ac/heroku-v5.2.40-09fa7ac-linux-amd64.tar.xz"
|
||||
if [[ -z "$(which wget)" ]]; then
|
||||
curl -s $HEROKU_CLIENT_URL | tar xJf -
|
||||
else
|
||||
wget -qO- $HEROKU_CLIENT_URL | tar xJf -
|
||||
fi
|
||||
|
||||
export PATH="$PATH:$BUILD_DIR/$VENDORED_HEROKU_CLI/heroku/bin"
|
||||
export XDG_DATA_HOME="$BUILD_DIR/.local"
|
||||
export XDG_CACHE_HOME="$BUILD_DIR/.cache"
|
||||
|
||||
# touch autoupdate file to prevent 'heroku update' (which breaks
|
||||
# tar as 'heroku update' alters what is being tar'd)
|
||||
mkdir -p $XDG_CACHE_HOME/heroku
|
||||
touch $XDG_CACHE_HOME/heroku/autoupdate
|
||||
# re-use node modules
|
||||
#ls $SALESFORCE_DIR/node_modules
|
||||
#mkdir -p $XDG_DATA_HOME/heroku/plugins
|
||||
#ln -s $SALESFORCE_DIR/node_modules $XDG_DATA_HOME/heroku/plugins/node_modules
|
||||
# install plugins
|
||||
heroku plugins:install salesforce-alm-buildpack-dev
|
||||
#heroku plugins:link $SALESFORCE_DIR/node_modules/salesforce-alm-buildpack-dev
|
||||
heroku plugins:install force-cli-dev
|
||||
heroku plugins
|
||||
|
||||
status "Heroku CLI and AppCloud and Force CLI Plugins installation complete"
|
||||
|
||||
### W R I T E E N V P R O F I L E S C R I P T
|
||||
# write env script to set various vars so release and test scripts
|
||||
# can use heroku cli and plugins
|
||||
export SALESFORCE_DEPLOY_DIR="\$HOME/$SALESFORCE_DIR_NAME"
|
||||
|
@ -144,13 +155,15 @@ export XDG_DATA_HOME="\$HOME/.local"
|
|||
export XDG_CACHE_HOME="\$HOME/.cache"
|
||||
# set so appcloud plugin can use for encryption
|
||||
export APPCLOUD_SECRET_TOOL_PATH="\$HOME/.apt/usr/bin/secret-tool"
|
||||
# set so appcloud plugin sets exitCode instead of invoking exit()
|
||||
export APPCLOUD_SOFT_EXIT=$APPCLOUD_SOFT_EXIT
|
||||
# set so appcloud plugin knows where deployment zip resides
|
||||
export SALESFORCE_DEPLOY_DIR="\$HOME/$SALESFORCE_DIR_NAME"
|
||||
# set node path to use shared modules
|
||||
export NODE_PATH="\$HOME/$SALESFORCE_DIR_NAME/node_modules"
|
||||
# set node path to shared modules
|
||||
export NODE_PATH="\$XDG_DATA_HOME/heroku/plugins/node_modules"
|
||||
|
||||
# log SALESFORCE_ and HEROKU_ config vars
|
||||
if [ "\$SALESFORCE_BUILDPACK_VERBOSE" == "true" ]; then
|
||||
if [ "\$SALESFORCE_BUILDPACK_DEBUG" == "true" ]; then
|
||||
echo "[DEBUG] PATH=\$PATH"
|
||||
for e in \$(env | grep '^SALESFORCE_\|^HEROKU_\|^APPCLOUD_\|^XDG_\|^NODE_'); do
|
||||
echo "[DEBUG] \$e"
|
||||
|
@ -164,31 +177,39 @@ $SALESFORCE_DIR_NAME/node/bin/node $SALESFORCE_DIR_NAME/force.js setup
|
|||
EOF
|
||||
|
||||
chmod +x $BUILD_DIR/.profile.d/salesforce-env.sh
|
||||
if [ "$SALESFORCE_BUILDPACK_VERBOSE" == "true" ]; then
|
||||
if [ "$SALESFORCE_BUILDPACK_DEBUG" == "true" ]; then
|
||||
debug "$BUILD_DIR/.profile.d/salesforce-env.sh:"
|
||||
debug "`cat $BUILD_DIR/.profile.d/salesforce-env.sh`"
|
||||
fi
|
||||
|
||||
status "Generating release phase deploy script to $SALESFORCE_DIR_NAME/deploy"
|
||||
|
||||
### R E L E A S E S C R I P T
|
||||
# write script triggering node-based deployment to-be-invoked bin/release
|
||||
cat <<EOF >$SALESFORCE_DIR/deploy
|
||||
$SALESFORCE_DIR_NAME/node/bin/node $SALESFORCE_DIR_NAME/force.js release
|
||||
|
||||
EOF
|
||||
status "Generated '$SALESFORCE_DIR_NAME/deploy' node script to be called in release phase to deploy source to target org (SALESFORCE_URL)"
|
||||
|
||||
chmod +x $SALESFORCE_DIR/deploy
|
||||
if [ "$SALESFORCE_BUILDPACK_VERBOSE" == "true" ]; then
|
||||
if [ "$SALESFORCE_BUILDPACK_DEBUG" == "true" ]; then
|
||||
debug "$SALESFORCE_DIR/deploy:"
|
||||
debug "`cat $SALESFORCE_DIR/deploy`"
|
||||
fi
|
||||
|
||||
|
||||
### F I N A L N O T E S
|
||||
highlight " "
|
||||
highlight "### N O T E ###"
|
||||
highlight "To DEPLOY source to org, to invoke '$SALESFORCE_DIR_NAME/deploy' in Procfile or in your release phase script."
|
||||
highlight "To TEST, invoke AppCloud Plugin test commands (force:apex:test or force:test) in the test section of your app.json. Eg:"
|
||||
highlight "Heroku CLI and Salesforce plugins were installed for use in release and test phase scripts."
|
||||
highlight " "
|
||||
highlight "To DEPLOY source to org, to invoke 'node $SALESFORCE_DIR_NAME/deploy' in Procfile or in your release phase script."
|
||||
highlight "To TEST, invoke Salesforce CLI test commands (force:apex:test or force:test) in the test section of your app.json. Eg:"
|
||||
highlight " $ heroku force:apex:test [params]"
|
||||
highlight "To IMPORT DATA, invoke AppCloud Plugin data command (force:data:import) in your release phase script. Eg:"
|
||||
highlight " $ heroku force:data:import [params]"
|
||||
highlight " "
|
||||
highlight "To use Salesforce CLI commands, source in '.profile.d/salesforce-env.sh' to ensure environment is properly setup."
|
||||
highlight "###############"
|
||||
highlight " "
|
||||
|
||||
|
||||
highlight "DONE! Completed in $(($SECONDS - $START_TIME))s"
|
||||
|
|
147
lib/force.js
147
lib/force.js
|
@ -8,14 +8,14 @@ const Promise = require('bluebird');
|
|||
|
||||
const fs_mkdir = Promise.promisify(fs.mkdir);
|
||||
|
||||
// AppCloud lib
|
||||
// Salesforce lib
|
||||
const _ = require(path.join(__dirname, 'utils'));
|
||||
const force = require('salesforce-alm-buildpack-dev');
|
||||
|
||||
// General
|
||||
const DEBUG = _.getEnvVarValue('SALESFORCE_BUILDPACK_DEBUG', false, false, true); // for development ONLY
|
||||
const VERBOSE = _.getEnvVarValue('SALESFORCE_BUILDPACK_VERBOSE', false, false, true);
|
||||
const HEROKU_APP_NAME = _.getEnvVarValue('HEROKU_APP_NAME', false, 'Salesforce Buildpack');
|
||||
const HEROKU_APP_NAME = _.getEnvVarValue('HEROKU_APP_NAME', false, 'SalesforceBuildpack');
|
||||
// FORCE_WORKSPACE=true if we're pushing source, false if deploying source
|
||||
const IS_SALESFORCE_WORKSPACE = _.getEnvVarValue('SALESFORCE_WORKSPACE', false, true, true); // set by bin/compile
|
||||
const SALESFORCE_SRC_PATH = _.getEnvVarValue('SALESFORCE_SRC_PATH', false, 'salesforce/src');
|
||||
|
@ -32,7 +32,7 @@ const SALESFORCE_ORG = 'org@salesforce.com';
|
|||
const SALESFORCE_URL_REGEX = /force:\/\/([A-Z0-9_\.]*):([A-Z0-9]*):([A-Z0-9_\.]*)@([\w-]+(\.[\w-]+)+\.?(:\d+)?)/ig;
|
||||
const PREVIEW_APP_NAME_REGEX = /-pr-\d+$/;
|
||||
|
||||
// AppCloud command invocation params
|
||||
// Salesforce command invocation params
|
||||
const HEROKU_APP_NAME_REPLACE_TOKEN = '[heroku-app-name]';
|
||||
const DEFAULT_ORG_SHAPE = {
|
||||
'Company': HEROKU_APP_NAME_REPLACE_TOKEN,
|
||||
|
@ -56,7 +56,6 @@ const PUSH_SOURCE_CMD = {
|
|||
name: 'org:push',
|
||||
flags: {
|
||||
targetname: SALESFORCE_ORG,
|
||||
all: true,
|
||||
workspace: true,
|
||||
json: true
|
||||
}
|
||||
|
@ -94,9 +93,10 @@ const MDAPI_DEPLOY_CMD = {
|
|||
}
|
||||
};
|
||||
|
||||
// Org config, accessToken, username, instance, etc
|
||||
// Organization config, accessToken, username, instance, etc
|
||||
let orgConfig;
|
||||
// determines deploy mechanism: true we use Metadata API, false we use AppCloud push
|
||||
let orgInstance;
|
||||
// determines deploy mechanism: true we use Metadata API, false we use Salesforce push
|
||||
let isByoo = _.getEnvVarValue('SALESFORCE_BYOO', false, false, true);
|
||||
|
||||
|
||||
|
@ -125,11 +125,14 @@ const parseOrgConfigFromUrl = function parseOrgConfigFromUrl(url, type, username
|
|||
throw new Error(`Invalid SALESFORCE_URL: '${url}'`);
|
||||
}
|
||||
SALESFORCE_URL_REGEX.lastIndex = 0; // reset
|
||||
if (type === 'workspace') {
|
||||
orgInstance = `${match[4]}`;
|
||||
}
|
||||
|
||||
// w/o accessToken
|
||||
return {
|
||||
orgId: '00Dxx0000000000',
|
||||
accessToken: 'REFRESH_ME', // AppCloud toolbelt commands will refresh
|
||||
accessToken: 'REFRESH_ME', // Salesforce toolbelt commands will refresh
|
||||
refreshToken: match[3],
|
||||
instanceUrl: `https://${match[4]}`,
|
||||
username: username || SALESFORCE_ORG,
|
||||
|
@ -148,7 +151,7 @@ const writeOrgConfig = function writeOrgConfig() {
|
|||
|
||||
if (SALESFORCE_URL === 'false') {
|
||||
if (VERBOSE) {
|
||||
_.info(`Skip writing user org config: ${SALESFORCE_URL_CONFIG_VAR_NAME} was not required.`);
|
||||
_.info(`Skip writing Organization config: ${SALESFORCE_URL_CONFIG_VAR_NAME} was not required.`);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
|
@ -157,7 +160,7 @@ const writeOrgConfig = function writeOrgConfig() {
|
|||
orgConfig = parseOrgConfigFromUrl(SALESFORCE_URL, 'workspace');
|
||||
|
||||
if (DEBUG) {
|
||||
_.info(`[DEBUG] Org config: ${JSON.stringify(orgConfig)}`);
|
||||
_.info(`[DEBUG] Organization configuration: ${JSON.stringify(orgConfig)}`);
|
||||
}
|
||||
|
||||
const orgConfigApi = new force.scratchOrgApi();
|
||||
|
@ -165,7 +168,11 @@ const writeOrgConfig = function writeOrgConfig() {
|
|||
return orgConfigApi.saveConfig(orgConfig)
|
||||
.then(() => {
|
||||
const orgConfigFilePath = force.util.getAppCloudFilePath(`${SALESFORCE_ORG}.json`);
|
||||
_.info(`Wrote '${orgConfig.username}' user org config to ${orgConfigFilePath}`);
|
||||
let msg = `Wrote Organization configuration '${orgInstance}'`;
|
||||
if (DEBUG) {
|
||||
msg += ` to ${orgConfigFilePath}`;
|
||||
}
|
||||
_.info(`${msg}`);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -191,7 +198,11 @@ const writeHubConfig = function writeHubConfig(required = true) {
|
|||
return hubConfigApi.saveConfig(hubConfig)
|
||||
.then(() => {
|
||||
const hubConfigFilePath = force.util.getAppCloudFilePath('hubConfig.json');
|
||||
_.info(`Wrote hub config to ${hubConfigFilePath}`);
|
||||
let msg = 'Wrote Environment Hub config';
|
||||
if (DEBUG) {
|
||||
msg += ` to ${hubConfigFilePath}`;
|
||||
}
|
||||
_.info(`${msg}`);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -219,9 +230,9 @@ const evalResult = function evalResult(cmd, result) {
|
|||
|
||||
// Create build org which we push source to and generate a zip
|
||||
// from; zip will be stored in slug and deployed to prod org
|
||||
const createBuildOrg = function pushSource() {
|
||||
const createBuildOrg = function createBuildOrg() {
|
||||
_.info('');
|
||||
_.action('### C R E A T E B U I L D O R G'); // REVIEWME: we may want to create org silently
|
||||
_.action('### C R E A T E B U I L D O R G A N I Z A T I O N'); // REVIEWME: we may want to create org silently
|
||||
|
||||
const createOrgCmd = new force.createOrg();
|
||||
|
||||
|
@ -242,19 +253,19 @@ const createBuildOrg = function pushSource() {
|
|||
_.info(`[DEBUG] CreateBuildOrg options: ${JSON.stringify(CREATE_ORG_CMD.flags)}`);
|
||||
}
|
||||
|
||||
_.info('Creating build org...');
|
||||
_.info('Creating build Organization..');
|
||||
const start = (new Date()).getTime();
|
||||
return createOrgCmd.validate(CREATE_ORG_CMD.flags)
|
||||
.bind(createOrgCmd)
|
||||
.then(createOrgCmd.execute)
|
||||
.then((result) => {
|
||||
_.info(`Create build org completed in ${_.toSec((new Date()).getTime() - start)}s`);
|
||||
_.info(`Create build Organization completed in ${_.toSec((new Date()).getTime() - start)}s`);
|
||||
|
||||
return evalResult(CREATE_ORG_CMD.name, result);
|
||||
})
|
||||
.then((result) => {
|
||||
if (VERBOSE) {
|
||||
_.info(`Created build org '${result.username}' [${result.orgId}]`);
|
||||
_.info(`Created build Organization '${result.username}' [${result.orgId}]`);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -266,7 +277,7 @@ const createBuildOrg = function pushSource() {
|
|||
};
|
||||
|
||||
// Push workspace source to workspace org
|
||||
const pushSource = function pushSource(targetOrg) {
|
||||
const pushSource = function pushSource(targetOrg, all) {
|
||||
_.info('');
|
||||
_.action('### P U S H');
|
||||
|
||||
|
@ -278,11 +289,16 @@ const pushSource = function pushSource(targetOrg) {
|
|||
PUSH_SOURCE_CMD.flags.targetname = targetOrg;
|
||||
}
|
||||
|
||||
if (all) {
|
||||
// if new org, push all source; if not new, push only what has changed
|
||||
PUSH_SOURCE_CMD.flags.all = true;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
_.info(`[DEBUG] Push options: ${JSON.stringify(PUSH_SOURCE_CMD.flags)}`);
|
||||
}
|
||||
|
||||
_.info(`Pushing workspace source to org '${PUSH_SOURCE_CMD.flags.targetname}'...`);
|
||||
_.info(`Pushing workspace source to Organization '${orgInstance}'...`);
|
||||
const start = (new Date()).getTime();
|
||||
return pushCmd.validate(PUSH_SOURCE_CMD.flags)
|
||||
.bind(pushCmd)
|
||||
|
@ -293,29 +309,36 @@ const pushSource = function pushSource(targetOrg) {
|
|||
return evalResult(PUSH_SOURCE_CMD.name, result);
|
||||
})
|
||||
.then((result) => {
|
||||
|
||||
|
||||
if (VERBOSE) {
|
||||
_.info(`Pushed source [${result.PushedSource.length}]:`);
|
||||
|
||||
result.PushedSource.sort((file1, file2) => {
|
||||
const field = file1.path ? 'path' : 'filePath';
|
||||
const fileName1 = file1[field].toUpperCase();
|
||||
const fileName2 = file2[field].toUpperCase();
|
||||
if (fileName1 < fileName2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fileName1 > fileName2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
const paths = [];
|
||||
result.PushedSource.forEach(file => {
|
||||
const field = file.path ? 'path' : 'filePath';
|
||||
paths.push(`${_.INDENT.LOG} ${file[field]}`);
|
||||
});
|
||||
if (result.PushedSource.length > 0) {
|
||||
result.PushedSource.sort((file1, file2) => {
|
||||
const field = file1.path ? 'path' : 'filePath';
|
||||
const fileName1 = file1[field].toUpperCase();
|
||||
const fileName2 = file2[field].toUpperCase();
|
||||
if (fileName1 < fileName2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fileName1 > fileName2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
|
||||
result.PushedSource.forEach(file => {
|
||||
const field = file.path ? 'path' : 'filePath';
|
||||
paths.push(`${_.INDENT.LOG} ${file[field]}`);
|
||||
});
|
||||
} else {
|
||||
paths.push(`${_.INDENT.LOG} No source changes detected`);
|
||||
}
|
||||
|
||||
console.log(paths.join('\n'));
|
||||
}
|
||||
|
@ -343,7 +366,7 @@ const retrieveZip = function retrieveZip(targetOrg) {
|
|||
_.info(`[DEBUG] Retrieve options: ${JSON.stringify(MDAPI_RETRIEVE_CMD.flags)}`);
|
||||
}
|
||||
|
||||
_.info(`Retrieving source metadata zip from org '${MDAPI_RETRIEVE_CMD.flags.targetname}'...`);
|
||||
_.info(`Retrieving source metadata zip from Organization '${MDAPI_RETRIEVE_CMD.flags.targetname}'...`);
|
||||
const start = (new Date()).getTime();
|
||||
return retrieveCmd.execute(MDAPI_RETRIEVE_CMD.flags)
|
||||
.then((result) => {
|
||||
|
@ -351,7 +374,6 @@ const retrieveZip = function retrieveZip(targetOrg) {
|
|||
return evalResult(MDAPI_RETRIEVE_CMD.name, result);
|
||||
})
|
||||
.then((result) => {
|
||||
_.info('');
|
||||
_.info(`Status: ${result.status}`);
|
||||
_.info(`Id: ${result.id}`);
|
||||
|
||||
|
@ -414,8 +436,6 @@ const retrieveZip = function retrieveZip(targetOrg) {
|
|||
console.error(problems.join('\n'));
|
||||
}
|
||||
|
||||
_.info('');
|
||||
|
||||
try {
|
||||
const stat = fs.statSync(result.zipFilePath);
|
||||
_.info(`Wrote retrieve zip to ${result.zipFilePath} (${_.toKb(stat.size)} KB)`);
|
||||
|
@ -449,7 +469,7 @@ const deploy = function deploy(addtlDeployOptions) {
|
|||
_.info(`[DEBUG] Deploy options: ${JSON.stringify(deployOptions)}`);
|
||||
}
|
||||
|
||||
_.info(`Deploying ${(addtlDeployOptions.deployroot ? 'source' : 'zip')} to org '${orgConfig.username}' at ${orgConfig.instanceUrl} (timeout: ${deployOptions.polltimeout}ms, interval: ${deployOptions.pollinterval}ms)...`);
|
||||
_.info(`Deploying ${(addtlDeployOptions.deployroot ? 'source' : 'zip')} to Organization '${orgInstance}' (timeout: ${deployOptions.polltimeout}ms, interval: ${deployOptions.pollinterval}ms)...`);
|
||||
|
||||
const start = (new Date()).getTime();
|
||||
return deployCmd.execute(deployOptions)
|
||||
|
@ -458,7 +478,6 @@ const deploy = function deploy(addtlDeployOptions) {
|
|||
return evalResult(MDAPI_DEPLOY_CMD.name, result);
|
||||
})
|
||||
.then((result) => {
|
||||
_.info('');
|
||||
_.action(`Status: ${result.status}`);
|
||||
_.info(`Id: ${result.id}`);
|
||||
_.info(`Completed: ${result.completedDate}`); // TODO: convert to locale
|
||||
|
@ -545,22 +564,24 @@ const compile = function compile() {
|
|||
return Promise.resolve()
|
||||
.then(() => {
|
||||
if (isByoo) {
|
||||
_.info('Found BYOO app.');
|
||||
if (DEBUG) {
|
||||
_.info('[DEBUG] Found Salesforce Production attached app');
|
||||
}
|
||||
|
||||
if (IS_SALESFORCE_WORKSPACE) {
|
||||
_.info('Found Force.com workspace project.');
|
||||
_.info('Generating deployment artifact...');
|
||||
_.info('Found Force.com workspace project');
|
||||
_.info('Generating deployment artifact..');
|
||||
|
||||
return prepareEnv()
|
||||
.then(writeHubConfig)
|
||||
.then(createBuildOrg)
|
||||
.then((result) => {
|
||||
if (!result && !result.username) {
|
||||
throw new Error('Expected org target');
|
||||
throw new Error('Expected Organization target');
|
||||
}
|
||||
|
||||
const targetName = result.username;
|
||||
return pushSource(targetName)
|
||||
return pushSource(targetName, true)
|
||||
.then(() => retrieveZip(targetName));
|
||||
})
|
||||
.then(() => {
|
||||
|
@ -579,17 +600,19 @@ const compile = function compile() {
|
|||
}
|
||||
|
||||
_.info('');
|
||||
_.action('Source zip deployment performed in release phase script or Procfile.');
|
||||
_.action('Source zip deployment performed in release phase script or Procfile');
|
||||
});
|
||||
} else {
|
||||
_.info('Found Force.com Metadata API project.');
|
||||
_.info('Found Force.com Metadata API project');
|
||||
_.info('');
|
||||
_.action('Source root deployment performed in release phase script or Procfile.');
|
||||
_.action('Source root deployment performed in release phase script or Procfile');
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
} else {
|
||||
_.info('Found Scratch Org app.');
|
||||
if (DEBUG) {
|
||||
_.info('[DEBUG] Found Review app');
|
||||
}
|
||||
|
||||
return prepareEnv()
|
||||
.then(pushSource);
|
||||
|
@ -609,7 +632,9 @@ const release = function release() {
|
|||
return Promise.resolve()
|
||||
.then(() => {
|
||||
if (isByoo) {
|
||||
_.info('Found BYOO app.');
|
||||
if (DEBUG) {
|
||||
_.info('[DEBUG] Found Salesforce Production attached app');
|
||||
}
|
||||
|
||||
let stats;
|
||||
try {
|
||||
|
@ -628,18 +653,20 @@ const release = function release() {
|
|||
return prepareEnv()
|
||||
.then(() => deploy({ zipfile: DEPLOY_ZIP_FILEPATH }));
|
||||
} else {
|
||||
_.info('Found Scratch Org app.');
|
||||
if (DEBUG) {
|
||||
_.info('[DEBUG] Found Review app');
|
||||
}
|
||||
|
||||
return writeOrgConfig()
|
||||
.then(writeHubConfig)
|
||||
.then(() => {
|
||||
if (IS_SALESFORCE_WORKSPACE) {
|
||||
_.info('Found Force.com workspace project.');
|
||||
_.info('Source pushed in compile phase.');
|
||||
_.info('Found Force.com workspace project');
|
||||
_.info('Source pushed in compile phase');
|
||||
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
_.info('Found Force.com Metadata API project.');
|
||||
_.info('Found Force.com Metadata API project');
|
||||
|
||||
// REVIEWME: project root should come from config var
|
||||
return deploy({
|
||||
|
@ -654,12 +681,12 @@ const release = function release() {
|
|||
/**
|
||||
* Setup.
|
||||
*
|
||||
* Setups env to invoke AppCloud and Force CLI plugin commands.
|
||||
* Setups env to invoke Salesforce and Force CLI plugin commands.
|
||||
*
|
||||
* @returns {Promise.<TResult>}
|
||||
*/
|
||||
const setup = function setup() {
|
||||
_.info('Setting up environment for AppCloud and Force CLI plugin commands.');
|
||||
_.info('Setting up environment for Salesforce plugin commands');
|
||||
return writeHubConfig(false)
|
||||
.then(writeOrgConfig);
|
||||
};
|
||||
|
@ -686,7 +713,7 @@ const main = function main() {
|
|||
|
||||
// since Review apps inherit from parent app and may have SALESFORCE_BYOO=true, let's
|
||||
// double-check that this isn't a Review app and if it is, set isByoo to false to
|
||||
// signal that we'll AppCloud push to org (instead of mdAPI deploy)
|
||||
// signal that we'll Salesforce push to org (instead of mdAPI deploy)
|
||||
isByoo = isByoo && PREVIEW_APP_NAME_REGEX.exec(HEROKU_APP_NAME) !== null ? false : isByoo;
|
||||
|
||||
switch (invoke) {
|
||||
|
|
62
lib/node.sh
62
lib/node.sh
|
@ -1,49 +1,51 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
create_signature() {
|
||||
if hash node 2>/dev/null; then
|
||||
echo "$(node --version)"
|
||||
else
|
||||
echo "missing node"
|
||||
fi
|
||||
if [ -f $1/node ]; then
|
||||
echo "$($1/node --version)"
|
||||
else
|
||||
echo "node missing"
|
||||
fi
|
||||
}
|
||||
|
||||
save_signature() {
|
||||
local sig_file="$1/signature"
|
||||
echo "$(create_signature)" > $sig_file
|
||||
local sig_file="$1/signature"
|
||||
echo "$(create_signature $1/bin)" > $sig_file
|
||||
}
|
||||
|
||||
load_signature() {
|
||||
local sig_file="$1/signature"
|
||||
if test -f $sig_file; then
|
||||
cat $sig_file
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
local sig_file="$1/signature"
|
||||
if test -f $sig_file; then
|
||||
cat $sig_file
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# Get the node binary from Heroku. Similar to how Heroku does it but
|
||||
# without package.json resolution for the node version, since we only need
|
||||
# to install node to make this build pack work, not to support customer
|
||||
# to install node to make this buildpack work, not to support customer
|
||||
# node scripts. See the following for reference
|
||||
#
|
||||
# Referenced from https://github.com/heroku/heroku-buildpack-nodejs/blob/master/lib/binaries.sh
|
||||
install_nodejs() {
|
||||
local dir="$1/node"
|
||||
local version=6.2.2
|
||||
local version_str="v$version-$(get_os)-$(get_cpu)"
|
||||
local dir="$1/node"
|
||||
|
||||
if [ "$(create_signature)" != "$(load_signature $dir)" ]; then
|
||||
status "Downloading and installing node $version..."
|
||||
mkdir -p "$dir"
|
||||
local download_url="https://s3pository.heroku.com/node/v$version/node-$version_str.tar.gz"
|
||||
curl "$download_url" --silent --fail --retry 5 --retry-max-time 15 -o /tmp/node.tar.gz || (echo "Unable to download node $version; does it exist?" && false)
|
||||
tar xzf /tmp/node.tar.gz -C /tmp
|
||||
rm -rf $dir/*
|
||||
mv /tmp/node-$version_str/* $dir
|
||||
chmod +x $dir/bin/*
|
||||
save_signature $dir
|
||||
else
|
||||
status "Using cached node version $version..."
|
||||
fi
|
||||
# TODO: get version from salesforce-alm package.json
|
||||
local version=${SALESFORCE_NODEJS_VERSION:-6.5.0}
|
||||
local version_str="v$version-$(get_os)-$(get_cpu)"
|
||||
|
||||
if [ "$(create_signature $dir/bin)" != "$(load_signature $dir)" ]; then
|
||||
status "Downloading and installing node $version..."
|
||||
mkdir -p "$dir"
|
||||
local download_url="https://s3pository.heroku.com/node/v$version/node-$version_str.tar.gz"
|
||||
curl "$download_url" --silent --fail --retry 5 --retry-max-time 15 -o /tmp/node.tar.gz || (echo "Unable to download node $version; does it exist?" && false)
|
||||
tar xzf /tmp/node.tar.gz -C /tmp
|
||||
rm -rf $dir/*
|
||||
mv /tmp/node-$version_str/* $dir
|
||||
chmod +x $dir/bin/*
|
||||
save_signature $dir
|
||||
else
|
||||
status "Using cached node version $version..."
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "force-com-buildpack",
|
||||
"name": "salesforce-buildpack",
|
||||
"version": "1.0.0",
|
||||
"description": "Buildpack for Force.com source",
|
||||
"repository": {
|
||||
|
@ -14,8 +14,7 @@
|
|||
"homepage": "https://github.com/heroku/salesforce-buildpack#readme",
|
||||
"dependencies": {
|
||||
"bluebird": "3.4.0",
|
||||
"express": "2.5.x",
|
||||
"salesforce-alm-buildpack-dev": "0.2.3"
|
||||
"salesforce-alm-buildpack-dev": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^3.4.0",
|
||||
|
|
Загрузка…
Ссылка в новой задаче