Part 3 - Gerrit Code Review with Jenkins CI : Tích hợp CI / CD

Index

Trong phần 1 của chuỗi bài viết , mình đã có bài giới thiệu sơ qua về Jenkins , những đặc điểm nổi trội và lợi ích mà nó mang lại trong hệ thống CI.

Phần này, mình sẽ cùng tìm hiểu về hệ thống CI / CD cùng với việc tích hợp Jenkins trong ứng dụng tích hợp, với mong muốn giúp bạn có cái nhìn tổng thể hơn.

Các nội dung chính

  1. About CI/CD 1.1 Khái niệm Continuous Integration 1.2 Khái niệm Continuous Deployment
  2. Install Jenkins & Plugin 2.1 Cài đặt Jenkins 2.2 Cấu hình plugins
  3. Tích hợp Jenkins với Gerrit 3.1 Trình bày workflow giữa Developer , CI System và Reviewer 3.2 Gerrit và Jenkins làm việc với nhau như thế nào ? 3.3 Cấp phép cho các nhóm đối tượng trên gerrit 3.4 Thiết lập account cho các nhóm 3.4. Cấu hình streaming gerrit event tới jenkins
  4. Practice sample 4.1 Cách tạo gerrit project 4.2 Tạo và cấu hình job verify trên jenkins 4.3 The first commit
    • Bước đầu làm việc với git repo
    • Install the hook to automatically insert Change-Id
    • Hướng phân tích lỗi khi verify failure
    • Cách push commit sửa đổi sau khi fix review comment
    • Đánh giá của reviewer
  5. Tổng kết

Vậy CI-CD là gì ?

CI là viết tắt của từ Continuous Integration , nó là một phương pháp trong phát triển phần mềm, nhằm giảm thiểu những rủi ro trong quá trình phát triển sản phẩm. Trong một teamwork, thì việc tích hợp implement, update các features với nhau giữa các members là việc sẩy ra thường xuyên. Trước khi tiến hành việc merge các functions, những bản update này sẽ được kiểm tra một cách tự động, nhằm phát hiện và tìm ra lỗi sớm nhất. Giúp cho developer sớm phát hiện được vấn đề và fix lỗi ngay trong quá trình implementation.

CI workflow

......................................................(ảnh minh họa từ internet)

  • Developer push các changes tới Source Control Server (như Gerrit, Github, Gitlab vv... )
  • Continuous Integration Server sẽ trigger request này và tiến hành Build, Test, Run UT, IT ..vv
  • Sau quá trình kiểm tra sẽ Notify Success or Failure cho phía developer
  • Nếu Change có issue, developer sẽ tiến hành fix lỗi và tiếp tục vòng lặp cho tới khi mọi thứ OK.

Khái niệm CD

CD được viết tắt của từ Continuous Deployment , là một khái niệm gắn liền với Continuous Integration và có mối quan hệ mật thiết. Sở dĩ mình nói rằng, CD gắn liền mật thiết với CI bởi lẽ source code trên Source Controler Server luôn là stable, do có sự kiểm soát chặt chẽ của CI ở mỗi giai đoạn merge functions . Mỗi khi bạn cần deploy sản phẩm lên các môi trường test, staging hay thậm chí cả production thì việc deploying được diễn ra một cách hoàn toàn tự động và bất cứ khi nào.

So với cách deployment truyền thống một cách manually như Continuous Delivery thì Continuous Deployment có những ưu điểm và an toàn hơn bởi quá trình diễn ra một cách tự động. Đôi khi cũng có sự khác biệt về cấu hình database, file server vv.. trên các môi trường test, staging hoặc production. Ví dụ như :

  • Staging server cần enable basic authen.
  • Production server cần disable basic authen.
  • Hay , cùng lúc bạn có thể build nhiều profiles cho các môi trường khác nhau.

==> Thì khi đó, sự kết hợp giữa CI - CD mang lại sự tiện lợi và an toàn hơn rất nhiều.

Cài đặt Jenkins

Jenkins có thể được cài đặt qua Docker hoặc trên một PC riêng biệt với một Servlet Container chẳng hạn như Tomcat, Jetty... Và tất nhiên bạn cần phải có môi trường JRE ( Java Runtime Environment) được cài đặt.

