Java项目版本构建是什么意思_Java项目的构建和版本号(ant,cvs,hudson)

什么是Java项目中的系统构建编号和版本号管理的当前最佳实践?特别:

>如何在分布式开发环境中系统地管理构建号

>如何维护源代码中的版本号/可用于运行时应用程序

>如何正确地与源存储库集成

>如何更自动地管理版本号与存储库标签

>如何与持续构建基础架构集成

有相当多的工具可用,和ant(我们使用的构建系统)有一个任务将维护一个内部版本号,但不清楚如何管理这个与多个并发开发人员使用CVS,svn或类似。

[编辑]

下面出现几个好的和有帮助的部分或具体的答案,所以我将总结其中几个。这听起来像我一样,没有真正的强大的“最佳实践”,而是一系列重叠的想法。下面,找到我的摘要和一些结果问题,人们可能会试图回答作为后续。 [新的stackoverflow …请提供意见,如果我做错了。]

>如果您使用SVN,特定签出的版本控制将随之而来。构建编号可以利用此来创建唯一的构建号,以标识特定的检出/修订。 [CVS,我们使用的是遗留的原因,不提供相当这样的洞察…手动干预标签得到你的一部分。

>如果您使用maven作为构建系统,则支持从SCM生成版本号,以及用于自动生成版本的发布模块。 [我们不能使用maven,出于各种原因,但这有助于那些可以。 [感谢marcelo-morales]]

>如果您使用ant作为构建系统,以下任务描述可以帮助生成捕获构建信息的Java .properties文件,然后可以通过多种方式将其折叠到构建中。 [我们扩展了这个想法,包括哈德森派生的信息,感谢marty-lamb]。

> Ant和maven(以及哈德逊和巡航控制)提供了将构建号存入.properties文件或.txt / .html文件的简单方法。这是“安全”,足以防止它被有意或无意地篡改吗?是否最好在构建时将其编译为“版本化”类?

>断言:构建编号应该在像hudson这样的连续集成系统中定义/制定[感谢marcelo-morales]我们采纳了这个建议,但它确实打开了发布工程问题:发布是如何发生的?发布中有多个buildnumbers吗?不同版本的构建器之间是否有有意义的关系?

>问题:构建号码背后的目标是什么?是用于QA吗?怎么样?它是主要由开发人员在开发过程中消除多个构建之间的歧异,或更多的QA来确定最终用户构建什么?如果目标是可重复性,理论上这是发布版本号应该提供什么 – 为什么不? (请回答这个作为您的答案的一部分,在下面,它将有助于照亮你已经/建议的选择…)

>问题:在手动构建中是否有构建号的地方?这是否有什么问题,每个人都应该使用CI解决方案?

>问题:应该将内部编号签入SCM吗?如果目标是可靠和明确地识别特定构建,如何处理可能崩溃/重启等各种连续或手动构建系统…

>问题:如果一个构建号是短和甜的(即单调增加整数),以便它容易粘到文件名中,以便归档,容易参考在通信等…或应该是长而充满的用户名,日期戳,机器名等?

>问题:请提供详细信息,了解内部版本号的分配如何适用于更大的自动发行流程。是的,maven爱好者,我们知道这是做了,做了,但不是我们所有的人都喝了kool助剂还… …

我真的想把这个东西变成一个完整的答案,至少对于我们的cvs / ant / hudson设置的具体例子,所以有人可以基于这个问题构建一个完整的策略。我将标记为“答案”任何人谁可以给这个特定的情况下汤 – 坚果描述(包括cvs标记方案,相关的配置项目和发布过程,将版本号折叠到版本中,以编程方式如果你想问/回答另一个特定的配置(比如,svn / maven /巡航控制),我将链接到这里的问题。 –JA

[EDIT 23 Oct 09]

我接受了最高票数的答案,因为我认为这是一个合理的解决方案,而其他几个答案也包括好的想法。如果有人想用marty-lamb的合成一些裂纹,我会考虑接受一个不同的。我对marty-lamb唯一关心的是它不产生可靠的序列化构建号 – 它依赖于构建器系统上的本地时钟来提供明确的构建号,这不是很好。

[编辑7月10]

我们现在包括一个类如下。这允许将版本号编译成最终的可执行文件。版本信息的不同形式在日志数据(长期归档输出产品)中发出,用于跟踪我们(有时是多年后)对特定版本的输出产品的分析。

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();

}

}

如果这应该成为一个wiki讨论,请发表评论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值