Tự động hoàn nguyên các cam kết không xây dựng được


44

Một đồng nghiệp của tôi nói với tôi rằng anh ta đang suy nghĩ trong việc đưa ra máy chủ CI của chúng tôi để cam kết Revert rằng thất bại trong việc xây dựng, vì vậy HEADtrong masterluôn ổn định (như trong truyền xây dựng ít nhất).

Đây có phải là một thực tiễn tốt nhất hoặc nó có thể có vấn đề hơn là chỉ masterbị hỏng cho đến khi nhà phát triển sửa nó?

Tôi nghĩ rằng việc hoàn nguyên cam kết sẽ làm cho nhiệm vụ của nó trở nên phức tạp hơn và sửa chữa (nhà phát triển sẽ phải hoàn nguyên lại và sau đó cam kết sửa lỗi, điều này cũng sẽ làm lộn xộn git log) và chúng ta chỉ nên để lại cam kết và sau đó cam kết sửa chữa. Mặc dù tôi thấy một số lợi thế trong việc masterổn định, nhưng việc hoàn thành các cam kết thất bại này không thuyết phục được tôi.

chỉnh sửa: Không quan trọng nếu nó là masterhoặc bất kỳ nhánh phát triển nào khác, nhưng câu hỏi vẫn giữ nguyên: hệ thống CI có nên hoàn nguyên một cam kết đã thất bại trong quá trình xây dựng không?

một chỉnh sửa (lenghty) khác: Ok, chúng tôi đang sử dụng gitmột cách kỳ lạ. Chúng tôi tin rằng khái niệm về các chi nhánh đi ngược lại với CI thực sự, bởi vì việc cam kết với một chi nhánh sẽ tách biệt bạn khỏi các nhà phát triển khác và những thay đổi của họ, đồng thời thêm thời gian khi bạn phải tái hòa nhập chi nhánh và giải quyết các xung đột có thể xảy ra. Nếu mọi người cam kết với masterxung đột này sẽ giảm đến mức tối thiểu và mọi cam kết đều vượt qua tất cả các bài kiểm tra.

Tất nhiên, điều này buộc bạn chỉ đẩy ổn định (hoặc bạn phá vỡ bản dựng) và lập trình cẩn thận hơn để không phá vỡ tính tương thích ngược hoặc thực hiện chuyển đổi tính năng khi giới thiệu các tính năng mới.

Có sự đánh đổi khi thực hiện CI theo cách này hoặc cách khác, nhưng đó là ngoài phạm vi câu hỏi (xem câu hỏi liên quan cho việc này). Nếu bạn thích, tôi có thể đặt lại câu hỏi: một nhóm nhỏ các nhà phát triển làm việc cùng nhau trong một nhánh tính năng. Nếu một nhà phát triển cam kết một cái gì đó phá vỡ bản dựng cho nhánh đó, hệ thống CI có nên hoàn nguyên cam kết hay không?


38
Xây dựng thất bại không bao giờ nên đạt được masterđể bắt đầu với. Đó là những gì các nhánh phát triển và tính năng được sử dụng cho. Những thay đổi đó diễn ra trong một cái gì đó giống như một nhánh tích hợp nơi bạn có thể kiểm tra xem tất cả các tính năng mới của một số nhà phát triển có hoạt động cùng nhau không và chỉ khi điều này được thử nghiệm mới có thể đi vào tổng thể. Hoặc ít nhất đó là một quy trình công việc có thể.
thorsten müller

1
@ thorstenmüller cũng tưởng tượng rằng nó nằm trong một nhánh phát triển mà tất cả các nhà phát triển sử dụng. Hệ thống CI có nên hoàn nguyên các lỗi không khi xây dựng không?
Carlos Campderrós

7
Có vẻ như bạn đang sử dụng git một cách kỳ lạ. Nói chung, mọi người nên làm việc trên các repos của riêng họ trong các chi nhánh của riêng họ và chỉ được đẩy lên chính một khi CI cho bản dựng cá nhân của họ xác minh rằng các thay đổi là ổn.
Wilbert

4
> "xung đột này được giảm đến mức tối thiểu"; bạn nhận được ít xung đột hơn tại thời điểm hợp nhất, nhưng bạn gặp vấn đề với việc hợp nhất xấu hơn rất nhiều. Giải pháp là liên tục hợp nhất từ ​​chủ đến chi nhánh của bạn như là một phần của quy trình của bạn, không phải là không chi nhánh.
deworde

2
... Tại sao không làm cho các bản dựng thất bại không được chấp nhận thành chủ để bắt đầu?
dùng253751

