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

Sponsored

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:

  1. Code commit — A developer pushes a change to the source repository (e.g., GitHub, GitLab).
  2. Automatic trigger — The push triggers a pipeline automatically. No manual starts.
  3. Build — The system compiles the code, resolves dependencies, and packages the application.
  4. Test — Automated tests run: unit, integration, and maybe end-to-end. This is where most problems get caught.
  5. Deploy to staging/QA — The artifact goes to a staging environment that mirrors production.
  6. Manual approval (for Continuous Delivery) — A human approves the release. For Continuous Deployment, this step is automated too.
  7. 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_request to the on: 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 / -v options 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

  1. Use GitLab CI instead of GitHub Actions — similar syntax but built into GitLab, good for self-hosted setups.
  2. Use a self-hosted Jenkins server for maximum control — ideal for enterprise environments with strict compliance.
  3. 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.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.