Bài viết này mình sẽ cài đặt Jenkins trên Ubuntu như một system service. Để biết các installation command , bạn có thể tham khảo trên jenkins wiki - Installing Jenkins on Ubuntu

Cài đặt qua APT

Mở Terminal, add jenkins repo , update package list và install jenkins như bên dưới.

wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

Cấu hình mặc định sau khi cài đặt.

  • Thư mục cài đặt : /var/lib/jenkins
  • Port sử dụng : 8080
  • Account jenkins đã được tạo tự động ( thư mục home cũng chính là thư mục cài đặt /var/lib/jenkins )

Bạn sẽ phải sử dụng account jenkins này, để có thể access vào một số file trong /var/lib/jenkins. Bạn cũng sẽ phải change password cho lần đầu sử dụng với command sau.

sudo passwd jenkins

Thiết lập plugins

Để bắt đầu thiết lập plugins, mở URL sau trên browser : http://localhost:8080 ( trong bài viết mình sẽ sử dụng IP LAN thay cho localhost , ví dụ : http://192.168.13.106:8080)

Màn hình Get Started xuất hiện, login bằng account jenkins bên trên, copy & paste nội dung file initialAdminPassword để tiếp tục

[email protected] / $ su jenkins     //login bằng `jenkins` account. 
Password: 
[email protected] / $ cat /var/lib/jenkins/secrets/initialAdminPassword 
e38f2037b4d5424a80fd38afd833ba83

Để hướng dẫn nhanh, mình sẽ chọn Install suggested plugins

Đợi cho quá trình cài đặt plugins hoàn tất...

Thiết lập admin user -> Save and finish. Việc cài đặt Jenkins và các plugins cơ bản đã hoàn tất.

Tích hợp Gerrit vs Jenkins CI

Để thực hiện mục này, mình sẽ sử dụng Gerrit Code Review làm Source Control Server, về cách cài đặt và cấu hình, bạn có thể xem tại phần 2 - Cài đặt , cấu hình Gerrit với apache basic authen

Workflow

Nói qua về workflow trên :

  1. Trước khi làm 1 task, developer cần fetch latest source code trên Git/Gerrit repo, việc pull này cũng được áp dụng nếu tại bước (2), gerrit nhận thấy rằng change này cần được rebase với latest source code.
  2. Developer modify source code, implement function ABC ... và push change cho việc reviewing.
  3. Jenkins CI sẽ auto trigger được những changes này và bắt đầu thực thi verifying, compiling , run test case vv...
  4. Kết quả verification đó được Jenkins CI trả về cho Gerrit với flag tương ứng :
    • -1 failure - developer cần check thông báo lỗi, vì sao lỗi để có hướng fix kịp thời.
    • +1 OK
  5. Quá trình được thực hiện bởi yếu tố con người (reviewer), với flag tương ứng từ -2 đến + 2 để đánh giá độ mức độ từ Critical cho đến Good
  6. Một khi change được Jenkins đánh dấu +1 và Reviewer đánh dấu +2, nó sẽ được phép merge vào target branch.

Gerrit và Jenkins làm việc với nhau như thế nào ?

Jenkins sẽ thực hiện kết nối đến Gerrit thông qua giao thức SSH. Để jenkins có thể trigger được các review request mỗi khi developer push source, thì trên phía Gerrit cần cấp permission Stream Events cho user mà jenkins sử dụng để connect đến gerrit( account jenkins_ci mình sẽ đề cập ở bên dưới).

Trên jenkins mình cũng sẽ install plugin Gerrit Trigger , plugin này cho phép quản lý connection, trigger các build mỗi khi có một change request mới hoặc hoặc patch set được tạo. Nó cũng sẽ cho phép customize các thông báo lỗi, thiếp lập flags cho kết quả build..vv

Cấp phép cho các nhóm đối tượng trên gerrit

Để các nhóm đối tượng có thể tương tác trên gerrit, thì không thể thiếu việc cấp phép permission. Tùy vào sự phân bổ của tổ chức sẽ có những cơ chế cấu hình khác nhau. Trong ví dụ này , mình sẽ thiết lập dạng simple nhất như sơ đồ bên dưới .

