Giao diện
9. Chính sách Workflow Nhóm
IMPORTANT
Đây không phải guideline mềm. Đây là policy vận hành cho team Penalgo hoặc HPN khi code đã có khả năng đi production.
Policy này giải quyết vấn đề gì?
Git không thất bại vì thiếu lệnh. Git thất bại vì team không thống nhất cách làm việc: branch đặt tên loạn, commit khó đọc, PR quá to, rebase sai chỗ, tag release không rõ nguồn gốc, rollback chậm và force-push trong hoảng loạn.
Policy này giải quyết đúng các điểm đó:
- giữ
mainluôn ở trạng thái có thể deploy hoặc rollback an toàn - buộc commit phải rõ nghĩa và có thể review
- tách ranh giới rõ ràng giữa làm sạch lịch sử cá nhân và bảo toàn lịch sử shared branch
- giảm thời gian phản ứng khi release lỗi hoặc lộ secret
Sơ đồ workflow mặc định của team
text
main (protected, deployable)
├── feature/<ticket>-<short-name>
├── fix/<ticket>-<short-name>
├── hotfix/<incident>-<short-name>
├── chore/<ticket>-<short-name>
└── release/vX.Y.Z
local cleanup only:
feature/... -> rebase allowed trước PR
shared integration:
feature/... -> Pull Request -> merge vào main
release/... -> tag annotated -> deploy
hotfix/... -> Pull Request khẩn -> merge vào main -> tag/release nếu cầnNon-negotiables
- Production first: mọi thay đổi phải nghĩ tới deploy, audit và rollback.
- Atomic commits: một commit chỉ chứa một ý thay đổi có thể giải thích được.
- Clarity over cleverness: commit message, PR title, tag message và branch name phải đọc là hiểu.
- Recovery before panic: production lỗi thì revert hoặc rollback trước, tranh luận kiến trúc sau.
- Không force-push lên shared branches:
main,release/*, và mọi branch có nhiều người cùng dùng.
1) Quy tắc đặt tên branch
Format bắt buộc
bash
feature/<ticket>-<short-name>
fix/<ticket>-<short-name>
hotfix/<incident>-<short-name>
chore/<ticket>-<short-name>
release/vX.Y.Z
docs/<ticket>-<short-name>Ví dụ hợp lệ
bash
feature/pla-142-payment-retry
fix/pla-203-login-timeout
hotfix/inc-481-checkout-null-guard
chore/pla-210-upgrade-vitest
release/v1.4.0
docs/pla-188-git-phase1-policyQuy tắc cụ thể
| Quy tắc | Bắt buộc |
|---|---|
| Prefix đúng loại công việc | feature, fix, hotfix, chore, docs, release |
| Có mã ticket hoặc incident | Để truy vết được lý do thay đổi |
| Dùng chữ thường, kebab-case | Không dấu cách, không camelCase |
| Tên ngắn nhưng đủ nghĩa | Tối đa khoảng 3-6 từ mô tả |
| Không dùng tên mơ hồ | Cấm test, update, final, new-branch |
CẤM LÀM
- commit trực tiếp trên
main - tạo branch kiểu
bugfix,temp,abc,work,trying - dùng một branch cho nhiều mục tiêu không liên quan
2) Quy tắc commit message
Format mặc định
text
<type>(<scope>): <mô tả ngắn>Types được dùng
| Type | Khi dùng |
|---|---|
feat | thêm tính năng |
fix | sửa bug |
docs | cập nhật tài liệu |
refactor | đổi cấu trúc nhưng không đổi behavior mong đợi |
test | thêm hoặc sửa test |
chore | việc bảo trì, config, tooling |
ci | pipeline, workflow automation |
perf | tối ưu hiệu năng |
revert | hoàn tác thay đổi đã có |
Scopes nên rõ theo domain
auth, payments, git, release, docs, ci, search, api, ui
Ví dụ đạt chuẩn
bash
feat(payments): add retry guard for duplicate webhook events
fix(auth): prevent session refresh loop on expired token
docs(git): define team workflow policy for phase 1
ci(release): require build before annotated tag creation
revert(checkout): rollback optimistic stock reservationVí dụ không đạt
bash
fix stuff
update code
WIP
final version
misc changesChính sách commit
- Không push commit
WIP,fix later,temp,debug,again. - Trước khi mở PR, author phải tự dọn các commit rác trên branch cá nhân.
- Không gom nhiều thay đổi không liên quan vào một commit chỉ để “ít commit hơn”.
- Nếu commit đã push lên shared branch và message dở, không rewrite lịch sử shared branch chỉ để làm đẹp.
3) Kỳ vọng với Pull Request
PR chỉ được mở khi đủ điều kiện
- branch build được hoặc ít nhất không làm hỏng trạng thái repo
- author đã tự review diff trước
- không còn file debug, secret, log tạm, dữ liệu local
- tiêu đề PR rõ mục tiêu business hoặc kỹ thuật
Nội dung PR bắt buộc
| Mục | Kỳ vọng |
|---|---|
| Problem | Đang sửa hoặc thêm cái gì |
| Scope | Những phần nào bị ảnh hưởng |
| Risk | Chỗ có thể gây lỗi production |
| Verification | Đã test gì |
| Rollback | Nếu lỗi sẽ revert commit hoặc tag nào |
Quy mô PR
- Lý tưởng: dưới ~400 dòng thay đổi thực chất để reviewer đọc trong một lần.
- Cần giải thích thêm: trên ~800 dòng hoặc chạm nhiều domain.
- Nên tách PR nếu vừa refactor, vừa đổi behavior, vừa đổi config release.
Review rules
- Tối thiểu 1 reviewer cho thay đổi thường.
- Tối thiểu 2 reviewer cho thay đổi liên quan
security,release,auth,payment, hoặc production incident. - Không tự merge khi còn comment quan trọng chưa được xử lý.
- Reviewer review logic và rủi ro, không chỉ nhìn pass CI.
4) Policy merge vs rebase
Rebase được phép khi nào?
- Chỉ trên branch cá nhân hoặc private branch
- Trước khi mở PR để dọn history
- Khi sync với
origin/mainmà branch chưa bị nhiều người cùng dùng
bash
git fetch origin
git rebase origin/mainMerge bắt buộc khi nào?
- Khi tích hợp code đã review vào
main - Khi branch đã shared cho nhiều người
- Khi cần giữ mốc tích hợp để audit, release hoặc rollback
Quy tắc cứng
| Tình huống | Policy |
|---|---|
main | Không rebase, không force-push |
release/* | Không rebase sau khi branch đã công bố |
hotfix/* | Có thể cleanup local, nhưng merge vào main qua PR |
| Branch cá nhân trước PR | Có thể interactive rebase |
| Branch đã nhiều người cùng dùng | Tránh rebase, ưu tiên merge |
Merge method mặc định của team
- Mặc định: merge PR bằng merge commit
- Cho phép squash chỉ khi branch có nhiều commit rác nhỏ và reviewer đồng ý
- Không dùng rebase merge vào
mainvì làm mất điểm tích hợp rõ ràng
WHY
Merge commit giữ dấu vết “feature này đi vào main ở thời điểm nào”, cực hữu ích khi audit release hoặc revert một cụm thay đổi.
5) Protected branch rules
Các branch phải được bảo vệ
mainrelease/*
Rule bắt buộc
- cấm push trực tiếp
- cấm force-push
- cấm delete branch nếu chưa theo policy release hoặc retention
- yêu cầu PR review trước khi merge
- yêu cầu status checks quan trọng pass trước khi merge
Status checks tối thiểu
- build
- test hoặc validation phù hợp với repo
- secret scan hoặc security gate nếu có
Quyền bypass
Chỉ maintainer được bypass trong incident thật sự, và vẫn phải:
- ghi rõ lý do trong kênh incident hoặc ticket
- tạo PR hoặc postmortem follow-up sau đó
- không dùng bypass để né review thông thường
6) Policy release tags
Format tag phát hành
bash
vX.Y.Z
vX.Y.Z-rc.1Rule bắt buộc
- Tag release phải là annotated tag
- Tag phải trỏ tới commit đã có trong
mainhoặcrelease/* - Không tag từ máy local chưa đồng bộ
- Release notes phải lấy từ commit history và PR thực tế, không “nhớ mang máng”
Ví dụ
bash
git tag -a v1.4.0 -m "Release v1.4.0"
git push origin v1.4.0Sai tag thì xử lý thế nào?
- Không retarget tag cũ sang commit khác
- Không force-update tag đã public
- Cách đúng: tạo tag mới, ví dụ
v1.4.1, và ghi rõ lý do correction
7) Policy secret handling
Tuyệt đối không commit
.env,.env.*- private keys, certificates, SSH keys
- access token, API key, webhook secret
- database dump, production snapshot, local SQLite file
- file config chứa credential thật
Phòng ngừa bắt buộc
- dùng secret manager hoặc environment variables
- cấu hình
.gitignoređúng từ đầu - review
git diff --cachedtrước mỗi commit quan trọng - bật secret scanning nếu nền tảng hỗ trợ
Nếu lỡ stage secret nhưng chưa commit
bash
git restore --staged <file>Nếu đã commit local nhưng chưa push
- xóa secret khỏi file
git commit --amendhoặc rebase local để sửa- verify lại diff trước khi push
Nếu đã push lên remote
- Rotate secret ngay
- báo team và maintainer ngay lập tức
- chặn hoặc thu hồi access liên quan
- đánh giá cần revert, purge history hay cả hai
- chỉ rewrite history khi đã có owner điều phối
THỨ TỰ ĐÚNG
Rotate trước. Dọn Git sau. Không làm ngược.
8) Kỳ vọng rollback và xử lý incident
Nguyên tắc chung
- Production lỗi thì ưu tiên khôi phục dịch vụ, không ưu tiên “giữ lịch sử đẹp”.
- Shared history đã public thì ưu tiên
git revert, không dùngreset --hard. - Mọi PR chạm production phải có ý rollback tối thiểu 1 dòng.
Team expectation
| Tình huống | Kỳ vọng |
|---|---|
| Release gây lỗi | quyết định rollback hoặc revert nhanh, không tranh luận quá lâu |
Commit lỗi trên main | tạo revert commit rõ ràng |
| Cần hotfix | tách branch hotfix/..., review nhanh, merge lại main |
| Không chắc nhánh nào an toàn | dùng tag release gần nhất hoặc commit đã xác minh |
Lệnh ưu tiên khi rollback shared branch
bash
git revert <commit>
git revert <oldest>^..<newest>Điều bị cấm trong incident
- force-push lên
main - rebase
main - xóa tag release để “coi như chưa từng xảy ra”
- sửa commit history trong lúc cả team đang pull
Khi nào không được phá lệ policy này?
Chỉ có hai trường hợp:
- incident production cần bypass tạm để khôi phục dịch vụ
- repo owner yêu cầu bằng văn bản trong ticket hoặc PR vì lý do đặc biệt
Ngoài hai trường hợp này, “để nhanh hơn” không phải lý do hợp lệ.
Nếu dùng sai policy thì khôi phục thế nào?
| Sai lầm | Cách khôi phục an toàn |
|---|---|
Commit nhầm lên main nhưng chưa push | tạo branch cứu hộ, reset local về đúng trạng thái |
| Commit xấu trên feature branch cá nhân | interactive rebase trước PR |
| Rebase nhầm shared branch | dừng lại, dùng git reflog, phối hợp maintainer trước mọi force action |
Merge sai vào main | git revert merge hoặc revert commit liên quan |
| Push secret | rotate secret, báo team, rồi mới xử lý history |
| Tag sai release | tạo tag release mới, không sửa tag cũ |
Ví dụ thực tế: release lỗi lúc 3 giờ sáng
Tình huống:
mainvừa merge PRfeat(payments): add retry worker- tag
v1.4.0đã phát hành - production bắt đầu tạo duplicate charge
Xử lý đúng theo policy:
- on-call xác nhận impact và dừng rollout
- team chọn rollback nhanh về release an toàn hoặc
git revertcommit lỗi - không rebase
main, không force-push - tạo
hotfix/inc-481-disable-retry-workernếu cần patch khẩn - sau khi dịch vụ ổn định mới làm RCA và tối ưu dài hạn
Điểm quan trọng: khôi phục trước, tối ưu sau. Người dùng không quan tâm lịch sử Git đẹp; họ quan tâm hệ thống sống lại.
Quick practice
Hãy tự trả lời 4 câu hỏi sau trước khi bạn mở PR tiếp theo:
- Branch của tôi có đúng format và truy vết được ticket chưa?
- Commit history của tôi có đọc hiểu được khi reviewer chưa biết context không?
- Nếu PR này gây lỗi production, tôi sẽ revert commit nào hoặc rollback tag nào?
- Tôi có đang dùng rebase đúng trên branch cá nhân, hay đang chuẩn bị phá shared history?
Trang trước: 08. Disaster Recovery Cheatsheet