Câu trả lời:


56

Tôi sẽ chống lại việc này vì những lý do sau:

  • Bất cứ khi nào bạn thiết lập một công cụ tự động để thay đổi mã thay mặt bạn , sẽ có nguy cơ nó bị sai hoặc tình huống sẽ xảy ra khi bạn cần nó để thực hiện thay đổi đó (ví dụ: phiên bản mới nhất của Google Mock có một lỗi trong đó, vì vậy đó không phải là mã của bạn bị lỗi) và bạn phải lãng phí thời gian để cấu hình lại nó. Ngoài ra, luôn có một rủi ro nhỏ rằng bản dựng sẽ thất bại do lỗi trong hệ thống bản dựng, thay vì lỗi trong mã của bạn. Đối với tôi, CI là về việc đạt được sự tin tưởng rằng mã của tôi là chính xác; điều này chỉ đơn thuần sẽ biến nó thành một nguồn vấn đề tiềm ẩn khác khiến tôi phải lo lắng.

  • Các loại lỗi phá vỡ "bản dựng" phải là những lỗi ngớ ngẩn mất rất ít thời gian để sửa (như bạn đã chỉ ra trong một nhận xét, điều này đúng với bạn). Nếu các lỗi tinh vi và phức tạp hơn thường xuyên xuất hiện trên bản chính, thì giải pháp chính xác là không "sửa nó nhanh hơn", nên cẩn thận hơn khi xem xét các nhánh tính năng trước khi chúng được hợp nhất.

  • Rời khỏi chủ không thể sửa chữa trong vài phút trong khi lỗi được khắc phục đúng cách không làm tổn thương bất cứ ai. Không giống như Giám đốc điều hành sẽ trực tiếp kiểm tra chính chủ và xuất bản mã trực tiếp cho khách hàng vào bất kỳ thời điểm ngẫu nhiên nào (ít nhất, hy vọng không phải không có sự tham gia của bạn). Trong trường hợp rất khó xảy ra là bạn cần phát hành thứ gì đó trước khi bạn có thể sửa lỗi, thì bạn có thể dễ dàng đưa ra quyết định hoàn nguyên thủ công trước khi xuất bản.


1
Bên cạnh đó, chỉ các bản dựng thành công mới kích hoạt việc tạo ra một "bản dựng thả" có thể được triển khai. Nếu một bản dựng thất bại, sẽ không có bản dựng có thể triển khai, do đó, sẽ không có rủi ro khi ai đó sẽ xuất bản mã xấu cho khách hàng.
Mark Freedman

1
Tôi chắc chắn có một tùy chọn khác được sử dụng và tốt hơn cái này tôi nghĩ và sử dụng nhiều (chúng tôi sử dụng nó trên twitter). đừng đặt các bản dựng thất bại lên chủ và những lỗi ngớ ngẩn cũng dễ sửa. Xem câu trả lời đầy đủ của tôi dưới đây.
Dean Hiller

26

Trước tiên hãy đồng ý về các điều khoản.

Cá nhân tôi sử dụng thuật ngữ Xây dựng liên tục và Tích hợp liên tục để phân biệt hai kịch bản khác nhau:

  • Xây dựng liên tục: một công cụ kiểm tra định kỳ nếu kho lưu trữ thay đổi kể từ lần xây dựng cuối cùng và xây dựng / kiểm tra nếu có.
  • Tích hợp liên tục: một công cụ lấy Yêu cầu kéo và xác thực chúng dựa trên đầu mới nhất trước khi hiển thị chúng.

Cái sau, Tích hợp liên tục, có nghĩa là kho lưu trữ mà nó bảo vệ luôn có màu xanh 1 : nó hoàn toàn tốt hơn.

Câu hỏi của bạn chỉ thực sự có ý nghĩa đối với Build liên tục, vì vậy tôi sẽ trả lời giả sử đây là thiết lập của bạn.

1 : Các nguyên nhân môi trường cũng có thể làm hỏng quá trình xây dựng, ví dụ thử nghiệm với năm mã hóa cứng (2015) có thể bắt đầu thất bại vào tháng 1 năm 2016, một đĩa có thể bị đầy, ... Và tất nhiên là có bệnh dịch không ổn định xét nghiệm. Tôi ngượng ngùng bỏ qua những vấn đề ở đây; khác chúng tôi sẽ không bao giờ nhận được bất cứ nơi nào.


