DevOps11/19/2025⏱️ 9 min read
CI/CD with GitHub Actions: Automating Your Development Workflow
CI/CDGitHub ActionsDevOpsAutomationContinuous IntegrationContinuous Deployment

CI/CD with GitHub Actions: Automating Your Development Workflow

Introduction

Continuous Integration and Continuous Deployment (CI/CD) have become essential practices in modern software development. GitHub Actions provides a powerful, integrated CI/CD platform that automates your development workflow directly in your GitHub repository.

This comprehensive guide covers CI/CD with GitHub Actions, from basic workflows to advanced automation. You'll learn how to automate testing, building, and deployment processes, improving code quality and deployment speed.

What is CI/CD?

CI/CD stands for Continuous Integration and Continuous Deployment:

Continuous Integration (CI):

  • Automatically test code on every commit
  • Catch bugs early in development
  • Ensure code quality
  • Run automated tests
  • Perform code analysis

Continuous Deployment (CD):

  • Automatically deploy code to production
  • Reduce manual deployment errors
  • Faster time to market
  • Consistent deployment process

Benefits:

  • Faster Development: Automated processes save time
  • Higher Quality: Catch issues early
  • Reduced Risk: Automated testing and deployment
  • Better Collaboration: Team sees results immediately
  • Consistent Deployments: Same process every time

Getting Started with GitHub Actions

GitHub Actions workflows are defined in YAML files:

# .github/workflows/ci.yml
name: CI

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

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run tests
      run: npm test

on:
  # Push to branches
  push:
    branches: [ main, develop ]
  
  # Pull requests
  pull_request:
    branches: [ main ]
  
  # Scheduled (cron)
  schedule:
    - cron: '0 0 * * *'  # Daily at midnight
  
  # Manual trigger
  workflow_dispatch:
  
  # Release
  release:
    types: [ published ]

Common CI/CD Workflows

Here are common CI/CD workflow patterns:

name: Node.js CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        node-version: [16, 18, 20]
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run linter
      run: npm run lint
    
    - name: Run tests
      run: npm test
    
    - name: Upload coverage
      uses: codecov/codecov-action@v3
      with:
        files: ./coverage/lcov.info

name: Python CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.9'
    
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
        pip install pytest pytest-cov
    
    - name: Run tests
      run: pytest --cov=src --cov-report=xml
    
    - name: Upload coverage
      uses: codecov/codecov-action@v3

name: Docker Build

on:
  push:
    branches: [ main ]
    tags:
      - 'v*'

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2
    
    - name: Login to Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}
    
    - name: Build and push
      uses: docker/build-push-action@v4
      with:
        context: .
        push: true
        tags: user/app:latest

Deployment Workflows

Automate deployment with GitHub Actions:

name: Deploy to AWS

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v2
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: us-east-1
    
    - name: Deploy to Elastic Beanstalk
      run: |
        eb init -p python-3.9 myapp
        eb deploy

name: Deploy to Vercel

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Deploy to Vercel
      uses: amondnet/vercel-action@v20
      with:
        vercel-token: ${{ secrets.VERCEL_TOKEN }}
        vercel-org-id: ${{ secrets.ORG_ID }}
        vercel-project-id: ${{ secrets.PROJECT_ID }}

name: Deploy to Kubernetes

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up kubectl
      uses: azure/setup-kubectl@v2
    
    - name: Configure kubectl
      run: |
        echo "${{ secrets.KUBECONFIG }}" > $HOME/.kube/config
    
    - name: Deploy
      run: |
        kubectl set image deployment/myapp myapp=myapp:${{ github.sha }}
        kubectl rollout status deployment/myapp

Advanced Workflow Features

GitHub Actions provides advanced features for complex workflows:

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [16, 18, 20]
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}

steps:
  - name: Run tests
    run: npm test
  
  - name: Deploy
    if: github.ref == 'refs/heads/main'
    run: npm run deploy

env:
  NODE_ENV: production
  API_URL: ${{ secrets.API_URL }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      DATABASE_URL: ${{ secrets.DATABASE_URL }}
    steps:
      - name: Deploy
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
        run: ./deploy.sh

steps:
  - name: Build
    run: npm run build
  
  - name: Upload artifacts
    uses: actions/upload-artifact@v3
    with:
      name: dist
      path: dist/
  
  - name: Download artifacts
    uses: actions/download-artifact@v3
    with:
      name: dist

Best Practices

Follow these best practices for effective CI/CD:

1. Fast Feedback:

  • Run quick tests first
  • Parallelize jobs when possible
  • Cache dependencies

2. Security:

  • Use secrets for sensitive data
  • Never commit secrets
  • Use least privilege
  • Scan for vulnerabilities

3. Reliability:

  • Use specific action versions
  • Test workflows locally
  • Handle failures gracefully
  • Use retry logic

4. Maintainability:

  • Reusable workflows
  • Clear workflow names
  • Document complex steps
  • Keep workflows simple

Example Reusable Workflow:

# .github/workflows/reusable-test.yml
name: Reusable Test

on:
  workflow_call:
    inputs:
      node-version:
        required: true
        type: string

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: ${{ inputs.node-version }}
    - run: npm ci
    - run: npm test

Conclusion

GitHub Actions provides a powerful, integrated CI/CD platform that automates your development workflow. By implementing CI/CD practices, you can improve code quality, reduce deployment time, and catch issues early.

Start with simple workflows and gradually add more automation. Focus on fast feedback, security, and reliability to build effective CI/CD pipelines. Remember that CI/CD is not just about automationβ€”it's about improving your development process and delivering better software faster.

With the right approach, GitHub Actions can transform your development workflow, making it more efficient, reliable, and enjoyable.

Share this article

Comments