Define CI/CD and DevOps
Define CI/CD and key DevOps concepts — CI/CD foundations. Learn the core ideas, see a practical walkthrough, and connect to the next lesson in the track.
Focus: define ci/cd and key devops concepts
You’ve written code that works on your machine, but when the team merges everything, the build breaks and nobody knows why. Or worse, you ship manually, cross your fingers, and discover the bug only after customers do. The pain is real: slow feedback loops, fragile releases, and the dreaded “works on my machine.” This lesson gives you the cure — a clear, practical definition of CI/CD and the core DevOps concepts behind it, so you can start building delivery pipelines that catch problems early and ship reliably.
The problem this lesson solves
Software delivery is messy. Old-school workflows treat integration and deployment as rare, high-risk events: developers work in isolation for days or weeks, then try to merge everything at once. This “integration hell” creates merge conflicts, hidden dependencies, and defects that surface long after they were introduced. Deployment becomes a manual, nervous ceremony performed by one person who knows the secret steps.
This approach fails because it delays feedback. The longer code sits unintegrated, the harder it is to fix. The more you rely on manual steps, the more human error creeps in. In today’s world, users expect frequent updates, and teams expect to deliver value fast. Without CI/CD, you’re stuck in a reactive cycle of firefighting — and that’s exactly what this DevOps course aims to replace.
The lesson you’re about to study solves a specific pain: you need a shared vocabulary and a mental model for automation before you can build effective pipelines. Whether you’re a developer, a DevOps engineer, or a tech lead, understanding CI/CD is the first step to delivering software continuously and confidently.
Core concept / mental model
Think of CI/CD as the assembly line for software. On a factory line, each station checks the work from the previous one, adds value, and passes it on. If a defect appears at station three, you stop the line, fix it right there, and never send it downstream. CI/CD applies the same principle to code.
-
CI stands for Continuous Integration. It means every change — no matter how small — is automatically merged into a shared mainline several times a day. Every merge triggers an automated build and a suite of tests. The goal is to detect integration issues early, not later.
-
CD stands for Continuous Delivery (or Continuous Deployment). Continuous Delivery ensures that every change that passes the pipeline is ready to be deployed to production at the push of a button. Continuous Deployment goes one step further and automates the actual release to production — no human button needed.
You’ll often hear the terms used together, but keep them distinct in your mind:
| Term | What it guarantees | Human involvement in release |
|---|---|---|
| Continuous Integration | Code merges are safe and tested | None for build/test |
| Continuous Delivery | Code is always releasable | Manual approval for production |
| Continuous Deployment | New releases happen automatically | None — full automation |
Around CI/CD, the DevOps philosophy creates a culture of collaboration between developers and operations. It’s about breaking down silos, automating repetitive tasks, and measuring everything. Core DevOps concepts include:
- Automation — replacing manual steps with scripts and tools.
- Infrastructure as Code (IaC) — managing servers and infrastructure with versioned config files instead of click-ops.
- Monitoring and observability — knowing what’s happening in production, so you can react fast.
- Version control — the single source of truth for all changes.
- Feedback loops — short cycles that let you learn and improve quickly.
Continuous is the keyword. It doesn’t mean we automate one thing; it means we make small, steady improvements — a mindset of constant delivery.
How it works step by step
Let’s look at the anatomy of a modern CI/CD pipeline. These steps happen in order, and each one is a safety checkpoint:
- Code commit — A developer pushes a change to the source repository (e.g., GitHub, GitLab).
- Automatic trigger — The push triggers a pipeline automatically. No manual starts.
- Build — The system compiles the code, resolves dependencies, and packages the application.
- Test — Automated tests run: unit, integration, and maybe end-to-end. This is where most problems get caught.
- Deploy to staging/QA — The artifact goes to a staging environment that mirrors production.
- Manual approval (for Continuous Delivery) — A human approves the release. For Continuous Deployment, this step is automated too.
- Deploy to production — The final step. The new release goes live.
Key components in a pipeline:
- Version control system (VCS) — every change is recorded and traceable.
- CI server (e.g., GitHub Actions, Jenkins, GitLab CI) — orchestrates the pipeline.
- Build tools (e.g., Maven, npm) — compile and package the code.
- Artifact repository (e.g., Docker Hub, JFrog) — stores the build output for later steps.
- Test runners — execute the test suites.
- Deployment tools — push artifacts to servers or containers.
The cause-and-effect chain is elegant: every change is treated as a release candidate. If the pipeline fails, no new version is produced. If it passes, you have a deployable artifact — every time, without exception.
Hands-on walkthrough
Let’s make this concrete with a minimal setup. We’ll use GitHub Actions, a popular CI/CD tool that’s free for public repos. You’ll create a simple pipeline that runs on every push.
Prerequisites
- A GitHub account
- A repository (you can use the one you created earlier in this track)
- A basic Python file to test
Step 1: Create a simple Python module and test
Create a file calculator.py in your repo:
def add(a, b):
return a + b
if __name__ == "__main__":
print(add(2, 3))
Create a test file test_calculator.py:
import unittest
from calculator import add
class TestCalculator(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2, 3), 5)
if __name__ == "__main__":
unittest.main()
Now, run the test locally to verify it passes:
python -m unittest test_calculator.py -v
Expected output:
test_add (test_calculator.TestCalculator) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Step 2: Create a GitHub Actions workflow
In your repo, create the folder .github/workflows/ and inside it a file ci.yml:
name: CI
on: [push]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install --upgrade pip
- name: Run tests
run: |
python -m unittest test_calculator.py -v
Push this file to GitHub:
git add .github/workflows/ci.yml calculator.py test_calculator.py
git commit -m "Add CI pipeline"
git push origin main
Step 3: Watch the pipeline run
After pushing, go to the Actions tab of your repository. You’ll see a run of the CI workflow. Click on it and watch the logs. If everything passes, you’ll see a green checkmark. If a test fails, you’ll see exactly which step failed and what the error was.
This is the heart of Continuous Integration: every push runs the tests, so defects are caught minutes after they’re written — not weeks later.
💡 Pro tip: Make your pipelines run on pull requests too, not just pushes. Add
pull_requestto theon:block. This way, tests run before a merge, protecting the main branch even more.
Compare options / when to choose what
What if you don’t want to use GitHub Actions? You have plenty of options. Here’s a quick comparison of popular CI/CD tools:
| Tool | Hosting | Best for | Key strength |
|---|---|---|---|
| GitHub Actions | Cloud (SaaS) | GitHub users | Native repo integration, free for public repos |
| GitLab CI | Cloud/Self-hosted | GitLab users, monorepos | Built into GitLab, powerful triggers |
| Jenkins | Self-hosted | Complex, on-prem setups | Mature, huge plugin ecosystem |
| CircleCI | Cloud/SaaS | Fast cloud builds | Parallelism and speed |
| Azure DevOps | Cloud/SaaS | Microsoft stack | Deep Azure integration |
Choosing the right tool depends on where your code lives, your team’s skill set, and your security needs. For this course, we stick with GitHub Actions because it’s widely used, easy to learn, and integrates seamlessly with the most popular code hosting service.
But CI/CD isn’t only about tools. There are process choices too:
- Trunk-based development vs. feature branching — with CI, it’s best to integrate small, frequent changes into the mainline, not huge branches that diverge for weeks.
- Continuous Delivery vs. Deployment — most teams start with delivery (manual approval) and evolve to deployment once confidence grows.
- Monolithic vs. microservices — an app architecture affects how you orchestrate pipelines. Monoliths have a single pipeline; microservices often need per-service pipelines.
When to choose what: If you’re a small team starting out, use a hosted CI like GitHub Actions. If you have strict compliance demands, self-host a tool like Jenkins. If you already live in GitLab, use GitLab CI. The key is to start with something and iterate.
Troubleshooting & edge cases
Let’s look at common issues you might hit while setting up your first pipeline.
1. Workflow doesn’t trigger
Symptoms: You push a commit, but no action appears in the Actions tab.
Fixes:
- Check the file is named *.yml or *.yaml and located in .github/workflows/.
- Verify the YAML syntax is correct — a single indentation error can break the file.
- Check permissions: if the repo is private, Actions may need to be enabled under Settings.
- If you used on: [push], make sure you pushed to the default branch.
2. Test fails in CI but passes locally
Why: Environment differences — different Python version, missing dependencies, or OS-specific behavior.
Fixes:
- Pin dependencies in requirements.txt or use a lock file.
- Specify the same Python version in the workflow as you use locally.
- Run your tests in a Docker container locally to replicate the CI environment.
3. Pipeline is slow
Symptoms: Build takes 10+ minutes, blocking development. Fixes: - Cache dependencies (e.g., pip/npm caches in Actions). - Run tests in parallel across multiple jobs. - Use a faster runner or hosted runners instead of slow self-hosted machines.
4. Secret management
Issue: Putting API keys or credentials in the workflow file.
Good practice: Never store secrets in the YAML file. Use GitHub Secrets (Settings → Secrets), and reference them with ${{ secrets.MY_SECRET }}. This prevents accidental exposure.
Edge case: A failed pipeline blocks everything
Your default branch is protected, so failed checks block merges — good! But if your test suite is flaky, your team gets stuck. Fix flaky tests promptly, or run them separately from critical checks. The goal is a fast, reliable green pipeline.
Troubleshooting tip: Always read the full build log. The error message is often at the very bottom, but the root cause may be in a middle step. Use
--verbose/-voptions when running tests locally to get more detail.
What you learned & what's next
Congratulations! You can now define CI/CD and key DevOps concepts — from the pain of manual delivery to the mental model of an automated assembly line, the step-by-step anatomy of a pipeline, and a real GitHub Actions workflow you built and ran yourself.
Recap of what you mastered:
- Explain the difference between Continuous Integration, Continuous Delivery, and Continuous Deployment.
- List the core DevOps concepts: automation, IaC, monitoring, version control, and feedback loops.
- Run a hands-on CI pipeline with GitHub Actions, including writing tests and watching them execute.
One more thing: note down the key benefit — the fast feedback loop. It changes how you code, test, and collaborate.
Next, in the course, we’ll go deeper into pipeline anatomy — you’ll learn about stages, jobs, and steps in more detail, and how to design complex workflows that handle builds, tests, and deployments efficiently. In fact, your ci.yml is already a simple pipeline; the next lesson will show you how to expand it to multiple environments like staging and production.
Keep this workflow handy — you’ll be building on it in the next exercise. Get ready to take the next step in mastering CI/CD and DevOps!
Practice recap
Now practice: enhance your GitHub Action by adding a second job that runs a simple lint step with python -m py_compile *.py. Push the change, watch the pipeline run again, and verify each step passes. This will prepare you for building multi-stage pipelines in the next lesson.
Common mistakes
- Thinking CI and CD are the same thing — CI is about merging and testing, CD is about releasing; they are separate but connected stages.
- Putting secrets like API keys directly into the workflow YAML file — they get committed to the repo and become a public leak; always use secret managers.
- Only running tests locally and skipping CI — you miss integration issues that only surface in the shared environment.
- Using a highly complex pipeline on day one — start small, learn the concepts, then add stages like deployment and security scans.
- Ignoring the 'continuous' in CI/CD — if you run CI only once a week, you’re not doing continuous integration, you’re doing occasional integration.
Variations
- Use GitLab CI instead of GitHub Actions — similar syntax but built into GitLab, good for self-hosted setups.
- Use a self-hosted Jenkins server for maximum control — ideal for enterprise environments with strict compliance.
- Adopt trunk-based development with short-lived branches — it amplifies CI benefits by keeping integration frequent.
Real-world use cases
- A startup automates its release pipeline with GitHub Actions so every merge to main triggers tests and an auto-deploy to a demo environment.
- An e-commerce platform uses CI to run 10,000+ tests on every pull request, preventing regressions before merging to production.
- A fintech company implements continuous delivery with manual approval — auditors must approve before the app goes live to customers.
Key takeaways
- CI/CD is about automating the journey from code commit to production release, creating fast feedback loops.
- Continuous Integration means frequently merging and testing — Continuous Delivery ensures code is always releasable; Continuous Deployment automates the release itself.
- The core DevOps concepts — automation, IaC, monitoring, version control, and feedback — support and accelerate CI/CD.
- A typical pipeline runs: commit → trigger → build → test → deploy to staging → manual/auto approval → production.
- Use a modern CI tool like GitHub Actions; start simple, then iterate — don't over-engineer early.
- Troubleshoot by checking file locations, YAML syntax, environment parity, and using secret managers.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.