Nếu bạn có thiết lập Xây dựng liên tục, bạn thực sự có thể tự động đảo ngược các cam kết có thể đã phá vỡ bản dựng, tuy nhiên có một số điểm tinh tế.

  • Bạn thực sự không thể loại bỏ các cam kết: các đồng nghiệp khác có thể đã kiểm tra chúng và sẽ đẩy họ trở lại trong lần tiếp theo họ cố gắng cam kết. Thay vào đó, một sự đảo ngược nên được thực hiện một khác biệt ngược lại . Ồ, và đồng nghiệp sẽ ghét bạn vì đã hoàn nguyên công việc của họ khi điều đó đúng vì họ sẽ phải tìm cách đẩy nó trở lại ...
  • Bạn thực sự không thể chỉ tước bỏ cam kết cuối cùng (đó là hợp nhất), nhưng cần phải loại bỏ tất cả các cam kết ... đến một điểm nhất định. Ví dụ, cam kết tốt đã biết cuối cùng (hãy cẩn thận khi khởi động hệ thống).
  • Bạn cần suy nghĩ về các nguyên nhân bên ngoài (các vấn đề môi trường) và tránh thiết lập hoàn nguyên mọi thứ cho đến ngày 0. Rất may, trở lại cam kết tốt đã biết cuối cùng vượt qua vấn đề này.
  • Bạn cần nghĩ rằng bản dựng tốt được biết đến cuối cùng có thể không còn bản dựng (vấn đề môi trường), trong trường hợp đó có khả năng tất cả các cam kết tiếp theo sẽ bị đảo ngược. Lý tưởng nhất là trong trường hợp thất bại và trước khi hoàn nguyên, bạn sẽ kiểm tra bản dựng tốt được biết đến cuối cùng và kiểm tra lại nó. Nếu nó đi qua, hoàn nguyên, nếu không, đưa ra một cảnh báo.

Lưu ý rằng với hệ thống này, trong trường hợp thử nghiệm không ổn định hoặc đồng nghiệp thường phạm phải tào lao, nhiều cam kết tốt sẽ bị đảo ngược. Đồng nghiệp của bạn sau đó sẽ ghét bạn.


Hy vọng rằng câu chuyện kinh dị của tôi đã phơi bày các vấn đề cho phép kho lưu trữ bị hỏng và bây giờ bạn sẽ triển khai một đường dẫn Tích hợp liên tục thích hợp, nơi PR không bao giờ được đẩy trực tiếp vào kho lưu trữ mà thay vào đó được xếp hàng để hợp nhất trong hàng đợi công việc và tích hợp từng lúc ( hoặc bằng cách cuộn lại):

  • lấy đầu của kho lưu trữ cục bộ
  • áp dụng yêu cầu kéo
  • xây dựng và thử nghiệm
  • trong trường hợp thành công, đẩy vào kho lưu trữ, nếu không đánh dấu là thất bại
  • chuyển đến các yêu cầu tiếp theo

Đã cố gắng cả hai, điều này là hoàn toàn tốt hơn.


2
Đây thực sự là câu trả lời đúng - giải pháp đúng đắn là ngăn chặn những thay đổi xấu không bao giờ đến được với nhánh chính, không để chúng hạ cánh và sau đó phải đối phó với việc đẩy chúng trở lại.
Daniel Pryden

Tôi nghĩ vấn đề ở đây là người hỏi tin rằng các chi phí đã nêu của việc "cách ly bạn khỏi các nhà phát triển khác và những thay đổi của họ" vượt xa lợi ích. Các chi phí đã nêu là sự nguy hiểm gia tăng của việc sáp nhập không tầm thường khi hai người phân kỳ lâu hơn. IMO lợi ích của việc bị cô lập khỏi mã bị hỏng là rõ ràng. Người hỏi muốn thực hiện một chiến lược "lạc quan", trong đó mã bị hỏng có sẵn trong thời gian ngắn masterđể được kéo, và sau đó khắc phục tình trạng này một khi các thử nghiệm thất bại. Mọi người khác thực hiện chiến lược "bi quan" như bạn khuyên và chỉ cung cấp mã có sẵn để kéo.
Steve Jessop

(trong đó bằng cách "có sẵn để kéo", ý tôi là "lấy từ master", lý tưởng là thứ mà các nhà phát triển có thể làm willy-nilly, nhưng để đạt được điều đó, bạn phải trì hoãn cam kết đến mastertrước khi họ thử nghiệm và vượt qua. Nếu nhà phát triển muốn cherry-pick chưa được kiểm tra hoặc thử nghiệm và thất bại mã đó cũng tốt, và mã này "có sẵn" theo nghĩa đó, đó không phải là những gì tôi đang đề cập đến)
Steve Jessop

