DEV Community

Discussion on: Explain CI/CD like I'm five.

Collapse
 
seankilleen profile image
Sean Killeen

In software, people work with code. Normally, in a case when more than one person is working on a piece of software, that means more than one person is changing the code.

This presents a few problems:

  • How do you make sure that a developer's change works with the code that's already there?
  • How do you make sure that after developer 1 changes code, developer 2's code won't break?
  • How do you make sure that when both developer 1 and 2's changes are made, the system overall will work correctly?

In historical times, developers would keep copies of their code that diverged and would have to have big meetings to manually change the files and make sure that changes didn't diverge too far from one another. Normally, they had, and this would be very painful; developers would have to sit together for a long time. This is a form of a feedback loop.

So, we started to shorten the feedback loop. We started to prefer smaller changes, and making them more often, so that those meetings were less painful. We started to prefer integrating small changes continually. This is sometimes known as trunk-based development. Rather than creating a branch of code that diverged from the main bit of code for many months, we start making our changes in smaller increments off of the main branch (sometimes called "main", "master", or "trunk").

But there was still another question: Even though the code looked good to the devs, how could we be sure it would always compile and work correctly? That it could always be deployed? This is where build scripts and continuous integration (CI) servers come into play. A CI server knows how to run the same build script on any branch of the code, and it therefore can tell us if anything breaks.

A CI server usually contains several quality gateways, such as:

  • Does the code compile?
  • Do the tests associated with the code run successfully?
  • Can I package this code for deployment?
  • Can I deploy it to a environment successfully?

These are steps we build up over time.

When combined with the right source control systems for check-in and check out, we can shorten the feedback loop even more. Rather than telling us that something is broken after we merge it, many CI systems can tell us if something will break when we're about to merge it. This way, we keep our builds "green" (successful) and ensure that a minor change isn't going to introduce a problem. git is a source control system whose idea of a "pull request" sets this up for success. Someone creates a request to pull code in on the project, and a CI server can see what the result will look like after that code is merged. It can then run all of its build process & tests on that tool.

Continuous deployment takes that one step farther. Once we have good quality gateways in place, we have a high degree of confidence that code will work. Continuous Deployment says "well, if the CI server feels good about it and we've deployed to various environments and run tests, let's push this code out to production". This system of automated delivery is very powerful, because in many cases it enables teams to deliver more quickly -- but also to recover from problems more quickly. It also forces teams to build up tests and better automated processes in important areas to alleviate any concerns about going to production. Building up to continuous delivery has a lot of efficiencies as well. Imagine if instead of filing a bug report, you could sit down together, write a test to prove the bug exists, fix the bug, watch all the tests pass, and then send that code write to production? A lot of intermediate steps -- massive bug reports, time spend discussing prioritization, etc. -- can be saved when this level of collaboration and safety is enabled.

I'd love to hear your questions if I can clarify this more!