🤖 AI vẫn chưa thể thay thế mình đâu, bạn có thể khám phá những gì mình đang làm tại đây!

Triển khai CI/CD với GitHub Actions

K
Võ Cao Kỳ

2025/02/26

CI/CD (Continuous Integration & Continuous Deployment) giúp tự động hóa việc build, test, và deploy code một cách nhanh chóng và hiệu quả. GitHub Actions là một công cụ mạnh mẽ giúp bạn thiết lập CI/CD ngay trong GitHub repository.


Tạo Workflow CI/CD với GitHub Actions

GitHub Actions sử dụng workflow files để định nghĩa các bước thực hiện CI/CD. Các file này được lưu trong thư mục .github/workflows/ trong từng repository của bạn.

Tạo file workflow

Trong project của bạn, tạo một file mới:
📂 .github/workflows/node-ci.yml

index.sh
name: Github Actions

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

jobs:
  build-job:
    timeout-minutes: 10
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [lts, 20]
    container:
      image: node:${{ matrix.node-version }}
      options: --user root
      volumes:
        - .:/app
    steps:
      - name: Check out repository code
        uses: actions/checkout@v4

      - name: Install packages
        run: npm ci --unsafe-perm=true --allow-root

      - name: Build
        run: npm run generate

      - name: Upload dist folder as artifact
        if: github.event_name == 'push' && github.ref == 'refs/heads/develop' && matrix.node-version == 'lts'
        uses: actions/upload-artifact@v4
        with:
          name: dist-${{ matrix.node-version }}-${{ github.run_id }}
          path: dist/
          retention-days: 1

Giải thích file workflow:

  • on: push: Kích hoạt khi có push lên branch develop.
  • on: pull_request: Kích hoạt khi có pull request mới được tạo vào nhánh base develop.
  • jobs: build-job: Tên công việc được thực hiện ở tác vụ CICD này.
  • timeout-minutes: 10: Số phút tối đa mà công việc có thể chạy trước khi Github hủy nó, mặc định sẽ là 360.
  • runs-on: ubuntu-latest: Chỉ định môi trường chạy là Ubuntu mới nhất
  • strategy.matrix.node-version: [lts, 20]: Matrix Strategy cho phép chạy workflow trên nhiều phiên bản Node.js khác nhau, ở đây workflow sẽ chạy với phiên bản lts và 20
  • container.image: node:${{ matrix.node-version }}: Chạy workflow trong container Node.js với phiên bản tương ứng trong matrix.node-version.
  • options: --user root: Chạy container với quyền root để có thể cài đặt thêm package hoặc chỉnh sửa file hệ thống nếu cần.
  • volumes: - .:/app: Mount thư mục hiện tại (.) vào đường dẫn /app bên trong container, giúp truy cập mã nguồn của dự án từ trong container.

Các bước trong steps:


Deploy lên Amazon S3 và CloudFront

Ngoài việc deploy lên server, bạn có thể sử dụng AWS S3CloudFront để lưu trữ và phân phối ứng dụng.

Cấu hình AWS Credentials

Vào GitHub RepositorySettingsSecrets and VariablesActionsNew repository secret và thêm:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_REGION
  • S3_BUCKET_NAME

💡 Mẹo:

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYAWS_REGION được tạo ở phần security credentials > access key trong IAM user

Chỉnh sửa workflow để deploy lên S3

Cập nhật file .github/workflows/node-ci.yml:

index.sh
deploy-job:
  timeout-minutes: 10
  needs: build-job
  runs-on: ubuntu-latest
  if: github.event_name == 'push' && github.ref == 'refs/heads/develop'

  steps:
    - name: Download dist artifact
      uses: actions/download-artifact@v4
      with:
        name: dist-lts-${{ github.run_id }}
        path: ./dist

    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v4
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ secrets.AWS_REGION }}

    - name: Deploy static site to S3 bucket
      run: |
        aws s3 sync ./dist s3://${{ secrets.S3_BUCKET_NAME }} --delete

    - name: Update index.html cache settings
      run: |
        aws s3 sync s3://${{ secrets.S3_BUCKET_NAME }}/ s3://${{ secrets.S3_BUCKET_NAME }}/ \
          --exclude "*" --include "index.html" \
          --cache-control "max-age=0, s-maxage=2592000, must-revalidate" \
          --content-type 'text/html' \
          --metadata-directive REPLACE

Invalidate CloudFront Cache

Để cập nhật nội dung nhanh chóng, thêm bước:

index.sh
- name: Invalidate CloudFront cache
  run: |
    aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*" >/dev/null

💡 Mẹo:

CLOUDFRONT_DISTRIBUTION_ID cần được thêm vào GitHub Secrets. Khi có thay đổi, nội dung trên CloudFront sẽ được cập nhật ngay.


Kết luận

GitHub Actions giúp tự động hóa quá trình triển khai ứng dụng, giảm thiểu lỗi và tăng tốc độ phát triển. Bạn có thể mở rộng CI/CD với các bước kiểm tra mã nguồn (Lint), chạy test (Jest), thông báo Slack, v.v.

🚀 Giờ đây, mỗi lần push lên develop, ứng dụng của bạn sẽ tự động được build và deploy lên S3 và CloudFront!



Cảm ơn tài liệu tham khảo từ 💓


Lưu ý: Tất cả các bài viết trên blog này được viết dựa trên kinh nghiệm cá nhân và quá trình tìm hiểu của mình. Mình hy vọng chúng có thể giúp ích cho bạn trong công việc và học tập, nhưng hãy xem đây như một nguồn tham khảo thay vì hướng dẫn tuyệt đối. Công nghệ luôn thay đổi, mỗi dự án có những đặc thù riêng, vì vậy bạn nên kiểm tra, thử nghiệm và điều chỉnh cho phù hợp với nhu cầu thực tế. Nếu có góp ý hay câu hỏi, đừng ngần ngại chia sẻ nhé!

Copyright © 2025 Vo Cao Ky

Cảm ơn Nuxt.js, ShadcnUI đã giúp mình build website này.