Giải thích về một số permission phía trên :

  • Stream Events: Cho phép thực hiện streaming gerrit event thông qua SSH.
  • Read : Có quyền access vào project (read only) qua HTTP hoặc SSH .
  • Push : Cho phép push commit lên git remote server
  • Abadon : Cho phép hủy bỏ change request này.
  • Label Code-Review : Cho phép reviewer đánh score cho mỗi change request, nó là một phần trong review process, để có thể merge được change request này vào main source, thì BẮT BUỘC change request phải có review score.
  • Label Verified : Giống với Label Code-Review nhưng được áp dụng cho CI tools khi thực thi một vài operations như compile, run UT, IT .. vv với mong muốn sư dụng Verified label để vote cho change request đang chạy .
  • Submit : Merge change request này vào branch tương ứng trên main repo.

Tạo lần lượt các group tương ứng Verifier, Developer, Reviewer.

  1. Đăng nhập vào gerrit với admin user.
  2. Di chuyển tới menu People --> Create New Group và tạo các groups tương ứng.
  3. Sau khi các groups được tạo , di chuyển tới màn hình access : Projects --> List --> All-Projects --> Access và cấp phép permission cho các groups tương ứng với sơ đồ tổ chức trên.

Thiết lập account cho các nhóm

Để có thể kiểm thử ở phần cuối của bài viết, mình sẽ tạo và các accounts với vai trò tương ứng trong nhóm.

  • dev1 : tạo tài khoản developer sẽ được add vào nhóm Developer
  • reviewer1 : tạo tài khoản reviewer sẽ được add vào nhóm Reviewer
  • jenkins_ci : tạo tài khoản cho Jenkins CI sẽ được add vào nhóm Verifier

Add lần lượt các account tương ứng trong user file htpasswd /etc/apache2/gerrit.htpasswd .

    sudo htpasswd /etc/apache2/gerrit.htpasswd  <user_name>

Về file gerrit.htpasswd , mình đã nhắc đến ở phần 2 của chuỗi bài viết, bạn có thể xem lại ở đây Cấu hình apache

Đăng nhập vào gerrit với lần lượt với các account vừa tạo : http://192.168.13.106/gerrit/ , mục đích của việc đăng nhập này là để gerrit sẽ thực hiện liên kết các account đó trên hệ thống gerrit cho lần đầu tiên đăng nhập.

Hãy nhớ rằng : Gerrit không quản lý account của bạn, nó chỉ lưu trữ các thông tin cần thiết liên quan đến account đó mà thôi chẳng hạn như : full name, sex, birdthday ..vv . Việc quản lý các account đó và authenticate sẽ do provider của phương thức xác thực mà bạn chọn đảm nhiệm(OPENID, HTTP, LDAP, OAUTH) ví dụ như OpenID Provider, LDAP Server , file .htpasswd của apache.

Quay trở lại gerrit dưới quyền admin user, add lần lượt các account vừa tạo vào các group tương ứng.

  1. Đăng nhập vào gerrit với admin user.
  2. Di chuyển tới menu People --> List Groups --> Select group tương ứng và thêm vào mục Members

Về cơ bản việc thiết lập phân quyền, tổ chức các nhóm đối tượng tham gia vào hệ thống CI là hoàn tất, việc tiếp theo mình cần cấu hình jenkins để nó có thể giao tiếp làm việc với gerrit đúng với vai trò của nó.

Streaming gerrit event tới jenkins

Như mình đã nói ở trên, giữa Gerrit và Jenkins làm việc với nhau thông qua SSH connection. Gerrit cần streaming event về cho phía jenkins. Hay nói cách khác , phía ci sẽ lắng nghe các event này để launch một vài owner process. Một số việc mình cần chuẩn bị như sau :

  1. Add public key cho account jenkins_ci lên gerrit ( account sử dụng bên phía jenkins ci để connect đến gerrit server)
  2. Cài đặt Gerrit Trigger plugin - plugin quản lý các kết nối, quản lý các servers cũng như trigger các build mỗi khi có change request được create hoặc update.

Generate & add public key

Do jenkins cài như một system service và chạy dưới process của account jenkins trên OS. Vì vậy bạn cần change login bằng account jenkins và generate public key dứơi account này

//change login to jenkins account
su jenkins 

//Generate public key
ssh-keygen -t rsa -C "Jenkins" 

Add public key lên gerrit site

  1. Copy nội dung public key trong file /var/lib/jenkins/.ssh/id_rsa.pub (default)
  2. Đăng nhập vào gerrit với account jenkins_ci
  3. Dưới mục Setting -> SSH Public Keys, paste và add public key mới.
  4. Test ssh connection ssh -p 29418 [email protected] (cần trust server cho Gerrit Trigger plugin phía dưới)

