Skip to content

Commit b8dda11

Browse files
jvm resources action is not reproducible (Cherry-pick of #21259) (#21269)
While we are trying to zip the file without extra data and same creation date, we noticed in CI that the action can produce different digests. This commit adds another strip jar action after zipping the resources. It would be great if this can be cherry-picked to 2.20.X and above Co-authored-by: Doron Somech <[email protected]>
1 parent 815adce commit b8dda11

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

src/python/pants/jvm/resources.py

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
FallibleClasspathEntries,
2929
FallibleClasspathEntry,
3030
)
31+
from pants.jvm.strip_jar.strip_jar import StripJarRequest
3132
from pants.jvm.subsystems import JvmSubsystem
3233
from pants.util.logging import LogLevel
3334

@@ -119,6 +120,9 @@ async def assemble_resources_jar(
119120
)
120121

121122
output_digest = resources_jar_result.output_digest
123+
if jvm.reproducible_jars:
124+
output_digest = await Get(Digest, StripJarRequest(output_digest, tuple(output_files)))
125+
122126
cpe = ClasspathEntry(output_digest, output_files, [])
123127

124128
merged_cpe_digest = await Get(

src/python/pants/jvm/resources_test.py

+51
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,54 @@ def test_resources_jar_is_deterministic(rule_runner: RuleRunner) -> None:
129129
z = ZipFile(BytesIO(contents[0].content))
130130
for info in z.infolist():
131131
assert info.date_time == (1980, 1, 1, 0, 0, 0)
132+
133+
134+
@maybe_skip_jdk_test
135+
def test_resources_reproducible_jars(rule_runner: RuleRunner) -> None:
136+
rule_runner.set_options(["--jvm-reproducible-jars"])
137+
rule_runner.write_files(
138+
{
139+
"BUILD": "resources(name='root', sources=['**/*.txt'])",
140+
"one.txt": "",
141+
"two.txt": "",
142+
"three/four.txt": "",
143+
"three/five.txt": "",
144+
"three/six/seven/eight.txt": "",
145+
"3rdparty/jvm/default.lock": EMPTY_JVM_LOCKFILE,
146+
}
147+
)
148+
149+
# Building the generator target should exclude the individual files and result in a single jar
150+
# for the generator.
151+
classpath = rule_runner.request(
152+
Classpath, [Addresses([Address(spec_path="", target_name="root")])]
153+
)
154+
155+
contents = rule_runner.request(DigestContents, list(classpath.digests()))
156+
assert contents[0].path == ".root.resources.jar"
157+
resources_filenames = set(filenames_from_zip(contents[0]))
158+
expected = {
159+
"one.txt",
160+
"two.txt",
161+
"three/",
162+
"three/four.txt",
163+
"three/five.txt",
164+
"three/six/",
165+
"three/six/seven/",
166+
"three/six/seven/eight.txt",
167+
}
168+
169+
assert resources_filenames == expected
170+
171+
# But requesting a single file should individually package it.
172+
classpath = rule_runner.request(
173+
Classpath,
174+
[Addresses([Address(spec_path="", target_name="root", relative_file_path="one.txt")])],
175+
)
176+
contents = rule_runner.request(DigestContents, list(classpath.digests()))
177+
assert contents[0].path == ".one.txt.root.resources.jar"
178+
assert filenames_from_zip(contents[0]) == ["one.txt"]
179+
180+
z = ZipFile(BytesIO(contents[0].content))
181+
for info in z.infolist():
182+
assert info.date_time == (2000, 1, 1, 0, 0, 0)

0 commit comments

Comments
 (0)