Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. For the examples in this book, you will use software source code as the files being version controlled, though, in reality, we can do this with nearly any type of file on a computer. There are many version control systems like Git, Subversion, and Mercurial which provide a logical means to organize files and coordinate their creation, controlled access, updating, and deletion across teams and organizations. Version control is closely related to automation. In fact, automation and continuous integration rely on these files for the source code of the automation itself, as well as the configuration to be automated and the data to be distributed.
What all needs to be Version Controlled?
A version control system records changes to files stored in the system. These files can be source code, assets, or other documents that might be part of a software development project. Teams make changes in groups called commits or revisions. Each revision, along with metadata related to the revision (such as who made the change and when), is stored in the system. This allows teams to commit, compare, merge, and restore to previous revisions. It also minimizes risks by establishing a way to revert objects in production to previous versions.
Teams must be able to restore production services repeatedly and predictably (and, ideally, quickly) even when catastrophic events occur, so they must check in the following assets to their shared version control repository:
Version control is just not about your application code, everything that is needed for building your application needs to be version controlled.
All application code and dependencies (for example, libraries and static content)
Any script used to create database schemas, application reference data, and so on
All environment creation tools and artifacts described in the previous step (for example, VMware or AMI image building scripts or Chef recipes)
Any file used to create and compose containers (for example, Docker files and buildpacks)
All supporting automated tests and any manual test scripts
Any script that supports code packaging, deployment, database migration, and environment provisioning
Supporting project artifacts (for example, requirements documentation, deployment procedures, and release notes)
Container orchestration (for example, Kubernetes configuration, Mesos configuration, and Docker Swarm configuration)
All cloud configuration files (for example, AWS Cloudformation templates, Cloud Deployment Manager configuration, Microsoft Azure Stack DSC files, OpenStack HEAT, Terraform files, and Pulumi stacks)
Any other script or configuration information required to create an infrastructure that supports multiple services (for example, enterprise service buses, database management systems, DNS zone files, configuration rules for firewalls, and other networking devices)
How Version control helps us?
Version control offers direct benefits such as disaster recovery and auditability.
Comprehensive use of version control, among other capabilities, predicts continuous delivery. In particular, version control helps you meet these critical requirements:
Reproducibility. Teams must be able to provision any environment in a fully automated fashion and know that any new environment reproduced from the same configuration is identical. A prerequisite for achieving this goal is having the scripts and configuration information that are required to provision an environment stored in a shared, accessible system.
Traceability. Teams should be able to pick any environment and determine quickly and precisely the versions of every dependency used to create that environment. They should also be able to compare two versions of an environment and see what has changed between them.
In simple terms
Backup and Restore. Files are saved as they are edited, and we can jump to any moment in time. Need that file as it was on Feb 23, 2019? No problem.
Synchronization. Lets people share files and stay up-to-date with the latest version.
Short-term undo. Monkeying with a file and messed it up? (That’s just like you, isn’t it?). Throw away your changes and go back to the “last known good” version in the database.
Long-term undo. Sometimes we mess up bad. Suppose you made a change a year ago, and it had a bug. Jump back to the old version, and see what change was made that day.
Track Changes. As files are updated, we can leave messages explaining why the change happened (stored in the VCS, not the file). This makes it easy to see how a file is evolving over time, and why.
Track Ownership. A VCS tags every change with the name of the person who made it. Helpful for blamestorming giving credit.
Sandboxing, or insurance against yourself. Making a big change? We can make temporary changes in an isolated area, test and work out the kinks before “checking in” our changes.
Branching and merging. A larger sandbox. We can branch a copy of your code into a separate area and modify it in isolation (tracking changes separately). Later, we can merge our work back into the common area.
Common pitfalls in version control
The most common pitfall in using version control is the limited application or use; in other words, applying version control only to software application code. Best practice requires the ability to reproduce all testing and production environments, including the software deployed on them, in a fully automated fashion by using scripts, source code, and configuration information that's stored in version control.
Ways to improve version control
You can improve version control in many ways. Here a few we recommend:
Ensure that every commit to version control triggers the automated creation of packages that can be deployed to any environment using only information in version control.
Make it possible to create production-like test environments on-demand using only scripts and configuration information from version control, and to create packages using the automated process described in the previous approach.
Script testing and production infrastructure so that teams can add capacity or recover from disasters in a fully automated fashion.
As we implement a version control system, focus on your constraints. For example, what's the biggest blocker to the fast flow of changes from version control to production? Are your builds too slow? Is it hard to re-create deployable packages? Is it difficult to create production-like test environments? These constraints can make it hard to achieve your goals and might indicate a problem to work on with your system's architecture.
Ways to measure version control
To measure how effectively your teams are using version control in their systems, try these recommendations:
Application code. Do you use version control for application code? What percentage of application code do you store in version control? How easily and quickly can a team recover application code from the version control system?
System configurations. Do you use version control for system configurations? What percentage of system configurations do you store in version control? How easily and quickly can teams reconfigure systems from version control?
Application configuration. Do you use version control for application configurations? What percentage of application configurations do you store in version control? How easily and quickly can the team reconfigure applications from code in the version control system?]
Scripts for automating build and configuration. Do you keep scripts for automating build and configuration in version control? What percentage do you store in version control? How quickly and easily can you reprovision systems by using scripts from version control?