back arrow

Đào sâu phía trunkbase và gitflow

13 - 08 - 2022

Mục tiêu

Mục tiêu của mình là ghi lại những thứ đọc được về 2 mô hình gitflowtrunkbased mà từ đó quyết định xem dự án hiện tại sẽ theo model nào.

Gitflow

Gitflow được đề xuất và trở nên phổ biến nhờ Vincent Driessen vào thời điêm 2010 tại nvie. Có lẽ gitflow được thể hiện rõ nhất qua hình sau:

Gitflow by Vincent Driessen
bug fixes phần release branch có lẽ là sửa code trực tiếp trên release mà không tạo nhánh hotfix

Vincent có cập nhật vào năm 2020 về post này về một “use case” hợp lý của gitflow là phần mềm với nhiều versions và cần support nhiều versions trong một thời gian không ngắn. Các phần mềm này điển hình có lẽ là desktop apps, commandline apps hoặc các thư viện. Các loại phần mềm không đòi hỏi support đồng thời nhiều versions bao gồm mobiles apps, webapp hoặc các plugin trên Chrome plugin hoặc VScode marketplace do các thể loại app này hầu hết người dùng chỉ sử dụng 1 version duy nhất.

Có một quan sát là việc merge code ở release vào developmaster bị lặp lại. Sẽ không đáng để nói nếu features được release là nhỏ nhưng với những lần release lớn thì nguy cơ có nhiều conflicts giữa releasedevelop hay master là tồn tại, công sức để xử lý các conflicts này sẽ là đáng kể.

Theo bài phân tích trên Toptal thì với project open-source, nhiều dev junior và là một sản phẩm đã thành công thì áp dụng gitflow sẽ phù hợp. Ẩn trong đó có lý do về chính trị dự án, thiếu niềm tin trong team và sự kiểm soát của Tech Lead trong những PR kéo dài. Nếu mục tiêu của bạn là tốc độ, bạn mới bắt đầu và nhiều senior dev thì trunkbase sẽ thích hợp với bạn hơn.

Với gitflow thì CI/CD không còn đúng.

Các nhánh features hoàn toàn có thể bị tách xa khỏi develop nếu như vì 1 lý do nào đó nhánh features bị chặn merge. release trong hình chỉ có 4 commits nên nhánh có thể chỉ tồn tại ngắn, tuy nhiên thực tế release có thể xảy ra nhiều bugfix khiến nhánh release được merge nhiều. Ngay trong model này thì có vẻ nhánh master mang chức năng lưu lại các hotfix và release hơn là thực tế được sử dụng trong quá trình làm việc. Công sức trong việc merge code giữa 2 nhánh developmaster có thể trở nên đáng kể giữa những đợt release lớn và gây áp lực cho Tech Lead. Một chuyện khác nữa là nhánh feature có thể tồn tại lâu qua nhiều bản release, dev hoặc nhóm dev trên feature độc lập này sẽ có nhiệm vụ cập nhật code giữa nhánh feature của mình với develop; và như trên thì với những release lớn nhiều bugfixes, công sức để cập nhật sẽ là đáng kể và nhu cầu giao tiếp giữa các thành viên release và xử lý bugfix ở release sẽ lớn tương đương. Với những team lớn và khi priority thay đổi thì có những nhánh features sẽ tồn tại rất lâu mà không được ai ngó ngàng tới và khó để làm việc cùng khi các priority kia hoàn thành.

Trunkbase

Theo như trang Trunk based development (Paul Hammat) thì đây là một model dựa vào 1 nhánh chính duy nhất (gọi là trunk). Theo như quan điểm này thì GitHub flowGitLab flow mặc dù có khác biệt nhưng đều có thể coi là thuộc về mô hình này.

Trunk based trong team lớn
Nhánh chính là master, tuỳ dự án mà có thể có nhánh release ngắn rồi xoá hoặc không có nhánh release như trong trường hợp của GitHub

Cũng theo nguồn này thì nhánh “trunk” (hay master/main) luôn ở trạng thái “release ready”. Trong suốt các giai đoạn phát triển, nhánh này luôn cần sự ổn định tương đối cho phép sản phẩm sẵn sàng go live bất cứ lúc nào.

