What is CI/CD? A Beginner's Guide to Workflow Automation
Apr 12, 2026
I still remember the exact moment I realized I’d been doing DevOps completely wrong for years.
It was 2019, and I was working at a mid-sized fintech startup over in Amsterdam. On the side, I had this Python web-scraping bot built with Scrapy that I’d written to track my Udemy course sales. Nothing fancy at all—literally just a script running on a cron job that would dump the results into a CSV file.
But here’s the thing: every single time I pushed an update, I’d manually SSH into the server, pull the latest code, restart the service, and pray nothing broke. When something inevitably did break (and it always did), I’d scramble through messy logs trying to figure out what went wrong. It was absolute chaos, and I was losing hours every week to these manual processes. Actually, let me be honest—it was way more than just hours. I was losing entire evenings to this stuff. I’d find myself staring at error messages at midnight, wondering why I’d chosen to build this bot in the first place.
That’s when I finally started understanding CI/CD beyond just being that annoying buzzword everyone kept throwing around at tech conferences.
I really needed to figure this out
I’d been in tech for a decade at that point—doing systems administration, some Ansible work, even a stint managing infrastructure with Vagrant for local testing. But honestly? I kept confusing myself.
For example, I thought Ansible Tower and Jenkins were basically the same thing. (They’re absolutely not, by the way—I was embarrassingly wrong about that for way longer than I’d like to admit.) I knew what CI/CD meant on paper, but I didn’t actually get why it mattered until I was literally losing sleep over broken deployments. Side note here—and maybe this is just me overthinking things—but I think a massive number of developers go through this exact same confusion when they try to wrap their heads around the DevOps ecosystem. The tooling landscape is just… completely overwhelming. There’s Jenkins, GitHub Actions, GitLab CI, CircleCI, Travis CI. Each one promises to solve your problems, and each one comes with its own learning curve. If you’re curious about which tools are actually worth your time, I’ve written about 7 DevOps Tools You Actually Need to Learn in 2024 separately.
The problem it actually solves
When you strip away all the enterprise jargon, CI/CD is really just about automating the manual busywork I was drowning in. Think of it like the difference between hand-crafting each product one at a time versus setting up an automated assembly line—once it’s running, you don’t have to touch it.
“Continuous Integration” just means your code gets tested automatically every single time someone pushes changes. “Continuous Deployment” means if those tests pass, the code goes live automatically. No more 2 AM SSH sessions wondering if your deployment is going to tank the whole system. No more 2 AM anything, really, which was the entire point for me. The beauty of it is that you can actually sleep knowing your changes are being validated before they hit production.
This whole approach really ties into something I covered in Infrastructure as Code Explained: Stop Clicking in the Console—it’s all about moving away from manual processes that are error-prone and impossible to reproduce consistently.
How I finally got started
I ended up picking GitHub Actions simply because it was the path of least resistance. My code was already sitting on GitHub, and I honestly didn’t want to learn Jenkins’ Byzantine configuration system. I’m not entirely sure if “Byzantine” is the exact right word there, but it certainly felt like navigating some ancient, overly complex labyrinth every time I looked at the Jenkins documentation.
So I created a basic .github/workflows/ directory, wrote a quick YAML file that would run my Python tests, and set it to rebuild my bot on every push to the main branch. Suddenly, I had exactly what I needed.
Looking back, I probably should have started even simpler—maybe just linting and unit tests, with no deployment at first. But the framework was there: the initial checkout stage pulled the code, followed by a setup stage that installed my dependencies, then the tests ran, and if everything passed, the rebuild would trigger. It sounds incredibly simple because it actually is. But watching that first automated pipeline turn green changed everything about how I view writing code. I went from dreading deployments to actually trusting the process, and it really makes me wonder what else we’re doing the hard way just because we’re used to it.
💡 Take the next step
If this resonated, RHCSA Bootcamp (RHEL 10) - Arabic is where I teach this systematically — no fluff, just the skills that matter in the real world.