Về cách add public key bạn cũng có thể xem lại phần 2 , mục Cấu hình email, SSH & git author

Cài đặt Gerrit Trigger plugin

Đi tới Manage Plugins screen, Manage Jenkins --> Manage Plugins select và install như sau

Một khi đã cài đặt , bạn sẽ thấy Gerrit Trigger item xuất hiện trong màn hình Manage Jenkins

Add & config gerrit server

Các bước để thực hiện add gerrit server cho streaming event như sau .

  1. Menu Manage Jenkins -> Gerrit Trigger -> Add New Server
  2. Đặt tên cho [Add New Server] và select Gerrit Server with Default Configurations
  3. OK

Thiết lập các thông tin tương ứng để kết nối đến Gerrit server ( IP của Gerrit server )

Nếu Test Connection thông báo success quay trở lại màn hình Gerrit Trigger click Status button để bắt đầu start việc nhận streaming event từ Gerrit

Practice sample

Ví dụ được thực hiện trên Java J2EE với Spring framework , bạn không cần phải có kiến thức về platform này, vì đơn giản mình chỉ cần demo với mục đích để bạn hiểu rõ quy trình hoạt động ra sao. Nào , giờ thì cũng xem lại workflow như bên dưới nhé.

Với githutb, gitlab ... bạn sẽ push modified source code lên fork của bạn, nó thực chất là 1 bản copy từ main repo. Với gerrit cũng vậy, tuy không có khái niệm fork giống như github , nhưng nó cũng ngầm tạo ra một vùng repo tạm ( staging area) là nơi sẽ lưu trữ các change request cho việc reviewing.

Tạo gerrit project

  1. Đăng nhập vào Gerrit bằng tài khoản admin
  2. Trên menu Projects --> Create New Project Rights Inherit From All-Project

Như hình ảnh trên, mình vừa tạo project với tên Bookstore kế thừa từ All-Projects , điều đó có nghĩa là mọi access right của project Bookstore cũng sẽ được kế thừa All-Projects. Trong ví dụ này chúng ta có 3 đối tượng tham gia ( developer, ci verifier , reviewer ) . Để xem lại access right , bạn có thể xem tại mục Cấp phép cho các nhóm đối tượng trên gerrit ở phần trên trong bài viết này.

Tạo và cấu hình job verify trên jenkins

  1. Đăng nhập vào jenkins với quyền admin
  2. Từ menu, chọn New Item và thiết lập các thông tin sau :
    • Enter an item name : tên của job. For example : bookstore_master_verifier
    • Select Freestyle project
    • OK
  3. Thiết lập Repositories tại Source Code Management :
    • Source Code Management type : git
    • Repository URL : có dạng ssh://[email protected]:port/project-name.
      • Trường hợp này, URL của mình sẽ là : ssh://[email protected]:29418/Bookstore
      • Bạn có thể tìm thông tin này trên Gerrit tại màn hình project detail --> General --> ssh
    • Click Advanced... button , mục Refspec giá trị cố định là $GERRIT_REFSPEC - nó là environment variable của Gerrit Trigger plugin đã cài đặt sẵn , cái sẽ chỉ định fetch source code của change request tương ứng để verifying.
    • Additional Behaviours : Click Add button và thêm Strategy for choosing what to build
      • Choosing strategy : chọn Gerrit Trigger

Credentials : Mặc định sẽ sử dụng public key của user jenkins trên OS( user start jenkins process) , public key này đã được add lên tài khoản jenkins_ci trên gerrit ở bước trên . Do vậy mình sẽ thiết lập là - none - Trong trường hơp bạn muốn sử dụng account khác để clone Repository URL. Thí có thể thêm Credentials với Add button và chọn Kind account tương ứng.

  1. Mục Build
    • Click Add build step
    • Chọn Execute shell để tạo 1 shell command - tại đây sẽ nhập các command tương ứng cho việc verify source code. Chúng ta cũng có thể sử dụng những plugin sẵn có để đơn giản hóa việc cấu hình. Trong khuôn khổ bài viết mình sẽ chỉ thực hiện verify đơn giản là compile source code mỗi khi có change request.
    • Save change và việc cấu hình đã hoàn tất

