CI/CD Pipeline — GitHub Actions

লেসন ৩৭ / ৩৮

🔄 CI/CD কী?

  • CI — Continuous Integration — code push → auto build + test
  • CD — Continuous Delivery/Deploy — test pass → auto release
  • Developer productivity 10x
  • Bug early caught, faster iteration

🛠️ Options

  • GitHub Actions — native GitHub, 2000 min free
  • GitLab CI — native GitLab
  • Jenkins — self-hosted king
  • CircleCI — cloud, fast
  • AWS CodePipeline — AWS native

📝 First Workflow

# .github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build

🐘 PHP Laravel Pipeline

name: Laravel CI/CD
on:
  push: {branches: [main]}

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: testing
        ports: [3306:3306]
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: "8.2"
      - run: composer install --prefer-dist --no-progress
      - run: cp .env.example .env && php artisan key:generate
      - run: php artisan migrate --force
      - run: vendor/bin/phpunit

  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == "refs/heads/main"
    steps:
      - uses: actions/checkout@v4
      - name: Deploy to VPS
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            cd /var/www/myapp
            git pull origin main
            composer install --no-dev --optimize-autoloader
            php artisan migrate --force
            php artisan config:cache
            sudo systemctl reload php8.2-fpm

🐳 Docker Build & Push

name: Docker
on:
  push: {branches: [main]}
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USER }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: user/myapp:latest,user/myapp:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

🔐 Secrets

Repo → Settings → Secrets → Actions → New
VPS_HOST, VPS_SSH_KEY, DB_PASSWORD, AWS_KEY

# Use
${{ secrets.VPS_HOST }}

📢 Slack Notification

- name: Slack notify
  if: always()
  uses: slackapi/slack-github-action@v1
  with:
    payload: |
      {
        "text": "Deploy ${{ job.status }}: ${{ github.ref }}"
      }
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

🔄 Rollback on Failure

deploy:
  steps:
    - name: Deploy
      id: deploy
      run: ./deploy.sh

    - name: Rollback on failure
      if: failure()
      run: |
        ssh $VPS "cd /var/www/app && git reset --hard HEAD~1 && ./restart.sh"

🌍 Matrix Build

strategy:
  matrix:
    node: [18, 20, 22]
    os: [ubuntu-latest, macos-latest]
steps:
  - uses: actions/setup-node@v4
    with: {node-version: ${{ matrix.node }}}

⏰ Scheduled Workflow

on:
  schedule:
    - cron: "0 2 * * *"   # 2am daily
jobs:
  backup:
    steps: [./backup.sh]

💡 Best Practices

  • Branch protection: require CI pass
  • Cache dependencies (npm, composer, pip)
  • Parallel jobs where possible
  • Deploy only from main branch
  • Tag release: v1.2.3 → deploy prod
  • Staging deploy on PR, prod on merge
  • Secret scanning enable (Dependabot)

🎓 মূল কথা ⭐

CI/CD = developer productivity 10x + bug prevention। GitHub Actions 2000 min free — small team cover। Push → test → deploy automatic = modern standard। Rollback plan থাকতে হবে।