paint-brush
Tất cả những gì bạn cần biết về tích hợp liên tục, hành động GitHub và đám mây Sonartừ tác giả@shai.almog
2,932 lượt đọc
2,932 lượt đọc

Tất cả những gì bạn cần biết về tích hợp liên tục, hành động GitHub và đám mây Sonar

từ tác giả Shai Almog18m2023/03/24
Read on Terminal Reader

dài quá đọc không nổi

Khi nó được thực hiện không tốt, quy trình CI có thể biến công cụ tuyệt vời này thành cơn ác mộng. CI nên làm cho cuộc sống của chúng ta dễ dàng hơn chứ không phải ngược lại.
featured image - Tất cả những gì bạn cần biết về tích hợp liên tục, hành động GitHub và đám mây Sonar
Shai Almog HackerNoon profile picture

Lần đầu tiên tôi biết đến khái niệm Tích hợp liên tục (CI) khi dự án Mozilla ra mắt. Nó bao gồm một máy chủ xây dựng thô sơ như một phần của quy trình và đây là một cuộc cách mạng vào thời điểm đó. Tôi đang duy trì một dự án C++ mất 2 giờ để xây dựng và liên kết.


Chúng tôi hiếm khi trải qua một quá trình xây dựng sạch sẽ tạo ra các vấn đề phức tạp do mã xấu được cam kết với dự án.


Rất nhiều thứ đã thay đổi kể từ những ngày xa xưa đó. Các sản phẩm CI có ở khắp mọi nơi và với tư cách là nhà phát triển Java, chúng tôi tận hưởng vô số khả năng chưa từng có trước đây. Nhưng tôi đang vượt lên chính mình… Hãy bắt đầu với những điều cơ bản.

Tích hợp liên tục là một phương pháp phát triển phần mềm trong đó các thay đổi mã được tự động xây dựng và kiểm tra một cách thường xuyên và nhất quán.


Mục tiêu của CI là nắm bắt và giải quyết các vấn đề tích hợp càng sớm càng tốt, giảm nguy cơ lỗi và các vấn đề khác xảy ra trong quá trình sản xuất.


CI thường đi đôi với Phân phối liên tục (CD) nhằm mục đích tự động hóa toàn bộ quy trình phân phối phần mềm, từ tích hợp mã đến triển khai trong sản xuất.


Mục tiêu của CD là giảm thời gian và nỗ lực cần thiết để triển khai các bản phát hành và bản sửa lỗi mới, cho phép các nhóm mang lại giá trị cho khách hàng nhanh hơn và thường xuyên hơn.


Với CD, mọi thay đổi mã vượt qua các bài kiểm tra CI đều được coi là sẵn sàng để triển khai, cho phép các nhóm tự tin triển khai các bản phát hành mới bất kỳ lúc nào. Tôi sẽ không thảo luận về việc phân phối liên tục trong bài đăng này, nhưng tôi sẽ quay lại vấn đề này vì có rất nhiều điều để thảo luận.


Tôi là một fan hâm mộ lớn của khái niệm này, nhưng có một số điều chúng ta cần theo dõi.

Công cụ tích hợp liên tục

Có nhiều công cụ tích hợp liên tục mạnh mẽ. Dưới đây là một số công cụ thường được sử dụng:


  • Jenkins : Jenkins là một trong những công cụ CI phổ biến nhất, cung cấp nhiều loại plugin và tích hợp để hỗ trợ các ngôn ngữ lập trình và công cụ xây dựng khác nhau. Nó là mã nguồn mở và cung cấp giao diện thân thiện với người dùng để thiết lập và quản lý các quy trình xây dựng.


    Nó được viết bằng Java và thường là “công cụ cần dùng” của tôi. Tuy nhiên, thật khó để quản lý và thiết lập. Có một số giải pháp “Jenkins với tư cách là một dịch vụ” cũng làm sạch trải nghiệm người dùng còn thiếu sót của nó.


  • Travis CI : Travis CI là một công cụ CI dựa trên đám mây tích hợp tốt với GitHub, khiến nó trở thành lựa chọn tuyệt vời cho các dự án dựa trên GitHub. Vì nó có trước GitHub Actions nên nó đã trở thành mặc định cho nhiều dự án nguồn mở trên GitHub.


  • CircleCI : CircleCI là một công cụ CI dựa trên đám mây hỗ trợ nhiều ngôn ngữ lập trình và công cụ xây dựng. Nó cung cấp một giao diện thân thiện với người dùng, nhưng điểm hấp dẫn lớn của nó là tốc độ xây dựng và phân phối.


  • GitLab CI/CD : GitLab là một công cụ quản lý mã nguồn phổ biến bao gồm các khả năng CI/CD tích hợp sẵn. Giải pháp GitLab linh hoạt nhưng đơn giản; nó đã đạt được một số sức hút trong ngành ngay cả bên ngoài phạm vi GitLab.


  • Bitbucket Pipelines : Bitbucket Pipelines là một công cụ CI dựa trên đám mây của Atlassian tích hợp hoàn hảo với Bitbucket, công cụ quản lý mã nguồn của họ. Vì là một sản phẩm của Atlassian nên nó cung cấp khả năng tích hợp JIRA liền mạch và chức năng hướng tới doanh nghiệp rất linh hoạt.


Lưu ý rằng tôi đã không đề cập đến các Tác vụ GitHub mà chúng ta sẽ sớm đề cập. Có một số yếu tố cần xem xét khi so sánh các công cụ CI:


  • Dễ sử dụng: Một số công cụ CI có quy trình thiết lập đơn giản và giao diện thân thiện với người dùng, giúp các nhà phát triển bắt đầu và quản lý quy trình xây dựng của họ dễ dàng hơn.


  • Tích hợp với các Công cụ quản lý mã nguồn (SCM) như GitHub, GitLab và Bitbucket. Điều này giúp các nhóm tự động hóa quy trình xây dựng, thử nghiệm và triển khai của họ dễ dàng hơn.


  • Hỗ trợ các ngôn ngữ lập trình và công cụ xây dựng khác nhau: Các công cụ CI khác nhau hỗ trợ các ngôn ngữ lập trình và công cụ xây dựng khác nhau, vì vậy điều quan trọng là phải chọn một công cụ tương thích với ngăn xếp phát triển của bạn.


  • Khả năng mở rộng: Một số công cụ CI phù hợp hơn với các tổ chức lớn hơn với quy trình xây dựng phức tạp, trong khi những công cụ khác phù hợp hơn với các nhóm nhỏ hơn với nhu cầu đơn giản hơn.


  • Chi phí: Các công cụ CI có nhiều loại chi phí, từ miễn phí và mã nguồn mở đến các công cụ thương mại có thể đắt tiền, vì vậy, điều quan trọng là phải chọn một công cụ phù hợp với ngân sách của bạn.


  • Tính năng: Các công cụ CI khác nhau cung cấp các tính năng riêng biệt, chẳng hạn như kết quả thử nghiệm và xây dựng theo thời gian thực, hỗ trợ cho các bản dựng song song và khả năng triển khai tích hợp.


Nói chung, Jenkins được biết đến với tính linh hoạt và thư viện plugin phong phú, khiến nó trở thành lựa chọn phổ biến cho các nhóm có quy trình xây dựng phức tạp. Travis CI và CircleCI được biết đến nhờ tính dễ sử dụng và tích hợp với các công cụ SCM phổ biến, khiến chúng trở thành lựa chọn tốt cho các nhóm vừa và nhỏ.


GitLab CI/CD là một lựa chọn phổ biến cho các nhóm sử dụng GitLab để quản lý mã nguồn của họ vì nó cung cấp các khả năng CI/CD tích hợp. Bitbucket Pipelines là một lựa chọn tốt cho các nhóm sử dụng Bitbucket để quản lý mã nguồn của họ, vì nó tích hợp hoàn hảo với nền tảng.

Đám mây so với tại chỗ

Việc lưu trữ các đại lý là một yếu tố quan trọng cần xem xét khi lựa chọn giải pháp CI. Có hai tùy chọn chính cho lưu trữ đại lý: dựa trên đám mây và tại chỗ.


  • Dựa trên đám mây : Các giải pháp CI dựa trên đám mây, chẳng hạn như Travis CI, CircleCI, GitHub Actions và Bitbucket Pipelines, lưu trữ các tác nhân trên máy chủ của riêng họ trên đám mây. Điều này có nghĩa là bạn không phải lo lắng về việc quản lý cơ sở hạ tầng bên dưới và bạn có thể tận dụng khả năng mở rộng và độ tin cậy của đám mây.


  • Tại chỗ : Các giải pháp CI tại chỗ, chẳng hạn như Jenkins, cho phép bạn lưu trữ các tác nhân trên máy chủ của riêng bạn. Điều này cho phép bạn kiểm soát nhiều hơn đối với cơ sở hạ tầng cơ bản nhưng cũng đòi hỏi nhiều nỗ lực hơn để quản lý và bảo trì máy chủ.


Khi chọn giải pháp CI, điều quan trọng là phải xem xét nhu cầu và yêu cầu cụ thể của nhóm bạn.


Ví dụ: nếu bạn có một quy trình xây dựng lớn và phức tạp, giải pháp tại chỗ như Jenkins có thể là lựa chọn tốt hơn vì giải pháp này cho phép bạn kiểm soát nhiều hơn đối với cơ sở hạ tầng bên dưới.


Mặt khác, nếu bạn có một nhóm nhỏ với nhu cầu đơn giản, giải pháp dựa trên đám mây như Travis CI có thể là lựa chọn tốt hơn vì giải pháp này dễ thiết lập và quản lý.

Trạng thái đại lý

Trạng thái xác định liệu các tác nhân có giữ lại dữ liệu và cấu hình của chúng giữa các bản dựng hay không.


  • Tác nhân có trạng thái : Một số giải pháp CI, chẳng hạn như Jenkins, cho phép tác nhân có trạng thái, nghĩa là tác nhân giữ lại dữ liệu và cấu hình của chúng giữa các bản dựng. Điều này hữu ích cho những trường hợp bạn cần duy trì dữ liệu giữa các bản dựng, chẳng hạn như khi bạn đang sử dụng cơ sở dữ liệu hoặc chạy thử nghiệm dài hạn.


  • Tác nhân phi trạng thái : Các giải pháp CI khác, chẳng hạn như Travis CI, sử dụng tác nhân phi trạng thái, nghĩa là tác nhân được tạo lại từ đầu cho mỗi bản dựng. Điều này cung cấp một phương tiện chặn rõ ràng cho mỗi bản dựng, nhưng điều đó cũng có nghĩa là bạn cần quản lý mọi cấu hình và dữ liệu được lưu giữ lâu dài bên ngoài, chẳng hạn như trong cơ sở dữ liệu hoặc bộ lưu trữ đám mây.


Có một cuộc tranh luận sôi nổi giữa những người ủng hộ CI về cách tiếp cận tốt nhất. Các tác nhân phi trạng thái cung cấp một môi trường sạch sẽ và dễ tái tạo. Tôi chọn chúng cho hầu hết các trường hợp và nghĩ rằng chúng là cách tiếp cận tốt hơn.


Các tác nhân không trạng thái cũng có thể đắt hơn vì chúng được thiết lập chậm hơn. Vì chúng tôi trả tiền cho tài nguyên đám mây nên chi phí đó có thể tăng lên. Nhưng lý do chính khiến một số nhà phát triển thích các tác nhân có trạng thái là khả năng điều tra.


Với một tác nhân phi trạng thái, khi một quy trình CI không thành công, bạn thường không có phương tiện điều tra nào ngoài nhật ký.


Với một tác nhân có trạng thái, chúng ta có thể đăng nhập vào máy và thử chạy quy trình theo cách thủ công trên máy đã cho. Chúng tôi có thể tạo lại một vấn đề không thành công và hiểu rõ hơn nhờ đó.


Một công ty mà tôi đã làm việc cùng đã chọn Azure thay vì GitHub Actions vì Azure cho phép các tác nhân có trạng thái. Điều này rất quan trọng đối với họ khi gỡ lỗi quy trình CI bị lỗi.


Tôi không đồng ý với điều đó, nhưng đó là ý kiến cá nhân. Tôi cảm thấy mình đã dành nhiều thời gian hơn để khắc phục sự cố dọn dẹp tác nhân xấu hơn là thu được lợi ích từ việc điều tra một lỗi. Nhưng đó là kinh nghiệm cá nhân và một số người bạn thông minh của tôi không đồng ý.

Bản dựng lặp lại

Các bản dựng có thể lặp lại đề cập đến khả năng tạo ra các tạo phẩm phần mềm chính xác giống nhau mỗi khi một bản dựng được thực hiện, bất kể môi trường hay thời gian quá trình xây dựng được thực hiện.


Từ góc độ DevOps, việc có các bản dựng có thể lặp lại là điều cần thiết để đảm bảo rằng việc triển khai phần mềm nhất quán và đáng tin cậy.


Lỗi liên tục là nguyên nhân của DevOps ở khắp mọi nơi và chúng rất khó theo dõi.


Thật không may, không có sửa chữa dễ dàng. Nhiều như chúng tôi muốn nó, một số tính không ổn định tìm đường vào các dự án có độ phức tạp hợp lý. Công việc của chúng tôi là giảm thiểu điều này càng nhiều càng tốt. Có hai trình chặn đối với các bản dựng có thể lặp lại:


  • Phần phụ thuộc - Nếu chúng tôi không sử dụng các phiên bản cụ thể cho phần phụ thuộc, thì ngay cả một thay đổi nhỏ cũng có thể phá vỡ bản dựng của chúng tôi.


  • Các bài kiểm tra không ổn định - Các bài kiểm tra thỉnh thoảng bị lỗi mà không có lý do rõ ràng là điều tồi tệ nhất tuyệt đối.