The first commit

Trước khi thực hiện commit đầu tiên. Đảm bảo rằng, bạn đã hoàn tất việc chuẩn bị các vấn đề liên quan đến môi trường , git config, git account, register gerrit email, public key ...vv . Để có thể connect đến gerrit server. Bạn có thể xem lại cách thiết lập ở bài trước Cấu hình email, SSH & git author

Mục tiêu của mục này như sau :

  1. Cách clone git repo với gerrit server
  2. Giải thích về change-id trong gerrit commit và cài đặt hook commit-msg để auto insert Change-Id trong commit footer.
  3. Hướng phân tích lỗi khi ci verifier failure
  4. Cách push 1 commit fix review comment và ý nghĩa của nó.
  5. Đánh giá chất lượng commit bởi reviewer

Các bước thực hiện commit

  1. Import project source lên gerrit
    • clone git repo từ gerrit --> về local repo
    • copy source code sang local repo
  2. Commit change tại local
  3. Push commit lên refer branch cho việc review HEAD:refs/for/master
  4. Jenkins CI sẽ tự động trigger có change request vừa tạo và run compile command.
  5. Reviewer sẽ thực hiện merge change request này sang --> master branch ( nếu jenkins verify +1 và reviewer đánh dấu +2)

Quá trình development sẽ lặp lại từ bước 2 --> 5 theo quy trình như vậy

Clone repo từ gerrit ( cú pháp tương tự với Repository URL khi thiết lập job bookstore_master_verifier trên jenkins)

git clone ssh://[email protected]:29418/Bookstore

Đánh dấu tất cả các files thay đổi và commit local

git add -A
git commit -m 'Import project'

Push commit lên refer branch cho review HEAD:refs/for/master

git push origin HEAD:refs/for/master 

Sau khi thực hiện lệnh push, có thể bạn sẽ gặp phải lỗi này. Đừng lo, mình sẽ giải thích và cách khắc phục lỗi trên ở phần dưới - Install the hook to automatically insert Change-Id.

Install the hook to automatically insert Change-Id

Đoạn lỗi trên đang mô tả việc missing Change-Id in commit footer . Trong gerrit , mỗi 1 commit sẽ tương ứng với 1 task bạn làm và mỗi 1 commit tương ứng với 1 change id, bắt đầu bằng change-id : tree-object-in-hash được append ở cuối của message commit . Format message của git commit giống như sau :

Import project

Change-Id: 4b825dc642cb6eb9a060e54bf8d69288fbee4904

Do vậy mình cần add Change-Id: 4b825dc642cb6eb9a060e54bf8d69288fbee4904 vào cuối của message commit. Vậy làm cách nào để lấy được mã hash tree object kia ?

Có 2 cách để tạo mã tree object trong Change-Id như sau :

  • Manually : get tree object sử dụng index hiện tại bởi command : git-write-tree và append nó vào cuối của commit message theo format change id như trên.

  • Automatic : download và install hook từ gerrit server , để get tree object tự động mỗi khi thực hiện lệnh commit. Trong ví dụ này, command của mình sẽ như sau :

      gitdir=$(git rev-parse --git-dir); scp -p -P 29418 [email protected]:hooks/commit-msg ${gitdir}/hooks/
    

Và tất nhiên rồi, mình sẽ thực hiện theo cách 2 và chạy lệnh commit --amend để rewrite lại message commit có chứa change-id, sau đó tiếp tục thực hiện bước 4.

git commit --amend
git push origin HEAD:refs/for/master

About Change-Id : Thực ra, Change-Id có thể không cần add vào commit message bằng cách thay đổi setting Require Change-Id in commit message = FALSE trên Project General. Nhưng mình not recommended điều này. Vì : Trong gerrit , mỗi 1 commit của bạn khi push lên dù là commit hay commit -amend, nếu không có Change-id thì gerrit sẽ ngầm định hiểu rằng đó là 1 commit mới với patchset bắt đầu là patch set 1. (với workflow này có vẻ hơi khác so với một số source control khác như github hoặc gitlab) Do vậy, để tránh nhiều issue rắc rối khi một commit depends trong commit khác thì nên add change-id ngay từ đầu.

Giờ thì bạn sẽ thấy commit được hiển thị trên Gerrit site với change request list đang open như hình dưới.