Giải pháp đúng đắn là ngăn chặn những thay đổi xấu từ bao giờ đến bất kỳ chi nhánh nào. Cam kết thất bại không bao giờ nên được công khai, bao giờ hết.
Miles Rout

5

Đây có phải là một thực tiễn tốt nhất hoặc nó có thể có vấn đề hơn là chỉ để chủ bị hỏng cho đến khi nhà phát triển sửa nó?

Đó là vấn đề. Một người quyết định "ĐẦU CHÍNH bị hỏng; tôi sẽ hoàn nguyên thay đổi hàng đầu" hoàn toàn khác với hệ thống CI làm tương tự.

Dưới đây là một vài nhược điểm:

  • Lỗi trong quá trình đảo ngược tự động sẽ làm hỏng kho lưu trữ;

  • điều này giả định một thay đổi duy nhất (trên cùng) làm hỏng quá trình xây dựng (không thực tế)

  • Các nhà bảo trì sẽ có nhiều việc phải làm để khắc phục vấn đề, hơn là chỉ điều tra và cam kết (họ cũng sẽ phải xem xét lịch sử ngược lại)

Chúng tôi tin rằng khái niệm về các chi nhánh đi ngược lại với CI thực sự, bởi vì việc cam kết với một chi nhánh sẽ tách biệt bạn khỏi các nhà phát triển khác và những thay đổi của họ, đồng thời thêm thời gian khi bạn phải tái hòa nhập chi nhánh và giải quyết các xung đột có thể xảy ra.

Niềm tin này (chi nhánh so với CI) là không chính xác. Cân nhắc việc giữ một nhánh ổn định, trong đó bạn chỉ cam kết các thay đổi được kiểm tra đơn vị . Phần còn lại (chi nhánh tính năng và chi nhánh địa phương) phải chịu trách nhiệm của từng nhà phát triển và không phải là một phần của chính sách CI của bạn dưới bất kỳ hình thức nào.

