Clojure:如何使 leiningen 构建可重现?

Clojure: how to make a leiningen build reproducible?

简介

reproducible-builds.org 所述,最好的做法是能够生成可以在任何 machine/os 上的任何人提供相同源代码时随时重新创建的构建.如何在 Clojure/Leiningen 环境中实现此目的?

例子

使用 Leiningen 创建项目和构建 .jar 文件的非常基本的示例用法:

lein new app hello
cd hello
lein uberjar
sha256sum target/uberjar/hello-0.1.0-SNAPSHOT-standalone.jar

这会输出一个特定的 sha256 散列,它在 .jar 文件中包含非确定性。如果您立即重新 运行 构建而不更改任何源文件,则校验和哈希无论如何都会不同:

lein uberjar
sha256sum target/uberjar/hello-0.1.0-SNAPSHOT-standalone.jar

问题

如何创建一个 .jar 文件,当再次 运行 时产生相同的校验和散列,例如在不同的 linux 发行版上,在未来的某个地方?

Jar 文件是不确定的,但它的内容是。尝试

unzip -c hello-0.1.0-SNAPSHOT-standalone.jar | md5sum

有一个可用的软件包:strip-nondeterminism, it supports .jar files as well. It's available in debian and ubuntu(可能还有其他基于 debian 的发行版),但您始终可以从源代码中使用它。

安装(debian/ubuntu/etc。):

sudo apt install strip-nondeterminism

构建:

lein uberjar
strip-nondeterminism -t jar target/uberjar/hello-0.1.0-SNAPSHOT-standalone.jar
sha256sum target/uberjar/hello-0.1.0-SNAPSHOT-standalone.jar

当构建 运行 多次时,这将输出相同的校验和哈希。它将所有文件时间戳重置为静态值。