Build 如何使用lein获得确定性构建?

Build 如何使用lein获得确定性构建?,build,clojure,leiningen,deterministic,Build,Clojure,Leiningen,Deterministic,连续运行两次leinuberjar,我得到两个不同的版本。经过一些解压/find/sort/diff shell魔术之后,我看到它归结为一些Maven文件:更具体地说是pom.properties文件 这里有一个区别: < #Tue Jan 14 07:07:50 CET 2014 --- > #Tue Jan 14 07:07:01 CET 2014 2014年1月14日星期二07:07:50 CET --- >#2014年1月14日星期二07:07:01 CET 如何使用Le

连续运行两次
leinuberjar
,我得到两个不同的版本。经过一些
解压/find/sort/diff shell
魔术之后,我看到它归结为一些Maven文件:更具体地说是pom.properties文件

这里有一个区别:

< #Tue Jan 14 07:07:50 CET 2014
---
> #Tue Jan 14 07:07:01 CET 2014
2014年1月14日星期二07:07:50 CET
---
>#2014年1月14日星期二07:07:01 CET
如何使用Leiningen(以及Maven)获得确定性Clojure构建?

我有一个本地补丁(我维护的项目)来解决这个问题,修复了
pom.properties
头时间到VCS(目前只有git)的提交时间,如果工作副本是完全干净的。我预计这项承诺将在下周某个时候完成,尽管我仍在考虑这项功能的可配置性

单凭这一点并不能保证罐子的稳定性,但这是第一件小事。同样令人感兴趣的是jar中文件的时间戳,它将改变zip头。规范化时间戳也应该很简单,但这是一个单独的步骤

lein voom对确定性构建感兴趣,这是一个您通常感兴趣的项目,因为它允许通过commit sha将依赖项直接指向特定的源版本,从而完全避免工件

lein voom非常年轻,文档和CLI非常粗糙,但核心功能非常可靠。请随意在上发布问题。

我有一个本地补丁(与我一起维护的项目),可以解决这个问题,修复
pom.properties
头时间到VCS(当前只有git)的提交时间(如果工作副本是完全干净的)。我预计这项承诺将在下周某个时候完成,尽管我仍在考虑这项功能的可配置性

单凭这一点并不能保证罐子的稳定性,但这是第一件小事。同样令人感兴趣的是jar中文件的时间戳,它将改变zip头。规范化时间戳也应该很简单,但这是一个单独的步骤

lein voom对确定性构建感兴趣,这是一个您通常感兴趣的项目,因为它允许通过commit sha将依赖项直接指向特定的源版本,从而完全避免工件

lein voom非常年轻,文档和CLI非常粗糙,但核心功能非常可靠。请随时在上发布问题。

a,然后回顾Maven的确定性构建。我在这里摘录了要点:

使用assembly插件并按如下方式进行配置:

src/main/assembly/zip.xml

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
  <id>deterministic</id>
  <baseDirectory>/</baseDirectory>
  <formats>
    <format>zip</format>
  </formats>
  <fileSets>
    <fileSet>
      <directory>${project.build.directory}/classes</directory>
      <outputDirectory>/</outputDirectory>
    </fileSet>
  </fileSets>
</assembly>
将一些插件添加到pom.xml中:

pom.xml:

<plugins>

... other plugins ...

    <!-- Step 1: Set all timestamps to same value -->
    <plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
      <execution>
        <id>1-touch-classes</id>
        <phase>prepare-package</phase>
        <configuration>
          <target>
            <touch datetime="01/01/2000 00:10:00 am">
              <fileset dir="target/classes"/>
            </touch>
          </target>
        </configuration>
        <goals>
          <goal>run</goal>
        </goals>
      </execution>
    </executions>
    </plugin>

    <!-- Step 2: Assemble as a ZIP to avoid MANIFEST.MF timestamp -->
    <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2.1</version>
    <configuration>
      <descriptors>
        <descriptor>src/main/assembly/zip.xml</descriptor>
      </descriptors>
    </configuration>
    <executions>
      <execution>
        <id>2-make-assembly</id>
        <phase>prepare-package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
    </plugin>

    <!-- Step 3: Rename ZIP as JAR -->
    <plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
      <execution>
        <id>3-rename-assembly</id>
        <phase>package</phase>
        <configuration>
          <target>
            <move file="${project.build.directory}/${project.build.finalName}-deterministic.zip"
                  tofile="${project.build.directory}/${project.build.finalName}-deterministic.jar"/>
          </target>
        </configuration>
        <goals>
          <goal>run</goal>
        </goals>
      </execution>
    </executions>
    </plugin>

