- 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.
- Figure: Bad example - Committing to master
- Figure: Good example - Committing to a new branch
- Figure: Great diagram from
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.
1) Create a branch
a) Create a "feature branch" for every PBI
When starting a PBI from the task board, 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 number of conflicts and churn of unfinished code during development of a feature. It allows features to be developed independently of each other and reduces the amount of expensive "pull latest from the server, and rebuild everything" operations, as well as greatly limiting the impact of commits with unfinished code.
b) Code away and complete the PBI
c) Create a commit - it will contain your changed files on your local PC
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.
d) Push your changes to your remote Feature Branch
2) Open a pull request (to merge from your current branch to the master)
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.
Tip: A best practice is to have another developer review your work and then approve.
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
Some prefer to move this step to after the merge, especially when using a release management tool like VSTS Release or 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.
3) Merge and Deploy (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.
After you completed the pull request, make sure you also delete the branch
that you made the pull request of. Deleting your completed branch will not just help yourself in the long run, but also everyone else. Having too many branches especially a stale one will confuse developers on what "may" be in progress, moreover it would cause so much pain to the future developer when they have to do a clean-up and the branch author has left.
Figure: Bad Example - Lots of stale branches that could cause confusion or potentially take a long time to resolve conflicts when merging
Otherwise, you can do it before you complete the pull request by ticking
delete branch option.
Figure: Good Example - Automatically delete the branch after the pull
request completion in Azure Devops
Figure: Good Example - Set the whole project to auto-delete branch after
merging in GitHub
master should immediately and automatically be deployed (in a perfect world, to production).