Grunt with Slack Hooks

As I now have multiple developers creating and pushing Release Branches on multiple repositories, I have started running into an issue with Developers creating the same branch.

A while ago, I created a grunt task to automate all the things needed to setup a release branch for one of our projects. This lead to a huge leap in conformity and productivity in our developers as menial tasks like updating the version numbers in package.json and version files were now done as part of this task. It even goes as far as creating a new git branch with the new semantic version number.

However, as I stated above, now developers are trying to create multiples of the same branch do to a lack of community and / or notification.

As you may remember from my earlier posts (Be Less Busy, and How to write a webhook in ColdFusion), I have implemented Slack into our office to help with Communication. So all I really needed here was a notification.

In comes grunt-slack-hook task.

This requires very little in terms of setup, and because its simply another task, I am able to chain it to the end of the create_release_branch task.

Setup Grunt

first you need to install the grunt task:

npm install grunt-slack-hook --save-dev  

Once that is completed, you need to add the task library to your grunt file and configure the task. I have 2 different targets which will allow me to send different messages to Slack. We also need to Register a new task in Grunt which will allow us to chain a number of tasks together.

module.exports = function(grunt) {  
    grunt.initConfig({
        pkg: grunt.file.readJSON("package.json"),
        slack: {
            options: {
                endpoint: "---URL FROM SLACK INTEGRATION---",
                channel: "---TARGET CHANNEL---"
            },
            newReleaseBranch: {
                text: "A new Release Branch (`Release-<%= pkg.version %>`) has been Created for `<%= pkg.name %>`"
            },
            newPatchBranch: {
                text: "A new Patch Branch (`Patch-<%= pkg.version %>`) has been Created for `<%= pkg.name %>`"
            }
        },
        // Task to Increment Version Number Configuration
    });

    grunt.loadNpmTasks("grunt-slack-hook");
    // Task to Increment Version Number

    grunt.registerTask("createMinorBranch",[
        // Task to Increment Version Number,
        "slack:newReleaseBranch"
    ]);
    grunt.registerTask("createPatchBranch",[
        // Task to Increment Version Number,
        "slack:newPatchBranch"
    ]);
};

Setup Slack

If you are an administrator on your slack account, than you should be able to add webhooks as one of your integrations. If you have not done this, I highly recommend you do so as it ads a tremendous amount of custom notification functionality to slack.

Add a new WebHook Integration point, and set the Webhook URL value as the slack grunt tasks endpoint option value. Optionally you can set the channel value as well in the grunt config. For better clarity for my developers, I have also setup the webhooks to be Grunt and to use the Grunt Logo as its avatar.

If you don't have access to do this, than ask your slack admin to get you a webhook for slack.

Running the Task

Once you are all setup, you should be able to run the grunt task

grunt createMinorBranch  

You should see a notification in Slack now in the selected channel regarding your grunt task. If you don't, than there is something wrong with your config or your address.

You should also notice that Grunt sent the previous version number, not the new one. This is because we told grunt to the value of pkg.version to send to slack, how at the time the grunt task started, it value was the prevision version number. To resolve this, we need to create a new custom task. The easiest thing to do while keeping inline with grunt style of code, is to set a new variable while can then update in the system. So our grunt file now looks like this:

module.exports = function(grunt) {  
    grunt.initConfig({
        pkg: grunt.file.readJSON("package.json")
        version: "<%= pkg.version %>",
        slack: {
            options: {
                endpoint: "---URL FROM SLACK INTEGRATION---",
                channel: "---TARGET CHANNEL---"
            },
            newReleaseBranch: {
                text: "A new Release Branch (`Release-<%= version %>`) has been Created for `<%= pkg.name %>`"
            },
            newPatchBranch: {
                text: "A new Patch Branch (`Patch-<%= version %>`) has been Created for `<%= pkg.name %>`"
            }
        },
        updateVersionVariable: {
            default: {}
        },
        // Task to Increment Version Number Configuration
    });

    grunt.loadNpmTasks("grunt-slack-hook");
    // Task to Increment Version Number

    grunt.registerTask("createMinorBranch",[
        // Task to Increment Version Number,
        "updateVersionVariable:default",
        "slack:newReleaseBranch"
    ]);
    grunt.registerTask("createPatchBranch",[
        // Task to Increment Version Number,
        "updateVersionVariable:default",
        "slack:newPatchBranch"
    ]);

    grunt.registerMultiTask("updateVersionVariable", function(action, filepath, target) {
        var pkg = grunt.file.readJSON("package.json");
        grunt.config.set("version", pkg.version);
    });
};

Now when we run our tasks, the version number should be updated when you see it in slack.

Thats about the gist of what needs to be done to make this type of notification work.