231 строка
8.2 KiB
JavaScript
231 строка
8.2 KiB
JavaScript
const async = require('async');
|
|
const pgp = require('pg-promise')();
|
|
const dbUrl = require('url');
|
|
const exec = require('child-process-promise').exec;
|
|
|
|
const dbParams = dbUrl.parse(process.env.DATABASE_URL);
|
|
const auth = dbParams.auth.split(':');
|
|
|
|
const config = {
|
|
host: dbParams.hostname,
|
|
port: dbParams.port,
|
|
user: auth[0],
|
|
ssl: true,
|
|
password: auth[1],
|
|
database: dbParams.pathname.split('/')[1],
|
|
idleTimeoutMillis: 1000,
|
|
max: 10
|
|
};
|
|
|
|
const db = pgp(config);
|
|
|
|
function setNewStage(settings, stage) {
|
|
settings.stage = stage;
|
|
return settings;
|
|
}
|
|
|
|
function deploymentStage(settings, complete = false) {
|
|
|
|
let scratchOrgUrlSql = '';
|
|
if (complete) {
|
|
scratchOrgUrlSql = `, scratch_url = '${settings.scratchOrgUrl}'`;
|
|
}
|
|
|
|
const updateQuery = `UPDATE deployments SET stage = '${settings.stage}', complete = ${complete}${scratchOrgUrlSql} WHERE guid = '${settings.guid}'`;
|
|
db.any(updateQuery, [true]);
|
|
return settings;
|
|
}
|
|
|
|
function deploymentSteps(settings) {
|
|
|
|
const message = settings.message.replace("'", "''");
|
|
const insertQuery = `INSERT INTO deployment_steps (guid, stage, message) VALUES ('${settings.guid}', '${settings.stage}', '${message}')`;
|
|
db.any(insertQuery, [true]);
|
|
return settings;
|
|
}
|
|
|
|
function deploymentError(guid, message) {
|
|
|
|
message = message.replace(/'/g, "''");
|
|
|
|
const insertQuery = `INSERT INTO deployment_steps (guid, stage, message) VALUES ('${guid}', 'error', '${message}')`;
|
|
db.any(insertQuery, [true]);
|
|
|
|
const updateQuery = `UPDATE deployments SET stage = 'error', error_message ='${message}', complete = true WHERE guid = '${guid}'`;
|
|
db.any(updateQuery, [true]);
|
|
}
|
|
|
|
function formatMessage(settings) {
|
|
|
|
let message = '';
|
|
|
|
if (settings.stderr) {
|
|
|
|
message = `Error: ${settings.stderr}.`;
|
|
|
|
if (settings.stderr.indexOf('Flag --permsetname expects a value') > -1) {
|
|
message = 'No permset specified.';
|
|
} else {
|
|
throw new Error(`GUID: ${settings.guid} ${settings.stderr}`);
|
|
}
|
|
|
|
} else {
|
|
message = `${settings.stdout}.`;
|
|
|
|
if (settings.stage === 'clone') {
|
|
message = `Successfully cloned ${settings.githubRepo}.`;
|
|
}
|
|
if (settings.stage === 'instanceUrl') {
|
|
message = `Set instance url to ${settings.instance_url}.`;
|
|
}
|
|
if (settings.stage === 'push') {
|
|
message = `Pushed ${settings.stdout} source files.`;
|
|
}
|
|
if (settings.stage === 'permset') {
|
|
if (!settings.assignPermset) {
|
|
message = 'No permset specified.';
|
|
} else {
|
|
message = `Permset '${settings.permsetName}' assigned.`;
|
|
}
|
|
}
|
|
if (settings.stage === 'test') {
|
|
if (settings.stdout !== '') {
|
|
message = `Apex tests: ${settings.stdout}.`;
|
|
}
|
|
else {
|
|
message = 'No Apex tests.';
|
|
}
|
|
}
|
|
if (settings.stage === 'url') {
|
|
settings.scratchOrgUrl = settings.stdout;
|
|
message = `Scratch org URL: ${settings.scratchOrgUrl}.`;
|
|
}
|
|
}
|
|
|
|
settings.stderr = '';
|
|
|
|
console.log('message', settings.stage, message);
|
|
settings.message = message;
|
|
return settings;
|
|
}
|
|
|
|
function executeScript(settings, script) {
|
|
return new Promise((resolve) => {
|
|
exec(script, (error, stdout, stderr) => {
|
|
|
|
if (stderr && error) {
|
|
settings.stderr = stderr.replace(/\r?\n|\r/, '').trim();
|
|
}
|
|
settings.stdout = stdout.replace(/\r?\n|\r/, '').trim();
|
|
|
|
resolve(settings);
|
|
});
|
|
});
|
|
}
|
|
|
|
// check for anything at init
|
|
async.whilst(
|
|
() => true,
|
|
(callback) => {
|
|
|
|
const selectQuery = "SELECT guid, username, repo, settings FROM deployments WHERE stage = 'init' AND complete = false LIMIT 1";
|
|
let guid = '';
|
|
|
|
db.any(selectQuery, [true])
|
|
.then((data) => {
|
|
|
|
// throw if no data to skip the subsequent promises
|
|
if (data.length === 0) {
|
|
throw new Error('norecords');
|
|
}
|
|
|
|
const settings = JSON.parse(data[0].settings);
|
|
|
|
settings.guid = data[0].guid;
|
|
guid = settings.guid;
|
|
|
|
console.log('found job', guid);
|
|
|
|
settings.tokenName = settings.access_token.replace(/\W/g, '');
|
|
settings.startingDirectory = process.env.STARTINGDIRECTORY;
|
|
settings.directory = `${settings.tokenName}-${settings.guid}`;
|
|
|
|
settings.cloneScript = `${settings.startingDirectory}rm -rf ${settings.directory};mkdir ${settings.directory};cd ${settings.directory};git clone ${settings.githubRepo} .`;
|
|
settings.instanceUrlScript = `${settings.startingDirectory}cd ${settings.directory};export FORCE_SHOW_SPINNER=;sfdx force:config:set instanceUrl=${settings.instance_url};`;
|
|
settings.createScript = `${settings.startingDirectory}cd ${settings.directory};export FORCE_SHOW_SPINNER=;sfdx force:org:create -v '${settings.access_token}' -s -f ${settings.scratchOrgDef}`;
|
|
settings.pushScript = `${settings.startingDirectory}cd ${settings.directory};export FORCE_SHOW_SPINNER=;sfdx force:source:push --json | jq '.result.pushedSource | length'`;
|
|
settings.permSetScript = `${settings.startingDirectory}cd ${settings.directory};export FORCE_SHOW_SPINNER=;sfdx force:user:permset:assign -n ${settings.permsetName}`;
|
|
settings.testScript = `${settings.startingDirectory}cd ${settings.directory};export FORCE_SHOW_SPINNER=;sfdx force:apex:test:run -r human --json | jq -r .result | jq -r .summary | jq -r .outcome`;
|
|
settings.urlScript = `${settings.startingDirectory}cd ${settings.directory};export FORCE_SHOW_SPINNER=;echo $(sfdx force:org:display --json | jq -r .result.instanceUrl)"/secur/frontdoor.jsp?sid="$(sfdx force:org:display --json | jq -r .result.accessToken)`;
|
|
settings.scratchOrgUrl = '';
|
|
settings.stderr = '';
|
|
settings.stdout = '';
|
|
|
|
return settings;
|
|
})
|
|
// clone
|
|
.then(settings => setNewStage(settings, 'clone'))
|
|
.then(settings => deploymentStage(settings))
|
|
.then(settings => executeScript(settings, settings.cloneScript))
|
|
.then(settings => formatMessage(settings))
|
|
.then(settings => deploymentSteps(settings))
|
|
// instanceUrl
|
|
.then(settings => setNewStage(settings, 'instanceUrl'))
|
|
.then(settings => deploymentStage(settings))
|
|
.then(settings => executeScript(settings, settings.instanceUrlScript))
|
|
.then(settings => formatMessage(settings))
|
|
.then(settings => deploymentSteps(settings))
|
|
// create
|
|
.then(settings => setNewStage(settings, 'create'))
|
|
.then(settings => deploymentStage(settings))
|
|
.then(settings => executeScript(settings, settings.createScript))
|
|
.then(settings => formatMessage(settings))
|
|
.then(settings => deploymentSteps(settings))
|
|
// push
|
|
.then(settings => setNewStage(settings, 'push'))
|
|
.then(settings => deploymentStage(settings))
|
|
.then(settings => executeScript(settings, settings.pushScript))
|
|
.then(settings => formatMessage(settings))
|
|
.then(settings => deploymentSteps(settings))
|
|
// permset
|
|
.then(settings => setNewStage(settings, 'permset'))
|
|
.then(settings => deploymentStage(settings))
|
|
.then(settings => executeScript(settings, settings.permSetScript))
|
|
.then(settings => formatMessage(settings))
|
|
.then(settings => deploymentSteps(settings))
|
|
// test
|
|
.then(settings => setNewStage(settings, 'test'))
|
|
.then(settings => deploymentStage(settings))
|
|
.then(settings => executeScript(settings, settings.testScript))
|
|
.then(settings => formatMessage(settings))
|
|
.then(settings => deploymentSteps(settings))
|
|
// url
|
|
.then(settings => setNewStage(settings, 'url'))
|
|
.then(settings => deploymentStage(settings))
|
|
.then(settings => executeScript(settings, settings.urlScript))
|
|
.then(settings => formatMessage(settings))
|
|
.then(settings => deploymentSteps(settings))
|
|
// completed
|
|
.then(settings => setNewStage(settings, 'complete'))
|
|
.then(settings => deploymentStage(settings, true))
|
|
.then((settings) => {
|
|
console.log('finished job', settings.guid);
|
|
})
|
|
.catch((error) => {
|
|
// handles cases where there are no records
|
|
if (error.message !== 'norecords') {
|
|
console.error('guid', guid);
|
|
console.error('error', error);
|
|
|
|
deploymentError(guid, error.message);
|
|
}
|
|
});
|
|
|
|
setTimeout(() => {
|
|
callback(null, true);
|
|
}, 3000);
|
|
},
|
|
(err) => {
|
|
console.error(`err: ${err}`);
|
|
}
|
|
); |