GitHub Actions là công cụ CI/CD tích hợp sẵn trong GitHub. Thay vì dùng Jenkins hay GitLab CI riêng, bạn có thể tự động hóa build, test, deploy ngay trong repository. Bài viết này hướng dẫn cách setup GitHub Actions từ cơ bản đến production.

GitHub Actions là gì?

GitHub Actions là nền tảng CI/CD (Continuous Integration/Continuous Deployment) của GitHub. Bạn có thể:

  • Automate tests: Chạy unit tests mỗi khi push code.
  • Build & Deploy: Tự động build và deploy khi merge code.
  • Custom workflows: Viết workflow bằng YAML.

Cấu trúc Workflow

Workflow được định nghĩa trong file .github/workflows/*.yml:

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

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

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - 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

1. Cơ bản: Node.js CI Pipeline

Tạo workflow đơn giản để test Node.js app:

name: Node.js CI

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

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18, 20, 22]

    steps:
    - uses: actions/checkout@v4

    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v4
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'

    - name: Install dependencies
      run: npm ci

    - name: Run tests
      run: npm test

    - name: Upload coverage
      uses: actions/upload-artifact@v4
      with:
        name: coverage-report
        path: coverage/

2. Python CI Pipeline

name: Python CI

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

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.10', '3.11', '3.12']

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
        pip install pytest pytest-cov

    - name: Run tests
      run: pytest --cov=./

    - name: Upload coverage
      uses: actions/upload-artifact@v4
      with:
        name: coverage-py-${{ matrix.python-version }}
        path: htmlcov/

3. Docker Build & Push

Tự động build và push Docker image lên Docker Hub hoặc GitHub Container Registry:

name: Docker Build & Push

on:
  push:
    branches: [ main ]
    tags:
      - 'v*'

jobs:
  build-push:
    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: |
          myusername/myapp:latest
          myusername/myapp:${{ github.sha }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

4. Deploy lên Server

Dùng SSH để deploy lên server:

name: Deploy to Server

on:
  push:
    branches: [ main ]

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

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

5. Deploy lên Kubernetes

name: Deploy to Kubernetes

on:
  push:
    branches: [ main ]

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

    - name: Setup kubectl
      uses: azure/setup-kubectl@v4

    - name: Configure kubectl
      run: |
        echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig
        echo "KUBECONFIG=$(pwd)/kubeconfig" >> $GITHUB_ENV

    - name: Deploy to Kubernetes
      run: |
        kubectl apply -f k8s/
        kubectl rollout status deployment/myapp

6. Caching Dependencies

Tăng tốc CI bằng cache:

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

    - name: Cache npm packages
      uses: actions/cache@v4
      with:
        path: ~/.npm
        key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
          ${{ runner.os }}-npm-

    - name: Cache pip packages
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
        restore-keys: |
          ${{ runner.os }}-pip-

    - name: Cache Docker layers
      uses: docker/build-push-action@v5
      with:
        cache-from: type=gha
        cache-to: type=gha,mode=max

7. Matrix Build

Build nhiều versions/destinations cùng lúc:

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - node-version: 18
            environment: staging
          - node-version: 20
            environment: production
          
    steps:
    - uses: actions/checkout@v4

    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v4
      with:
        node-version: ${{ matrix.node-version }}

    - name: Deploy to ${{ matrix.environment }}
      run: |
        echo "Deploying Node ${{ matrix.node-version }} to ${{ matrix.environment }}"

8. Notifications

Slack Notification

name: CI with Slack

on:
  push:
    branches: [ main ]

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

  notify:
    needs: ci
    runs-on: ubuntu-latest
    if: always()
    
    steps:
    - name: Notify Slack
      uses: slackapi/slack-github-action@v1
      with:
        channel-id: ${{ secrets.SLACK_CHANNEL_ID }}
        payload: |
          {
            "text": "Build ${{ job.status }}: ${{ github.event.head_commit.message }}"
          }
      env:
        SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

9. Environment Secrets

Thêm secrets trong GitHub: Settings → Secrets and variables → Actions

  • DOCKERHUB_USERNAME — Docker Hub username
  • DOCKERHUB_TOKEN — Docker Hub token
  • SERVER_HOST — Server IP/domain
  • SERVER_USER — SSH username
  • SERVER_SSH_KEY — SSH private key

10. Reusable Workflows

Tái sử dụng workflow trong nhiều repositories:

# .github/workflows/deploy.yml (reusable)
name: Reusable Deploy

on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ inputs.environment }}
    steps:
    - uses: actions/checkout@v4
    - name: Deploy
      run: echo "Deploying to ${{ inputs.environment }}"
# .github/workflows/ci.yml (caller)
jobs:
  deploy-staging:
    uses: ./.github/workflows/deploy.yml
    with:
      environment: staging

Common Patterns

  • on push: Chạy khi push code
  • on pull_request: Chạy khi tạo PR
  • on schedule: Chạy theo cron (VD: every day at midnight)
  • on release: Chạy khi tạo release
  • needs: Job phụ thuộc job khác

Kết Luận

GitHub Actions là công cụ CI/CD mạnh mẽ, tích hợp sẵn trong GitHub. Với syntax YAML đơn giản, bạn có thể automate mọi thứ từ test đến deploy.

Chào các bạn mình là Quốc Hùng , mình sinh ra thuộc cung song tử ,song tử luôn khẳng định chính mình ,luôn luôn phấn đấu vượt lên phía trước ,mình sinh ra và lớn lên tại vùng đất võ cổ truyền ,đam mê của mình là coder ,ngày đi học tối về viết blog ...