Skip to content

Commit 342f2d5

Browse files
Marcono1234tibor-universe
authored andcommitted
Make Maven build reproducible (google#2543)
However, it might still be necessary to use the same OS and JDK version to actually be able to create identical artifacts. This commit also formats the `pom.xml` files in the way the Maven Release Plugin would.
1 parent 9ee906e commit 342f2d5

File tree

9 files changed

+154
-13
lines changed

9 files changed

+154
-13
lines changed

.github/workflows/build.yml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
cache: 'maven'
2424
- name: Build with Maven
2525
# This also runs javadoc:jar to detect any issues with the Javadoc generated during release
26-
run: mvn --batch-mode --update-snapshots --no-transfer-progress verify javadoc:jar
26+
run: mvn --batch-mode --no-transfer-progress verify javadoc:jar
2727

2828
native-image-test:
2929
name: "GraalVM Native Image test"
@@ -42,4 +42,29 @@ jobs:
4242
- name: Build and run tests
4343
# Only run tests in `graal-native-image-test` (and implicitly build and run tests in `gson`),
4444
# everything else is covered already by regular build job above
45-
run: mvn test --batch-mode --update-snapshots --no-transfer-progress --activate-profiles native-image-test --projects graal-native-image-test --also-make
45+
run: mvn test --batch-mode --no-transfer-progress --activate-profiles native-image-test --projects graal-native-image-test --also-make
46+
47+
verify-reproducible-build:
48+
name: "Verify reproducible build"
49+
runs-on: ubuntu-latest
50+
51+
steps:
52+
- uses: actions/checkout@v3
53+
- name: "Set up JDK 17"
54+
uses: actions/setup-java@v3
55+
with:
56+
distribution: 'temurin'
57+
java-version: 17
58+
cache: 'maven'
59+
60+
- name: "Verify no plugin issues"
61+
run: mvn artifact:check-buildplan --batch-mode --no-transfer-progress
62+
63+
- name: "Verify reproducible build"
64+
# See https://maven.apache.org/guides/mini/guide-reproducible-builds.html#how-to-test-my-maven-build-reproducibility
65+
run: |
66+
mvn clean install --batch-mode --no-transfer-progress -Dproguard.skip -DskipTests
67+
# Run with `-Dbuildinfo.attach=false`; otherwise `artifact:compare` fails because it creates a `.buildinfo` file which
68+
# erroneously references the existing `.buildinfo` file (respectively because it is overwriting it, a file with size 0)
69+
# See https://issues.apache.org/jira/browse/MARTIFACT-57
70+
mvn clean verify artifact:compare --batch-mode --no-transfer-progress -Dproguard.skip -DskipTests -Dbuildinfo.attach=false

ReleaseProcess.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,72 @@ This section was borrowed heavily from [Doclava release process](https://code.go
3737

3838
See [OSSRH Publish Guide](https://central.sonatype.org/publish/publish-guide/).
3939

40+
## Testing Maven release workflow locally
41+
42+
The following describes how to perform the steps of the release locally to verify that they work as desired.
43+
44+
**Warning:** Be careful with this, these steps might be outdated or incomplete. Doublecheck that you are working on a copy of your local Gson Git repository and make sure you have followed all steps. To be safe you can also temporarily turn off your internet connection to avoid accidentally pushing changes to the real remote Git or Maven repository.\
45+
As an alternative to the steps described below you can instead [perform a dry run](https://maven.apache.org/maven-release/maven-release-plugin/usage.html#do-a-dry-run), though this might not behave identical to a real release.
46+
47+
1. Make a copy of your local Gson Git repository and only work with that copy
48+
2. Make sure you are on the `main` branch
49+
3. Create a temp directory outside the Gson directory\
50+
In the following steps this will be called `#gson-remote-temp#`; replace this with the actual absolute file path of the directory, using only forward slashes. For example under Windows `C:\my-dir` becomes `C:/my-dir`.
51+
4. Create the directory `#gson-remote-temp#/git-repo`
52+
5. In that directory run
53+
54+
```sh
55+
git init --bare --initial-branch=main .
56+
```
57+
58+
6. Create the directory `#gson-remote-temp#/maven-repo`
59+
7. Edit the root `pom.xml` of Gson
60+
1. Change the `<developerConnection>` to
61+
62+
```txt
63+
scm:git:file:///#gson-remote-temp#/git-repo
64+
```
65+
66+
2. Change the `<url>` of the `<distributionManagement>` to
67+
68+
```txt
69+
file:///#gson-remote-temp#/maven-repo
70+
```
71+
72+
3. If you don't want to use GPG, remove the `maven-gpg-plugin` entry from the 'release' profile.\
73+
There is also an entry under `<pluginManagement>`; you can remove that as well.
74+
8. Commit the changes using Git
75+
9. Change the remote repository of the Git project
76+
77+
<!-- Uses `txt` instead of `sh` to avoid the `#` being highlighted in some way -->
78+
```txt
79+
git remote set-url origin file:///#gson-remote-temp#/git-repo
80+
```
81+
82+
10. Push the changes
83+
84+
```sh
85+
git push origin main
86+
```
87+
88+
Now you can perform the steps of the release:
89+
90+
1. ```sh
91+
mvn release:clean
92+
```
93+
94+
2. ```sh
95+
mvn release:prepare
96+
```
97+
98+
3. ```sh
99+
mvn release:perform
100+
```
101+
102+
4. Verify that `#gson-remote-temp#/git-repo` and `#gson-remote-temp#/maven-repo` contain all the desired changes
103+
5. Afterwards delete all Gson files under `${user.home}/.m2/repository/com/google/code/gson` which have been installed in your local Maven repository during the release.\
104+
Otherwise Maven might not download the real Gson artifacts with these version numbers, once they are released.
105+
40106
## Running Benchmarks or Tests on Android
41107
42108
* Download vogar

extras/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
<name>Gson Extras</name>
2828
<description>Google Gson grab bag of utilities, type adapters, etc.</description>
2929

30+
<properties>
31+
<!-- Make the build reproducible, see root `pom.xml` -->
32+
<!-- This is duplicated here because that is recommended by `artifact:check-buildplan` -->
33+
<project.build.outputTimestamp>2023-01-01T00:00:00Z</project.build.outputTimestamp>
34+
</properties>
35+
3036
<licenses>
3137
<license>
3238
<name>Apache-2.0</name>

graal-native-image-test/pom.xml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
-->
16-
<project xmlns="http://maven.apache.org/POM/4.0.0"
17-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
18-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
16+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
1917

2018
<modelVersion>4.0.0</modelVersion>
2119

@@ -27,6 +25,10 @@
2725
<artifactId>graal-native-image-test</artifactId>
2826

2927
<properties>
28+
<!-- Make the build reproducible, see root `pom.xml` -->
29+
<!-- This is duplicated here because that is recommended by `artifact:check-buildplan` -->
30+
<project.build.outputTimestamp>2023-01-01T00:00:00Z</project.build.outputTimestamp>
31+
3032
<!-- GraalVM is JDK >= 17, however for build with regular JDK these tests
3133
are also executed with JDK 11, so for them exclude JDK 17 specific tests -->
3234
<maven.compiler.testRelease>11</maven.compiler.testRelease>

gson/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@
3636
</license>
3737
</licenses>
3838

39+
<properties>
40+
<!-- Make the build reproducible, see root `pom.xml` -->
41+
<!-- This is duplicated here because that is recommended by `artifact:check-buildplan` -->
42+
<project.build.outputTimestamp>2023-01-01T00:00:00Z</project.build.outputTimestamp>
43+
</properties>
44+
3945
<dependencies>
4046
<dependency>
4147
<groupId>junit</groupId>

metrics/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
<name>Gson Metrics</name>
2828
<description>Performance Metrics for Google Gson library</description>
2929

30+
<properties>
31+
<!-- Make the build reproducible, see root `pom.xml` -->
32+
<!-- This is duplicated here because that is recommended by `artifact:check-buildplan` -->
33+
<project.build.outputTimestamp>2023-01-01T00:00:00Z</project.build.outputTimestamp>
34+
</properties>
35+
3036
<licenses>
3137
<license>
3238
<name>Apache-2.0</name>

pom.xml

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
1818
This file has been modified by Happeo Oy.
1919
-->
20-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
21-
child.project.url.inherit.append.path="false">
20+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" child.project.url.inherit.append.path="false">
2221
<modelVersion>4.0.0</modelVersion>
2322

2423
<groupId>com.google.code.gson</groupId>
@@ -43,6 +42,10 @@
4342
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
4443
<maven.compiler.release>8</maven.compiler.release>
4544
<maven.compiler.testRelease>17</maven.compiler.testRelease>
45+
46+
<!-- Make the build reproducible, see https://maven.apache.org/guides/mini/guide-reproducible-builds.html -->
47+
<!-- Automatically updated by Maven Release Plugin -->
48+
<project.build.outputTimestamp>2023-01-01T00:00:00Z</project.build.outputTimestamp>
4649
</properties>
4750

4851
<!-- These attributes specify that the URLs should be inherited by the modules as is, to avoid constructing
@@ -171,8 +174,8 @@
171174
<!-- For Markdown files removing trailing whitespace causes issues for hard line breaks,
172175
which use two trailing spaces. However, the trailing spaces are difficult to notice anyway;
173176
prefer a trailing `\` instead of two spaces. -->
174-
<trimTrailingWhitespace/>
175-
<endWithNewline/>
177+
<trimTrailingWhitespace />
178+
<endWithNewline />
176179
<indent>
177180
<spaces>true</spaces>
178181
<!-- This seems to mostly (or only?) affect the suggested fix in case code contains tabs -->
@@ -194,10 +197,29 @@
194197
<reorderImports>true</reorderImports>
195198
<formatJavadoc>true</formatJavadoc>
196199
</googleJavaFormat>
197-
<formatAnnotations/> <!-- Puts type annotations immediately before types. -->
200+
<formatAnnotations /> <!-- Puts type annotations immediately before types. -->
198201
</java>
199202
</configuration>
200203
</plugin>
204+
205+
<!-- Attaches a `.buildinfo` file which contains information for reproducing the build,
206+
such as OS, JDK version, ...
207+
Since this is a multi-module Maven project, only one aggregated file will be created for
208+
the last module, see the note on https://maven.apache.org/plugins/maven-artifact-plugin/usage.html#recording-buildinfo-file -->
209+
<!-- The other goals of this plugin are run by the GitHub workflow to verify that
210+
the build is reproducible (see `artifact:...` usage in the workflow) -->
211+
<plugin>
212+
<groupId>org.apache.maven.plugins</groupId>
213+
<artifactId>maven-artifact-plugin</artifactId>
214+
<version>3.5.0</version>
215+
<executions>
216+
<execution>
217+
<goals>
218+
<goal>buildinfo</goal>
219+
</goals>
220+
</execution>
221+
</executions>
222+
</plugin>
201223
</plugins>
202224

203225
<pluginManagement>

proto/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
<name>Gson Protobuf Support</name>
2828
<description>Gson support for Protobufs</description>
2929

30+
<properties>
31+
<!-- Make the build reproducible, see root `pom.xml` -->
32+
<!-- This is duplicated here because that is recommended by `artifact:check-buildplan` -->
33+
<project.build.outputTimestamp>2023-01-01T00:00:00Z</project.build.outputTimestamp>
34+
</properties>
35+
3036
<licenses>
3137
<license>
3238
<name>Apache-2.0</name>

shrinker-test/pom.xml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
See the License for the specific language governing permissions and
1515
limitations under the License.
1616
-->
17-
<project xmlns="http://maven.apache.org/POM/4.0.0"
18-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
17+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
2018
<modelVersion>4.0.0</modelVersion>
2119

2220
<parent>
@@ -28,6 +26,10 @@
2826
<artifactId>shrinker-test</artifactId>
2927

3028
<properties>
29+
<!-- Make the build reproducible, see root `pom.xml` -->
30+
<!-- This is duplicated here because that is recommended by `artifact:check-buildplan` -->
31+
<project.build.outputTimestamp>2023-01-01T00:00:00Z</project.build.outputTimestamp>
32+
3133
<maven.compiler.release>8</maven.compiler.release>
3234
</properties>
3335

0 commit comments

Comments
 (0)