This repository has been archived by the owner on Jan 28, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deploy support for non-scratch orgs (app name not *pr* or SALESFORCE_USE_MDAPI_DEPLOY=true)
- Loading branch information
Showing
1 changed file
with
84 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,20 +31,37 @@ const SFDX_DEV_HUB_AUTH_URL_CONFIG_VAR_NAME = 'SFDX_DEV_HUB_AUTH_URL'; | |
// force://${clientId}:${clientSecret}:${refreshToken}@${instanceUrl} | ||
const SFDX_AUTH_URL_REGEX = /^force:\/\/(?:(\w*):(\w*):)?([\w.]*)@([\w@:/\-.]*)$/; | ||
const PREVIEW_APP_NAME_REGEX = /-pr-\d+$/; | ||
// mdapi | ||
const USE_MDAPI_DEPLOY = utils.getEnvVarValue('SALESFORCE_USE_MDAPI_DEPLOY', false, false, true); | ||
|
||
const METADATA_API_SOURCE_DIR = `.cache${path.sep}mdapi-source`; | ||
const WORKSPACE_ORG = '[email protected]'; | ||
const DEV_HUB_ORG = '[email protected]'; | ||
|
||
// Push source options | ||
const PUSH_SOURCE_OPTIONS = { | ||
// Deploy options | ||
polltimeout: parseInt(utils.getEnvVarValue('SALESFORCE_DEPLOY_POLL_TIMEOUT_MS', false, 180 * 1000 /* 3 min */)), | ||
polltimeout: parseInt(utils.getEnvVarValue('SALESFORCE_DEPLOY_POLL_TIMEOUT_MS', false, 10 * 60 * 1000 /* 10 min */)), | ||
pollinterval: parseInt(utils.getEnvVarValue('SALESFORCE_DEPLOY_POLL_INTERVAL_MS', false, 10 * 1000 /* 10 sec */)), | ||
// API options | ||
targetusername: WORKSPACE_ORG, | ||
force: true, | ||
wait: parseInt(utils.getEnvVarValue('SALESFORCE_DEPLOY_POLL_TIMEOUT_MS', false, 10 * 60 * 1000 /* 10 min */)), | ||
verbose: VERBOSE, | ||
json: true | ||
}; | ||
|
||
// Deploy options | ||
const DEPLOY_SOURCE_OPTIONS = { | ||
// mdapi options | ||
polltimeout: parseInt(utils.getEnvVarValue('SALESFORCE_DEPLOY_POLL_TIMEOUT_MS', false, 10 * 60 * 1000 /* 10 min */)), | ||
pollinterval: parseInt(utils.getEnvVarValue('SALESFORCE_DEPLOY_POLL_INTERVAL_MS', false, 10 * 1000 /* 10 sec */)), | ||
runtests: utils.getEnvVarValue('SALESFORCE_DEPLOY_RUNTESTS', false, undefined), | ||
testlevel: utils.getEnvVarValue('SALESFORCE_DEPLOY_TESTLEVEL', false, undefined), | ||
rollbackonerror: utils.getEnvVarValue('SALESFORCE_DEPLOY_ROLLBACK_ON_ERROR', false, undefined), | ||
// API option | ||
// API options | ||
deploydir: METADATA_API_SOURCE_DIR, | ||
targetusername: WORKSPACE_ORG, | ||
wait: parseInt(utils.getEnvVarValue('SALESFORCE_DEPLOY_POLL_TIMEOUT_MS', false, 10 * 60 * 1000 /* 10 min */)), | ||
verbose: VERBOSE, | ||
json: true | ||
}; | ||
|
@@ -118,7 +135,7 @@ const auth = function auth(authUrl, defaultFlag, alias) { | |
flags[defaultFlag] = true; | ||
} | ||
const authApi = new force.authApi(); | ||
return authApi.execute(flags) | ||
return authApi.execute(flags) | ||
.catch((err) => { | ||
throw err; | ||
}); | ||
|
@@ -134,15 +151,9 @@ const pushSource = function pushSource(targetUsername = WORKSPACE_ORG) { | |
PUSH_SOURCE_OPTIONS.targetusername = targetUsername; | ||
} | ||
|
||
if (PREVIEW_APP_NAME_REGEX.exec(HEROKU_APP_NAME) === null) { | ||
// if standard org (Sandbox or Production, push all source; if not new (Review app), push only what has changed | ||
PUSH_SOURCE_OPTIONS.all = true; | ||
} else { | ||
// TODO: enable when Review app push-only-changed is supported | ||
// utils.info('Found Review app: will push only what has changed since previous push'); | ||
} | ||
|
||
if (DEBUG) { | ||
PUSH_SOURCE_OPTIONS.loglevel = 'debug'; | ||
|
||
utils.info(`[DEBUG] Push options: ${JSON.stringify(PUSH_SOURCE_OPTIONS)}`); | ||
} | ||
|
||
|
@@ -171,6 +182,62 @@ const pushSource = function pushSource(targetUsername = WORKSPACE_ORG) { | |
}); | ||
}; | ||
|
||
// Convert workspace source to Metadata API format, Metadata API then deploy to org | ||
const deploySource = function deploySource(targetUsername = WORKSPACE_ORG) { | ||
utils.info(''); | ||
utils.action('### D E P L O Y S O U R C E'); | ||
|
||
if (targetUsername) { | ||
// set target org to which we'll push; targetOrg must reference ~/.sfdx config file | ||
DEPLOY_SOURCE_OPTIONS.targetusername = targetUsername; | ||
} | ||
|
||
if (DEBUG) { | ||
DEPLOY_SOURCE_OPTIONS.loglevel = 'debug'; | ||
|
||
utils.info(`[DEBUG] Deploy options: ${JSON.stringify(DEPLOY_SOURCE_OPTIONS)}`); | ||
} | ||
|
||
const sourceConvertApi = new force.sourceConvertApi(); | ||
const orgPromise = force.orgApi.create(WORKSPACE_ORG, force.orgApi.Defaults.USERNAME); | ||
|
||
const start = (new Date()).getTime(); | ||
return orgPromise | ||
.then(() => sourceConvertApi.validate({ outputdir: METADATA_API_SOURCE_DIR, json: true })) | ||
.bind(sourceConvertApi) | ||
.then(sourceConvertApi.execute) | ||
.then(() => { | ||
if (DEBUG) { | ||
utils.info(`[DEBUG] Converted workspace source to Metadata API source: ${METADATA_API_SOURCE_DIR}`); | ||
} | ||
|
||
utils.info(`Deploying source to Organization '${getOrgInstance()}'...`); | ||
const mdapiDeployApi = new force.mdapiDeployApi(orgPromise.value()); | ||
return mdapiDeployApi.validate({ flags: DEPLOY_SOURCE_OPTIONS }) | ||
.then((options) => mdapiDeployApi.deploy(options)) | ||
.catch((err) => { | ||
throw err; | ||
}); | ||
}) | ||
.then((result) => { | ||
utils.info(`Deploy completed in ${utils.toSec((new Date()).getTime() - start)}s`); | ||
|
||
if (!result || result === null) { | ||
throw new Error('No result from deploy operation'); | ||
} | ||
|
||
if (result.status && result.status === 'error') { | ||
throw new Error(result); | ||
} | ||
|
||
return Promise.resolve(result); | ||
}) | ||
.catch((err) => { | ||
utils.error(`Deploy failed: ${err.message}`); | ||
throw err; | ||
}); | ||
}; | ||
|
||
/** | ||
* Setup. | ||
* | ||
|
@@ -191,7 +258,8 @@ const setupEnv = function setupEnv() { | |
* @returns {Promise.<TResult>} | ||
*/ | ||
const release = function release() { | ||
return pushSource(); | ||
const shouldDeploy = PREVIEW_APP_NAME_REGEX.exec(HEROKU_APP_NAME) === null || USE_MDAPI_DEPLOY; | ||
return shouldDeploy ? deploySource() : pushSource(); | ||
}; | ||
|
||
/** | ||
|
@@ -202,13 +270,13 @@ const release = function release() { | |
const redirect = function redirect() { | ||
utils.info(''); | ||
utils.action('### R E D I R E C T T O S A L E S F O R C E O R G A N I Z A T I O N'); | ||
|
||
const startUrl = process.env.SALESFORCE_START_URL || '/one/one.app'; | ||
const app = express(); | ||
|
||
const port = process.env.PORT || 5000; | ||
app.set('port', port); | ||
|
||
utils.info(`Will redirect requests to ${startUrl}`); | ||
|
||
app.get('*', (request, response) => { | ||
|
@@ -276,4 +344,4 @@ const main = function main() { | |
}; | ||
|
||
// go!!!! | ||
main(); | ||
main(); |