Với trunkbased thì master là chính nên devs luôn check out từ phía master chứ ko phải là develop, mọi việc đều bắt đầu từ phía master tương đối ổn định thay vì develop biến đổi và có thể không chắc chắn. Sự ổn định của master được chắc chắn thêm nhờ việc cần pass build trước khi merge vào master. Team devs cam kết ko bao giờ break the build, mọi commit đều cần được build thành công. Điều này cũng đạt được nhờ lượng code trong 1 PR cần nhỏ (nhưng thế nào là “nhỏ” thì tuỳ team định nghĩa). Với mô hình của GitLab thì sự chắc chắn này đạt được nhờ chạy test.

Các nhánh feature đều rất đoản mạng (aka “short-lived”) và ở nhiều nơi thì nhánh release cũng đoản mạng hoặc ko hề tồn tại (GitHub). Tuổi thọ của một nhánh feature được khuyến cáo là từ 1-2 ngày.

Nỗi sợ lớn nhất của trunkbased là bug không break build nhưng là “edge cases” gây hỏng luồng hay sai logic. Với gitflow, bạn fix trực tiếp ở nhánh release hoặc tạo hotfix rồi fix trên master. Nhưng khi bạn ở trunkbased ko có nhánh release hoặc nhánh này nằm ngoài thẩm quyền của bạn (không được merge vào release) thì bạn nên làm gì? Paul Hammat có viết trên blog riêng 1 bài viết rất hay về vấn đề này. Có những team chọn fix-forward (roll forward) nghĩa là họ cho phép sự tồn tại của bug trên production và chấp nhận hậu quả của bug khi nó xảy ra. Các hotfix sau đó ngay lập tức release thành bản vá lỗi nhờ sự chấp thuận và kiểm tra từ QA. Các features đã được merge từ sau thời điểm phát hiện bug được giấu đi nhờ các nút bấm hoặc các endpoint nội bộ. Bạn luôn có thể sử dụng feature flags tuy nhiên thì các đoạn code được gắn feature flags có thể nằm khắp mọi nơi trong codebase khiến Tech debt tăng nếu ko được xử lý tốt. Khi sự đồng thuận bị thiếu từ phía QAs, team trở nên bảo thủ hơn, do vậy mà việc rollback phiên bản trước và đẩy lùi lịch release cho đến khi bug được sửa và bản release trở nên ổn định là có thể xảy ra. Khi chuyện này xảy ra, việc tối quan trọng là bugfix cần được merge ngược lại về phía master. Nếu như team quên merge code ngược lại về master thì regression = bug cũ trở lại là điều không ai muốn và team devs sẽ thực sự mất mặt theo như Hammat.

Fix-forward hay roll forward
Fix-forward hay roll-forward tạo ra nhiều bản patch

Tình huống

Dự án mình đang làm việc là 1 dự án là web (phiên bản duy nhất) với team nhỏ - số lượng chưa tới 10 người khá thạo việc và Tech Lead theo phong cách “hand-off”, có vẻ như các nhận tố để thực hiện trunkbased là khá rõ ràng. Có điều khoảng cách giữa team devs nội bộ và team QAs của khách hàng sẽ là thách thức về đồng thuận mà team devs cần vượt qua. Thách thức thứ 2 có thể thấy được là giai đoạn phát triển sau khi go live. Dự án có thể thay đổi bản chất nhanh chóng sau thành công của go live, các stakeholders hoàn toàn có thể kỳ vọng vào sự ổn định của sản phẩm bởi mọi bug hoặc thiếu sót của team devs hoàn toàn có thể trở thành thiệt hại về mặt kinh doanh. Các doanh nghiệp lớn rất thường có xu hướng này và đây cũng là lời khuyên của Konrad ở Toptal. Ở giai đoạn chuyển tiếp này, sự hiểu biết về bản chất của dự án và các quyết định của stakeholders sẽ là cần thiết để team devs lựa chọn mô hình branching phù hợp.

Tham khảo: