DevOps

Panduan Lengkap CI CD Pipeline dengan GitHub Actions untuk Deploy Otomatis

CI/CD pipeline adalah tulang punggung dari praktik DevOps modern. Dengan Continuous Integration dan Continuous Deployment, Anda bisa mengotomatiskan proses build, test, dan deploy aplikasi secara konsisten dan andal. GitHub Actions, fitur bawaan dari GitHub, menawarkan solusi CI/CD yang powerful tanpa perlu tools tambahan.

Artikel ini akan membahas secara lengkap cara membuat CI/CD pipeline menggunakan GitHub Actions, mulai dari konsep dasar hingga deployment ke VPS production. Semua contoh dilengkapi dengan workflow YAML yang bisa langsung Anda gunakan.

Apa Itu CI/CD Pipeline

CI/CD terdiri dari dua konsep utama yang bekerja bersama-sama:

  • Continuous Integration (CI): Setiap kali developer push kode ke repository, proses build dan test berjalan secara otomatis. Ini memastikan kode baru tidak merusak fungsionalitas yang sudah ada.
  • Continuous Deployment (CD): Setelah lolos semua test, kode otomatis di-deploy ke staging atau production environment tanpa intervensi manual.

Pipeline yang baik mengurangi human error, mempercepat release cycle, dan memberikan feedback cepat kepada developer tentang kualitas kode mereka.

Mengapa Memilih GitHub Actions

GitHub Actions memiliki beberapa keunggulan dibanding tools CI/CD lain seperti Jenkins, GitLab CI, atau CircleCI:

  • Terintegrasi langsung: Tidak perlu setup server terpisah, langsung berjalan di ekosistem GitHub
  • Free tier generous: 2000 menit per bulan untuk private repository, unlimited untuk public
  • Marketplace kaya: Ribuan pre-built actions yang bisa digunakan langsung
  • YAML-based: Konfigurasi dalam bentuk file, bisa di-version control
  • Multi-platform: Support Ubuntu, Windows, dan macOS runners

Struktur Dasar Workflow GitHub Actions

Setiap workflow GitHub Actions didefinisikan dalam file YAML yang disimpan di direktori .github/workflows/. Berikut struktur dasarnya:


name: CI/CD Pipeline

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

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm test
      
      - name: Build project
        run: npm run build

Penjelasan komponen utama:

  • name: Nama workflow yang tampil di tab Actions di GitHub
  • on: Trigger yang memicu workflow berjalan (push, pull_request, schedule, dll)
  • jobs: Kumpulan langkah yang berjalan secara paralel atau berurutan
  • runs-on: Jenis runner (virtual machine) yang digunakan
  • steps: Langkah-langkah individual dalam setiap job
  • uses: Menggunakan pre-built action dari marketplace
  • run: Menjalankan command shell langsung

Contoh Pipeline Lengkap untuk Aplikasi Node.js

Berikut workflow lengkap yang mencakup linting, testing, building, dan deployment:


name: Node.js CI/CD Pipeline

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

env:
  NODE_ENV: production
  APP_NAME: my-app

