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:
Chris Wall 2016-10-11 16:46:01 -05:00
Родитель 5749bb588f
Коммит fb5959545f
4 изменённых файлов: 209 добавлений и 160 удалений

Просмотреть файл

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

Просмотреть файл

@ -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) {

Просмотреть файл

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