Theo tôi, đây là công cụ quan trọng bậc nhất trong những nhóm thực hành Agile với quy mô vừa tới lớn. CI (Continous Integration – tích hợp liên tục) là một quy trình / công cụ giúp nhóm phát triển ngay lập tức nhận diện được những ảnh hưởng của một commit (một đoạn code hay một chức năng được thêm vào) với toàn bộ hệ thống nhằm phản ứng tức thì để đảm bảo toàn hệ thống hoạt động như mong đợi.

Khác với mô hình phát triển phần mềm truyền thống khi việc những module được thiết kế rất tỉ mỉ, phát triển độc lập và được thực hiện việc tích hợp vào giai đoạn cuối của việc phát triển nhằm phục vụ việc kiểm thử tích hợp và kiểm thử hệ thống; Agile coi trọng việc phát triển những chức năng liên tục theo kiểu “bồi đắp”. Cá biệt, trong Scrum, một vài phần tăng trưởng phải được chuyển giao sau mỗi Sprint – là những chức năng phải vận hành được bởi người dùng. Do đó, việc kiểm thử tích hợp và kiểm thử hệ thống diễn ra thường xuyên hơn (tối thiểu là trong mỗi Sprint), khiến việc thực hiện công việc tích hợp thủ công không khả thi. Ý tưởng về một công cụ thực hiện việc tích hợp vì thế đã xuất hiện.

Tuy vậy, chúng ta có thể hiểu CI là một quy trình, yêu cầu những thay đổi trên hệ thống phải được nhanh chóng nhận biết sự ảnh hưởng của chúng thông qua việc tích hợp sớm với hệ thống đang có, và thực hiện việc kiểm thử tích hợp và kiểm thử hệ thống. Lúc này CI liên quan mật thiết đến khái niệm “daily build”: toàn bộ mã nguồn của hệ thống phải được build hàng ngày nhằm nhận biết những lỗi tiềm năng và khắc phục sớm.

Tại sao phải là “daily build”? Hãy nhớ rằng, bất cứ thành viên nào trong nhóm phát triển đều có thể là một nhà thiết kế phần mềm, và một công việc của họ có thể ảnh hưởng rất nhiều tới hệ thống. Ví dụ, nhóm phát triển chạy nước rút với Sprint 2 tuần (10 ngày làm việc), với 2 lập trình viên cùng thực hiện việc thay đổi database nhằm hoàn thành 2 user story song song và mất 5 ngày thực hiện, việc tích hợp vào ngày thứ 6 với hàng tá xung đột về ràng buộc trong database có thể là một cơn ác mộng. Daily build chính là giải pháp để phát hiện xung đột xảy ra ngay từ ngày thứ 2 để nhóm phát triển có cách giải quyết thích hợp.

Nói chung, daily build giống như Daily Scrum về mặt mặt mã nguồn hệ thống. Trong Daily Scrum, nhóm thực hiện việc tích hợp, đồng bộ công việc với nhau cho các task hay user story. Trong daily build, nhóm thực hiện việc tích hợp, đồng bộ công việc với nhau cho mã nguồn và những thành phần liên quan như database, service… Xét cho cùng, kết quả của những task hay user story trên cũng là mã nguồn và những thành phần liên quan; bởi vậy, việc thực hiện Daily Scrum mà không có daily build giống như chúng ta đang đồng bộ những vấn đề “trên trời” mà không giải quyết những xung đột cụ thể.

Với nhiều nhóm thực hành Agile, daily build thậm chí là không đủ, nhóm cần tới commit build – thực hiện việc tích hợp, kiểm thử cho mỗi commit vào source code repository.

Một hệ thống CI thông thường thực hiện những tác vụ sau:

  1. Phát hiện thay đổi trong source code repository (xuất hiện commit mới)
  2. Phân tích chất lượng source code
  3. Thực hiện build
  4. Chạy toàn bộ unit test
  5. Chạy toàn bộ integration test
  6. Sinh ra những tạo tác có thể triển khai được, gọi là deployable artifact
  7. Có thể, deploy những artifact này và thực hiện những kiểm thử khác nếu cần

Nếu một trong những bước trên không thành công:

  • Tuỳ thuộc vào mức độ nghiêm trọng, việc tích hợp có thể dừng lại hoặc đi tiếp
  • Kết quả tích hợp được thông báo tới nhóm phát triển qua email, hệ thống chat. Thông qua sour code repository, CI có thể nhận biết cá nhân đã thực hiện việc commit gây ra lỗi trong việc tích hợp.
  • Nhóm phát triển hoặc cá nhân thực hiện commit thực hiện sửa lỗi và commit
  • CI phát hiện thay đổi trong source code repository và thực hiện lại những bước trên

Trong những tác vụ trên, tác vụ 1, 3, 6 thực sự rất dễ thực hiện và được hỗ trợ bởi hầu hết những công cụ CI hiện có trên thị trường. Những tác vụ 2, 4, 5 không đơn giản chỉ là sự hỗ trợ của công cụ, tư tưởng và cách thực hiện phía sau quan trọng hơn rất nhiều; chúng ta sẽ bàn về những vấn đề này ở những bài viết sau. Tác vụ 7 lại liên quan tới một hệ thống CD (Continuos Deployment – triển khai liên tục) với tư tưởng giống với CI nhưng dưới góc độ “triển khai” và lại phụ thuộc vào tần suất release của sản phẩm và độ phức tạp của môi trường nên không hẳn là một công cụ tiên quyết trong việc thực hành Agile.

