Chapter 2. Version Control

Controlling versions of text files (code, configuration, static data, etc.) is a crucial facet of Continuous Delivery. Version control provides traceability, predictability, and repeatability, because we’re forced to treat the version control system as the definitive source of truth. Version control is also a central communication mechanism between teams and team members, indicating the intent and purpose of our changes so that people can make better decisions.

Key Version Control Practices

Some important principles for version control in a Continuous Delivery context are:

  • Commits to version control should be cohesive and meaningful, helping people to see why a change was made.

  • Commits should happen many times per day—if your version control system or practices work against multiple daily commits, you’re likely using the wrong approach.

  • Branch as little as possible (see “Branching Options”)—use techniques such as feature toggles to manage partially completed work. Focus on completing a small number of changes rather than tackling many things in parallel.

  • Any non-trunk branches should be short-lived—especially feature branches.

Furthermore, for Continuous Delivery, we tend to prefer many smaller repositories to one large repository, using package management to bring together dependent modules (see “Use NuGet to Manage Internal Dependencies”).

Version Control Technologies

In 2015 and beyond, you should choose or switch to a hosted (SaaS) version control solution unless you have a very clear understanding of why you need a self-hosted (on-premise) tool. Only those organizations with an excellent capability in infrastructure and security management should consider on-premise version control. If you’re certain that self-hosted/on-premise is right for you, then good options are GitHub Enterprise, Bitbucket Server (formerly Stash), and RhodeCode.

The most effective SaaS version control providers for Windows and .NET software include:

The SaaS hosting solution acts as the definitive central location for code integration and collaboration.

Note

Modern SaaS version control tools provide enterprise-level features such as integration with LDAP and fine-grained security permissions control, along with private repositories. Using a SaaS provider does not mean that your files need to be open sourced.

You will also need client tools to run on each workstation, build agent, or server. Client tools are generally free of charge.

Git

Git is currently the de facto standard for version control and is a powerful, safe, and flexible version control tool. You should choose a Git-based solution for Continuous Delivery with Windows and .NET unless you have a good reason to use a different tool, and invest in Git training for everyone using version control, including SysAdmins and DBAs.

Free client tools for Git on Windows include:

Git for Windows (or git bash)

Good for cross-platform work

GitHub for Windows

A GUI tool from GitHub

Atlassian SourceTree

Rich GUI tool for beginners and experts

POSH-git

PowerShell environment for Git

Git Extensions

Git integration for Visual Studio

TFS 2013 or later

(Using the Git option for version control)

In practice, if you choose to use Git, you will need a hosted solution such as GitHub, Bitbucket, or Visual Studio Online.

Mercurial

Mercurial is similar to Git. Some Windows and .NET-based tools support Mercurial, but with the popularity of Git and GitHub, along with Git’s superior branch handling, it’s unlikely that Mercurial will provide much benefit over Git for most teams.

If you need to use Mercurial on Windows, one of the best client tools is currently Atlassian SourceTree. SourceTree is a free download and supports Git as well as Mercurial.

Subversion

Subversion is a well-established version control system that can work well for small- to medium-sized repositories in a Continuous Delivery context. Subversion uses a central server for the definitive repository copy along with operations such as svn log for seeing history. This means that some operations (particularly viewing the log) are slow compared to similar operations in Git or Mercurial.

Compelling reasons to use Subversion include TortoiseSVN, which provides rich integration with the Windows Explorer shell, and Subversion’s native support for binary files, making updates and fresh checkouts (for CI) much quicker than with Git for large numbers of binary files.

TFS

Until the release of Team Foundation Server (TFS) 2013, the Team Foundation Version Control (TFVC) component of TFS alone provided version control features using a central server. The early versions of TFS/TFVC (2005, 2008, 2010, and 2012) possessed several features of Microsoft’s legacy Visual Source Safe VCS that were incompatible with Continuous Delivery [Hammer].

However, TFS 2013 added support for Git repositories, thereby combining the richness of Visual Studio with the flexibility and power of Git. Future versions of TFS and Visual Studio Online will provide support for accessing Git repositories over SSH (currently, only Git over HTTPS is supported). With TFS 2015 there is also expanded support for the cloud-based Visual Studio Online, integration with Azure, and native integration with GitHub.

With strong support for Git, as well as programmability via REST APIs and agile-oriented features, TFS 2015 promises to be a much better fit for Continuous Delivery than previous versions.

Branching Options

A developer has a problem to fix, so they create a feature branch. Now they have two problems to fix.

Anon.

