Skip to main content

deterministic-zip wrapped for usage with pip and/or python.

Project description

deterministic-zip

GitHub Release PyPI version DockerHub Pulls GitHub all releases download count CircleCI Build Status codecov Renovate Quality Gate Status Maintainability Rating Go Report Card Security Rating


Simple (almost drop-in) replacement for zip that produces deterministic files.

Features

  • Drop-in tool for zip
  • Removes all metadata from files added for all platforms
  • Creates immutable zip files
  • Supports SOURCE_DATE_EPOCH for setting the modified date

Installation

Automatic install

bash <(curl -sS https://raw.githubusercontent.com/timo-reymann/deterministic-zip/main/installer)

Set the environment variable DETERMINISTIC_ZIP_VERSION to install a specific version

Manual

Linux (64-bit)

curl -LO https://github.com/timo-reymann/deterministic-zip/releases/download/$(curl -Lso /dev/null -w %{url_effective} https://github.com/timo-reymann/deterministic-zip/releases/latest | grep -o '[^/]*$')/deterministic-zip_linux-amd64 && \
chmod +x deterministic-zip_linux-amd64 && \
sudo mv deterministic-zip_linux-amd64 /usr/local/bin/deterministic-zip

Darwin (Intel)

brew
brew tap timo-reymann/deterministic-zip
brew install deterministic-zip
manual
curl -LO https://github.com/timo-reymann/deterministic-zip/releases/download/$(curl -Lso /dev/null -w %{url_effective} https://github.com/timo-reymann/deterministic-zip/releases/latest | grep -o '[^/]*$')/deterministic-zip_darwin-amd64 && \
chmod +x deterministic-zip_darwin-amd64 && \
sudo mv deterministic-zip_darwin-amd64 /usr/local/bin/deterministic-zip

Install with go

go install github.com/timo-reymann/deterministic-zip@latest

Install with pip(x)

Using pipx you can just use the following command use deterministic-zip as it is:

pipx install deterministic-zip-go

If you want to use it directly using the subprocess module you can install it with pip:

pip install deterministic-zip-go

And use the package like this:

import subprocess

from deterministic_zip_go import exec

# Run process and prefix stdout and stderr
exec.exec_with_templated_output(["--help"])

# Create a subprocess, specifying how to handle stdout, stderr
exec.create_subprocess(["--help"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# Perform command with suppressed output and return finished proces instance,
# on that one can also check if the call was successfully
exec.exec_silently(["--version"])

Docker

Please check the Containerized section in Usage for more details.

Supported platforms

The following platforms are supported (and have prebuilt binaries / ready to use integration):

  • Linux
    • 32-bit
    • 64-bit
    • ARM 64-bit
    • ARM 32-bit
  • Darwin
    • 64-bit
    • ARM (M1/M2)
  • Windows
    • ARM
    • 32-bit
    • 64-bit
  • FreeBSD
    • 32-bit
    • 64-bit
    • ARM 64-bit
    • ARM 32-bit
  • OpenBSD
    • 32-bit
    • 64-bit
  • OCI compatible container engines (Docker, podman etc)
    • ARM
    • 64-bit
  • CircleCI
  • GitHub Actions

Where to find the latest release for your platform

Binaries

Binaries for all of these can be found on the latest release page.

Docker

For the docker image check the docker hub.

CI Provider

Usage

Command Line

If you installed the binary via Releases, Install-Script or using go you can just run deterministic-zip as a command.

deterministic-zip -h

Containerized

Please be aware that the image contains just the binary, no OS, libs or anything else. It also runs as root to be able to zip files no matter the ownership, feel free to build your own images based on that as well.

Using the container directly

If you want to use the tool on a platform not supported yet or dont want to install the tool locally you can also mount your folder in /workspace which is the default working directory. Than you can just execute commands as you want to.

docker run -v $PWD:/workspace timoreymann/deterministic-zip:latest

Integrating into your CI image

If you want to integrate the tool directly into your build image, you can also utilize the auto updates from tools like renovatebot or dependabot. Using docker built in features you can just get the binary directly from the image.

FROM base-image:tag
# do your customizations
COPY --from=timoreymann/deterministic-zip:latest /deterministic-zip /usr/bin/deterministic-zip

Motivation

Why another zip-tool? What is this deterministic stuff?!

When we are talking about deterministic it means that the hash of the zip file won't change unless the contents of the zip file changes.

This means only the content, no metadata. You can achieve this with zip, yes.

The problem that still remains is that the order is almost unpredictable and zip is very platform specific, so you will end up with a bunch of crazy shell pipelines. And I am not even talking about windows at this point.

So this is where this tool comes in, it is intended to be a drop-in replacement for zip in your build process.

The use cases for this are primary:

  • Zipping serverless code
  • Backups or other files that get rsynced

Want to know more about the topic of deterministic/reproducible builds?

I can recommend the following resources:

Documentation

How reliable is it?

Of course, it is not as reliable as the battle-proven and billions of times executed zip.

Even though I am heavily relying on the go stdlib this software can of course have bugs. And you are welcome to report them and help make this even more stable. Of course there will be tests to cover most use cases but at the end this is still starting from scratch, so if you need advanced features or just dont feel comfortable about using this tool don't do it!

Differences between zip and deterministic-zip

Please see docs/differences

Contributing

I love your input! I want to make contributing to this project as easy and transparent as possible, whether it's:

  • Reporting a bug
  • Discussing the current state of the configuration
  • Submitting a fix
  • Proposing new features
  • Becoming a maintainer

To get started please read the Contribution Guidelines.

Development

Requirements

Test

make test-coverage-report

Build

make build

Alternatives

As far as I know the following (GitHub) projects exist:

All in all they are just simply not what I needed. My favourite is Rust, because its just simply dropping in a binary. Something that's very convenient especially when it comes to Docker builds.

The main problem that all these solutions share is that it in my opinion cool things like excluding patterns, that I regularly use are simply not implemented, and i REALLY love glob patterns.

Credits

This whole project wouldnt be possible with the great work of the following libraries:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

deterministic_zip_go-6.1.0-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.0 MB view details)

Uploaded Python 3manylinux: glibc 2.12+ x86-64

deterministic_zip_go-6.1.0-py3-none-macosx_11_0_arm64.whl (979.5 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

deterministic_zip_go-6.1.0-py3-none-macosx_10_9_x86_64.whl (1.0 MB view details)

Uploaded Python 3macOS 10.9+ x86-64

File details

Details for the file deterministic_zip_go-6.1.0-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for deterministic_zip_go-6.1.0-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 fa6f3dc6767461eb2287676a44bc9a8eb9f9f52497b63c015807e452b572770d
MD5 18394063d61c2e3af437a20907f11a56
BLAKE2b-256 4b3a404a2c7c94b87f532c5dcb05fab7e0f6b8855b8b7da7213bd47449dac9b9

See more details on using hashes here.

File details

Details for the file deterministic_zip_go-6.1.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for deterministic_zip_go-6.1.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6fc02a4cc52096d6aa5f909fa99e0a6dbc1378592610b94138b0c0cf65cfbc76
MD5 d9995249b0df810d86249a6de8fcdf1b
BLAKE2b-256 e5dd91975412f01cc3f7aeb478d007c60e2e21c7d6705d2f4dfd071747df3fd0

See more details on using hashes here.

File details

Details for the file deterministic_zip_go-6.1.0-py3-none-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for deterministic_zip_go-6.1.0-py3-none-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 7e9214b635dec5f410a156d678868c02dbe765d3fc327449f3dfead1151b0170
MD5 c8212a2ce4fedb1410c0d08d4eda68c7
BLAKE2b-256 5dd0688653bea959a2ef23c5f6e0d05069880da81fcbbfad34a5996bc7ee4d51

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page