... more plugins ...

</plugins>

... 其他插件。。。
由比特币核心项目使用,并在VirtualBox环境中指定特定JVM。通过这种方式,多个开发人员可以独立地从源代码构建,然后对二进制文件进行签名,以表明他们是一致的。当达到某个阈值时,代码被认为是确定的,可以发布。

a同时回顾Maven的确定性构建。我在这里摘录了要点:

使用assembly插件并按如下方式进行配置:

src/main/assembly/zip.xml

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
  <id>deterministic</id>
  <baseDirectory>/</baseDirectory>
  <formats>
    <format>zip</format>
  </formats>
  <fileSets>
    <fileSet>
      <directory>${project.build.directory}/classes</directory>
      <outputDirectory>/</outputDirectory>
    </fileSet>
  </fileSets>
</assembly>
将一些插件添加到pom.xml中:

pom.xml:

<plugins>

... other plugins ...

    <!-- Step 1: Set all timestamps to same value -->
    <plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
      <execution>
        <id>1-touch-classes</id>
        <phase>prepare-package</phase>
        <configuration>
          <target>
            <touch datetime="01/01/2000 00:10:00 am">
              <fileset dir="target/classes"/>
            </touch>
          </target>
        </configuration>
        <goals>
          <goal>run</goal>
        </goals>
      </execution>
    </executions>
    </plugin>

    <!-- Step 2: Assemble as a ZIP to avoid MANIFEST.MF timestamp -->
    <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2.1</version>
    <configuration>
      <descriptors>
        <descriptor>src/main/assembly/zip.xml</descriptor>
      </descriptors>
    </configuration>
    <executions>
      <execution>
        <id>2-make-assembly</id>
        <phase>prepare-package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
    </plugin>

    <!-- Step 3: Rename ZIP as JAR -->
    <plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
      <execution>
        <id>3-rename-assembly</id>
        <phase>package</phase>
        <configuration>
          <target>
            <move file="${project.build.directory}/${project.build.finalName}-deterministic.zip"
                  tofile="${project.build.directory}/${project.build.finalName}-deterministic.jar"/>
          </target>
        </configuration>
        <goals>
          <goal>run</goal>
        </goals>
      </execution>
    </executions>
    </plugin>

... more plugins ...

</plugins>

... 其他插件。。。

由比特币核心项目使用,并在VirtualBox环境中指定特定JVM。通过这种方式,多个开发人员可以独立地从源代码构建,然后对二进制文件进行签名,以表明他们是一致的。当达到某个阈值时,代码被认为是确定的,可以发布。

我不明白。看起来该文件应该记录构建发生的时间,所以在不同的运行中它当然会有所不同。为什么要抑制这个特性,这可能是maven的标准部分?另外,我认为通常的做法是永远归档二进制结果。那就是你的真理之源。例如,如果在不同的JDK上编译相同的源代码,可能会得到不同的字节码。如果你想要真正确定的构建,你必须“签入”你的整个环境(和物理硬件!)。@amalloy:“确定性构建”从安全角度来说是非常重要的。看到最近所有关于后门出现在许多软件和硬件中的“大兄弟主义”披露,越来越多的项目现在采用确定性构建。例如,Mozilla Firefox现在正朝着确定性构建方向发展。这是一个非常理想的特性,它允许在不同的体系结构/硬件(可能受到损害)上进行编译,然后比较结果。阻止确定性构建的“特性”是一个严重的安全弱点。严格来说,这种行为既不是leiningen特性,也不是Maven特性。这是因为
pom.properties
文件是用[(
java.util.properties
)创建的,它将当前时间戳存储在文件顶部的注释头中。上面应该链接到
存储(java.io.Writer,java.lang.String)
method,但Oracle的anchor和StackOverflow合谋反对我。我不明白。看起来该文件应该记录生成的时间,所以在不同的运行过程中,它当然会有所不同。为什么要抑制此功能,这可能是maven的标准部分?另外,我认为它的作用是永远归档二进制结果。这就是你的标准真理来源。例如,如果你在不同的JDK上编译相同的源代码,你可能会得到不同的字节码。如果你想要真正的确定性构建,你必须“签入”你的整个环境(和物理硬件!)。@amalloy:“确定性构建”从一个s的角度来看是非常重要的