Modern version control systems allow for branching of the source code, thereby allowing for multiple parallel streams of work on the same project. This is an alluring prospect that gives the illusion that multiple development streams can be achieved on the same codebase without impacting one another. Unfortunately, this method is fraught with issues when the time comes to bring these parallel streams back together.

Where possible, avoid many long-lived branches, preferring instead either trunk-based development or short-lived feature branches. Trunk-based development is the practice of making changes directly onto the trunk or master branch without feature branches. This practice requires a discipline in the developers to ensure that the HEAD of the trunk is always in a releasable state; a stepping-stone toward trunk-based development is GitHub Flow, the practice of using pull requests.

Warning

Do not be tempted to rush into branching just because your version control tool has good branching support. Git in particular supports branching well, but Git was designed for collaboration on the Linux kernel code by geographically separated individuals. Your software teams (should) have much better communication than the Linux kernel team, so give preference to communication instead of branching!

Pull Requests

Pull requests, or merge requests, are becoming a popular way to manage development. They work in a similar way to feature branches, although on a much smaller scale.

The developer works on a local clone of the codebase, making a small change that is pushed to her centrally hosted clone. Then, using the hosted tool, GitHub, Bitbucket Server (formerly Stash), or something similar, the developer makes a request to the owners of the origin repository to review and merge the change.

The process stems from open source development where developers are spread out throughout the world and in various time zones. It allows for the owners to review and judge each request as to whether it is suitable for merging. For this scenario it is perfect, although in larger organizations it can make the flow of changes quite stilted.

Warning

The GitFlow model for development work with Git is popular but in our view can lead to situations where CI happens less frequently than with other branching models. GitFlow also has a steep learning curve for people new to version control. We recommend that you explore other models before trying GitFlow.

Feature Toggles

Large features and changes are always needed. We can decompose the work to be as small as possible, yet there will be times when they are part of something larger that can only work together once fully implemented. This can still be achieved in trunk-based development by employing Feature Toggles.

Feature Toggles, at their simplest, can merely be if statements surrounding the usage of your new functionality. They could also be implemented through factory methods or instantiating different implementations via IoC. The scope and complexity of the toggle depends on what your feature change is.

Tip

For further reading on branching strategies, look up Steve Smith’s excellent blog series on Version Control Strategies.

Use NuGet for Dependencies

NuGet is the open source dependency package management tool for .NET. NuGet is distributed as a Visual Studio Extension and is preinstalled by default in Visual Studio version 2012 and later. NuGet can also be used from the command line, which is useful for automated scripting. The NuGet client tools provide the ability to both produce and consume packages. NuGet Gallery is the central package repository used by open source package authors and consumers.

NuGet is similar in its goals to package managers used in other languages, such as Java’s Maven, Ruby’s Gems, and Node’s NPM. It provides a way to specify a package for installation and along with it installs that package’s dependencies at the required versions.

As seen in Figure 2-1, the NuGet Visual Studio Extension provides a GUI for finding and installing packages from the NuGet Gallery.

NuGet Visual Studio interface
Figure 2-1. The NuGet Visual Studio Interface

The following sections cover some good practices for working with packages and package management.

Do Not Store Packages in Version Control

Store only the packages.config files in version control, not actual packages. Use NuGet Package Restore and the packages will be re-downloaded, from a local cache if available, to your project at compile time. This way you can prevent the binaries from bloating your version control. The restore is an MSBuild step included in the solution file and is generally supported on CI servers.

Use NuGet to Manage Internal Dependencies

Your own internally shared libraries are excellent candidates for NuGet packages. By making your shared libraries available in this way you are ensuring that the library is built only once, as is the case with all other artifacts in a Continuous Delivery pipeline.

To generate the NuGet package, simply run the following:

nuget pack MyProject.csproj
Note

Originally, the NuGet package format was for build-time dependencies only, although several tools now use the NuGet format for deployable artifacts too. For a clearer distinction between build-time and run-time dependencies, use Chocolatey, currently the de facto apt-get tool for Windows and .NET. In the future, other package managers may appear, facilitated by the emerging OneGet packager manager management framework.

There are various NuGet hosting applications that can be installed on premise such as Artifactory and ProGet, and SaaS-based tools such as MyGet and Artifactory Cloud. Some other tools, including TeamCity and Octopus, support built-in hosting of NuGet feeds; in fact, TeamCity includes an optional build step to generate NuGet packages.

Summary

Version control of all text-based files is an essential foundation for Continuous Delivery. When choosing tools for version control, it’s important to consider not only developers but also people in testing and operations.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.57.126