- Note: This rule applies to git. For branching advice in TFVC, see Do you know when to branch in TFVC?
The best way to handle continuous development and deployment is following GitHub Flow. The basic idea is to always deploy from master, and to create a feature branch for every feature. When the feature is complete, it is merged back to master via a pull request, which provides a trigger for other developers to build.
Using this strategy, master is always production-ready and deployable.
1) Set up build system to deploy from the master branch
Your build systems should always deploy from master, and should automatically deploy on every commit to master.
Since master is always being deployed, it must always be in a deployable state.
2) Create a "feature branch" for every PBI
When starting a PBI from the taskboard, create a branch from master with a descriptive name for that feature.
- Figure: Bad example - Branch name is not descriptive
- Figure: Good Example - Branch name describes the intent of the change
It is critical that this branch always comes off master, not another feature branch. Master is the only branch that is mandated to be in a deployable state, so any other option is unsafe.
Obviously, we're creating a lot of branches and merging a lot under this strategy - and that's ok. Be sure to keep your PBIs small (as per do you break large tasks into smaller tasks), and you will not have much merge pain.
The benefit of creating feature branches is to reduce the amount of conflicts and churn of unfinished code during development of a feature. It allows features to be development independently of each other, and reduces the amount of expensive "pull latest from server, and rebuild everything" operations, as well as greatly limiting the impact of commits with unfinished code.
3) Commit your code to the branch
While working, commit frequently to this branch with nice, descriptive messages. For example, "Added a field to hold the product category to our timesheet read model" and "added a column to the timesheet summary UI for the product category".
- Figure: Bad Example - Commit message does not describe what was changed
- Figure: Good Example - Commit message describes exactly what was changed.
4) Open a pull request
When the change is complete, or when you want feedback on anything, open a pull request to merge the branch back to master. The pull request is more than just a request to merge, it is a request to have someone review the code and architecture, and to discuss any issues. Resolve these issues with more commits in the branch before continuing.
It is easy to chalk this step up as busy-work, but it is one of the most valuable parts of the strategy
Deploy the changes to a staging environment. This allows the features to be tested before being merged to master.
Some prefer to move this step to after the merge , especially when using a release management tool like Octopus Deploy (see Do you use the best deployment tool). If you decide to go this route, remember that master should remain deployable and production ready at all times, and that all branches come from master. If skipping this step, ensure that you have CI on your feature branch to ensure that your branch compiles and passes all tests before merging.
6) Merge to master
Once everyone is happy and everything is tested, complete the pull request, which will merge back to master. Ensure you are not using the "Fast Forward" merge option (git), or details about the branch will be lost - it will appear as though all work was done in master. Being able to see the feature branches in the git log is very useful.
- Figure: Good Example - Each change is well described, small and in its own feature branch.
Once merged, master should immediately and automatically be deployed (in a perfect world, to production) .