One of the most important things to happen in the evolution of development over the past many years is the widespread adoption of continuous integration and continuous deployment, or CI/CD. (Sometimes the "CD" stands for "continuous delivery," depending on who you're talking to.)
It's a concept that jettisons a lot of older ideas about how systems should be managed and instead gives you a way to update code and integrate changes as live rolling deployments while ensuring that the new code is tested and slots in smoothly with stuff that's already running. A properly architected CI/CD pipeline means you can get code changes into production faster and with fewer errors. But what does that look like in practice?
It looks like Ars Technica, because we've adopted a CI/CD workflow to take full advantage of the flexibility afforded us by serverless cloud hosting. Welcome to part three of our four-part series on how we host Ars—here, we’re going to swing away from the "ops" side of "DevOps" and peer more closely at the "dev" part instead. Join us for a look behind the curtain at how Ars uses CI/CD in both our deployed applications and our infrastructure management!
Version control is not optional
For the benefit of folks who only do the "ops" part of DevOps, let's get a working definition going for "version control," as the term underpins our entire approach toward maintaining code. When we say "version control" in this context, we're talking about a method by which we're able to track changes made to our production codebase—that is, the repository of files that makes Ars function.
Ensuring that production codebase is subject to some form of version control is a lot like turning on "track changes" in Word: the version control system keeps a record of every change made to every file, along with a correlated list of who made the change and when it happened. Version control is a critical component of most large-scale IT projects, and in some cases, it's even a mandated regulatory requirement.
But version control is a hard problem to solve, and many of the solutions that are common now—including and especially Git—are still relatively young. Not that long ago, there was a time I don’t remember with fondness—a time in which you edited code in a text editor and then FTP’d it to a production server. This was a low and filthy era, rife with lost changes, production crashes, and ad-hoc backups with names like
oops-1997-05-21.tar.gz. To be sure, even back in those primitive days, there were bearded wizards that spoke of inscrutable technologies like CVS (Concurrent Versions System, not the pharmacy), but such things were conspicuously absent from most folks' experience within the burgeoning universe of web development.
While many of us probably recall SVN repositories (and with many thoughts and prayers to those of you still dealing with SVN), it wasn’t until Git that version control gained massive popularity. Why? In part because tools like Git and GitHub made it dead simple to create and maintain repositories—just type a few commands, and you’re up and running. Most of the world’s developers now maintain code repositories on GitHub, and Ars is no exception.
How do changes flow from GitHub into deployed applications?
Well, we start by firing up our favorite FTP client, Transmit. I kid, I kid—but Transmit was (and apparently still is) an awesome app. For real, now: We start by working on a particular branch in one of our repositories. Remember from our previous installments that Ars is composed of four main applications, each running in its own container inside AWS ECS tasks:
- Arx: Our local Docker Compose development setup and Nginx server container
- Acta: The main WordPress application
- Civis: Our discussion forum software
- Taberna: Our e-commerce and subscription system
Each of these applications has its own repository on GitHub. When large changes are made, a new branch is created. Eventually, that new feature branch will be merged into a staging branch via a pull request. After testing, staging will be merged into the main branch with another pull request.