Isaac.

GitHub Actions for CI/CD

Automate building, testing, and deploying with GitHub Actions.

By EMEPublished: February 20, 2025
github actionsci/cdautomationdeploymenttesting

A Simple Analogy

GitHub Actions is like hiring robots to run your tests and deploy your code. Every time you push, robots automatically test, build, and deploy—no manual work needed.


Why GitHub Actions?

  • Automation: No manual testing/deployment
  • Integrated: Runs right in GitHub
  • Flexible: Write custom workflows
  • Free tier: Generous free minutes
  • Notifications: Slack, email alerts

Basic Workflow

# .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: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run tests
      run: npm test
    
    - name: Run linter
      run: npm run lint

.NET Workflow

name: .NET CI

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

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup .NET
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: '8.0.x'
    
    - name: Restore dependencies
      run: dotnet restore
    
    - name: Build
      run: dotnet build --configuration Release
    
    - name: Test
      run: dotnet test --configuration Release --no-build
    
    - name: Publish
      run: dotnet publish -c Release -o release

Deployment Workflow

name: Deploy

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Build Docker image
      run: docker build -t myapp:${{ github.sha }} .
    
    - name: Push to registry
      run: |
        echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
        docker push myapp:${{ github.sha }}
    
    - name: Deploy to server
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USER }}
        key: ${{ secrets.SSH_KEY }}
        script: |
          docker pull myapp:${{ github.sha }}
          docker run -d -p 80:3000 myapp:${{ github.sha }}

Matrix Testing

name: Test Multiple Versions

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16.x, 18.x, 20.x]
        os: [ubuntu-latest, windows-latest]
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
    
    - run: npm ci
    - run: npm test

Secrets Management

name: Secure Deployment

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 AWS
      run: |
        aws s3 cp . s3://my-bucket --recursive
        aws cloudfront create-invalidation --distribution-id ${{ secrets.DISTRIBUTION_ID }} --paths "/*"

Best Practices

  1. Keep workflows simple: One job per responsibility
  2. Use actions from marketplace: Don't reinvent
  3. Cache dependencies: Speed up builds
  4. Manage secrets securely: Never hardcode
  5. Notify on failure: Get alerts quickly

Related Concepts

  • GitLab CI/CD
  • Jenkins
  • CircleCI
  • Artifact storage

Summary

GitHub Actions automates testing and deployment directly from your repository. Define workflows in YAML to build, test, and deploy with every push.