Từ bảng hình ảnh trên, bạn có thể nhìn sơ lược thông tin về commit.

  • Các thông tin về subject message, owner , target branch ..vv
  • CR : tương ứng với Code Review ( trạng thái review của Reviewer)
  • V : Verified ( trạng thái reviewer của ci verifier với V (xanh) nếu +2 hoặc X(đỏ) nếu -1)

Và có vẻ như commit của chúng ta có vấn đề gì đó khiến ci verifier đánh dấu build failure X. Vậy trong trường hợp này sẽ tìm và giải quyết vấn đề như thế nào.

Hướng phân tích lỗi khi verify failure

Để tìm root cause dẫn đến ci verifier đánh failure, sẽ có một số mẹo sau :

  • Mở màn hình commit detail
  • Dưới mục History sẽ log lại Build URL của jenkins ci cho patch set này(1 commit có thể có nhiều patchset ) - truy cập URL tương ứng để mở Console Output trên jenkins

Từ đó bạn có thể investigate root cause nằm ở đâu để có hướng fix sớm nhất.


Với Console Output của job build tương ứng trên jenkins, bạn có thể xem toàn bộ log trong quá trình verifier. Và hình như chúng ta có 1 vấn đề gì đó trong class IndexController.java dòng 18

Log console output của job bookstore_master_verifier trên jenkins ci http://192.168.13.106:8080/job/bookstore_master_verifier/1/


Ohmm, thiếu đóng ngoặc } cho method indexAction .
Và như vậy bạn đã thấy, jenkins ci đã làm tốt vai trò của nó ,source code đã được kiểm tra trước ,để có thông báo lỗi sớm nhất và hướng fix kịp thời. Nào, giờ thì fix issue ngay còn kịp , sau đó push 1 commit --amend để update bản sửa đổi vào commit hiện tại.

Push commit sửa đổi sau khi fix review comment

Như mình đã nói ở trên, trong gerrit :

  • Mỗi 1 commit sẽ tương ứng với 1 task.
  • Và 1 commit cũng sẽ tương ứng với 1 change id.

==> Do vậy sau khi fix review comment, bạn cần commit --amend để append sửa đổi vào commit hiện tại (duy nhất 1 commit cho task hiện tại) Với từng lần push commit update từ phía local lên gerrit như vậy, thì sẽ có 1 patchset mới được tạo ra. Và jenkins ci lại tiếp tục công việc của nó - verify các patchset này.

git commit --amend  #save message và giữ nguyên change id 
git push origin HEAD:refs/for/master 

Trở lại với màn hình detail trên Gerrit , bạn sẽ thấy History với log Build Successful từ jenkins CI

CI verifier +1 Log build với kết quả SUCCESS

Cuối cùng là đánh giá của reviewer

Một khi passed verify auto bởi ci, thì đến đây sẽ cần verify bởi yếu tố con người là không thể thiếu. Người reviewer sẽ trực tiếp đánh giá chất lượng của source code từ -2 đến.. +2.

Trong hình ảnh bên dưới , bạn cần chú ý các điều kiện sau :

  • Button Reply.. để đánh giá cho điểm về commit này từ -2 đến.. +2.
  • Button Code-Review+2 để chấp nhận commit đã được passed - Button này chỉ hiển thị khi ci verifier đánh giá +1

.............................. Trước khi Code-Review+2...........................................

.............................. Sau khi Code-Review+2...........................................

Và cuối cùng là button Submit để merge commit này vào target branch ( master)

Tổng kết

Như vậy, mình đã kết thúc phần hướng dẫn cài đặt và tích hợp Gerrit vs Jenkins CI nhằm xây dựng 1 hệ thống CI / CD hoàn chỉnh. Cũng như những khái niệm và practice sample để các bạn có thể hiểu rõ hơn cách hoạt động theo phương pháp này. Với khái niệm Continuous Deployment , về cơ bản nó vẫn gắn liên với Continuous Integration, công việc mà nó đảm nhận cũng gần giống với job verify bookstore_master_verifier mà mình đã config.Tuy nhiên sẽ thực hiên theo từng business công việc riêng là deploy product lên các môi trường tương ứng. Do đó mình sẽ không tạo practice sample về phần CD này.

Nếu có điều gì cần chia sẻ, hãy cùng comment phía dưới nhé, thank you!