Khi xác định các phụ thuộc, chúng ta cần tập trung vào các phiên bản cụ thể. Có nhiều kế hoạch lập phiên bản, nhưng trong thập kỷ qua, việc lập phiên bản ngữ nghĩa ba số tiêu chuẩn đã chiếm lĩnh ngành công nghiệp.


Sơ đồ này cực kỳ quan trọng đối với CI vì việc sử dụng nó có thể ảnh hưởng đáng kể đến độ lặp lại của bản dựng, ví dụ như với maven, chúng ta có thể thực hiện:

 <dependency> <groupId>group</groupId> <artifactId>artifact</artifactId> <version>2.3.1</version> </dependency>


Điều này rất cụ thể và tuyệt vời cho khả năng lặp lại. Tuy nhiên, điều này có thể trở nên lỗi thời một cách nhanh chóng. Chúng tôi có thể thay thế số phiên bản bằng LATEST hoặc RELEASE sẽ tự động lấy phiên bản hiện tại. Điều này thật tệ vì các bản dựng sẽ không thể lặp lại được nữa.


Tuy nhiên, cách tiếp cận ba số được mã hóa cứng cũng có vấn đề. Thông thường, một phiên bản vá đại diện cho một bản sửa lỗi bảo mật cho một lỗi. Trong trường hợp đó, chúng tôi muốn cập nhật hoàn toàn lên bản cập nhật nhỏ mới nhất chứ không phải các phiên bản mới hơn.


Ví dụ: đối với trường hợp trước đó, tôi muốn sử dụng hoàn toàn phiên bản 2.3.2 chứ không phải 2.4.1 . Điều này đánh đổi một số khả năng lặp lại đối với các lỗi và cập nhật bảo mật nhỏ.


Nhưng một cách tốt hơn là sử dụng Maven Versions Plugin và gọi lệnh mvn versions:use-latest-releases theo định kỳ. Điều này cập nhật các phiên bản mới nhất để giữ cho dự án của chúng tôi được cập nhật.


Đây là phần đơn giản của các bản dựng lặp lại. Khó khăn là trong các bài kiểm tra dễ vỡ. Đây là một vấn đề phổ biến đến mức một số dự án xác định “số lượng hợp lý” các thử nghiệm không thành công và một số dự án chạy lại bản dựng nhiều lần trước khi thừa nhận lỗi.


Một nguyên nhân chính của sự bong tróc thử nghiệm là rò rỉ trạng thái. Các thử nghiệm có thể không thành công do các tác dụng phụ tinh vi còn sót lại từ thử nghiệm trước. Lý tưởng nhất là một bài kiểm tra sẽ tự dọn dẹp để mỗi bài kiểm tra sẽ chạy riêng biệt.


Trong một thế giới hoàn hảo, chúng tôi sẽ chạy mọi thử nghiệm trong một môi trường trong lành hoàn toàn biệt lập, nhưng điều này không thực tế. Điều đó có nghĩa là các thử nghiệm sẽ mất quá nhiều thời gian để chạy và chúng tôi sẽ cần đợi rất nhiều thời gian cho quy trình CI.


Chúng tôi có thể viết các bài kiểm tra với các mức cô lập khác nhau; đôi khi chúng tôi cần cách ly hoàn toàn và có thể cần quay một thùng chứa để thử nghiệm. Nhưng hầu hết thời gian, chúng tôi không làm như vậy và sự khác biệt về tốc độ là rất đáng kể.


Dọn dẹp sau khi kiểm tra là rất khó khăn. Đôi khi, rò rỉ trạng thái từ các công cụ bên ngoài chẳng hạn như cơ sở dữ liệu có thể gây ra lỗi thử nghiệm không ổn định. Để đảm bảo khả năng lặp lại lỗi, một thực tế phổ biến là sắp xếp các trường hợp kiểm thử một cách nhất quán; điều này đảm bảo các lần chạy bản dựng trong tương lai sẽ thực hiện theo cùng một thứ tự.


Đây là một chủ đề được tranh luận sôi nổi. Một số kỹ sư tin rằng điều này khuyến khích các bài kiểm tra lỗi và che giấu các vấn đề mà chúng tôi chỉ có thể phát hiện ra với một thứ tự kiểm tra ngẫu nhiên. Theo kinh nghiệm của tôi, điều này thực sự đã tìm thấy lỗi trong các bài kiểm tra, nhưng không tìm thấy lỗi trong mã.


