Using the 12-factor methodology is the right way to write applications in 2020. These dozen factors are guidelines for ideal app development that take into account maximum possible agility, onboarding new developers, and how an app will scale over time.
The first of those 12 factors prescribes one codebase tracked in revision control. Let’s look at our codebases more closely and consider frequently misunderstood or overlooked examples of what “in revision control” means for development teams.
Think of it this way: If a meteorite landed square on your office and obliterated all your hardware, how long would it take you to restart normal development activities? For some of the projects I manage, that time to recovery would be around three minutes: pull a convenient desktop off the shelf, clone a copy of the repository and launch a standard installation.
Other projects would probably never recover. Even though their repositories are formally comprehensive, the QA department keeps its own copies of tests on a server outside central control. Or unit tests depend on environment variables whose configuration no human entirely remembers. Or the user experience team hosts its visual designs on a fileshare whose backup I can’t access. And so on.
Test that it’s all in there
Make a task out of this. Bring in an experienced developer or tester who doesn’t know your project, and have them go as far as possible going off just your README.
Does it take four pages of project-specific instructions before they can run the first project-specific unit tests? That probably represents a lot of opportunities to script more of your installation. Does your project install easily, but programmers new to it require a couple of hours of training in the IDE and tool configuration before they accomplish anything useful?
Prep default configurations and make them part of the standard installation. Script the first-time installation for a beginning programmer, and make sure that is in the repository. Include explicit details about how to take the first steps in a README, which of course is itself under version control.
Do you have utilities that you use occasionally, perhaps to help generate favicons or run business metrics for the project? Make sure they’re in the repository. Do you need to verify backups periodically, or scan include libraries for security vulnerabilities? Script those scheduled processes, and put the script under version control.
Your repository automatically generates a history or log of commits, plus their annotations. Consider writing an additional narrative of prominent milestones — not for every business-oriented story or card or enhancement, but for a couple of the biggest technical advances from each month, with hyperlinks to pertinent commits or tickets. Maintain that narrative under version control, and help your team be able to find details about how, why, and when your project changed its front-end framework or swapped its back-end load balancer or migrated to an industry-standard library for a specific algorithm.
“Red books,” or crib sheets that help operators diagnose problems in production, also deserve to be under version control. It is advantageous both to coordinate their management with the artifacts that produce application behavior and to document who committed which updates when.
Does your red book tell operators what to do when a particular process is anomalously slow? Are its example screenshots from the version from three years ago, and the threshold for “slow” outdated by fourteen months? Those details are easier to get right when coordinated with the “canonical truth” of the central repository.
Too many organizations say they have DevOps but just proliferate silos under new names. A consolidated, well-maintained central source repository is one symptom of healthy cooperation among different roles.
There are some exceptions
A few exceptions to this commandment are important to understand. Binaries generally don’t belong under source control, especially distributed source control like Git. Secrets are another important exception. Do not check passwords or customer data into source repositories, even if the repositories themselves are maintained as trade secrets.
More subtly, some things don’t belong under source control because they already have other and better homes. Your team probably has a dedicated task manager or problem ticketer. Don’t duplicate the information there; simply refer to it. Don’t write up an emergency incident in the source comments of a particularly crucial algorithm; instead, provide URLs in source comments — something along with the order of:
/* See <URL: http://$SOME_URL > for an example of why it’s
important to limit MAX_HOSTS to 16. */
Check your code repository before you need it
Programming and testing teams usually point confidently to a particular repository with the thought that it holds their sources. That naive belief is different, though, from 100% certainty that everything is in its proper place.
Just as IT regularly tests backups, it’s equally imperative that your team verify that your repository truly does all for you that you expect. Trace the steps and examples above, and fill any gaps before an emergency arrives.