“Máy mình chạy được” chưa trả lời câu hỏi liệu một pull request có chạy được từ checkout sạch hay không. Với team nhỏ, một workflow kiểm tra ngắn và đáng tin thường hữu ích hơn một pipeline nhiều bước nhưng không ai hiểu vì sao thất bại.
Bài này hướng dẫn một cấu hình tham khảo cho repository Node.js dùng npm. Tài liệu được kiểm tra ngày 21/10/2026; ví dụ chọn Node.js 24, không mặc định mọi dự án đều nâng lên phiên bản đó. Hãy dùng phiên bản mà repository của bạn hỗ trợ.
1. Thống nhất lệnh chạy ở local trước
Repository cần commit package-lock.json và định nghĩa ba script lint, test, build trong package.json. Nội dung cụ thể phụ thuộc công cụ của dự án. Chạy lần lượt:
npm ci
npm run lint
npm test
npm run build
Nếu test đang bật chế độ watch, hãy cấu hình lệnh chạy một lần cho CI theo tài liệu test runner đang dùng. Nếu dự án không có bước build, bỏ bước build trong workflow một cách có chủ đích. Không thêm --if-present chỉ để biến một script bị quên thành trạng thái xanh.
Theo tài liệu npm ci, lệnh yêu cầu lockfile hiện có và báo lỗi khi dependency trong lockfile không khớp package.json. Đây là kiểm tra hữu ích cho một bản checkout sạch, chứ không chỉ là lựa chọn cài package nhanh hơn.
2. Thêm workflow nhỏ và đọc được
Tạo file .github/workflows/quality.yml trong repository bạn muốn kiểm tra:
name: Quality checks
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
quality:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v7
with:
node-version: '24'
cache: npm
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
- name: Test
run: npm test
- name: Build
run: npm run build
Các major version của action trong ví dụ được đối chiếu với hướng dẫn Node.js của GitHub. Khi áp dụng vào repository có chính sách pin commit SHA hoặc runner riêng, hãy theo chính sách đó và kiểm tra yêu cầu runner của từng action.
Workflow này dành cho dự án npm tại thư mục gốc. Nếu mã nằm trong apps/web, bạn cần đặt working directory và cache dependency path tương ứng. Đừng chỉ đổi đường dẫn của bước test rồi để bước install chạy nhầm thư mục.
3. Hiểu cache đang giải quyết việc gì
Trong setup-node, cấu hình cache npm hỗ trợ dùng lại dữ liệu của package manager. Nó không thay thế npm ci, cũng không chứng minh dependency đã cài trong một lần chạy trước còn phù hợp.
Khi CI lỗi cài package, trước tiên hãy đọc lỗi lockfile, phiên bản Node và cấu hình registry. Xóa cache có thể giúp điều tra một số lỗi, nhưng không sửa được việc repository quên commit lockfile mới.
4. Chạy thử bằng một pull request nhỏ
Bạn có thể thêm một test thuần cho một hàm đang có, rồi xác nhận ba điều:
- Pull request tạo đúng một lượt kiểm tra mà team mong đợi.
- Khi chủ động đổi assertion thành sai, bước test chuyển đỏ và log chỉ ra assertion đó.
- Khi sửa lại, workflow chạy qua cả build, không chỉ dừng ở test.
Đây là quy trình kiểm chứng đề xuất. Ví dụ trong bài chưa được chạy trên repository của bạn; trạng thái cuối cùng cần được xác nhận từ lượt Actions thực tế. Nếu test đụng dịch vụ bên ngoài, hãy chuẩn bị môi trường test phù hợp trước khi coi lỗi mạng là lỗi của pull request.
5. Phân biệt workflow chạy được và quy tắc merge
Một check xanh cung cấp bằng chứng cho những lệnh thực sự đã chạy. Nó không tự nói rằng mọi hành vi của sản phẩm đã được kiểm tra. Một workflow được khai báo cũng chưa đủ nếu nhánh đích vẫn cho merge mà không yêu cầu check đó.
Sau khi tên check ổn định, cấu hình ruleset hoặc branch protection theo quy trình của team. Đọc tài liệu nhánh được bảo vệ để hiểu required status checks và quyền có thể bỏ qua quy tắc.
Lỗi thường gặp
- Local xanh, CI đỏ: so sánh Node, biến môi trường, chữ hoa/thường trong tên file và khả năng chạy từ checkout sạch.
- CI không kết thúc: kiểm tra test runner có đang watch hoặc giữ kết nối mở không.
- Check xanh nhưng không thấy test: mở log và tìm số test thực sự chạy; exit code 0 của một script rỗng không phải bằng chứng kiểm thử.
Bắt đầu bằng các lệnh mà team có thể chạy lại ở local. Khi workflow ổn định, bạn mới nên thêm ma trận phiên bản, chia job hoặc tối ưu cache theo nút thắt đã đo.


