Syncs a local project with the Mozu Developer Center.
This plugin requires Grunt.
If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
npm install grunt-mozu-appdev-sync --save-dev
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
grunt.loadNpmTasks('grunt-mozu-appdev-sync');
In your project's Gruntfile, add a section named mozusync
to the data object passed into grunt.initConfig()
.
grunt.initConfig({
mozusync: {
options: {
// Task-specific options go here.
applicationKey: 'namespace.applicationname.1.0.0.Release',
context: {
developerAccount: {
emailAddress: '[email protected]'
},
developerAccountId: 2
},
noclobber: true
},
upload: {
// Target-specific file lists and/or options go here.
src: ['./assets/dist/**/*']
},
del: {
// If you're using the grunt-contrib-watch adapter,
// a separate task for deletion is usually necessary.
// The delete task does not use the `files` array.
options: {
action: 'delete'
},
src: ['./assets/dist/**/*'],
remove: []
}
},
})
The above depicted configuration is nice and simple, but it does hardcode specific Mozu environment information into the Gruntfile. You may be moving your project work from theme to theme in your Mozu account, or sharing your work with other developers. It's best to keep your Mozu environment information separate from the Gruntfile itself.
If you used the Mozu Yeoman theme generator to scaffold your theme project folder, or you are familiar with the Mozu Node SDK, you know that it likes to store credentials in a file called mozu.config.json
. You can maintain this file, and then hook it up to the Grunt task, using the following pattern, which takes advantage of Grunt's template interpolation:
grunt.initConfig({
mozuconfig: require('./mozu.config.json'),
mozusync: {
options: {
applicationKey: '<%= mozuconfig.workingApplicationKey %>',
context: '<%= mozuconfig %>',
noclobber: true
},
// individual mozusync task config below
}
});
The Yeoman theme generator will put this in a Gruntfile for you, either by creating a new one or modifying your existing one.
You can also install the Mozu App generator and use it to create a mozu.config.json
file.
To install the generator, run
npm install -g generator-mozu-app
And then, in any directory, you can create or modify your mozu.config.json
environment file by running:
yo mozu-app --config
Type: String
Required
The application key of the application, theme, or extension you are working on in Developer Center.
Type: Object
Required
A context object to use to create a Mozu Node SDK client. It should include:
developerAccountId
: a developer account ID. You can see your developer account ID in the Mozu Launchpad when you select which Dev Center to login to. This is required.developerAccount
: an object representing your user login. Unless you are supplying this information at the command line as described below, this is required. It should be an object with anemailAddress
property containing your user email, as shown above. You can also supply apassword
here to avoid being prompted, but be careful not to put a plaintext password in your Gruntfile. You could, for instance, useprocess.env
to assign the value of an environment variable.baseUrl
: a URL representing the Mozu environment. Unless you have special access to an internal preproduction Mozu environment, you don't need to provide this.
Type: Boolean
Default value: false
The task will normally prompt you for your password and then store authentication tokens in your home directory using Multipass. It never stores passwords in plaintext. However, if you want to manage your authentication manually instead, you can remove this behavior by setting noStoreAuth
to true
.
Type: String
Default value: 'upload'
A string value describing the type of sync action to take. The default is 'upload'
, which both creates and updates files.
The full set of options is:
'upload'
-- create and/or update files in Developer Center'delete'
-- delete files in Developer Center'deleteAll'
-- delete all files in Developer Center'rename'
-- rename files in Developer Center
The different actions use slightly different configuration, so you can think of them as different tasks, though they will share common options.
Use normal Grunt file specification formats, including globbing.
For the upload
action, only a src
is necessary. The dest
doesn't make sense, since the file destination is Developer Center.
For the delete
action, the files collection won't work. Grunt automatically filters the runtime files array for files that exist. The delete action is often run in the context of a file watch, so by the time the action runs, the relevant files don't exist anymore! For this reason, the delete
action looks for an array of strings representing filenames under the property remove
.
For the rename
action, populate a files
object with src
/dest
mappings of each file you want to rename. You will probably not configure this manually in your Gruntfile. You'll want to configure a grunt-contrib-watch
adapter to do it dynamically.
For the deleteAll
action, the files
object is irrelevant. They're all doomed.
Type: Boolean
Default value: false
for the upload
and rename
actions, true
for the delete
and deleteAll
actions
Some actions are destructive, such as delete
and deleteAll
, so this options serves as a safety measure: the task will only run if it was called directly from the command line, as in grunt mozusync:del
, instead of as part of a grouped task, such as grunt
or grunt build
.
Type: Boolean
Default value: false
This option applies to the upload
action. If this is set to true
, then the uploads will include a last modified date from your local file system. If you attempt to upload a file that is older than the one in Developer Center, the upload will fail. If it is set to false
, then all uploads will override regardless of modified date.
Type: Boolean
Default value: false
This option applies to the upload
action. By default, this action will use checksums to determine if the local file and the remote file are identical, and will skip the upload if they are. Set this to true to override this behavior.
By default, the task will pause Grunt execution and prompt the user to input a password in the terminal. If Grunt is running on a continuous integration server and/or you are using this task in an automated deployment, it would be more appropriate to supply a password as part of the scripted environment. You can provide username and password information as command-line arguments to Grunt instead.
Assuming that you have configured a mozusync
task target called upload
, as in the example above, you can supply the username and password like this:
grunt mozusync:upload:[email protected]:my_password_123
Or, you can set the developerAccount.emailAddress
in mozu.config.json
and supply only the password:
grunt mozusync:upload:my_password_123
Note that you must run the mozusync
task separately to use command-line authentication; you cannot run it as part of an aggregate task or default build, to avoid exposing password information to untrusted code. If mozusync
is part of your default task, just configure a separate aggregate task that doesn't include mozusync
, and configure your CI server to run that task, before running grunt mozusync
separately with the provided authentication.
The grunt-contrib-watch is useful for filesystem watching and synchronizing on save. One common problem is that the watch task can only run other tasks, and other tasks are not aware of which files changed, so by default they will run on all files. The task already checks with the Mozu App Dev APIs and compares file checksums to avoid unnecessary uploads, but the act of checking this for every file in your theme is itself slow.
Earlier versions of this plugin had "watch adapters", meant to hook directly in to grunt-contrib-watch
. This had a number of disadvantages, so it has been removed. The new recommendation is to use the grunt-newer
plugin in conjunction with grunt-contrib-watch
and grunt-mozu-appdev-sync
, which will optimize your workflow by only uploading necessary files.
An example optimal workflow:
watch: {
javascript: {
files: [
'scripts/**/*.js'
],
tasks: [
'newer:jshint:develop',
'mozutheme:quickcompile',
'newer:mozusync:upload'
]
},
sync: {
files: [
'admin/**/*',
'labels/**/*',
'resources/**/*',
'packageconfig.xml',
'scripts/**/*',
'stylesheets/**/*',
'templates/**/*',
'theme.json',
'*thumb.png',
'*thumb.jpg',
'theme-ui.json',
'!*.orig',
'!.inherited'
],
tasks: [
'newer:mozusync:upload'
]
}
},
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.
Copyright (c) Volusion Inc.. Licensed under the MIT license.