Lewati ke konten
Kembali ke Blog

Cara Setup CI/CD dengan GitHub Actions

Β· Β· 6 menit baca

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: 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.

Ditulis oleh

Hendra Wijaya

Hanya hamba Allah Ta'ala yang berusaha berbuat baik..

Tinggalkan Komentar

Email tidak akan ditampilkan.