Salin dan Bagikan
Cara Setup CI/CD dengan GitHub Actions - Panduan lengkap setup CI/CD pipeline dengan GitHub Actions untuk automation deployment

Cara Setup CI/CD dengan GitHub Actions

GitHub Actions memungkinkan automation workflow untuk CI/CD. Mari pelajari cara setup dari dasar.

Apa itu GitHub Actions?

Konsep Dasar

GitHub Actions adalah:
- CI/CD platform built into GitHub
- Automate workflows (build, test, deploy)
- Event-driven (push, PR, schedule)
- Free untuk public repos
- 2000 minutes/month untuk private (free tier)

Terminologi

Workflow: Automation process (.yml file)
Job: Set of steps in workflow
Step: Individual task
Action: Reusable unit of code
Runner: Server yang menjalankan workflow
Event: Trigger untuk workflow

Basic Workflow

File Structure

repository/
├── .github/
│   └── workflows/
│       ├── ci.yml
│       └── deploy.yml
├── src/
└── package.json

Simple CI Workflow

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

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

jobs:
  build:
    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"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm test

      - name: Build
        run: npm run build

Events dan Triggers

Common Events

on:
  # Push to specific branches
  push:
    branches:
      - main
      - "release/*"
    paths:
      - "src/**"
      - "!src/**/*.md"

  # Pull request
  pull_request:
    branches: [main]
    types: [opened, synchronize, reopened]

  # Manual trigger
  workflow_dispatch:
    inputs:
      environment:
        description: "Environment to deploy"
        required: true
        default: "staging"
        type: choice
        options:
          - staging
          - production

  # Scheduled
  schedule:
    - cron: "0 0 * * *" # Daily at midnight

  # Release
  release:
    types: [published]

Jobs dan Steps

Multiple Jobs

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        run: npm test

  build:
    runs-on: ubuntu-latest
    needs: test # Wait for test job
    steps:
      - uses: actions/checkout@v4
      - name: Build
        run: npm run build

  deploy:
    runs-on: ubuntu-latest
    needs: [test, build] # Wait for both
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Deploy
        run: echo "Deploying..."

Matrix Strategy

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [18, 20, 22]
        exclude:
          - os: windows-latest
            node-version: 18

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm test

Environment Variables

Set Variables

env:
  NODE_ENV: production
  API_URL: https://api.example.com

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      BUILD_DIR: ./dist

    steps:
      - name: Use env vars
        run: |
          echo "Node env: $NODE_ENV"
          echo "Build dir: $BUILD_DIR"
        env:
          STEP_VAR: step-level

Secrets

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to server
        env:
          SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          API_TOKEN: ${{ secrets.API_TOKEN }}
        run: |
          echo "$SSH_KEY" > key.pem
          chmod 600 key.pem
          # Use for deployment

GitHub Context

steps:
  - name: Use GitHub context
    run: |
      echo "Repository: ${{ github.repository }}"
      echo "Branch: ${{ github.ref_name }}"
      echo "SHA: ${{ github.sha }}"
      echo "Actor: ${{ github.actor }}"
      echo "Event: ${{ github.event_name }}"

Caching

Cache Dependencies

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

      - name: Setup Node.js with cache
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      # Or manual caching
      - name: Cache node_modules
        uses: actions/cache@v4
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - run: npm ci

Artifacts

Upload Artifacts

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-files
          path: dist/
          retention-days: 7

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          name: build-files
          path: dist/

Common Workflows

Node.js CI/CD

name: Node.js CI/CD

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

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

  build:
    needs: 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 build
      - uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/
      - name: Deploy to server
        run: |
          # Add deployment commands
          echo "Deploying..."

Docker Build & Push

name: Docker Build

on:
  push:
    branches: [main]
    tags: ["v*"]

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

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - 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:
          context: .
          push: true
          tags: |
            username/app:latest
            username/app:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Deploy to Cloud

# Vercel
- name: Deploy to Vercel
  uses: amondnet/vercel-action@v25
  with:
    vercel-token: ${{ secrets.VERCEL_TOKEN }}
    vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
    vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
    vercel-args: "--prod"

# Netlify
- name: Deploy to Netlify
  uses: nwtgck/actions-netlify@v3
  with:
    publish-dir: "./dist"
    production-branch: main
    github-token: ${{ secrets.GITHUB_TOKEN }}
    deploy-message: "Deploy from GitHub Actions"
  env:
    NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
    NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

# AWS S3
- name: Deploy to S3
  uses: jakejarvis/s3-sync-action@master
  with:
    args: --delete
  env:
    AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    SOURCE_DIR: "dist"

Reusable Workflows

Create Reusable Workflow

# .github/workflows/reusable-build.yml
name: Reusable Build

on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: "20"
    secrets:
      npm-token:
        required: false

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

Use Reusable Workflow

# .github/workflows/main.yml
name: Main

on:
  push:
    branches: [main]

jobs:
  build:
    uses: ./.github/workflows/reusable-build.yml
    with:
      node-version: "20"
    secrets:
      npm-token: ${{ secrets.NPM_TOKEN }}

Best Practices

Security

# Pin action versions
- uses: actions/checkout@v4  # Use specific version

# Use secrets for sensitive data
env:
  API_KEY: ${{ secrets.API_KEY }}

# Limit permissions
permissions:
  contents: read
  pull-requests: write

# Use environments for production
jobs:
  deploy:
    environment: production
    runs-on: ubuntu-latest

Performance

# Enable caching
- uses: actions/cache@v4

# Use fail-fast
strategy:
  fail-fast: true

# Cancel in-progress runs
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

Kesimpulan

GitHub Actions adalah powerful tool untuk CI/CD yang terintegrasi langsung dengan GitHub. Mulai dengan simple workflow lalu kembangkan sesuai kebutuhan project.

Artikel Terkait

Link Postingan : https://www.tirinfo.com/cara-setup-cicd-github-actions/

Hendra WIjaya
Tirinfo
4 minutes.
7 January 2026