Trong các nhánh tính năng bạn muốn tách biệt khỏi các nhà phát triển khác. Điều này cho phép bạn:

  • thực hiện mã hóa thăm dò

  • thử nghiệm với cơ sở mã

  • thực hiện các cam kết một phần (cam kết hiệu quả mã không hoạt động) để thiết lập các điểm sao lưu (trong trường hợp bạn làm hỏng), để tạo thêm lịch sử thay đổi đầy đủ (thông qua các thông báo cam kết) và sao lưu công việc của bạn và chuyển hoàn toàn sang một thứ khác (trong thời gian bạn cần để viết "git commit && git checkout")

  • thực hiện các nhiệm vụ ưu tiên thấp mất nhiều thời gian (ví dụ: bạn muốn thực hiện tái cấu trúc làm thay đổi tất cả 80 lớp của lớp dữ liệu: bạn thay đổi hai lớp mỗi ngày, cho đến khi bạn thay đổi tất cả chúng một mã biên dịch (nhưng bạn có thể làm điều này mà không ảnh hưởng đến bất cứ ai cho đến khi bạn có thể thực hiện một cam kết).

Nếu một nhà phát triển cam kết một cái gì đó phá vỡ bản dựng cho nhánh đó, hệ thống CI có nên hoàn nguyên cam kết hay không?

Nó không nên. Cam kết mã ổn định trên nhánh CI của bạn là trách nhiệm của người ủy quyền, không phải là một hệ thống tự động.


2

Tôi sẽ đề nghị sử dụng môi trường Gerrit + Jenkins để giữ cho nhánh chủ của bạn luôn ở trạng thái tốt. Mọi người đẩy mã mới của họ đến Gerrit, điều này kích hoạt công việc của Jenkins để kéo bản vá đó, xây dựng, kiểm tra, v.v. Nếu các nhà phát triển khác như bản vá của bạn và Jenkins hoàn thành công việc của mình thành công, thì Gerrit sẽ hợp nhất đoạn mã đó vào nhánh chính của bạn.

Đây là một môi trường tương tự được mô tả bởi @ brian-vandenberg

Bên cạnh việc giữ cho chi nhánh của bạn ở trạng thái tốt, bạn cũng thêm một bước xem xét mã để cải thiện chất lượng mã và chia sẻ kiến ​​thức về phần mềm của bạn.

[1] Jenkins https://jenkins-ci.org/

[2] Gerrit https://www.gerritcodereview.com/


1

CI không bao giờ nên thay đổi lịch sử cam kết của repo.

Giải pháp chính xác ở đây là không có cam kết nào được thêm vào nhánh chính nếu chúng chưa được kiểm tra và xác minh.

Bạn có làm việc trên các nhánh tính năng, có CI chạy tự động trên các nhánh đó không và nếu các bản dựng không thành công, đừng hợp nhất chúng thành chủ.

Bạn có thể có một bản dựng bổ sung để kiểm tra hợp nhất nếu đó là một mối quan tâm, bằng cách chạy trên nhánh tính năng và trong quá trình xây dựng hợp nhất tổng thể / tích hợp / bất cứ thứ gì vào nhánh cục bộ, sau đó chạy thử nghiệm.


1
Điều này không trả lời câu hỏi theo bất kỳ cách nào. Nếu quá trình xây dựng thất bại trong nhánh tính năng, CI có nên hoàn nguyên cam kết không?
Carlos Campderrós

Điều gì xảy ra nếu quá trình xây dựng thành công trên nhánh tính năng, nhưng thất bại sau khi hợp nhất?
Matthieu M.

@MatthieuM. hợp nhất là một cam kết, bước CI có hợp nhất hoàn nguyên bản dựng không?
Carlos Campderrós

@ CarlosCampderrós: ​​Cá nhân tôi sẽ không bao giờ có một thiết lập cố gắng hoàn nguyên các cam kết; quá phức tạp
Matthieu M.

Tôi đã giải quyết các ý kiến.
Daenyth

1

Chúng tôi sử dụng Jenkins cho máy chủ xây dựng của mình và sử dụng mô hình gatekeeper để đẩy các cam kết - trong đó sự kết hợp giữa Jenkins và các trình kích hoạt cam kết (đảm bảo các nhà đánh giá ngang hàng đã thực hiện công việc của họ) là người gác cổng.

Các cam kết được đẩy gián tiếp thông qua một cuộn tròn tới Jenkins, nơi nó nhân bản repo chính sau đó kéo theo (các) cam kết được sáp nhập và thực hiện tất cả các bản dựng cần thiết (cho Linux / solaris). Nếu tất cả các bản dựng hoàn thành, cam kết sẽ được đẩy.

Điều này tránh được nhiều nếu không phải tất cả các vấn đề được thảo luận cho đến nay:

  • thay đổi lịch sử
  • lấy lịch sử chính xác nếu bạn là người phải sửa chữa sự cố
  • sự không ổn định (ở dạng bản dựng bị hỏng) không bao giờ được giới thiệu

Nó cũng cho phép chúng tôi thực thi trực tiếp các yêu cầu khác như kiểm tra đơn vị hoàn thành thành công.


re: downvote, bạn có phiền khi bình luận về những gì bạn không thích về câu trả lời của tôi không?
Brian Vandenberg

0

Đã bao nhiêu lần bạn nhận được email tự động nói rằng cam kết cuối cùng của bạn đã phá vỡ bản dựng? Bao nhiêu lần là sai? Nhưng bây giờ bạn phải đi kiểm tra xem liệu đó có thực sự là bạn hay ai đó đã thực hiện một cam kết khác cùng một lúc không. Hoặc có thể đó là một cái gì đó môi trường.

Nếu hệ thống không biết chắc chắn, thì tôi chắc chắn không muốn tự động hóa nó.


0

Câu hỏi được hỏi là thiếu sót. Tôi tôn trọng tuyên bố này mặc dù

"Chúng tôi tin rằng khái niệm về các chi nhánh đi ngược lại với CI thực sự, bởi vì cam kết với một chi nhánh sẽ tách bạn khỏi các nhà phát triển khác và những thay đổi của họ"

Những gì bạn nên làm là những bước này

  • làm việc với chủ nếu bạn thích (điều đó tốt và tiếp tục thay đổi mọi người) NHƯNG KHÔNG cam kết làm chủ tại địa phương
  • CHỈ TRƯỚC KHI bạn sẽ cam kết thay đổi của mình thành chủ, tạo một nhánh với submit_XXXXXX
  • xây dựng tự động của bạn nhận tất cả các bản dựng chi nhánh submit_XXX
  • Tùy chọn 1: xây dựng các ngắt, hoặc hợp nhất các ngắt ... thay đổi bị từ chối và nó không bao giờ rơi vào chủ
  • Tùy chọn 2: xây dựng công trình, jenkins đẩy chủ và cập nhật nó

THEN, những gì chúng tôi làm là đặt một git commit hook trong việc ngăn chặn MỌI NGƯỜI thực sự cam kết thành thạo. Nó hoạt động rất tốt .... KHÔNG có bản dựng bị hỏng bao giờ và KHÔNG hoàn nguyên cam kết từ chủ.

sau đó, trưởng khoa

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.