Created
December 22, 2017 05:29
-
-
Save j-fischer/af781d18550c6b5b12730456cf4ddaab to your computer and use it in GitHub Desktop.
Sample Gruntfile and batch script to work with SFDX Projects
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
module.exports = function (grunt) { | |
// load all grunt tasks needed for this run | |
require('jit-grunt')(grunt); | |
// configurable paths | |
var config = { | |
module: 'force-app', | |
src: 'force-app/main/default', | |
test: 'force-app/test/default', | |
bundles: 'resource-bundles', | |
artifacts: { | |
build: '.tmp/build', | |
buildSrc: '.tmp/build/src', | |
jsdoc: '.tmp/docs', | |
root: '.tmp' | |
}, | |
git: { | |
enabled: false, | |
commitMessage: "DEV - Changes detected by the automated Salesforce org export" | |
}, | |
deployWaitTime: 10, | |
}; | |
grunt.initConfig({ | |
config: config, | |
env: process.env, | |
prompt: { | |
sfdcAlias: { | |
options: { | |
questions: [ | |
{ | |
config: 'env.SFALIAS', | |
type: 'input', | |
message: 'Salesforce DX Alias?', | |
when: function() { | |
if (grunt.config('env.SFALIAS')) { | |
grunt.log.ok('Using alias: ' + grunt.config('env.SFALIAS')); | |
return false; | |
} | |
return true; | |
} | |
}, | |
] | |
} | |
}, | |
sfdcPackage: { | |
options: { | |
questions: [ | |
{ | |
config: 'env.SFPACKAGE', | |
type: 'input', | |
message: 'Salesforce Package Name?', | |
when: function() { | |
return !grunt.config('env.SFPACKAGE'); | |
} | |
}, | |
] | |
} | |
}, | |
}, | |
clean: { | |
options: { | |
force: true | |
}, | |
artifacts: '<%= config.artifacts.root %>', | |
profiles: '<%= config.artifacts.build %>/profiles' | |
}, | |
mkdir: { | |
build: { | |
options: { | |
create: ['<%= config.artifacts.build %>'] | |
} | |
} | |
}, | |
todo: { | |
options: { | |
marks: [ | |
{ | |
name: "FIX", | |
pattern: /FIXME/, | |
color: "red" | |
}, | |
{ | |
name: "TODO", | |
pattern: /TODO/, | |
color: "yellow" | |
} | |
] | |
}, | |
src: [ | |
'*/<%= config.module %>/**/*.cls', | |
'*/<%= config.module %>/**/*.page', | |
'*/<%= config.bundles %>/**/*.js', | |
'*/<%= config.bundles %>/**/*.css', | |
'!*/<%= config.bundles %>/**/lib/*.js' | |
], | |
}, | |
jshint: { | |
options: { | |
jshintrc: '.jshintrc', | |
reporter: require('jshint-stylish') | |
}, | |
src: [ | |
'Gruntfile.js', | |
'<%= config.bundles %>/{,*/}*.js' | |
] | |
}, | |
package_folders: { | |
staticResources: { | |
options: { | |
extension: '', | |
deleteFolder: false | |
}, | |
files: [{ | |
filter: 'isDirectory', | |
cwd: '<%= config.bundles %>', | |
src: ['*'], | |
dest: '<%= config.src %>/staticresources' | |
}] | |
} | |
}, | |
shell: { | |
'lightning-lint': { | |
command: 'sfdx force:lightning:lint <%= config.src %>/aura', | |
options: { | |
callback: function (err, stdout, stderr, cb) { | |
if (err) { | |
cb(err); | |
return; | |
} | |
var re = /\d+ problems? \([1-9] errors?, \d+ warnings\)/ig; | |
var result = re.exec(stdout); | |
if (result) { | |
cb(new Error("Found linting errors in lightning components")); | |
return; | |
} | |
cb(); | |
} | |
} | |
}, | |
'force-push': { | |
command: 'sfdx force:source:push -u <%= env.SFALIAS %>' | |
}, | |
'force-pull': { | |
command: 'sfdx force:source:pull -u <%= env.SFALIAS %>' | |
}, | |
'force-test': { | |
command: 'sfdx force:apex:test:run --resultformat human -u <%= env.SFALIAS %>' | |
}, | |
'force-deploy': { | |
command: 'sfdx force:mdapi:deploy -u <%= env.SFALIAS %> -l RunLocalTests -w <%= config.deployWaitTime %> -d <%= config.artifacts.build %>', | |
}, | |
'force-deploy-ignore-tests': { | |
command: 'sfdx force:mdapi:deploy -u <%= env.SFALIAS %> -l NoTestRun -w <%= config.deployWaitTime %> -d <%= config.artifacts.build %>', | |
}, | |
'force-retrieve': { | |
command: 'sfdx force:mdapi:retrieve -u <%= env.SFALIAS %> -r <%= config.artifacts.build %> -p <%= env.SFPACKAGE %>', | |
}, | |
'force-check-deploy': { | |
command: 'sfdx force:mdapi:deploy -u <%= env.SFALIAS %> -c -l RunLocalTests -w <%= config.deployWaitTime %> -d <%= config.artifacts.build %>', | |
}, | |
'force-check-deploy-ignore-tests': { | |
command: 'sfdx force:mdapi:deploy -u <%= env.SFALIAS %> -c -w <%= config.deployWaitTime %> -l NoTestRun -d <%= config.artifacts.build %>', | |
}, | |
'force-convert-source': { | |
command: 'sfdx force:source:convert -r <%= config.module %> -d <%= config.artifacts.build %>' | |
}, | |
'force-convert-md': { | |
command: 'sfdx force:mdapi:convert -r <%= config.artifacts.buildSrc %>/' | |
}, | |
'git-commit-changes': { | |
command: [ | |
'git add -A', | |
'git commit -a -m "Changes detected by the automated Salesforce org export"', | |
'git push origin master' | |
].join('&&'), | |
options: { | |
execOptions: { | |
cwd: '<%= config.module %>' | |
} | |
} | |
} | |
} | |
}); | |
grunt.registerMultiTask('package_folders', "Zips up static resources to the proper binary needed for deployments", function () { | |
/* NOTE: This is a bit of a hackish solution specifically for the configuration provided in package_folders.staticResource. | |
* It has not been tested with any other configurations! | |
* Inspired by: https://github.com/AlexMeah/grunt-zip-directories | |
*/ | |
var async = require('async'); | |
var done = this.async(); | |
var archiver = require('archiver'); | |
var fs = require('fs-extra'); | |
var path = require('path'); | |
var os = require('os'); | |
process.setMaxListeners(0); | |
var options = this.options({ | |
extension: '.zip', | |
deleteFolder: false | |
}); | |
function begin(file, callback) { | |
var folders = file.src.toString().split(','); | |
var numZipFilesToCreate = folders.length; | |
folders.forEach(function (value) { | |
var folder = value; | |
var output = fs.createWriteStream(file.dest + "/" + folder + options.extension); | |
var archive = archiver('zip'); | |
grunt.log.debug('Zipping ' + folder + " to " + file.dest + "/" + folder + options.extension); | |
output.on('close', function() { | |
if (options.deleteFolder) { | |
var path = file.dest + "/" + folder + "/."; | |
grunt.log.debug("Removing: " + path); | |
fs.removeSync(path, function (error) { | |
if (error) { | |
grunt.log.error("Failed to delete folder '" + folder + "': " + error); | |
} | |
grunt.log.debug("Deleted folder '" + folder); | |
}); | |
} | |
if (--numZipFilesToCreate === 0) { | |
callback(); | |
} | |
}); | |
archive.on('error', function(err) { | |
throw err; | |
}); | |
archive.pipe(output); | |
grunt.log.debug(file.cwd + ' ' + folder); | |
archive.glob('**', { | |
cwd: file.cwd + '/' + folder, | |
}, {}); | |
archive.finalize(function(err) { | |
if (err) { | |
throw err; | |
} | |
}); | |
}); | |
} | |
if (!this.filesSrc) { | |
grunt.fail.fatal('No files found!'); | |
} | |
// Iterate over all specified file groups. | |
async.eachLimit(this.files, os.cpus().length, begin, function (err) { | |
if (err) { return console.log(err); } | |
grunt.log.ok('Zipping complete'); | |
done(); | |
}); | |
}); | |
/* | |
* BUILD TARGETS | |
*/ | |
grunt.registerTask('build', [ | |
'clean:artifacts', | |
'jshint:src', | |
'shell:lightning-lint', | |
'todo', | |
'package_folders:staticResources' | |
]); | |
grunt.registerTask('push', [ | |
'build', | |
'prompt:sfdcAlias', | |
'shell:force-push' | |
]); | |
grunt.registerTask('pull', [ | |
'prompt:sfdcAlias', | |
'shell:force-pull' | |
]); | |
grunt.registerTask('test', [ | |
'push', | |
'shell:force-test' | |
]); | |
grunt.registerTask('test-deploy', "Test deployment of all metadata files to a regular Salesforce org; available option: --ignore-tests", function() { | |
grunt.task.run([ | |
'build', | |
'prompt:sfdcAlias', | |
'shell:force-convert-source', | |
]); | |
if (grunt.option('ignore-tests')) { | |
grunt.task.run(['shell:force-check-deploy-ignore-tests']); | |
} else { | |
grunt.task.run(['shell:force-check-deploy']); | |
} | |
}); | |
grunt.registerTask('deploy', "Deploy all metadata files to a regular Salesforce org; available option: --ignore-tests", function() { | |
grunt.task.run([ | |
'build', | |
'prompt:sfdcAlias', | |
'shell:force-convert-source', | |
]); | |
if (grunt.option('ignore-tests')) { | |
grunt.task.run(['shell:force-deploy-ignore-tests']); | |
} else { | |
grunt.task.run(['shell:force-deploy']); | |
} | |
}); | |
// Setup default task that runs when you just run 'grunt' | |
grunt.registerTask('default', ['test']); | |
}; |
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
@echo off | |
:: Place file in the root folder of your SFDX project | |
IF NOT EXIST Gruntfile.js ( | |
echo Please make sure to run this script in your DX root folder. | |
exit \B 1 | |
) | |
SET /P SFALIAS="Your Salesforce DX Alias? " | |
echo Alright, let's create your scratch org with the alias "%SFALIAS%". | |
echo Before we begin, let's make sure your environment is ready. | |
call npm install | |
echo Ok, now it is time to create the scratch org. | |
sfdx force:org:create -s -f config\project-scratch-def.json -a %SFALIAS% -d 14 | |
sfdx force:org:open -u %SFALIAS% | |
echo Please turn on Omni in the settings and hit enter when done... | |
pause | |
:pushMetadata | |
echo Let's push the metadata... | |
call grunt push | |
:end | |
echo That's it, you are ready to go :) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And here are the dev dependencies for the Gruntfile, they might be a bit outdated:
"devDependencies": { "archiver": "^2.0.3", "async": "^2.0.1", "extract-zip": "^1.6.5", "fs-extra": "^4.0.1", "grunt": "^1.0.1", "grunt-batch": "^0.2.4", "grunt-contrib-clean": "^1.0.0", "grunt-contrib-copy": "^1.0.0", "grunt-contrib-jshint": "^1.0.0", "grunt-jslint": "1.1.15", "grunt-prompt": "^1.3.3", "grunt-shell": "^2.1.0", "grunt-todo": "^0.5.0", "jit-grunt": "^0.10.0", "jshint-stylish": "^2.2.0", "time-grunt-win": "^1.0.0" }