Các cách thực hành tốt nhất hiện nay để đánh số hệ thống và quản lý số phiên bản trong các dự án Java là gì? Đặc biệt:
Cách quản lý số lượng xây dựng một cách có hệ thống trong môi trường phát triển phân tán
Cách duy trì số phiên bản trong nguồn / khả dụng cho ứng dụng thời gian chạy
Cách tích hợp đúng với kho lưu trữ nguồn
Cách tự động quản lý số phiên bản so với thẻ kho
Cách tích hợp với cơ sở hạ tầng xây dựng liên tục
Có khá nhiều công cụ có sẵn và ant (hệ thống xây dựng chúng tôi đang sử dụng) có một nhiệm vụ sẽ duy trì số bản dựng, nhưng không rõ cách quản lý công cụ này với nhiều nhà phát triển đồng thời sử dụng CVS, svn hoặc tương tự .
[BIÊN TẬP]
Một số câu trả lời một phần hoặc cụ thể và hữu ích đã xuất hiện bên dưới, vì vậy tôi sẽ tóm tắt một vài trong số chúng. Đối với tôi có vẻ như không thực sự có một "thực tiễn tốt nhất" mạnh mẽ nào về vấn đề này, mà là một tập hợp các ý tưởng chồng chéo. Dưới đây, tìm tóm tắt của tôi và một số câu hỏi kết quả mà mọi người có thể cố gắng trả lời như tiếp theo. [Mới đối với stackoverflow ... vui lòng cung cấp nhận xét nếu tôi làm sai.]
Nếu bạn đang sử dụng SVN, phiên bản thanh toán cụ thể sẽ xuất hiện trong chuyến đi. Đánh số bản dựng có thể khai thác điều này để tạo số bản dựng duy nhất xác định thanh toán / sửa đổi cụ thể. [CVS, mà chúng tôi đang sử dụng vì lý do di sản, không cung cấp mức độ hiểu biết sâu sắc này ... can thiệp thủ công với các thẻ giúp bạn tham gia vào đó.]
Nếu bạn đang sử dụng maven làm hệ thống xây dựng của mình, có hỗ trợ sản xuất số phiên bản từ SCM, cũng như mô-đun phát hành để tự động tạo các bản phát hành. [Chúng tôi không thể sử dụng maven, vì nhiều lý do, nhưng điều này giúp những người có thể. [Cảm ơn marcelo-morales ]]
Nếu bạn đang sử dụng ant làm hệ thống xây dựng của mình, mô tả tác vụ sau đây có thể giúp tạo tệp Java .properations nắm bắt thông tin bản dựng, sau đó có thể được xếp vào bản dựng của bạn theo một số cách. [Chúng tôi đã mở rộng ý tưởng này để bao gồm thông tin có nguồn gốc từ hudson, cảm ơn marty-lamb ].
Ant và maven (và hudson và điều khiển hành trình) cung cấp các phương tiện dễ dàng để lấy số bản dựng thành tệp .properations hoặc vào tệp .txt / .html. Điều này có "an toàn" đủ để giữ cho nó khỏi bị giả mạo hay cố ý hay vô tình? Có tốt hơn để biên dịch nó thành một lớp "phiên bản" tại thời điểm xây dựng không?
Khẳng định: Xây dựng số nên được xác định / ban hành trong một hệ thống tích hợp liên tục như hudson . [Cảm ơn marcelo-morales ] Chúng tôi đã đưa ra gợi ý này, nhưng nó mở ra câu hỏi về kỹ thuật phát hành: Làm thế nào để phát hành xảy ra? Có nhiều bản dựng trong một bản phát hành không? Có một mối quan hệ có ý nghĩa giữa các nhà xây dựng từ các bản phát hành khác nhau?
Câu hỏi: Mục tiêu đằng sau số xây dựng là gì? Nó được sử dụng cho QA? Làm sao? Có phải nó được sử dụng chủ yếu bởi các nhà phát triển để phân tán giữa nhiều bản dựng trong quá trình phát triển hoặc nhiều hơn cho QA để xác định bản dựng nào mà người dùng cuối có? Nếu mục tiêu là khả năng tái tạo, theo lý thuyết thì đây là số phiên bản phát hành sẽ cung cấp - tại sao không? (vui lòng trả lời câu hỏi này như một phần câu trả lời của bạn bên dưới, nó sẽ giúp làm sáng tỏ những lựa chọn bạn đã thực hiện / đề xuất ...)
Câu hỏi: Có chỗ nào cho số bản dựng trong bản dựng thủ công không? Điều này có vấn đề đến nỗi MỌI NGƯỜI nên sử dụng giải pháp CI?
Câu hỏi: Có nên kiểm tra số xây dựng trong SCM không? Nếu mục tiêu đáng tin cậy và rõ ràng xác định một bản dựng cụ thể, làm thế nào để đối phó với nhiều hệ thống xây dựng liên tục hoặc thủ công có thể gặp sự cố / khởi động lại / v.v ...
Câu hỏi: Số xây dựng có nên ngắn và ngọt (nghĩa là số nguyên tăng đơn điệu) để dễ dàng gắn vào tên tệp để lưu trữ, dễ tham khảo trong giao tiếp, v.v ... hoặc nên dài và đầy đủ tên người dùng, dấu thời gian, tên máy, vv?
Câu hỏi: Vui lòng cung cấp chi tiết về cách gán số bản dựng phù hợp với quy trình phát hành tự động lớn hơn của bạn. Vâng, những người yêu thích maven, chúng tôi biết điều này đã được thực hiện và đã hoàn thành, nhưng không phải tất cả chúng ta đều đã uống kool-Aid khá ...
Tôi thực sự muốn đưa ra một câu trả lời hoàn chỉnh, ít nhất là cho ví dụ cụ thể về thiết lập cvs / ant / hudson của chúng tôi, để ai đó có thể xây dựng một chiến lược hoàn chỉnh dựa trên câu hỏi này. Tôi sẽ đánh dấu là "Câu trả lời" cho bất kỳ ai có thể đưa ra mô tả súp-to-nut cho trường hợp cụ thể này (bao gồm sơ đồ gắn thẻ cvs, các mục cấu hình CI có liên quan và quy trình phát hành có thể gấp số bản dựng vào bản phát hành sao cho theo lập trình có thể truy cập.) Nếu bạn muốn hỏi / trả lời cho một cấu hình cụ thể khác (giả sử, svn / maven / điều khiển hành trình) tôi sẽ liên kết đến câu hỏi từ đây. --JA
[EDIT 23 tháng 10 09] Tôi đã chấp nhận câu trả lời được bình chọn hàng đầu bởi vì tôi nghĩ đó là một giải pháp hợp lý, trong khi một số câu trả lời khác cũng bao gồm những ý tưởng hay. Nếu ai đó muốn có một cơ hội để tổng hợp một số trong số này với marty-lamb , tôi sẽ xem xét chấp nhận một cái khác. Mối quan tâm duy nhất tôi có với marty-lamb là nó không tạo ra số bản dựng nối tiếp đáng tin cậy - nó phụ thuộc vào đồng hồ địa phương tại hệ thống của nhà xây dựng để cung cấp số bản dựng rõ ràng, không tuyệt vời.
[Chỉnh sửa ngày 10 tháng 7]
Bây giờ chúng tôi bao gồm một lớp như dưới đây. Điều này cho phép các số phiên bản được biên dịch thành tệp thực thi cuối cùng. Các dạng khác nhau của thông tin phiên bản được phát ra trong dữ liệu ghi nhật ký, các sản phẩm đầu ra được lưu trữ dài hạn và được sử dụng để theo dõi phân tích (đôi khi nhiều năm sau) của chúng tôi về một sản phẩm cụ thể.
public final class AppVersion
{
// SVN should fill this out with the latest tag when it's checked out.
private static final String APP_SVNURL_RAW =
"$HeadURL: svn+ssh://user@host/svnroot/app/trunk/src/AppVersion.java $";
private static final String APP_SVN_REVISION_RAW = "$Revision: 325 $";
private static final Pattern SVNBRANCH_PAT =
Pattern.compile("(branches|trunk|releases)\\/([\\w\\.\\-]+)\\/.*");
private static final String APP_SVNTAIL =
APP_SVNURL_RAW.replaceFirst(".*\\/svnroot\\/app\\/", "");
private static final String APP_BRANCHTAG;
private static final String APP_BRANCHTAG_NAME;
private static final String APP_SVNREVISION =
APP_SVN_REVISION_RAW.replaceAll("\\$Revision:\\s*","").replaceAll("\\s*\\$", "");
static {
Matcher m = SVNBRANCH_PAT.matcher(APP_SVNTAIL);
if (!m.matches()) {
APP_BRANCHTAG = "[Broken SVN Info]";
APP_BRANCHTAG_NAME = "[Broken SVN Info]";
} else {
APP_BRANCHTAG = m.group(1);
if (APP_BRANCHTAG.equals("trunk")) {
// this isn't necessary in this SO example, but it
// is since we don't call it trunk in the real case
APP_BRANCHTAG_NAME = "trunk";
} else {
APP_BRANCHTAG_NAME = m.group(2);
}
}
}
public static String tagOrBranchName()
{ return APP_BRANCHTAG_NAME; }
/** Answers a formatter String descriptor for the app version.
* @return version string */
public static String longStringVersion()
{ return "app "+tagOrBranchName()+" ("+
tagOrBranchName()+", svn revision="+svnRevision()+")"; }
public static String shortStringVersion()
{ return tagOrBranchName(); }
public static String svnVersion()
{ return APP_SVNURL_RAW; }
public static String svnRevision()
{ return APP_SVNREVISION; }
public static String svnBranchId()
{ return APP_BRANCHTAG + "/" + APP_BRANCHTAG_NAME; }
public static final String banner()
{
StringBuilder sb = new StringBuilder();
sb.append("\n----------------------------------------------------------------");
sb.append("\nApplication -- ");
sb.append(longStringVersion());
sb.append("\n----------------------------------------------------------------\n");
return sb.toString();
}
}
Để lại ý kiến nếu điều này xứng đáng để trở thành một cuộc thảo luận wiki.
gradle
và / hoặc git
?