Mục tiêu của tôi không phải là xây dựng các bài kiểm tra hoàn hảo và vì vậy tôi thích chạy các bài kiểm tra theo thứ tự nhất quán, chẳng hạn như thứ tự chữ cái.


Điều quan trọng là phải giữ số liệu thống kê về các lỗi thử nghiệm và không bao giờ chỉ cần nhấn thử lại. Bằng cách theo dõi các bài kiểm tra có vấn đề và thứ tự thực hiện lỗi, chúng tôi thường có thể tìm ra nguồn gốc của vấn đề.


Hầu hết, nguyên nhân cốt lõi của lỗi xảy ra là do quá trình dọn dẹp bị lỗi trong lần thử nghiệm trước, đó là lý do tại sao thứ tự lại quan trọng và tính nhất quán của nó cũng quan trọng.

Trải nghiệm của nhà phát triển và Hiệu suất CI

Chúng tôi ở đây để phát triển một sản phẩm phần mềm, không phải một công cụ CI. Công cụ CI ở đây để làm cho quá trình tốt hơn. Thật không may, nhiều khi trải nghiệm với công cụ CI khiến chúng tôi khó chịu đến mức cuối cùng chúng tôi dành nhiều thời gian hơn cho công việc hậu cần hơn là thực sự viết mã.


Thông thường, tôi đã dành nhiều ngày cố gắng vượt qua kiểm tra CI để có thể hợp nhất các thay đổi của mình. Mỗi khi tôi đến gần, một nhà phát triển khác sẽ hợp nhất thay đổi của họ trước và sẽ phá vỡ bản dựng của tôi.


Điều này góp phần tạo ra trải nghiệm kém xuất sắc hơn cho nhà phát triển, đặc biệt là khi nhóm mở rộng quy mô và chúng tôi dành nhiều thời gian hơn trong hàng CI thay vì hợp nhất các thay đổi của mình. Có rất nhiều điều chúng ta có thể làm để giảm bớt những vấn đề này:


  • Giảm trùng lặp trong các thử nghiệm - Thử nghiệm quá mức là một triệu chứng phổ biến mà chúng tôi có thể phát hiện bằng các công cụ bảo hiểm.


  • Loại bỏ kiểm tra không ổn định - Tôi biết việc xóa hoặc tắt kiểm tra là một vấn đề. Đừng làm điều đó một cách nhẹ nhàng. Nhưng nếu bạn dành nhiều thời gian để gỡ lỗi bài kiểm tra hơn là gỡ lỗi mã của mình, thì giá trị của nó là điều gây tranh cãi.


  • Phân bổ các máy bổ sung hoặc nhanh hơn cho quy trình CI.


  • Song song hóa quá trình CI. Chúng tôi có thể song song hóa một số loại bản dựng và một số thử nghiệm.



Cuối cùng, điều này kết nối trực tiếp với năng suất của các nhà phát triển. Nhưng chúng tôi không có hồ sơ cho các loại tối ưu hóa này. Chúng tôi phải đo lường mỗi lần; điều này có thể là khó khăn.

Hành động GitHub

GitHub Actions là một nền tảng tích hợp liên tục/phân phối liên tục (CI/CD) được tích hợp trong GitHub. Nó không trạng thái mặc dù nó cho phép các tác nhân tự lưu trữ ở một mức độ nào đó. Tôi đang tập trung vào nó vì nó miễn phí cho các dự án nguồn mở và có hạn ngạch miễn phí kha khá cho các dự án nguồn đóng.


Sản phẩm này là một ứng cử viên tương đối mới trong lĩnh vực này, nó không linh hoạt như hầu hết các công cụ CI khác đã đề cập trước đây. Tuy nhiên, nó rất thuận tiện cho các nhà phát triển nhờ tích hợp sâu với GitHub và các tác nhân phi trạng thái.


Để kiểm tra các Tác vụ GitHub, chúng tôi cần một dự án mới, trong trường hợp này, tôi đã tạo bằng JHipster với cấu hình được thấy ở đây:


Tôi đã tạo một dự án riêng thể hiện việc sử dụng Tác vụ GitHub tại đây. Lưu ý rằng bạn có thể làm theo điều này với bất kỳ dự án nào; mặc dù chúng tôi bao gồm các hướng dẫn maven trong trường hợp này, nhưng khái niệm này rất đơn giản.


Sau khi dự án được tạo, chúng ta có thể mở trang dự án trên GitHub và chuyển đến tab hành động.


Chúng ta sẽ thấy một cái gì đó như thế này:


