如何将确定性的唯一buildId注入Gradle的Java jar清单中?

问题描述 投票:3回答:2

我们在磁盘上存储了计算数据的缓存。我们想知道计算的数据是否来自此版本或构建的其他版本。当前,我们使用MANIFEST.MF中存储的提交+时间戳作为标识构建的相对独特的方式。但是,时间戳会导致gradle中的增量生成问题,因为gradle知道时间已更改,重新生成MANIFEST.MF,然后重新打包jar,即使没有其他更改。

我们希望在MANIFEST.MF中将时间戳替换为更好的'buildId'。要求是:

  • 对于不同的版本来说是唯一的:仅提交是不够的,因为开发计算机上可能存在未提交的更改
  • 确定性:时间戳不起作用,因为Gradle会将其视为依赖项中的“更改”,并且即使其他依赖项未更改也可以重新构建jar。

我认为正确的解决方案是对'jar'任务使用实际依赖项的哈希,即'classes',即将包含在jar中的所有已编译的类文件。

我可以,[[理论上,创建一个任务,该任务接受所有类的哈希,并将其注入到清单中。

但是,Gradle已经在执行此操作,这就是它确定任务是否最新的方式。它接受输入的哈希值和输出的哈希值,并检查该组合是否在其数据库中。因此,有没有办法使用一些罕见的Gradle API或使用反射来访问此信息?

或者也许还有其他解决方案?

java gradle build.gradle
2个回答
2
投票
[我认为您可能希望退后一步,并重新评估将清单ID添加到清单文件中要实现的目标。具体来说,您所说的关于在开发机器上构建的第一个要求没有多大意义。通常,您希望在清单文件中添加某种buildId的原因是,您可以跟踪构建jar的位置和时间,从而可以确定要去哪组源代码并在出现问题时查看。如果要基于开发人员文件系统的内容生成内部版本,则永远无法回头确定该内部版本的来源。如果buildId是基于生成的类文件,甚至是基于开发人员机器上的源文件本身,则开发人员所要做的就是在单个文件中更改单个字符,并且该构建永久消失并且无法重新生成除非该开发人员可以执行撤消操作,以使文件系统恢复到原来的状态。

相反,您应该将buildIds建立在无需开发人员记住任何内容的情况下,可以重新创建的内容上。为了做到这一点,buildIds必须始终可搜索,并且随时可供团队的所有成员使用。修订控制提交满足了所有这些要求,并且听起来已经使用了某些东西,因此没有额外的开销可将其添加到工作流中。

我建议您忘记基于buildID的信息基于文件系统的内容,而是基于提交。如果您担心开发人员能够生成不是来自master / trunk / etc的构建,则所有主要的版本控制系统都提供了一些分支创建方法,该方法仍将允许开发人员检入不会干扰代码的代码。初级生产版本。如果您使用修订号/哈希值来跟踪jar的版本,那么您有一种方法可以返回并准确地重现该版本,即使该版本仅来自开发人员计算机上的本地分支也是如此。我不建议您最后使用本地分支,除非您知道构建的生命周期很短,但是,团队中的其他任何人都无法搜索基于单个开发人员计算机本地分支的buildId。相反,如果您使用的是分布式版本控制系统,建议您将构建中使用的所有更改推送到中央位置,以便其他可能在射击该构建时遇到麻烦的人都可以访问用于该构建的代码。


0
投票
您可以执行一个任务来生成构建ID,并使用这些类作为输入,而输出是具有构建ID的文件。

构建ID不必是输入的哈希,而可以只是一个时间戳。

但是由于生成构建ID的任务取决于类,因此仅在发生更改时才重新生成构建ID时间戳。

© www.soinside.com 2019 - 2024. All rights reserved.