How do you make distTar produce a compressed, reproducible archive, and what knobs control compression?
answer
- distTar is a Tar -> compression = Compression.GZIP
- isReproducibleFileOrder = true
- isPreserveFileTimestamps = false
- withType<AbstractArchiveTask>().configureEach
- pin file/dir permissions for stable modes
basics
~10 sConfigure the distTar task: set compression = Compression.GZIP to produce a .tgz-style gzip tar, and set isReproducibleFileOrder = true and isPreserveFileTimestamps = false for byte-stable, reproducible archives.
solid answer
~40 s`distTar` is a `Tar` task, so it exposes `compression`. Set `tasks.distTar { compression = Compression.GZIP }` (or BZIP2) to gzip the tar — also fix the extension via `archiveExtension.set("tgz")` if you want. For **reproducible** archives (identical bytes across machines/time so builds are cacheable and verifiable), set on both `distTar` and `distZip`: `isReproducibleFileOrder = true` (sort entries deterministically) and `isPreserveFileTimestamps = false` (zero out per-file timestamps). `distZip`, being a `Zip`, additionally has those same two flags. These are the standard `AbstractArchiveTask` reproducibility knobs and pair well with the `dirMode`/`fileMode` permission settings for stable Unix modes. Gradle ships a convenience `tasks.withType<AbstractArchiveTask>().configureEach { ... }` so you can apply reproducibility to every archive, including distZip/distTar, in one place.
code
kotlin · 11 linesimport org.gradle.api.tasks.bundling.Compression
tasks.distTar {
compression = Compression.GZIP
archiveExtension.set("tgz")
}
tasks.withType<AbstractArchiveTask>().configureEach {
isReproducibleFileOrder = true
isPreserveFileTimestamps = false
}go deeper
Know distTar can be gzip-compressed via the compression property.
Set GZIP compression and adjust the extension; recognize the two reproducibility flags exist.
Explain why ordering + timestamps cause nondeterminism and configure both flags (plus permissions) across all archive tasks.
Mandate reproducible builds for supply-chain/verification, applying archive reproducibility via a convention plugin and tying it to build-cache/attestation policy.
## Compression on distTar `distTar` is a `Tar` task. A plain tar is uncompressed; you opt into compression with the `compression` property: ```kotlin import org.gradle.api.tasks.bundling.Compression tasks.distTar { compression = Compression.GZIP // or Compression.BZIP2 / Compression.NONE archiveExtension.set("tgz") // cosmetic: name it .tgz } ``` `distZip` is always DEFLATE-compressed (zip's native scheme); there is no `compression` enum for it — its `entryCompression` can be set to `STORED` vs `DEFLATED` if you need uncompressed entries. ## Why reproducibility matters A **reproducible archive** produces byte-identical output given the same inputs, regardless of build machine, filesystem ordering, or wall-clock time. That makes archives verifiable (supply-chain integrity), and lets Gradle's build cache and up-to-date checks treat them as stable. Two sources of nondeterminism in archives are *entry ordering* (filesystem walk order varies) and *per-entry timestamps* (mtime of files at build time). ## The two flags On any `AbstractArchiveTask` (so on both distZip and distTar): ```kotlin tasks.withType<AbstractArchiveTask>().configureEach { isReproducibleFileOrder = true // deterministic, sorted entry order isPreserveFileTimestamps = false // constant timestamp instead of real mtime } ``` - `isReproducibleFileOrder = true` sorts entries so the order doesn't depend on the filesystem. - `isPreserveFileTimestamps = false` writes a fixed timestamp (a constant) for every entry instead of the file's real modification time. ## Permissions File/dir modes can also vary; pin them with `filePermissions { unix("644") }` / `dirPermissions { unix("755") }` (Gradle 8.3+; older: `fileMode`/`dirMode`). This keeps executable bits on start scripts stable across platforms. ## Applying broadly Because distZip/distTar are just archive tasks, the idiomatic move is the `withType<AbstractArchiveTask>().configureEach { }` block — it covers the jar, the dist archives, and any custom archives uniformly, which is the right altitude for a release build.
- Why set isPreserveFileTimestamps = false for reproducibility?Real file mtimes vary per build, so archives differ byte-for-byte; writing a constant timestamp removes that source of nondeterminism.
- Does distZip have a `compression` enum like distTar?No — zip uses DEFLATE natively; distZip exposes `entryCompression` (STORED vs DEFLATED) instead of the Tar `compression` enum.
- How do you apply reproducibility to all archive tasks at once?Use `tasks.withType<AbstractArchiveTask>().configureEach { ... }`, which covers jar, distZip, distTar, and custom archives.
saying these in an interview costs you the question
- Saying distZip takes a `Compression.GZIP` value — that enum is for Tar; zip uses entryCompression.
- Claiming reproducible archives just need a fixed name — ordering and timestamps are the real levers.
- Forgetting to also disable timestamp preservation, leaving archives non-reproducible despite sorted order.