How Our Work Flows

Published on March 13, 2015, by Brian


One discussion that often raises its head in developer circles is workflow. How you do is often as important as what you do, especially when you are the one doing it!

There are millions of blogs out there extolling the virtues of various approaches, and it is up to you to take what is good from each and integrate it properly into your workflow. Much like religions, there is no correct one, but lots of people believe that theirs is the best. I gitflow, therefore I develop. You do not, thus I must convert you!

Instead of comparing, contrasting, and pontificating about different approaches, today I will just describe how we work here at RhodeCode and go through some of the highlights. I’ll also cover some of the rough edges we still seek to smooth out to dispel claims of impartiality.

Fork It

Each product has a repository which has a stable and dev branch. The goal being that every two weeks a promote is made from development to stable so that we are always within two weeks of shipping the next release. This lets us run through a release cycle every fortnight and get the process fine tuned.

But really, the devil is in the detail. What happens on the development branch is, as they say on MTV cribs, where the magic happens.

Dev Branch Workflow

Each team is responsible code quality, merging, and ensuring test coverage is acceptable for their repository. To achieve this, and keep bottlenecks to a minimum, everyone has write access to the repository but all contributions must be made through a pull-request, and all pull-requests must be reviewed by at least one team member.

This is combined with a detailed checklist for pull-requests so that they are always handled in a thorough manner. The process and checklist are continuously improved and the knowledge gained shared amongst the teams.

Here is a walkthrough of the process:

  1. Pick a task from the current sprint backlog, and please choose high-priority first! Currently we use Redmine for tickets, but with Jira and Taiga freedom fighters regularly firing salvos over the canteen table!
  2. Fork the repository. Here each developer has some flexibility, either have your own fork which you constantly update, or create a new fork for each task.
  3. Develop some code to address the task.
  4. Once finished, commit your changes to the fork and test them.
  5. Open a pull-request and add a reviewer from the team. The whole team is treated as a pool of reviewers and encouraged to spread this duty around.
  6. Peer code-review of the pull-request happens, and you address the necessary changes.
  7. Before merging a shell script is run that calls the test suite. This is not run by the pull-request author. This is one rough edge that we want to fix, as ideally this would be hooked into Jenkins and you would see the test results as a small comment on the pull-request.
  8. If your tests pass, merge the pull-request.
  9. Merging the pull-request triggers a Jenkins build, and this automatically runs the test suite again. This is basically a sanity check until these tests can be automated as part of step 5.
  10. Once merged, the code is in the repository but if the Jenkins build fails we treat the repository as “red” and fixing it becomes the top priority until it is “green”.

Our Tools

One thing that is unique here, is that at RhodeCode we see the results of this workflow on a daily basis. Improvements to different features are reflected on our system as we work with the latest development version to ensure we test it as much as possible before it is shipped. The latest build is deployed numerous times daily.

Using RhodeCode Enterprise in this way is exciting as you get to really play with the tools you are working on. It is nice to see our new features come into being, and it is also fun to think of additions to current ones that would improve the user experience. Ahem, this really means trying to get rid of the things that annoy us!

Pull Requests

Our pull request functionality was recently updated, and it is already proving its worth. Pull requests can now be updated and merged from the web interface. This lets the reviewer set the status, and if approved, click the merge button and be done. Who wouldn’t love a magic merge button?

But the main part of the pull request process is handling feedback, or even rejection. Using side-by-side diffs, leaving inline comments, or starting a debate about a particular pull-request is what allows the development team to share information and keep it all in context. These review features let us give precise feedback, speed up the review process, and keep the code quality high.

One issue though is that our inline comments are not tracked once the pull request is updated, so after the first pass they can become hard to follow. This is a sore point in the functionality and a rather large technical topic to fix. It is certainly not all plain sailing using your own tools, and seeing the short-comings on your screen daily.

But one step in the right direction being worked on in the interim is to be able to see the review status of a pull request, and if it is updated the status of previous review comments is reset. Internally we are calling this “reliable update behaviour”.

Conclusion

There is no silver bullet to finding the most suitable workflow for your team. It requires trial and error, and constant tweaking for optimisation, and maybe even optimism. Once you are on the right track though, the next step is to get buy-in from all those involved. Finding a productive flow, the right tools, and engendering a collaborative tone for code-review requires this buy-in from
everyone involved.

The best work-flow isn’t a 5 step recipe, it is a constant work-in-progress encompassing the right tools, people skills, and maybe some religious belief in the ritual.