Chiều thứ Sáu, chuẩn bị release sản phẩm cho khách hàng. Team mình ngày trước thường rơi vào cảnh hỗn loạn. Dev A khẳng định: “Bản này là v1.2”. Dev B cãi lại: “Vừa fix bug xong phải là v1.2.1 chứ?”. Kết quả là trên server xuất hiện một đống file nén kiểu source_code_final.zip, source_code_final_v2.zip, rồi source_code_FIX_CUOI_CUNG.zip. Nhìn vào chẳng ai biết đâu là bản chạy ổn định nhất.
Mọi thứ thay đổi khi mình áp dụng Git Tag kết hợp Semantic Versioning (SemVer). Quy trình này giúp dọn dẹp đống hỗn độn và biến việc deploy thành một lệnh push duy nhất. Cuộc sống của mình và đồng nghiệp nhẹ nhàng hơn hẳn.
Những sai lầm “kinh điển” khi đánh dấu phiên bản
Nhiều team hiện nay vẫn dùng 3 cách thủ công để đánh dấu cột mốc release:
- Copy-Paste Folder: Nén source code theo ngày tháng. Cách này cực kỳ tốn dung lượng. Chỉ cần 5 người cùng làm, bạn sẽ sớm mất kiểm soát.
- Lạm dụng Release Branch: Mỗi bản release lại tạo một branch như
release-v1.0. Git Graph lúc này trông như một mớ dây điện chằng chịt, cực kỳ khó quản lý. - Ghi chú thủ công: Chỉ ghi phiên bản vào file CHANGELOG. Cách này máy tính không hiểu được, nên bạn không thể tự động hóa quy trình CI/CD.
Mình từng làm dự án với team 8 người. Việc lạm dụng branch khiến việc merge code thành ác mộng. Có những branch bị bỏ quên cả năm trời vì không ai dám xóa. Đó là lúc mình nhận ra Git Tag là giải pháp bắt buộc.
Git Tag khác gì so với Branch?
Nhiều bạn mới học Git thường nhầm lẫn giữa hai khái niệm này. Hãy tưởng tượng: Branch giống như một con đường đang thi công, luôn thay đổi và tiến về phía trước. Tag lại giống như một cột mốc cây số cố định trên con đường đó. Khi bạn gắn Tag vào một commit, nó sẽ đứng yên mãi mãi, bất kể sau đó bạn có thêm bao nhiêu code đi nữa.
Tại sao nên dùng Tag?
- Tính bất biến (Immutable): Tag
v1.0.0sẽ luôn trỏ về đúng commit đó. Không ai có thể vô tình commit đè lên. - Siêu nhẹ: Tag thực chất chỉ là một con trỏ nhỏ, không làm nặng repository.
- Truy xuất cực nhanh: Bạn có thể nhảy về đúng trạng thái code của phiên bản cũ để fix bug trong 3 giây.
Áp dụng Semantic Versioning (SemVer) vào thực tế
Đừng đặt tên tag kiểu v1, v2 tùy hứng. Hãy dùng chuẩn MAJOR.MINOR.PATCH (Ví dụ: 1.2.3). Cách này giúp mọi người nhìn vào là hiểu ngay mức độ thay đổi:
- MAJOR (Số đầu tiên): Tăng khi có thay đổi lớn làm hỏng tính tương thích cũ (Breaking changes). Ví dụ: Bạn thay đổi toàn bộ cấu trúc API khiến app cũ không gọi được nữa.
- MINOR (Số ở giữa): Tăng khi thêm tính năng mới nhưng vẫn chạy tốt với code cũ. Ví dụ: Thêm nút “Gửi ảnh qua chat”.
- PATCH (Số cuối cùng): Tăng khi chỉ sửa lỗi (Bug fixes). Không thêm tính năng, không làm hỏng cái cũ.
Từ ngày áp dụng quy tắc này, team Tester của mình làm việc hiệu quả hơn hẳn. Nếu chỉ tăng số PATCH, họ chỉ cần test nhanh. Nếu tăng số MAJOR, họ biết phải tổng kiểm tra toàn bộ hệ thống.
Triển khai Git Tag: Các lệnh cần nhớ
Có hai loại tag: Lightweight (chỉ là cái tên) và Annotated (có thông tin người tạo, ngày tháng). Mình luôn ưu tiên Annotated tag cho các bản release vì nó chuyên nghiệp và đầy đủ thông tin hơn.
1. Tạo Tag mới
Giả sử bạn vừa fix xong lỗi hiển thị và muốn lên bản v1.0.1:
# Tạo một Annotated Tag kèm mô tả
git tag -a v1.0.1 -m "Fix lỗi hiển thị trên Safari và cập nhật endpoint API"
# Xem danh sách tag hiện có
git tag
2. Đẩy Tag lên Server
Lưu ý: Lệnh git push thông thường sẽ không đẩy tag lên GitHub/GitLab. Bạn cần dùng lệnh riêng:
# Đẩy một tag cụ thể
git push origin v1.0.1
# Đẩy tất cả tag hiện có (dùng cẩn thận)
git push origin --tags
3. Xử lý khi tag nhầm
Nếu lỡ tay tag sai, đừng quá lo lắng. Bạn có thể xóa và tạo lại theo các bước sau:
# Xóa tag ở máy cá nhân
git tag -d v1.0.1
# Xóa tag trên server
git push --delete origin v1.0.1
Tự động hóa CI/CD với Git Tag
Đây là phần giúp bạn tiết kiệm hàng giờ làm việc. Thay vì lên server gõ lệnh thủ công, hãy cấu hình để hệ thống tự build mỗi khi thấy tag mới. Dưới đây là ví dụ với GitHub Actions:
name: Deploy Production
on:
push:
tags:
- 'v*' # Chạy script khi push tag bắt đầu bằng 'v'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Build and Push Docker
run: |
docker build -t my-app:${{ github.ref_name }} .
docker push my-app:${{ github.ref_name }}
Với cấu hình này, mỗi khi bạn push tag v1.1.0, hệ thống sẽ tự đóng gói và đẩy lên production. Bạn có thể thong thả uống cafe thay vì ngồi chờ thanh progress bar chạy.
Lời khuyên từ thực tế
Sau nhiều năm quản lý các dự án lớn, mình rút ra ba nguyên tắc vàng:
- Không sửa code trực tiếp trên Tag: Nếu bản
v1.0.0có lỗi, hãy tạo branchhotfix, sửa xong rồi mới tag bảnv1.0.1. - Luôn dùng tiền tố ‘v’: Đặt tên
v1.0.0thay vì1.0.0giúp các script tự động hóa hoạt động chính xác hơn. - Viết Message có tâm: Đừng ghi
-m "Update". Hãy tóm tắt các thay đổi chính để sau này tự động xuất file Changelog cho khách hàng.
Git Tag và SemVer không chỉ là kỹ thuật, đó là tư duy quản lý. Khi mọi thứ rõ ràng, việc giao tiếp giữa Dev, Tester và khách hàng sẽ trơn tru hơn. Nếu team bạn còn đang loay hoay với file zip, hãy thử chuyển sang dùng Tag ngay hôm nay.

