Last Updated: February 25, 2016
· ktstowell

Using Grunt to deploy to your AppFog App


  • grunt
  • grunt-cli
  • grunt-shell
  • AppFog gem (gem install af)

  • If you're writing this Grunfile from scratch (i.e not generated from Yeoman, etc), remember to follow each module's instructions for loading their own tasks, etc. *

The Config

  shell: {
    afDeploy: {
      // Your command may vary in terms of what directory 
      // you run this in. For example,
      // my build script builds everything into /dist
      command: 'cd dist; af login --email <%= af.username %> --passwd <%= af.password %>; af update <%= af.appName %>;',
      options: {
        stdout: true // Outputs grunt-shell commands to the terminal

The Task

grunt.registerTask('afDeploy', function(appName, username, password) {
    // You can go as elaborate as you want on 
    // the argument fallbacks,
    // for the sake of this ProTip, I'm just using 'arguments'

    if(arguments.length === 0) {
      // Log an error
      grunt.log.error("afDeploy: No arguments provided. Please provide the App Name, Username and Password.");
      // Return false to short circuit the task.
      return false;

    // Set args as config items, 'af' here is arbitrary, it can be anything
    // as long as you reference it by this name in your Grunt config.
    // As this is how we're able to have <%= af.appName %> mean something
    grunt.config.set('af.appName', appName);
    grunt.config.set('af.username', username);
    grunt.config.set('af.password', password);

    var tasks = [
      // Whatever your build tasks are, i.e compass:dist, etc.
      'shell:afDeploy' // It depends on your build but most likely you'll want to do this as the very last step.

    // Run tasks;

The Shell

To run your build script:

grunt afDeploy:myAppName:myAfLoginName:myAfLoginPasswd


Hopefully this gave you a small glimpse of how awesome Grunt is. Tasks like these can be extended and written in so many ways, making development workflow much more efficient.


Think of how you could incorporate an environment based deployment!