Kiểm soát chất lượng
Quality gate tự động
Danh sách đầy đủ các cổng chặn tự động, đặt ở đâu, chặn cái gì, chạy trong bao lâu. Đây là xương sống kỹ thuật của shift left.
Nội dung bài
Thuật ngữ trong bài (17)
- quality gate · cổng chất lượng
- build · bản dựng
- CI · tích hợp liên tục
- commit · điểm lưu thay đổi
- linter · máy soát mã
- merge · gộp nhánh
- pipeline · dây chuyền tự động
- pull request · yêu cầu gộp mã
- bug · lỗi
- coverage · độ phủ test
- e2e · kiểm thử đầu-cuối
- integration test · kiểm thử tích hợp
- unit test · kiểm thử đơn vị
- release · bản phát hành
- secret · thông tin bí mật
- migration · chuyển đổi dữ liệu
- token · khóa truy cập
Nguyên tắc đặt cổng
Một quality gate là một phép kiểm tra tự động chặn code đi tiếp khi không đạt. Ba luật:
- Đặt càng gần chỗ sinh ra lỗi càng tốt. Kiểm tra chạy được trong editor thì đừng để nó chỉ chạy trên CI.
- Cổng phải nhanh tương xứng với vị trí. Cổng ở gần dev mà chạy 5 phút thì dev sẽ tìm cách bỏ qua, và cổng đó coi như không tồn tại.
- Cổng đỏ nghĩa là dừng. Không có nút "merge dù sao". Nếu một cổng hay sai, sửa cổng hoặc gỡ cổng — không dạy cả đội thói quen bỏ qua tín hiệu đỏ.
Bốn tầng cổng
| Tầng | Chạy khi nào | Ngân sách thời gian | Ai thấy trước tiên |
|---|---|---|---|
| 1. Trong editor | Lúc gõ, lúc save | Dưới 10 giây | Chỉ mình dev |
| 2. Pre-commit hook | Lúc commit | Dưới 30 giây | Chỉ mình dev |
| 3. Trên pull request | Khi push | Dưới 10 phút | Dev + người review |
4. Trên main và trước release | Sau merge, trước khi phát hành | Dưới 30 phút | Cả đội |
Càng xuống dưới, phản hồi càng chậm và càng nhiều người bị ảnh hưởng. Nên mỗi lần thêm một phép kiểm tra, câu hỏi đầu tiên là: đẩy nó lên tầng nào cao hơn được không?
Tầng 1 — trong editor
Chạy ngay khi gõ, dev sửa trước cả khi commit:
- Kiểm tra kiểu dữ liệu theo thời gian thực.
- Linter với auto-fix khi save.
- Formatter khi save.
- Cảnh báo import vòng, biến không dùng, nhánh switch thiếu.
Cấu hình editor được commit vào repo (thư mục cấu hình dùng chung), không để mỗi người cài mỗi kiểu. Máy mới của người mới phải chạy được ngay sau một lệnh cài đặt.
Tầng 2 — pre-commit hook
Chạy trên file đang thay đổi, không chạy toàn repo, nên phải rất nhanh:
| Kiểm tra | Chặn khi |
|---|---|
| Format | Có file sai format |
| Lint | Có lỗi mức error |
| Secret scanner | Phát hiện token, khoá, chuỗi kết nối |
| Định dạng commit message | Không đúng conventional commit |
| Kích thước file | Có file nhị phân lớn bất thường |
Secret scanner ở tầng này là bắt buộc. Một secret lọt vào lịch sử git là đã lộ, dù sau đó có xoá commit — chặn ở đây rẻ hơn xoay vòng khoá sau này rất nhiều.
Hook được cài tự động khi cài dependency, không dựa vào việc từng người nhớ cài.
Tầng 3 — trên pull request
Tầng chặn chính. Mọi mục dưới đây phải xanh mới được merge:
| Cổng | Chặn khi | Ngân sách |
|---|---|---|
| Build | Không build được ở mọi nền tảng đích | 3 phút |
| Kiểm tra kiểu toàn dự án | Có lỗi kiểu | 1 phút |
| Lint toàn dự án | Có lỗi mức error hoặc warning mới | 1 phút |
| Unit test | Có test đỏ | 2 phút |
| Integration test | Có test đỏ | 3 phút |
| Coverage trên code mới | Dưới 80% | Tính kèm test |
| Quét dependency | Có lỗ hổng mức cao trở lên | 1 phút |
| Quét secret toàn nhánh | Phát hiện secret | 30 giây |
| Kích thước gói cài đặt | Tăng quá 3% so với main | 1 phút |
| Migration dữ liệu | Không có kịch bản lùi | 30 giây |
Tổng phải dưới 10 phút. Vượt ngưỡng này thì dev sẽ chuyển sang việc khác trong lúc chờ, mất mạch, và vòng phản hồi thực tế dài ra gấp nhiều lần con số trên đồng hồ.
Cách giữ dưới 10 phút: chạy song song, chỉ chạy test liên quan tới phần thay đổi ở vòng đầu, đẩy các bài test chậm xuống tầng 4.
Tầng 4 — trên main và trước release
Những thứ quá chậm để chạy ở mỗi PR:
- Toàn bộ E2E test trên thiết bị thật, các phiên bản hệ điều hành trong danh sách hỗ trợ.
- Test hiệu năng: thời gian khởi động, thời gian mở các màn hình chính, mức dùng bộ nhớ.
- Test nâng cấp từ phiên bản trước với dữ liệu cũ.
- Test truy cập cho người khuyết tật.
- Quét bảo mật sâu.
- Kiểm tra ngân sách kích thước và thời gian phản hồi so với ngưỡng đã đặt.
Cổng tầng 4 đỏ thì chặn release, và hạng mục gây đỏ được xử lý trước mọi việc khác.
Cổng cho từng module
Thêm vào các cổng chung ở trên:
| Module | Cổng riêng |
|---|---|
| Chat | Test mạng chập chờn tự động; kiểm tra không có log nội dung tin nhắn |
| Task | Test ma trận phân quyền đầy đủ; test chuyển trạng thái không hợp lệ |
| Bán hàng | Bộ test tính tiền với bảng ca biên; kiểm tra không dùng kiểu số thực cho tiền |
Cổng của module Bán hàng chạy ở cả tầng 3 và tầng 4.
Khi cổng đỏ
- Người gây đỏ sửa. Không phải người nhìn thấy đầu tiên, không phải người trực.
- Đỏ trên
mainlà ưu tiên cao nhất của cả đội — vì nó chặn mọi người khác merge. - Sửa trong 30 phút, hoặc revert. Revert không phải thất bại.
- Trong lúc
mainđỏ, không ai merge thêm — merge chồng lên làm nguyên nhân khó tìm gấp bội.
Nuôi cổng cho khoẻ
Quality gate là code, và nó cũng hỏng dần nếu không chăm:
- Cổng hay sai (đỏ khi code đúng) phải được sửa trong tuần, hoặc gỡ. Cổng hay sai độc hại hơn không có cổng.
- Cổng chậm dần phải được đo và tối ưu. Theo dõi thời gian chạy pipeline như một chỉ số sức khoẻ, xem ở nhịp làm việc.
- Mỗi cổng phải chặn được một loại lỗi đã từng xảy ra thật. Cổng dựng vì lo xa mà chưa bao giờ bắt được gì thì đem ra xem lại.
- Mỗi khi một bug lọt ra production, câu hỏi bắt buộc là: cổng nào lẽ ra phải chặn nó, và vì sao không chặn được? Câu trả lời thường dẫn tới một cổng mới hoặc một cổng được mở rộng. Xem tư duy shift left.

