SSW Foursquare

Rules to Better Branching and Builds - 5 Rules

  1. Do you check your Workspaces when defining a new build?

    When defining a build, you should always check the Workspace tab. Only the workspace relevant to your build should be included.

    If you have a number of Team Projects open from the same TFS Project Collection, all of their workspaces will be included by default. You should remove those workspaces that aren’t being used otherwise the build server will get the source for every workspace in this list before starting a build.

    bad workspace
    Figure: Bad example – Several workspaces from other team projects are included by default

    good workspace
    Figure: Good example – Only the relevant workspace has been included in this build definition

  2. Do you know how to name your builds?

    You should always follow a naming standard when naming your builds. This helps you identify their purpose at a glance.

    The build name should have the following suffixes, depending on their purpose:

    • .CI - For continuous integration builds. These are triggered automatically and do not deploy anywhere.
    • .CD.[Environment] - For continuous delivery builds. These are triggered automatically and deploy to an environment. You should specify which environment it deploys to as well.

    buildnames

    Good Example: We have two continuous delivery builds to our staging environment.

  3. Do you know that branches are better than Labels?

    Although labels are useful they can be changed after they have been created with no way to tell that they have been changed.

    TFSLabel
    Figure: Bad example, labels can be edited after the fact (they are mutable)

    tfslabe2
    Figure: Good example, branches give absolute certainty of versions (they are immutable)

    Fact #1 : Creating a branch of 1GB of source code does not increase the size of your database by 1GB. It just adds a bunch of pointers. Only the differences are actually stored. Fact #2 : When you delete a branch it is not really “deleted”, you are just ending the history. You can undelete at a later time.

    Tip : Find deleted items by ticking “Tools | Options | Source Control | Visual Studio Team Foundation Server | Show deleted items in the Source Control Explorer”

  4. Do you know when to branch in git?

    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.

    finishing a feature with world class flow

    Note: This rule applies to git. For branching advice in TFVC, see when to branch.

    commit master bad
    Figure: Bad example - Committing to master

    commit branch good
    Figure: Good example - Committing to a new branch

    github flow
    Figure: Great diagram from GitHub

    The process

    Assumption

    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.

    Step 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.

    git branch start-stuff

    Figure: Bad example - Branch name is not descriptive

    git branch create-basic-web-application

    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 breaking 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" or "added a column to the timesheet summary UI for the product category".

    git commit -m "Started report change"

    Figure: Bad example - Commit message does not describe what was changed

    git commit -m "Added a product category filter to the timesheet summary report UI"

    Figure: Good example - Commit message describes exactly what was changed

    d) Push your changes to your remote Feature Branch

    Step 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, or image 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.

    Assumption

    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 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.

    Step 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.

    GoodGitHistory
    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.

    bad figure stale branches2
    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.

    delete branch in devops
    Figure: Good example - Automatically delete the branch after the pull request completion in Azure Devops

    github settings
    Figure: Good example - Set the whole project to auto-delete branch after merging in GitHub

    Once merged, master should immediately and automatically be deployed (in a perfect world, to production).

  5. Do you swarm to fix the build?

    If you or someone on your team has broken the build, the whole team should swarm to fix the problem immediately.

    It is PERFECTLY ok to have the CI build go red, that is what is there for, but when the build goes red the team should go immediately into corrective action mode and make sure the build goes green again.

    Two things should be done:

    1. Get it Green
    2. Find out WHY it went green locally but red on build server. This may indicate something is brittle in the application structure, and that is the underlying cause – and should of course also be fixed.

    broken builds

    Bad Example: Too many broken builds in a row.

    good builds

    Good Example: Broken build was fixed immediately.

We open source. Powered by GitHub