Ở góc dưới cùng bên phải, chúng ta có thể thấy loại dự án Java với Maven. Khi chúng tôi chọn loại này, chúng tôi chuyển sang tạo tệp maven.yml như được hiển thị ở đây:


Thật không may, maven.yml mặc định do GitHub đề xuất có vấn đề. Đây là mã chúng ta thấy trong hình ảnh này:

 name: Java CI with Maven on: push: branches: [ "master" ] pull_request: branches: [ "master" ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'temurin' cache: maven - name: Build with Maven run: mvn -B package --file pom.xml # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive - name: Update dependency graph uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6


Ba dòng cuối cùng cập nhật biểu đồ phụ thuộc. Nhưng tính năng này không thành công, hoặc ít nhất là nó không thành công đối với tôi. Loại bỏ chúng đã giải quyết vấn đề. Phần còn lại của mã là cấu hình YAML tiêu chuẩn.


Các dòng pull_requestpush gần đầu mã tuyên bố rằng các bản dựng sẽ chạy trên cả yêu cầu kéo và đẩy lên bản chính. Điều này có nghĩa là chúng tôi có thể chạy thử nghiệm của mình đối với yêu cầu kéo trước khi cam kết. Nếu thử nghiệm không thành công, chúng tôi sẽ không cam kết.


Chúng tôi có thể không cho phép cam kết với các thử nghiệm không thành công trong cài đặt dự án. Khi chúng tôi cam kết tệp YAML, chúng tôi có thể tạo yêu cầu kéo và hệ thống sẽ chạy quy trình xây dựng cho chúng tôi. Điều này bao gồm việc chạy thử nghiệm vì mục tiêu “gói” trong maven chạy thử nghiệm theo mặc định.


Mã gọi các bài kiểm tra nằm trong dòng bắt đầu bằng “run” ở gần cuối. Đây thực sự là một dòng lệnh Unix tiêu chuẩn. Đôi khi, thật hợp lý khi tạo một tập lệnh shell và chỉ chạy nó từ quy trình CI.


Đôi khi, việc viết một tập lệnh shell tốt dễ dàng hơn là xử lý tất cả các tệp YAML và cài đặt cấu hình của các ngăn xếp CI khác nhau.


Nó cũng dễ mang theo hơn nếu chúng ta chọn chuyển đổi công cụ CI trong tương lai. Ở đây, chúng tôi không cần nó mặc dù maven là đủ cho nhu cầu hiện tại của chúng tôi.


Chúng ta có thể thấy yêu cầu kéo thành công ở đây:


Để kiểm tra điều này, chúng ta có thể thêm một lỗi vào mã bằng cách thay đổi điểm cuối “/api” thành “/myapi” . Điều này tạo ra sự thất bại hiển thị dưới đây. Nó cũng kích hoạt một email báo lỗi được gửi tới tác giả của cam kết.


Khi xảy ra lỗi như vậy, chúng ta có thể nhấp vào liên kết “Chi tiết” ở bên phải. Điều này đưa chúng tôi trực tiếp đến thông báo lỗi mà bạn thấy ở đây:


Thật không may, đây thường là một thông báo vô dụng không cung cấp trợ giúp trong việc giải quyết vấn đề. Tuy nhiên, cuộn lên sẽ hiển thị lỗi thực tế thường được đánh dấu thuận tiện cho chúng tôi như được thấy ở đây:


Lưu ý rằng thường có nhiều lỗi nên bạn nên cuộn lên thêm. Trong lỗi này, chúng ta có thể thấy lỗi là một xác nhận trong dòng 394 của AccountResourceIT mà bạn có thể xem tại đây, lưu ý rằng số dòng không khớp. Trong trường hợp này, dòng 394 là dòng cuối cùng của phương thức:

 @Test @Transactional void testActivateAccount() throws Exception { final String activationKey = "some activation key"; User user = new User(); user.setLogin("activate-account"); user.setEmail("[email protected]"); user.setPassword(RandomStringUtils.randomAlphanumeric(60)); user.setActivated(false); user.setActivationKey(activationKey); userRepository.saveAndFlush(user); restAccountMockMvc.perform(get("/api/activate?key={activationKey}", activationKey)).andExpect(status().isOk()); user = userRepository.findOneByLogin(user.getLogin()).orElse(null); assertThat(user.isActivated()).isTrue(); }


Điều này có nghĩa là cuộc gọi khẳng định không thành công. isActivated() trả về false và thất bại trong bài kiểm tra. Điều này sẽ giúp nhà phát triển thu hẹp vấn đề và hiểu nguyên nhân gốc rễ.

Đi xa hơn

Như chúng tôi đã đề cập trước đây, CI là về năng suất của nhà phát triển. Chúng ta có thể tiến xa hơn nhiều so với việc chỉ biên dịch và thử nghiệm. Chúng tôi có thể thực thi các tiêu chuẩn viết mã, cắt xén mã, phát hiện các lỗ hổng bảo mật, v.v.


Trong ví dụ này, hãy tích hợp Sonar Cloud, một công cụ phân tích mã mạnh mẽ (linter). Nó tìm ra các lỗi tiềm ẩn trong dự án của bạn và giúp bạn cải thiện chất lượng mã.


SonarCloud là phiên bản dựa trên đám mây của SonarQube, cho phép các nhà phát triển liên tục kiểm tra và phân tích mã của họ để tìm và khắc phục các sự cố liên quan đến chất lượng mã, bảo mật và khả năng bảo trì. Nó hỗ trợ nhiều ngôn ngữ lập trình khác nhau như Java, C#, JavaScript, Python, v.v.


SonarCloud tích hợp với các công cụ phát triển phổ biến như GitHub, GitLab, Bitbucket, Azure DevOps, v.v. Các nhà phát triển có thể sử dụng SonarCloud để nhận phản hồi theo thời gian thực về chất lượng mã của họ và cải thiện chất lượng mã tổng thể.


Mặt khác, SonarQube là một nền tảng nguồn mở cung cấp các công cụ phân tích mã tĩnh cho các nhà phát triển phần mềm. Nó cung cấp một bảng điều khiển hiển thị tóm tắt về chất lượng mã và giúp các nhà phát triển xác định và khắc phục các sự cố liên quan đến chất lượng mã, bảo mật và khả năng bảo trì.


Cả SonarCloud và SonarQube đều cung cấp các chức năng tương tự, nhưng SonarCloud là dịch vụ dựa trên đám mây và yêu cầu đăng ký, trong khi SonarQube là nền tảng nguồn mở có thể được cài đặt tại chỗ hoặc trên máy chủ đám mây.


Để đơn giản, chúng tôi sẽ sử dụng SonarCloud nhưng SonarQube sẽ hoạt động tốt. Để bắt đầu, chúng tôi truy cập sonarcloud.io và đăng ký. Lý tưởng nhất là với tài khoản GitHub của chúng tôi. Sau đó, chúng tôi được cung cấp một tùy chọn để thêm kho lưu trữ để theo dõi bởi Sonar Cloud như được hiển thị ở đây:


Khi chúng tôi chọn tùy chọn Phân tích trang mới, chúng tôi cần cấp quyền truy cập vào kho lưu trữ GitHub của mình. Bước tiếp theo là chọn các dự án chúng tôi muốn thêm vào Sonar Cloud như được hiển thị ở đây:


Khi chúng tôi chọn và tiến hành quá trình thiết lập, chúng tôi cần chọn phương pháp phân tích. Vì chúng tôi sử dụng Tác vụ GitHub, nên chúng tôi cần chọn tùy chọn đó trong giai đoạn sau như được thấy ở đây:


Khi điều này được thiết lập, chúng tôi sẽ bước vào giai đoạn cuối cùng trong trình hướng dẫn Sonar Cloud như trong hình ảnh sau đây. Chúng tôi nhận được mã thông báo mà chúng tôi có thể sao chép (mục 2 bị mờ trong hình ảnh) và chúng tôi sẽ sớm sử dụng mã đó.


Lưu ý rằng cũng có các hướng dẫn mặc định để sử dụng với maven xuất hiện khi bạn nhấp vào nút có nhãn "Maven".


Quay lại dự án trong GitHub, chúng ta có thể chuyển đến tab cài đặt dự án (đừng nhầm với cài đặt tài khoản ở menu trên cùng). Tại đây, chúng ta chọn “Bí mật và biến số” như hình sau:


Trong phần này, chúng tôi có thể thêm bí mật kho lưu trữ mới, cụ thể là khóa và giá trị SONAR_TOKEN mà chúng tôi đã sao chép từ SonarCloud như bạn có thể thấy ở đây:


Bí mật kho lưu trữ GitHub là một tính năng cho phép nhà phát triển lưu trữ an toàn thông tin nhạy cảm được liên kết với kho lưu trữ GitHub, chẳng hạn như khóa API, mã thông báo và mật khẩu, được yêu cầu để xác thực và cho phép truy cập vào các dịch vụ hoặc nền tảng bên thứ ba khác nhau được sử dụng bởi kho lưu trữ .


Khái niệm đằng sau Bí mật kho lưu trữ GitHub là cung cấp một cách an toàn và thuận tiện để quản lý và chia sẻ thông tin bí mật mà không phải tiết lộ thông tin công khai trong mã hoặc tệp cấu hình.


Bằng cách sử dụng bí mật, nhà phát triển có thể tách biệt thông tin nhạy cảm khỏi cơ sở mã và bảo vệ thông tin đó khỏi bị lộ hoặc bị xâm phạm trong trường hợp vi phạm bảo mật hoặc truy cập trái phép.


Bí mật kho lưu trữ GitHub được lưu trữ an toàn và chỉ có thể được truy cập bởi những người dùng được ủy quyền đã được cấp quyền truy cập vào kho lưu trữ. Bí mật có thể được sử dụng trong quy trình công việc, hành động và các tập lệnh khác được liên kết với kho lưu trữ.


Chúng có thể được chuyển dưới dạng biến môi trường cho mã để mã có thể truy cập và sử dụng các bí mật theo cách an toàn, đáng tin cậy.


Nhìn chung, GitHub Repository Secrets cung cấp một cách đơn giản và hiệu quả để các nhà phát triển quản lý và bảo vệ thông tin bí mật được liên kết với một kho lưu trữ, giúp đảm bảo tính bảo mật và tính toàn vẹn của dự án cũng như dữ liệu mà nó xử lý.


Bây giờ chúng ta cần tích hợp điều này vào dự án. Đầu tiên, chúng ta cần thêm hai dòng này vào tệp pom.xml. Lưu ý rằng bạn cần cập nhật tên tổ chức để khớp với tên của riêng bạn. Chúng nên đi vào phần trong XML:


 <sonar.organization>shai-almog</sonar.organization> <sonar.host.url>https://sonarcloud.io</sonar.host.url>


Lưu ý rằng dự án JHipster mà chúng tôi tạo đã có hỗ trợ SonarQube nên được xóa khỏi tệp pom trước khi mã này hoạt động.


Sau này, chúng ta có thể thay thế phần “Build with Maven” của tệp maven.yml bằng phiên bản sau:

 - name: Build with Maven env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=shai-almog_HelloJHipster package


Khi chúng tôi làm điều đó, SonarCloud sẽ cung cấp báo cáo cho mọi yêu cầu kéo được hợp nhất vào hệ thống như được hiển thị ở đây:


Chúng ta có thể thấy một báo cáo bao gồm danh sách các lỗi, lỗ hổng bảo mật, mùi và các vấn đề bảo mật. Nhấp vào từng vấn đề đó sẽ dẫn chúng ta đến một thứ như thế này:


Lưu ý rằng chúng tôi có các tab giải thích chính xác lý do tại sao sự cố lại xảy ra, cách khắc phục sự cố, v.v. Đây là một công cụ cực kỳ mạnh mẽ đóng vai trò là một trong những công cụ đánh giá mã có giá trị nhất trong nhóm.


Hai yếu tố thú vị bổ sung mà chúng tôi đã thấy trước đây là báo cáo về phạm vi bảo hiểm và trùng lặp. SonarCloud hy vọng rằng các thử nghiệm sẽ có mức độ phù hợp mã 80% (kích hoạt 80% mã trong yêu cầu kéo), đây là mức cao và có thể được định cấu hình trong cài đặt.


Nó cũng chỉ ra mã trùng lặp có thể cho thấy vi phạm nguyên tắc Không lặp lại chính mình (DRY).

Cuối cùng

CI là một chủ đề lớn với nhiều cơ hội để cải thiện quy trình dự án của bạn. Chúng tôi có thể tự động hóa việc phát hiện lỗi. Hợp lý hóa việc tạo tác phẩm, phân phối tự động và hơn thế nữa. Nhưng theo quan điểm khiêm tốn của tôi, nguyên tắc cốt lõi đằng sau CI là trải nghiệm của nhà phát triển.


Nó ở đây để làm cho cuộc sống của chúng tôi dễ dàng hơn.


Khi nó được thực hiện không tốt, quy trình CI có thể biến công cụ tuyệt vời này thành cơn ác mộng. Vượt qua các bài kiểm tra trở thành một bài tập vô ích. Chúng tôi thử đi thử lại nhiều lần cho đến khi cuối cùng chúng tôi có thể hợp nhất. Chúng tôi chờ đợi hàng giờ để hợp nhất vì hàng đợi đông đúc, chậm chạp.


Công cụ được cho là có ích này lại trở thành kẻ thù không đội trời chung của chúng ta. Đây không phải là trường hợp. CI nên làm cho cuộc sống của chúng ta dễ dàng hơn chứ không phải ngược lại.