QA Gatekeeper: blog tự fix lỗi 24/7 GitHub Actions
![QA Gatekeeper architecture]
Có một câu hỏi mà mọi blogger kỹ thuật đều phải đối mặt: làm sao viết bài liên tục mà không phá production? Trên blog cá nhân, mình đã merge hơn 100 pull request chỉ trong một ngày mà không phải lo lắng về việc deploy fail hay code lỗi. Bí mật nằm ở một tính năng tên là QA Gatekeeper — một hệ thống checkpoint tự động chạy trên CI/CD pipeline, kết hợp với self-healing bot mỗi 6 tiếng. Bài này phân tích tại sao cơ chế này độc đáo, cách nó hoạt động, và lý do nó khiến việc viết blog trở nên cực kỳ ngầu.
1. Vấn đề: viết blog liên tục dễ phá production
Trước khi có QA Gatekeeper, mỗi lần mình muốn thêm bài mới hay sửa một tính năng nhỏ, có hàng loạt thứ có thể đi sai:
- Conflict marker quên xoá sau merge (
<<<<<<<,=======,>>>>>>>) làm Zola build fail - Hardcoded secret vô tình commit (GitHub PAT, OpenAI key, AWS access key) làm leak bảo mật
- SCSS thiếu dấu
}→ compile error chỉ phát hiện khi deploy - Frontmatter thiếu title/date làm Tera template crash
- Image quá nặng (>500KB) làm LCP score tụt thê thảm
Mỗi vấn đề nhỏ có thể đỏ production vài giờ. Trên blog cá nhân thì còn đỡ — chỉ mình thấy. Nhưng nếu blog có 1000 visitor/ngày thì mỗi phút downtime là uy tín bị bào mòn.
2. Kiến trúc QA Gatekeeper: 3 lớp phòng vệ
QA Gatekeeper không phải một workflow đơn lẻ — đây là kiến trúc 3 tầng kết hợp:
Tầng 1: Pre-commit hook (chạy local, trước khi push)
↓
Tầng 2: QA Gatekeeper workflow (chạy CI, trên PR + push main)
↓
Tầng 3: Self-Healing QA bot (chạy cron mỗi 6 tiếng)
Mỗi tầng có vai trò riêng và mỗi tầng đều có thể auto-fix nếu phát hiện vấn đề có thể sửa cơ học.
Tầng 1: pre-commit hook local
Trước khi commit code lên Git, hook chạy qa_check.py trên file
đã stage. Nếu phát hiện error → block commit ngay.
# .git/hooks/pre-commit
#!/bin/bash
python3 qa_check.py $(git diff --cached --name-only)
exit $?
Lợi ích: bug bị bắt từ máy local, chưa lên CI → tiết kiệm 30s đợi GitHub Actions chạy.
Tầng 2: QA Gatekeeper workflow
Khi PR được tạo hoặc commit push thẳng main, GitHub Action chạy
qa.yml workflow. Đây là gatekeeper thực sự — nếu fail, PR
KHÔNG merge được (khi repo bật required status check).
name: QA Gatekeeper
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
qa-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run QA checks
run: python3 qa_check.py
- name: Zola build smoke test
run: zola build
Hai bước quan trọng:
- qa_check.py: scan conflict markers, secrets, frontmatter, SEO, performance threshold
- Zola build smoke test: thực sự chạy Zola build trong CI để bắt lỗi Tera template + SCSS compile mà Python check không thấy được
Bug nổi tiếng SCSS empty body block đã từng break production — chỉ cần ~5 giây Zola check là phát hiện ngay.
Tầng 3: Self-Healing QA bot
Đây là tầng độc đáo nhất. Mỗi 6 tiếng, một workflow cron chạy
qa_check.py --fix safe để tự động sửa các vấn đề "mechanical"
(không cần đoán nội dung):
- Normalize tags: lowercase + dedupe + sort
- Date format:
2026/06/15→2026-06-15 - Trim trailing whitespace trong frontmatter
- Đảm bảo file kết thúc bằng đúng 1 newline
- Thêm
aliasestừ slug (deterministic)
Sau khi fix, bot mở 1 PR duy nhất tên fix/auto-qa (rolling branch
single PR) cho mình review + merge. Không bao giờ auto-merge vì
mechanical fix vẫn cần human verify.
python3 qa_check.py --fix safe 2>&1 | tee fix-log.txt
grep '^FIXED:' fix-log.txt > fixed-summary.txt3. Tính độc đáo: 4 yếu tố khiến QA Gatekeeper khác biệt
3.1. Stdlib only — 0 dependency
qa_check.py viết bằng Python stdlib hoàn toàn. Không pip install, không requirements.txt cho QA. Lợi ích:
- Workflow chạy nhanh (không pip install)
- Không bao giờ break vì dep version mismatch
- Portable: chạy được trên Python 3.8+
- Source code đơn giản, dễ debug
So với các tool QA phổ biến như pre-commit framework, flake8,
black, prettier — vốn yêu cầu npm/pip install hàng GB → mình
tránh được toàn bộ overhead.
3.2. Phân chia rõ Fix vs Warning vs Error
QA Gatekeeper phân loại issue thành 3 mức:
| Mức | Hành động | Ví dụ |
|---|---|---|
| ERROR | Block commit + CI đỏ | Conflict marker, hardcoded secret |
| WARNING | Báo nhưng không block | Image >250KB, JS file >50KB |
| FIX | Auto-fix qua self-healing | Tags chưa lowercase, date format sai |
Khác biệt với pre-commit hooks truyền thống: mỗi loại có flow khác nhau, không phải all-or-nothing.
3.3. Smart secret detection — high confidence patterns
Regex secret detection rất dễ rơi vào trap false positive (vd: nhầm test code có chuỗi giả sk-xxxxx). QA Gatekeeper dùng pattern chính xác:
SECRET_PATTERNS = [
("GitHub PAT classic", r"ghp_[A-Za-z0-9]{36}"),
("GitHub PAT fine-grained", r"github_pat_[A-Za-z0-9_]{82}"),
("OpenAI/Anthropic-style", r"sk-[A-Za-z0-9]{32,}"),
("AWS access key", r"AKIA[0-9A-Z]{16}"),
("Slack token", r"xox[baprs]-[A-Za-z0-9-]{10,}"),
("Private key block", r"-----BEGIN (RSA )?PRIVATE KEY-----"),
]
Mỗi pattern là exact format của secret thật → 0 false positive trong 100+ commits đã chạy.
Special case: Google API key (AIzaSy*) intentionally committed
cho PageSpeed Insights API vì key này rate-limited theo HTTP referer
của domain → skip pattern này.
3.4. Defense in depth — không bao giờ tin một lớp duy nhất
Triết lý chính: không bao giờ tin một check duy nhất. Cùng một vấn đề được check ở nhiều tầng:
- Local pre-commit hook (chống commit lỗi)
- CI workflow (chống merge PR lỗi)
- Cron self-healing (sửa lỗi đã merge nhưng bot phát hiện)
- Pre-build smoke test (Zola compile check)
Nếu một tầng miss, tầng sau bắt. Không có single point of failure.
4. Cách viết blog 100 PR/ngày mà không lo
Với QA Gatekeeper, workflow viết bài của mình trở nên cực kỳ streamlined:
- Mở editor → viết Markdown
- Commit local → pre-commit hook auto-check (~1s)
- Push → CI chạy QA + Zola build (~30s)
- Merge PR → deploy production (~2 phút)
Không có manual review checklist, không phải tự nhớ "đã xoá conflict marker chưa?", "tag đã lowercase chưa?", "frontmatter có date không?". Bot làm hết.
Tốc độ viết bài tăng 5-10 lần. Mỗi bài nhỏ chỉ tốn ~2 phút từ ý tưởng đến live production.
5. Khi nào QA Gatekeeper không đủ?
Có 3 trường hợp QA Gatekeeper không thể tự fix:
- Tera template syntax — khi mình viết bug
{% set x = {a:1} %}(Tera không support dict literal) → bot không hiểu ngữ cảnh, chỉ Zola build mới catch - Logic bug — code đúng syntax nhưng sai logic (vd: tính sai score formula) → cần human review
- Security beyond regex — vd: API endpoint exposed, CORS misconfig → cần dedicated security audit workflow
Cho trường hợp 1 + 2: tầng 2 (Zola build smoke test) bắt.
Cho trường hợp 3: workflow riêng security-audit.yml chạy weekly
với pip-audit + gitleaks.
6. Lessons learned và best practices
Sau 200+ commits chạy qua QA Gatekeeper, mình rút ra:
- Mechanical fix idempotent: fix function PHẢI tự bồi (apply 2 lần → kết quả giống 1 lần). Tránh infinite loop khi self-heal.
- Single rolling PR: bot luôn dùng 1 PR
fix/auto-qaforce-push thay vì tạo PR mới mỗi 6 tiếng → tránh spam inbox. - Không bao giờ auto-merge: kể cả fix "100% safe" vẫn cần human verify. Một lần trust quá → một lần production hỏng.
- Log everything: mỗi fix có dòng
FIXED:để dễ trace. Khi self-heal làm gì lạ, mình có thể track từ log. - Bypass mechanism: hook có option
--no-verifykhi user thực sự cần override (vd: commit emergency hotfix lúc 2h sáng).
7. Code mẫu setup QA Gatekeeper cho repo của bạn
Nếu bạn muốn implement tương tự, đây là minimum viable setup:
Bước 1: Tạo qa_check.py
import re, sys
from pathlib import Path
CONFLICT = re.compile(r"^(<<<<<<<|=======|>>>>>>>)\s")
def check_file(path):
text = Path(path).read_text(encoding="utf-8", errors="ignore")
if CONFLICT.search(text):
return f"ERROR {path}: conflict marker"
return None
if __name__ == "__main__":
errors = []
for f in Path(".").rglob("*"):
if f.is_file() and f.suffix in {".py", ".md", ".yml"}:
err = check_file(f)
if err: errors.append(err)
for e in errors: print(e)
sys.exit(1 if errors else 0)Bước 2: Pre-commit hook
# .git/hooks/pre-commit
#!/bin/bash
python3 qa_check.pyBước 3: GitHub Actions
# .github/workflows/qa.yml
name: QA
on: [push, pull_request]
jobs:
qa:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: python3 qa_check.py
3 file. 20 dòng code. Hết.
Kết luận: automation thay vì discipline
QA Gatekeeper minh chứng cho một triết lý: automation luôn thắng discipline. Bạn không thể yêu cầu bản thân nhớ check 20 thứ trước mỗi commit. Bạn cũng không thể yêu cầu mình review 100 PR/ngày một cách kỹ lưỡng.
Nhưng bạn CÓ THỂ viết một script chạy 1 giây để check tất cả 20 thứ đó. Và bạn CÓ THỂ chạy script đó tự động trên mỗi commit, mỗi PR, mỗi 6 tiếng.
Đó là sự khác biệt giữa viết blog cảm hứng (nhiều rủi ro) và viết blog có hệ thống (an toàn 24/7). QA Gatekeeper là hệ thống đó.
Đọc thêm về kiến trúc blog này tại Hành trình công nghệ blog cá nhân hoặc xem cách Semantic Related Posts với SBERT được tự động build qua GitHub Actions workflow tương tự.
Reference: GitHub Actions docs, pre-commit framework, gitleaks, pip-audit.
Tham khảo & Nguồn dữ liệu
1. Liên kết bên ngoài được sử dụng trong bài viết
2. Liên kết nội bộ liên quan
3. Bản quyền & Ghi nguồn
Một phần dữ liệu trong bài viết được tham khảo từ GitHub Actions docs, gitleaks, pip-audit và pre-commit framework. Mọi thương hiệu, tên sản phẩm và tài liệu gốc thuộc quyền sở hữu của chủ sở hữu tương ứng. Bài viết chỉ trích dẫn, tổng hợp và phân tích — không nhằm thay thế tài liệu chính thức.
Câu hỏi thường gặp
QA Gatekeeper hoạt động thế nào?
CI/CD cho blog cá nhân có cần thiết không?
Self-healing CI là gì?
💬 BÌNH LUẬN
Đăng nhập GitHub để comment. Hỗ trợ markdown, reaction, reply.