Tuy vậy, nhiều nhóm thực hành Agile vẫn lựa chọn việc triển khai CI và CD đồng thời bởi một trong những best practice của CI là đảm bảo môi trường đồng nhất (hoặc gần giống nhất) giữa môi trường kiểm thử (tích hợp) và môi trường production.

Chúng ta dễ dàng nhận thấy ưu điểm của commit build so với daily build vì cô lập được thay đổi theo từng commit khiến việc xử lý xung đột đơn giản hơn. Tuy vậy, thời gian để CI thực hiện toàn bộ 7 tác vụ trên có thể rất nhiều với một số môi trường của dự án khiến việc này không khả thi; nên nhiều nhóm thực hành Agile vẫn lựa chọn daily build. Tôi là một người theo trường phái commit build và luôn cố gắng duy trì CI theo cách này. Với những dự án phức tạp, tôi thường sử dụng nhiều build agent để thực hiện việc tích hợp song song với những commit cùng thời điểm. Một giải pháp khác là, lược bỏ những tác vụ không cần thiết (ví dụ tác vụ 7) để vẫn thực hiện việc tích hợp với từng commit và thực hiện một “long build” vào cuối ngày.

Hiện nay có rất nhiều công cụ CI cho phép nhóm thực hành Agile lựa chọn với những tác vụ cơ bản như trên, phổ biến nhất có lẽ là Jenkins – hệ thống mã nguồn mở với rất nhiều plugin phù hợp với nhiều điều kiện hệ thống khác nhau. Tôi cũng là một kẻ hâm mộ Jenkins nhưng lại thường sử dụng những công cụ khác khi có thể, chỉ bởi giao diện của Jenkins thì quá tệ và cũng vì cónhiều người sử dụng quá.

821 total views, no views today

Every developers know the importance of source code versioning and how to use SVN, Git etc to achieve but DB versioning seems unfamiliar and more difficult to most of them. But in my opinion, DB versioning is as important as source code versioning, especially when you are working in an Agile project where whole team is responsible to the environment. In this post, I try to describe the common issue with DB and how to solve this.

Problem

Most of software use DB now and of course, it need to be changed during the development and shared with the modules or whole system. And its problem is exact the same as source code where everybody works in only 1 source code repository at the same time:

  • When a developer makes a DB change, how can others aware it? It seems so easy with the source code with SVN or Git because they support the check-in, check-out. So before committing the code, a developer can view the log, see the code changes by other’s check-in.
  • When conflicts occur, how can developers aware and resolve them?

Why do you rarely care?

Let start with the traditional software development process, where the DB:

  • is built in the design stage
  • and it’s mostly fixed during the development.
  • and it’s taken care by a deployment person or team who normally put in charged of environment configuration.

So the developer doesn’t need to care about this. But in the Agile project, its design is unfixed as we may has increments, code or structure refactoring, and the DB schema is often updated sprint by sprint.

What do you usually handle? And their issues?

Follow my experience, there 2 normal ways we are using to handle this problem:

  • Shared environment. The easiest (and sometimes it is the best way) is using shared environment. For example, a developer works on his checked-out source code individually but query on a single shared DB server. It seems a good way but still facing some issues:
    • Performance. Normally it speeds is not as good as using local environment because the shared DB needs to serve all developers’ uses while the local one is more specific on the current module. And it may affect to the productivity.
    • Revision. It so hard to manage the DB revision because it need to go parallel with source code revision where we sometimes roll source code back to the good one. One solution is storing all the DB backup for each commit, but it takes a large amount of storage.
  • Scripting the changes. Whenever we have change on DB, script it and apply to all developer locals. It is the good way to reduce the storage and make easier to version the change. But how team members aware that the scripts are updated and resolve the conflicts?

Solution

DB versioning control

DB versioning control is an approach to keep track the changes on DB schema and data in a shared repository to make sure that team can aware and apply these changes easier.

How does it work?

There are some ways to implement the DB versioning but the most popular one is versioning DB by versioning its change scripts. So the DB versioning problem becomes the source code versioning problem that is solved really good right now.

The details of DB versioning implementation are vary project by project but the key points usually are:

  • DB changes are built by scripts. To reduce the storage and easy to update, we should script DB to files and arrange them in a good structure.
  • DB is under the source control. After scripting DB to files, it makes sense to keep them under the source control because they are the source code now.
  • The DB changes are verified during the project build or application start-up. It makes the developers aware changes that need to be applied. In my opinion, the verification should occur as soon as possible to avoid wasted time. The application start should be failed if the changes haven’t been applied. But it’s better with the failure during the build stage.
  • The DB versions are stored in the DB itself. It’s a good approach to keep the solution simple by for example, a table that stores the run history.

Better solution?

The purpose and a good approach is described above, but there are various specific solutions from project to project. I will have another post to describe an hand-on implementation in a specific project later but you should try to go further by this start as I think DB versioning is very important in Agile projects.

Reference: http://www.infoq.com/articles/db-versioning-scripts

261 total views, no views today

It’s my presentation in monthly meetup of Agile Vietnam in May, 2015. In 2 hours, I shared our case study about applying Agile in both working environment (by promoting flat-management) and software projects.

I also got a lot of feedbacks and questions and highly appreciated. Thank you for joining.

50 total views, no views today