category

article

Easily deploy a build to Heroku with Grunt

Posted on: June 28th, 2013 6 Comments

Here's a tip on deploying Node app builds to Heroku - use the grunt-shell task to make things simple.

Let's say you have this scenario - an Angular JS app, served by a Connect or Express server. Your web app needs a build (Coffeescript, SASS, concat, uglify etc). I use Grunt for running tasks, and Yeoman's Angular Generator to get started.

When you have a Node app, the only option for doing Heroku deployments is via Git. So your build needs to be part of the repo. Say you type grunt build, and you end up with a build in dist/. You now have to add the dist/ directory tree to the index (because stuff under it might have been cleaned up), and make a commit. Here's how to automate it:

// Gruntfile.js
module.exports = function (grunt) {
  ...
  grunt.initConfig({
    ...
    shell: {
      'git-add-dist': {
        command: 'git add '
      },
      'git-commit-build': {
        command: 'git commit -am"build"'
      }
    }
  });
  
  // load the grunt-shell task:
  grunt.loadNpmTasks('grunt-shell');
  ...

  // add these tasks to the build task:
  grunt.registerTask('build', [
    'clean:dist',
    'jshint',
    'test',
    'coffee',
    'compass:dist',
    'useminPrepare',
    'concat',
    'imagemin',
    'cssmin',
    'htmlmin',
    'copy',
    'cdnify',
    'ngmin',
    'uglify',
    'rev',
    'usemin',
    'shell:git-add-dist',
    'shell:git-commit-build'
  ]);
  ...
};

Now type grunt build, and it's ready for deployment:

Alex:tested-form alex$ grunt build
Running "clean:dist" (clean) task
...
Running "shell:git-add-dist" (shell) task

Running "shell:git-commit-build" (shell) task

Done, without errors.
Alex:tested-form alex$ git log -1
commit ad9d9595a2b7d1dae385f63376480c765e27f166
Author: Alex Urdea
Date:   Fri Jun 28 16:52:15 2013 +0300

    build

So now it's in the repo, waiting for a deploy. You can create a heroku task that chains this with a push to your dynos:

// Add these to Gruntfile.js
grunt.initConfig({
  ...
  shell: {
    ...
    'heroku': {
      command: 'git push heroku master'
    }
  }
});
...
grunt.registerTask('heroku', ['build', 'shell:heroku']);

And you're good to go: grunt heroku

6 Responses

  1. zach

    July 1, 2013

    I tried to install the grunt-shell package on a brand new yo angular app and I essentially copied and pasted what you had above initially and got the following error.. >> TypeError: Object # has no method ‘loadNpmTask’

    I’m curious if you had this issue as well.. also grunt-shell seemed to install correctly via npm so I don’t think that was the issue.

    Reply
    • alex

      July 1, 2013

      Zach – it’s loadNpmTasks, not loadNpmTask 🙂 – my typo in the example, now corrected. Sorry about that…

      Reply
  2. Affeman

    July 1, 2013

    Hi,

    nice articles so far, keep em coming! I’ve been playing with yeoman, angular and express but so far i haven’t found a straight on solution on how to get the generated angular and express to work togheter. Would you care to explain how your setup works?

    Reply
    • alex

      July 1, 2013

      Affeman – `grunt build` will put the build under the dist/ directory (which can be changed if you edit the line in your Gruntfile):

      // configurable paths
      var yeomanConfig = {
      app: ‘app’,
      dist: ‘dist’
      };

      I’m just using Express to do some routing, serve 404s and serve the build with the Express `static` middleware from the /dist directory.


      app.use(‘/subscribe’, express.static(path.resolve(__dirname, ‘../dist/’)));
      … etc

      Reply
  3. Douglas Mak

    November 6, 2013

    I tried using stdout: true for the shell task, and I still cannot see the output when deploying to heroku. Did you find anyway to output everything from git push heroku master?

    Reply
  4. 94Violet

    August 8, 2017

    Hi blogger, i must say you have high quality content here.
    Your website can go viral. You need initial
    traffic boost only. How to get it? Search for: Mertiso’s
    tips go viral

    Reply

Leave a Reply