Saturday, January 3, 2015

How to make the ultimate Heroku/Trello/Github/Salesforce/Hipchat agile development integration - Part 1

About two years ago I was asked to assume the role of "scrum master" for the company where I work, Samanage. I didn't really know what to expect and how to approach this new role. At first I thought that my main objective was to just make sure everyone in the engineering department knew their current task, how long it will take, and what their next task will be. As time passed, I realized that my mission should be problem solving and making sure the development process runs smoothly in all aspects.

Master Status and the birth of SCRUManage

Like most SaaS companies we have three environments: Development (local machines), Stage (a similar environment to the actual live production environment for testing purposes before a deploy, usually deployed from our 'Master' git branch) and Production (the actual live product, deployed from our 'Production' branch, usually after having the Master branch merged into it). As we moved from deploying once a week to continuous deployment, and as our team grew significantly, we needed a tool to keep track of our 'master' git branch. Mainly, we needed to know at any given point if the Master branch was ok to be merged into the Production branch and then deployed to the production environment. If there was an issue with the Master branch and a quick fix had to be applied to the production environment, we could just apply the patch to the Production branch and deploy it without merging Master into it.
I decided to take this project on and find a solution. I needed a simple server that everyone on the team could have access to and would be very simple to update and get data from. I had recently played around with Heroku and decided to deploy a very small Rails project which will keep track of the Master branch. The project started out simple. A developer sends a PUT http request with a predefined token, the developer's name, the message and the color to use when printing the result in the terminal. To get the status, all that is needed is a GET request with the token.

Here is the code that I use to set the status.
#!/usr/bin/env ruby
require 'net/http'

host = "name_of_app.herokuapp.com"
username = `git config --get user.name`.strip.gsub(" ", "_")
path = "/master_statuses/1?app_token=123456789&current_status=Master_is_dirty!_DO_NOT_DEPLOY!&color=red&username=#{username}"

req = Net::HTTP::Put.new(path, initheader = { 'Content-Type' => 'text/plain'})
req.body = "whatever"
response = Net::HTTP.new(host).start {|http| http.request(req) }
puts response.body


In order to keep everyone informed and make their lives easier, I wrote a quick script which added a git hook to automatically get the status of the master branch after every pull. If someone wanted to mark the master branch as dirty all they had to do was run "dirty_master" or "clean_master" in order to mark it as clean. Here is how it looks:





My team really liked this feature and I decided to expand it further. The project, SCRUManage, was born.

My stage!

A lot of times a developer needs to test his work on the stage environment before merging his branch into master or for any other testing purposes. This meant that somebody either had to go around the office, or ask in our Hipchat room if they could use the stage. This was not only annoying but it was also not very effective. A lot of times someone would not hear/see that someone else needs to use the stage and would deploy over their work.
I decided to expand the Master Status idea and added the 'my_stage' and 'not_my_stage' commands. The result looks like this:


Again, these messages are automatically pulled from the SCRUManage servers after every pull from github. I decided to automate things just a bit more. When someone began a deploy to stage, the stage would be marked as his automatically. I did this by adding the following lines to our Capistrano recipe:


before "deploy", "scrum:my_stage"

namespace(:scrum) do
  desc "Tasks related to Scrumanage"
  task :my_stage do
    run_locally('my_stage') if ARGV[0] == "staging"
  end
end
After a while I decided to harness Hipchat to my cause and now whenever someone marks the master branch as dirty/clean or the stage as his/not his, a Hipchat room message is sent:






In part II of this post, I will explain how we synched our Trello 'Engineering' board with Github's pull requests and our deploy process. I will also explain how our sales team uses SCRUManage to sync their Salesforce account with their Trello 'Sales Opportunities' board.