From 5ee72ee5217df0bf7d1cae35c4e2f2297bd9e840 Mon Sep 17 00:00:00 2001 From: Robert Stupp Date: Fri, 5 Dec 2025 11:09:51 +0100 Subject: [PATCH 1/3] Enhance docs about reproducible builds --- .../reproducible-builds/README.md | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/docs/configuration/reproducible-builds/README.md b/docs/configuration/reproducible-builds/README.md index 6b4b1b609..5a5d5d043 100644 --- a/docs/configuration/reproducible-builds/README.md +++ b/docs/configuration/reproducible-builds/README.md @@ -3,23 +3,52 @@ By default, JAR files generated by Gradle (with or without Shadow) for a single project with the same source code may not be identical to each other. Sometimes it's desirable to configure a project to consistently output a byte-for-byte identical JAR on every build. Gradle supports this with the following configuration, and Shadow will correctly respect -these settings too: +these settings too. + +Beside file timestamps and file order, this configuration also ensures that all files in the JAR are set to have the +same permissions, irrespective of the locally configured umask. + +More information about reproducible builds can be found at [reproducible-builds.org](https://reproducible-builds.org/). === "Kotlin" ```kotlin + import java.nio.file.Files + import java.nio.file.attribute.PosixFilePermission + tasks.withType().configureEach { isPreserveFileTimestamps = false isReproducibleFileOrder = true + + eachFile { + permissions { + val isExec = + Files.getPosixFilePermissions(file.toPath()).contains(PosixFilePermission.OWNER_EXECUTE) + unix(if (isExec) "755" else "644") + } + } + dirPermissions { unix("755") } } ``` === "Groovy" ```groovy + import java.nio.file.Files + import java.nio.file.attribute.PosixFilePermission + tasks.withType(AbstractArchiveTask).configureEach { preserveFileTimestamps = false reproducibleFileOrder = true + + eachFile { + permissions { + def isExec = + Files.getPosixFilePermissions(file.toPath()).contains(PosixFilePermission.OWNER_EXECUTE) + unix(isExec ? "755" : "644") + } + } + dirPermissions { unix("755") } } ``` From 83ca32b0ae1e836aaed7ac59d34f7583c40f6137 Mon Sep 17 00:00:00 2001 From: Zongle Wang Date: Fri, 5 Dec 2025 18:17:13 +0800 Subject: [PATCH 2/3] Apply suggestions from code review --- docs/configuration/reproducible-builds/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration/reproducible-builds/README.md b/docs/configuration/reproducible-builds/README.md index 5a5d5d043..a23759fa6 100644 --- a/docs/configuration/reproducible-builds/README.md +++ b/docs/configuration/reproducible-builds/README.md @@ -45,10 +45,10 @@ More information about reproducible builds can be found at [reproducible-builds. permissions { def isExec = Files.getPosixFilePermissions(file.toPath()).contains(PosixFilePermission.OWNER_EXECUTE) - unix(isExec ? "755" : "644") + unix(isExec ? '755' : '644') } } - dirPermissions { unix("755") } + dirPermissions { unix('755') } } ``` From 6eaf9004b7d66fc5f8388f2ff8f84f21ba0dc539 Mon Sep 17 00:00:00 2001 From: Zongle Wang Date: Fri, 5 Dec 2025 18:21:19 +0800 Subject: [PATCH 3/3] Update docs/configuration/reproducible-builds/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/configuration/reproducible-builds/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/reproducible-builds/README.md b/docs/configuration/reproducible-builds/README.md index a23759fa6..4af22701c 100644 --- a/docs/configuration/reproducible-builds/README.md +++ b/docs/configuration/reproducible-builds/README.md @@ -5,7 +5,7 @@ not be identical to each other. Sometimes it's desirable to configure a project identical JAR on every build. Gradle supports this with the following configuration, and Shadow will correctly respect these settings too. -Beside file timestamps and file order, this configuration also ensures that all files in the JAR are set to have the +Besides file timestamps and file order, this configuration also ensures that all files in the JAR are set to have the same permissions, irrespective of the locally configured umask. More information about reproducible builds can be found at [reproducible-builds.org](https://reproducible-builds.org/).