10000 Feature of destruct metadata by xgeek-net · Pull Request #8 · xgeek-net/pipeline · GitHub
[go: up one dir, main page]

Skip to content

Feature of destruct metadata #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 22, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add destruct metadata feature
  • Loading branch information
xgeek-net committed Oct 21, 2018
commit 4a44579edbfd2b4eb435b52fb7e61aed4684259e
44 changes: 41 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "pipeline",
"description": "Be less busy, less mistake in Salesforce metadata deploy",
"version": "1.0.1",
"version": "1.1.0",
"private": false,
"main": "src/main.js",
"dependencies": {
Expand All @@ -21,7 +21,8 @@
"rimraf": "^2.6.2",
"sfdc-generate-package": "^2.2.1",
"url": "^0.11.0",
"uuid": "^3.3.2"
"uuid": "^3.3.2",
"xmlbuilder": "^10.1.0"
},
"keywords": [
"Pipeline",
Expand Down
37 changes: 36 additions & 1 deletion src/class/Metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ const fs = require('fs');
const path = require('path');
const makeDir = require('make-dir');
const rimraf = require('rimraf');
const xmlbuilder = require('xmlbuilder');
const archiver = require('archiver');
const sgp = require('sfdc-generate-package');

const SfdcApi = require('./SfdcApi.js');
const Connect = require('./Connect.js');

const PACKAGE_XML_FILE_NAME = 'package.xml';
const DESTRUCTIVE_XML_FILE_NAME = 'destructiveChanges.xml';

class Metadata {
constructor(opts) {

Expand Down Expand Up @@ -108,6 +112,37 @@ class Metadata {
});
}

/**
* Generate package.xml and destructiveChanges.xml for Destruct
* @param {String} metaPath - pipeline cache path
*/
createDestructiveChanges(targetPath, opts) {
opts = opts || {};
const metaPath = path.join(targetPath, 'metadata', 'src');

return new Promise(function(resolve, reject) {
// Rename to destructiveChanges.xml
fs.renameSync(metaPath + '/' + PACKAGE_XML_FILE_NAME, metaPath + '/' + DESTRUCTIVE_XML_FILE_NAME);
// Generate blank package.xml
const xml = xmlbuilder.create('Package')
.att('xmlns', 'http://soap.sforce.com/2006/04/metadata')
.dec('1.0', 'UTF-8')
.ele('version')
.t(opts.version || '40.0');
const xmlContent = xml.end({ pretty: true, indent: ' ', newline: '\n' });
fs.writeFileSync(metaPath + '/' + PACKAGE_XML_FILE_NAME, xmlContent);

// Remove metadata files
fs.readdirSync(metaPath).filter(function (file) {
if(fs.statSync(metaPath+'/'+file).isDirectory()) {
rimraf.sync(metaPath+'/'+file);
}
return resolve();
});
});

}

/**
* Archive metadata package zip
* @param {String} targetPath (zip file root path('output/' )
Expand Down Expand Up @@ -161,7 +196,7 @@ class Metadata {
})
.catch(function(err){
return reject(err);
})
});
});
}

Expand Down
34 changes: 28 additions & 6 deletions src/class/Pipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,32 +254,54 @@ class Pipeline {
// Refresh Token for bitbucket
connect.restoreToken(fromConn, token);
}
if(pipeline.action == 'destruct') {
// Destruct metadata
return Promise.resolve(true);
}
return metadata.checkConnect(toConn);
})
.then(function(success) {
pipelineLog('[SF.api] Authorize : ' + success);
return client.getFiles(pipeline, fromConn, pipelineLog);
//return Promise.resolve(true);
})
.then(function(success) {
// Generate package.xml file
return metadata.createPackageXml(pPath, { version : pipeline.toApiVersion });
})
.then(function() {
if(pipeline.action == 'destruct') {
// Generate destructiveChanges.xml, package.xml files
return metadata.createDestructiveChanges(pPath, { version : pipeline.toApiVersion });
}
return Promise.resolve(true);
})
.then(function() {
pipelineLog('[Metadata] Generate package.xml Done.');
// Zip Metadata
return metadata.archive(pPath);
})
.then(function(zipPath) {
// Do Deploy
// opts @see https://jsforce.github.io/jsforce/doc/Metadata.html#deploy
let opts = { rollbackOnError : true, runAllTests : (pipeline.runTests === true) };
return metadata.deploy(toConn, zipPath, opts, function(deployResult) {
self.outputDeployProcessLog(pipelineLog, deployResult);
});
let opts = { rollbackOnError : true };
if(pipeline.action == 'destruct') {
// Do Destruct
opts['purgeOnDelete'] = true;
return metadata.deploy(fromConn, zipPath, opts, function(deployResult) {
self.outputDeployProcessLog(pipelineLog, deployResult);
});
} else {
// Do Deploy
opts['runAllTests'] = (pipeline.runTests === true);
return metadata.deploy(toConn, zipPath, opts, function(deployResult) {
self.outputDeployProcessLog(pipelineLog, deployResult);
});
}
})
.then(function(deployResult) {
// Save deploy result
deployResult['url'] = toConn.instanceUrl + '/changemgmt/monitorDeploymentsDetails.apexp?asyncId=' + deployResult.id
const targetConn = (pipeline.action == 'destruct') ? fromConn : toConn;
deployResult['url'] = targetConn.instanceUrl + '/changemgmt/monitorDeploymentsDetails.apexp?asyncId=' + deployResult.id
self.outputDeployLog(pipelineLog, deployResult);
const now = new Date();
const endTime = now.toISOString();
Expand Down
18 changes: 10 additions & 8 deletions src/view/js/vue-components/app-newpipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ Vue.component('app-newpipeline', {
fromApiVersion : '',
to : '',
toApiVersion : '',
action : 'deploy',
runTests : false
},
validate : false,
connection : null,
actionList : [ {value : 'deploy', label : 'Deploy (Add/Update)'}, {value : 'destruct', label : 'Destruct (Delete)'} ],
apiVersionList : []
}
},
Expand All @@ -34,7 +36,7 @@ Vue.component('app-newpipeline', {
},
methods: {
reload : function() {
this.pipeline = { from : '', fromApiVersion : '', to : '', toApiVersion : '', runTests : false };
this.pipeline = { from : '', fromApiVersion : '', to : '', toApiVersion : '', action : 'deploy', runTests : false };
this.validate = false;
this.connection = null;
this.initApiVerList();
Expand Down Expand Up @@ -103,6 +105,7 @@ Vue.component('app-newpipeline', {
pipeline['to'] = self.pipeline.to;
pipeline['toApiVersion'] = self.pipeline.toApiVersion;
pipeline['fromApiVersion'] = self.pipeline.fromApiVersion;
pipeline['action'] = self.pipeline.action;
pipeline['runTests'] = self.pipeline.runTests;
pipeline['status'] = 'ready';
pipeline['created_at'] = now.toISOString();
Expand Down Expand Up @@ -149,7 +152,7 @@ Vue.component('app-newpipeline', {
if(!pipeline.from || pipeline.from.length == 0) {
return 'CONNECTION (FROM) is required';
}
if(!pipeline.to || pipeline.to.length == 0) {
if(pipeline.action != 'destruct' && (!pipeline.to || pipeline.to.length == 0)) {
return 'CONNECTION (TO) is required';
}
if(!pipeline.name || pipeline.name.length == 0) {
Expand Down Expand Up @@ -222,9 +225,8 @@ Vue.component('app-newpipeline', {
</label>
<div class="slds-form-element__control slds-size_4-of-12">
<div class="slds-select_container">
<select class="slds-select" disabled="disabled">
<option value="deploy">Deploy (Add/Update)</option>
<option value="destruct">Destruct (Delete)</option>
<select class="slds-select" v-model="pipeline.action">
<option v-for="act in actionList" v-bind:value="act.value" v-bind:seleced="pipeline.action==act.value">{{ act.label }}</option>
</select>
</div>
</div>
Expand All @@ -233,12 +235,12 @@ Vue.component('app-newpipeline', {
<footer class="slds-card__footer"></footer>
</article>
</div><!-- .slds-size_5-of-12 -->
<div class="new-pipeline-connect-icon mt4">
<div class="new-pipeline-connect-icon mt4" v-if="pipeline.action!='destruct'">
<div class="slds-align_absolute-center">
<span class="pipeline-from-icon"><i class="fas fa-arrow-right"></i></span>
</div>
</div><!-- .slds-size_1-of-12 -->
<div class="new-pipeline-connect">
<div class="new-pipeline-connect" v-if="pipeline.action!='destruct'">
<article class="slds-card ">
<div class="slds-card__header slds-grid">
<div class="slds-media__figure">
Expand Down Expand Up @@ -302,7 +304,7 @@ Vue.component('app-newpipeline', {
<div class="slds-size_12-of-12 mt1" v-if="validate==true">
<div class="slds-wrap slds-text-align_right">
<button class="slds-button slds-button_neutral" v-on:click="savePipeline">Save</button>
<button class="slds-button slds-button_brand" v-on:click="runPipeline">Run Pipeline</button>
<button class="slds-button" v-bind:class="{'slds-button_brand': pipeline.action!='destruct', 'slds-button_destructive': pipeline.action=='destruct'}" v-on:click="runPipeline">Run Pipeline</button>
</div>
</div><!-- .slds-size_11-of-12 -->
</div><!-- #pipeline-new -->
Expand Down
0