zip -q and -X: Quiet, Reproducible Archives
zip -q suppresses progress output and zip -X drops extra file attributes that change between runs.
CI logs fill up fast with per-file zip output, and byte-for-byte reproducible archives need the variable metadata removed. -q and -X address both.
What it does
zip -q runs quietly, suppressing the line-per-file listing. zip -X excludes extra file attributes (such as the local extra fields holding uid/gid and some timestamps) so the archive contents depend only on the file data and names, not the machine that built it.
Common usage
zip -q -r build.zip dist
# strip extra metadata for a more reproducible archive
zip -q -X -r build.zip distOptions
| Flag | What it does |
|---|---|
| -q | Quiet mode, no per-file output |
| -X | Exclude extra file attributes (uid/gid, some metadata) |
| -r | Recurse into directories |
| -9 | Maximum compression (slower, smaller) |
| -D | Do not add directory entries |
In CI
For reproducible builds, zip still records each file modification time, so identical inputs with different mtimes produce different bytes. Normalize timestamps first (for example touch every file to a fixed date) and add -X to strip the variable extra fields. Sorting the input file list also helps because zip stores entries in the order it receives them.
Common errors in CI
Reproducibility usually fails not because of zip itself but because mtimes or file ordering differ between runs; -X alone does not fix the stored timestamps. If two archives that should match differ, compare with unzip -v to see whether the file times or the entry order changed. -q hides warnings too, so drop it temporarily when debugging a "name not matched" problem.