Skip to content

Instantly share code, notes, and snippets.

@Theminijohn
Created May 10, 2016 18:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Theminijohn/864d48edf026712351883e57dc49142c to your computer and use it in GitHub Desktop.
Save Theminijohn/864d48edf026712351883e57dc49142c to your computer and use it in GitHub Desktop.

Our workflow - From story to production

Everything that's happening engineering-wise should be well documented, so we don't lose track. Whether it's a feature or a bug, or just some tech related work, it needs to be written down. The log for all activity right now is Pivotal Tracker, and we use per application projects there.

Pivotal Tracker allows you to add three types of entries; features, bugs and chores. Anything that provides measurable value to the app is considered a feature. Bugs are defects in the software. Chores are tasks that while adding value to the product, this value cannot be measured directly. Cleaning up tech debt falls on this category.

The projects on Pivotal Tracker are visible from both Product and Engineering. Sometimes a task in Tracker can be further broken down to smaller tasks. Sometimes a task in Tracker makes sense from a Product point of view, but developers speak a different language. That's why we replicate issues on Github. Every task in Tracker should be linked to one or more Github issues.

Starting out

So you want to work on a certain task. You should use the following steps.

  1. Go to the Pivotal Tracker project, find the task and start it.
  2. Open the task and copy its URL (Copy link button).
  3. Go to the related repo on Github and open an issue. Add a short descriptive title. Make sure to add the Tracker link on top. Give a description of what we want to achieve and optionally how we're going to do it. Add a label to the issue and assign it to yourself.
  4. Go to Tracker again and add a task with the Github issue's URL.

Doing the actual work

1. Create a branch

Ok, you're done with the paperwork and now you're ready to work on the actual issue. Assuming your work isn't part of a bigger release, you're likely going to be targeting your work against the master branch. In any case, you should find the base branch for your work.

We should pull the latest changes from the base branch and create a new branch off of it. The naming convention for branches is <gh-issue-id>-<short-description>. For our needs, let's say we're going to be working on Github issue number 1677 and we want the changes to end up in the master branch. Our work involves fixing an issue with a spinner animation that doesn't stop loading. We should:

$ git checkout master
$ git pull origin master
$ git checkout -b 1677-non-stop-spinner

2. Do the work

This is the easiest part. That's what you know how to do. You can commit as many times as you want and give working titles for your commit messages. At this point it doesn't matter. When you're done, you should run the test suite to make sure you don't break anything else.

$ vi some_file.rb
$ git add some_file.rb
$ git commit

Github is able to detect all commits that start with an issue number and relate them to the specific issue in the UI. In order to take advantage of this, we start every commit message with the issue number (prefixed with the '#' symbol). All commit message rows should not exceed 80 characters and you should write a message title, leave a blank line and then a more detailed description of what this commit is about.

An example template for a commit would be

#1677 Stop spinner from loading infinitely

Make sure that when the page finished loading, the spinner icon stops
animating. Had to decrease animation duration too.

3. Publish it

This is the part where you push your changes to the remote, creating a branch with the same name as yours.

$ git push origin 1677-non-stop-spinner

At this point you want to also create a pull request so that your changes can be merged to the target branch. This allows other members of the team to view your changes in Github in a "diff" manner. While there are several ways to create a Github pull request, it is suggested that you use hub.

The advantage of using hub is that it takes a Github issue and transforms it to a Github pull request (PR). When you create the PR you need to specify the target branch and the issue number.

$ hub pull-request -i 1677 -b master

After the PR is successfully created, you go to Github, find the issue and add the "needs review" label. Then you wait for at least one other member of the team to review your changes. At this point, there might be some back and forth where you have to make further changes based on the comments you get. Maybe you missed something. Maybe something can be done better. At some point, you and the reviewer(s) will agree that the code is ok to be shipped. Great! All you need now is product acceptance.

Make sure you also mark the task as "Finished" in Pivotal Tracker.

4. Let Product know

Once your peers tell you that the code is ok to ship, we need to somehow let Product test it. What we do is deploy our changes to the staging environment. First of all, you remove the "needs review" label from the Github task and instead add the "staging" label. Then, you merge your changes to the staging branch.

$ git checkout staging
$ git pull origin staging
$ git merge 1677-non-stop-spinner
$ git push origin staging

The last part involves the actual deployment. We can use Heroku's git hooks for this. Assuming you've named the remote for the Heroku staging app staging, you do:

$ git push staging staging:master

Once the deployment completes successfully, you go to the Pivotal Tracker task and "Deliver" it. This is the part where you wait again. Once somebody for Product reviews your work, they might either "Reject" or "Approve" it. If you get rejected, you continue adding work on your branch and basically go through steps 2-4 of this guide.

5. Accepted

Great news! Your work just got final acceptance from Product. You cannot wait to deploy the code to production where it actually matters.

All that's left to do is merge your pull request to master. You can do this easily from Github's interface. You can optionally delete the remote and local branches once you've merged your changes. Make sure you remove the "staging" label too.

The preferred way to merge your PR would be to do it from the console, because Github merges pull requests with the no-ff option. This means you can do:

$ git checkout master
$ git pull origin master
$ git checkout 1677-non-stop-spinner
$ git rebase master
$ git push -f origin 1677-non-stop-spinner
$ git checkout master
$ git merge 1677-non-stop-spinner
$ git push origin master

To deploy to production, you can use the Heroku hooks. Make sure you notify everybody before deploying, preferably on chat. Assuming that the remote corresponding to Heroku's production app is named production you just do:

$ git checkout master
$ git pull origin master
$ git push production master:master

That's it!

Gotchas

Back and forth until the changes are finalized

During the time that the code is being reviewed either by Engineering or by Product, you may have to make additional changes. Don't be afraid to rewrite the branch's commit history. Consistent commits are appreciated. The only downside is the maintenance required to rebase your branch and deal with any conflicts while merging to staging.

In general, we support the "one commit per issue" mantra. Although you are encouraged to commit often while working on the issue, you should rebase your branch and squash commits before you deploy. Last thing you want is polluting the branch history with unfinished commits.

Bear in mind that this is not a hard requirement, but the general idea is that no commit should break the master branch or leave it in an "incomplete" state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment