At the end of 2015, I decided to move from California to Indiana. I will await your gasps and inevitable chuckle or head nod.
It's true, I left a mega corporation with 50,000+ employees to work at a small company with 9 employees. And I have already learned so much. I also have been able to contribute a lot from my previous experience—especially experience with migrating an existing legacy app to the new and shiny technologies.
Git 'Er Done
One such experience is moving away from TFVC (Team Foundation Version Control) and instead using Git. Previously, we would have all developers making changes on a single branch. You might try to check in changes and have a conflict because someone else checked in the same file 10 minutes before you. For a release, someone would merge the
Dev branch into the
Release branch, trigger a build, then we could deploy. There was a separate
Patch branch that was used to make changes for a hotfix that needed to be deployed the same day. The change was checked into
Patch which has a separate build and deployment step.
The question we would ask is "Which version of the code is in production?" We were deploying from different branches and our builds don't last forever. Additionally, it was a pain maintaining and merging these branches because TFVC doesn't make it easy and the tooling was limited.
Migrating from TFVC to Git was actually quite trivial since the official git docs actually have a section to describe code migration. The only additional steps were to add a
.gitattributes that would meet our needs.
Now our development happens on separate branches for each feature. We do a proper code review process when the branch is ready, then it gets tested in isolation, and finally merged into the
master branch. All of the branches are using CI via Jenkins to build and run tests for each commit. Now we only deploy builds from the
master branch which will create a tag with the unique build name. Now it is easy to see which code is in production because there is a corresponding tag with the same version number. We also don't deal with merge conflicts until a branch is ready to be merged so we can do rapid development or even abandon a branch if it is not salvageable.
I was not really happy with the way Jenkins handles building branches with a single job. It was easy to setup, but difficult to find your build. Usually you only care about the latest build for a particular branch. So I wrote a chrome extension that put a button on the Pull Request for a branch. When clicked, it would query the Jenkins API to find the latest build for the given branch, then deploy that branch to our Test environment. This made it really easy for anyone who needed to review the functionality of the new feature, to deploy and test it.
There is still much to be improved and we are looking at using Docker in the future. But I'll save that for a different time.