jobs:
  lint:
    name: Code Linting
    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

  test:
    name: Unit Tests
    runs-on: ubuntu-latest
    needs: lint
    strategy:
      matrix:
        node-version: [18, 20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm test -- --coverage
      - name: Upload coverage
        uses: actions/upload-artifact@v4
        with:
          name: coverage-${{ matrix.node-version }}
          path: coverage/

  build:
    name: Build Application
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm run build
      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: dist/

  deploy:
    name: Deploy to Server
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    environment: production
    steps:
      - name: Download build artifact
        uses: actions/download-artifact@v4
        with:
          name: build-output
          path: dist/

      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/html/${{ env.APP_NAME }}
            git pull origin main
            npm ci --production
            npm run build
            pm2 restart ${{ env.APP_NAME }}

Deploy ke VPS dengan SSH

Untuk deploy ke VPS, kita menggunakan SSH action. Pertama, Anda perlu mengkonfigurasi secrets di repository GitHub:

  1. Buka repository GitHub Anda
  2. Klik menu Settings kemudian Secrets and variables > Actions
  3. Tambahkan secrets berikut:
  • SERVER_HOST: IP address atau domain VPS Anda (contoh: 192.168.1.100)
  • SERVER_USER: Username SSH (contoh: root atau deploy)
  • SSH_PRIVATE_KEY: Isi dari private key SSH (contoh: isi file id_rsa)

Untuk generate SSH key pair jika belum punya:


ssh-keygen -t ed25519 -C "github-deploy" -f ~/.ssh/github_deploy -N ""

# Copy public key ke VPS
ssh-copy-id -i ~/.ssh/github_deploy.pub user@your-vps-ip

# Copy private key untuk disimpan di GitHub Secrets
cat ~/.ssh/github_deploy

Pipeline untuk Aplikasi PHP dengan CodeIgniter 4

Bagi pengguna PHP, berikut contoh pipeline untuk aplikasi CodeIgniter 4:


name: PHP CI/CD - CodeIgniter 4

on:
  push:
    branches: [main]

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

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          extensions: mbstring, intl, json, mysql
          coverage: xdebug

      - name: Install Composer dependencies
        run: composer install --no-progress --prefer-dist

      - name: Copy env file
        run: cp env .env

      - name: Generate app key
        run: php spark key:generate

      - name: Run tests
        run: vendor/bin/phpunit

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

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'

      - name: Install dependencies
        run: composer install --no-dev --optimize-autoloader

      - name: Deploy to server
        uses: SamKirkland/[email protected]
        with:
          server: ${{ secrets.FTP_SERVER }}
          username: ${{ secrets.FTP_USERNAME }}
          password: ${{ secrets.FTP_PASSWORD }}
          local-dir: ./
          server-dir: /var/www/html/
          exclude: |
            **/.git*
            **/.env*
            **/tests/**
            **/.github/**
            writable/debugbar/**

Menggunakan Environment Variables dan Secrets

GitHub Actions menyediakan dua cara untuk menyimpan konfigurasi sensitif:


jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Deploy with secrets
        env:
          DB_HOST: ${{ secrets.DB_HOST }}
          DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
          API_KEY: ${{ secrets.API_KEY }}
        run: |
          echo "Deploying to production..."
          # Gunakan environment variables dalam script deploy

Perbedaan antara Secrets dan Variables:

  • Secrets: Untuk data sensitif (password, API key, token). Nilainya tidak bisa dibaca setelah disimpan, hanya muncul di log jika Anda secara eksplisit menggunakannya.
  • Variables: Untuk konfigurasi non-sensitif (URL, nama aplikasi, environment name). Bisa dilihat dan diedit oleh siapa saja yang punya akses repository.

Caching untuk Mempercepat Pipeline

Caching dependencies bisa menghemat waktu build secara signifikan:


steps:
  - uses: actions/checkout@v4

  # Cache untuk Node.js
  - uses: actions/setup-node@v4
    with:
      node-version: '20'
      cache: 'npm'  # Otomatis cache folder node_modules

  # Cache untuk PHP/Composer
  - name: Cache Composer packages
    uses: actions/cache@v4
    with:
      path: vendor
      key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
      restore-keys: |
        ${{ runner.os }}-composer-

  - name: Install dependencies
    run: composer install --no-progress --prefer-dist

Scheduled Workflow dan Cron Jobs

Selain trigger dari push atau pull request, Anda juga bisa menjalankan workflow secara terjadwal:


name: Scheduled Tasks

on:
  schedule:
    # Setiap hari jam 2 pagi UTC
    - cron: '0 2 * * *'
    # Setiap hari Senin jam 8 pagi UTC
    - cron: '0 8 * * 1'

jobs:
  database-backup:
    runs-on: ubuntu-latest
    steps:
      - name: Backup database via SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            mysqldump -u ${{ secrets.DB_USER }} -p${{ secrets.DB_PASSWORD }}               ${{ secrets.DB_NAME }} > /backups/db_$(date +%Y%m%d).sql
            gzip /backups/db_$(date +%Y%m%d).sql

Matrix Strategy untuk Multi-Environment Testing

Matrix strategy memungkinkan Anda menjalankan tests di berbagai versi atau konfigurasi secara paralel:


jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        php-version: ['8.1', '8.2', '8.3']
        database: ['mysql', 'postgres']
        exclude:
          - php-version: '8.1'
            database: 'postgres'
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-version }}
      - name: Run tests
        run: vendor/bin/phpunit
        env:
          DB_TYPE: ${{ matrix.database }}

Notification dan Slack Integration

Anda bisa menambahkan notifikasi Slack untuk memberitahu tim tentang status deployment:


jobs:
  notify:
    runs-on: ubuntu-latest
    needs: [test, deploy]
    if: always()
    steps:
      - name: Slack notification
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          channel: '#deployments'
          fields: repo,message,commit,author
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Best Practices CI/CD Pipeline

Untuk mendapatkan hasil maksimal dari CI/CD pipeline Anda, ikuti best practices berikut:

  • Pisahkan jobs berdasarkan fungsi: Jangan gabung lint, test, dan deploy dalam satu job. Pisahkan agar bisa berjalan paralel dan memudahkan debugging.
  • Gunakan environment protection rules: Untuk production deployment, tambahkan approval step agar tidak semua push langsung ke production.
  • Minimalkan secrets exposure: Jangan pernah mencetak secrets ke log. Gunakan environment variables dan mask sensitive data.
  • Pin action versions: Selalu gunakan versi spesifik (actions/checkout@v4) bukan versi major (actions/checkout@main) untuk menghindari breaking changes.
  • Gunakan concurrency groups: Hindari multiple deployment berjalan bersamaan yang bisa menyebabkan conflict.

concurrency:
  group: production-deploy
  cancel-in-progress: true

Troubleshooting Common Issues

Beberapa masalah umum yang sering terjadi saat setup CI/CD pipeline:

  • Workflow tidak ter-trigger: Pastikan branch name di trigger sesuai dengan branch yang Anda push. Juga cek apakah repository sudah meng-enable Actions di Settings.
  • SSH connection timeout: Pastikan VPS firewall mengizinkan koneksi dari GitHub IP ranges. Gunakan action appleboy/ssh-action yang sudah support timeout dan retry.
  • Permission denied saat deploy: Pastikan user SSH memiliki permission yang cukup untuk menulis ke direktori deployment. Gunakan deploy user dengan akses terbatas, bukan root.
  • Secrets tidak terbaca: Secrets tidak tersedia di pull request dari fork. Ini fitur keamanan, bukan bug.

Dengan CI/CD pipeline yang terkonfigurasi dengan baik, proses development menjadi lebih efisien, konsisten, dan andal. Mulailah dengan pipeline sederhana, lalu tambahkan fitur seiring kebutuhan tim Anda berkembang.


You may also like


0 Comments


Leave a Reply

Comments with links or spam keywords will be rejected.
Scroll to Top