DevOps Roadmap — Part 6: CI/CD Pipelines

By Suraj Ahir November 04, 2025 6 min read

Kubernetes Basics
Kubernetes Basics
← Part 5 DevOps Roadmap · Part 6 of 12 Part 7 →

CI/CD is one of the most important practices in modern software delivery. It is what separates teams that deploy once a month with high stress and frequent rollbacks from teams that deploy dozens of times a day with confidence. In this part, we will understand what CI/CD really means and build real pipelines from scratch.

What is CI/CD?

Continuous Integration (CI) means that every code change automatically triggers a series of automated checks: the code is built, tests are run, and the team gets immediate feedback on whether the change is safe. The goal is to catch integration problems early, when they are small and cheap to fix.

Continuous Deployment (CD) means that code that passes CI is automatically deployed to staging or production without manual intervention. The goal is to reduce the time between writing code and delivering it to users.

Together, CI/CD turns software delivery from a risky, manual event into a routine, automated process. Quality goes up, stress goes down, and teams ship faster.

CI/CD Pipeline Stages

A typical pipeline runs these stages in sequence:

  1. Source — Developer pushes code to Git repository
  2. Build — Code is compiled or packaged (Docker image built, JAR created, etc.)
  3. Test — Unit tests, integration tests, security scans run automatically
  4. Staging Deploy — Successful builds are deployed to a staging environment
  5. Acceptance Tests — Automated or manual testing in staging
  6. Production Deploy — After approval, the build is deployed to production

GitHub Actions — Real Pipeline

.github/workflows/ci.yml
name: CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'

      - name: Install dependencies
        run: |
          pip install -r requirements.txt
          pip install pytest pytest-cov

      - name: Run tests with coverage
        run: pytest tests/ -v --cov=. --cov-report=xml

      - name: Upload coverage report
        uses: codecov/codecov-action@v3

  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: yourusername/myapp:${{ github.sha }},yourusername/myapp:latest

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    environment: production
    steps:
      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            docker pull yourusername/myapp:latest
            docker compose up -d

Pipeline Best Practices

Environment-Specific Deployments

Multi-Environment Pipeline
on:
  push:
    branches:
      - develop    # → deploys to staging
      - main       # → deploys to production

jobs:
  deploy-staging:
    if: github.ref == 'refs/heads/develop'
    environment: staging
    # ... staging deploy steps

  deploy-production:
    if: github.ref == 'refs/heads/main'
    environment: production
    # ... production deploy steps with approval gate

In Part 7, we will cover Infrastructure as Code with Terraform — how DevOps teams manage cloud resources through code instead of clicking through web consoles.

Pipeline as Code Best Practices

Defining CI/CD pipelines in code files checked into version control provides the same benefits as infrastructure as code: auditability, reproducibility, and collaborative improvement. Store pipeline definitions alongside the application code they build — this creates a clear relationship and ensures pipeline changes go through the same review process as code changes. Use reusable pipeline components where your CI/CD tool supports them — GitHub Actions reusable workflows, GitLab CI includes, Jenkins shared libraries — to avoid duplicating pipeline logic across repositories. Version your pipeline actions and dependencies explicitly rather than using floating tags that could change without notice.

Security in CI/CD Pipelines

CI/CD pipelines have access to production systems and sensitive credentials, making them high-value targets. Follow these security practices: store all credentials as secrets, never in pipeline code or logs. Use short-lived credentials where possible — OIDC (OpenID Connect) integration between GitHub Actions and AWS/GCP/Azure provides temporary credentials without stored secrets. Scan code for secrets before commits using tools like git-secrets or Gitleaks. Scan dependencies for vulnerabilities in the pipeline. Use separate pipelines with minimal permissions for different environments, especially production. Require manual approval gates for production deployments.

Practice Exercise

Set up a complete CI/CD pipeline for a simple web application using GitHub Actions: trigger on push to main, run linting and tests, build a Docker image, push to Docker Hub using stored secrets, and deploy to a simple hosting environment. Add a status badge to your README.md showing the CI pipeline status. Verify the pipeline runs end-to-end successfully by pushing a change and following the pipeline execution in the Actions tab.

The Continuous Improvement Mindset

DevOps is not a destination but a continuous journey of improvement. The practices covered here — automation, monitoring, infrastructure as code, CI/CD pipelines — are tools in service of a deeper goal: enabling teams to deliver software changes to production quickly, safely, and reliably. The measurement that matters is not which tools you use but how long it takes to go from a committed code change to running in production, and how confident you are in that process. The best DevOps teams measure their deployment frequency, lead time for changes, change failure rate, and mean time to recovery (the DORA metrics), and treat these as engineering objectives to improve over time.

Consistent application of the principles covered here, combined with ongoing learning and hands-on practice, is what separates those who understand technology conceptually from those who can build and operate real systems. The investment in depth pays dividends for years. Keep learning, keep building, and keep asking the questions that drive deeper understanding.

Disclaimer: This content is for educational purposes only. SRJahir Tech does not guarantee any specific outcome or job placement.