Skip to content

Honour SOURCE_DATE_EPOCH for reproducible builds#176

Open
krishnapermi wants to merge 5 commits into
apple:mainfrom
krishnapermi:honour-source-date-epoch
Open

Honour SOURCE_DATE_EPOCH for reproducible builds#176
krishnapermi wants to merge 5 commits into
apple:mainfrom
krishnapermi:honour-source-date-epoch

Conversation

@krishnapermi

Copy link
Copy Markdown

Motivation

I was trying to build a reproducible OCI image - same source, same digest every time - and noticed that containertool always writes 0 as the tar entry mtime and Date(timeIntervalSince1970: 0) as the image creation timestamp, regardless of any environment variables. The SOURCE_DATE_EPOCH convention is the standard way to communicate a canonical build time to tools like this, and issue #41 tracks exactly this gap.

Because tar entry mtimes feed into layer digest computation and the image timestamp is baked into the image config digest, both need to use the same epoch value for the build to be truly reproducible.

Modifications

  • Added an mtime: Int = 0 parameter (defaulting to 0, so existing behaviour is unchanged) to Archive.appendFile, Archive.appendDirectory, Archive.appendingFile, Archive.appendingDirectory, and all the recursive helpers in Archive+appending.swift.
    • In RegistryClient+publish.swift, read SOURCE_DATE_EPOCH from the environment once at the start of the publish call and thread it through to all Archive calls and the image config timestamp.
    • In Plugins/ContainerImageBuilder/main.swift, extend the env-var filter (which already allowlists CONTAINERTOOL_-prefixed vars) to also forward SOURCE_DATE_EPOCH to the containertool subprocess.
      Result

When SOURCE_DATE_EPOCH is set, containertool uses that value for all tar entry mtimes and the image creation timestamp, making layer and config digests deterministic across builds from the same source. When the variable is absent, behaviour is identical to before (mtime = 0, Unix epoch timestamp).

Test Plan

export SOURCE_DATE_EPOCH=1234567890
swift package --disable-sandbox plugin containertool --repository <registry>/<name> ...
# build twice from the same source - verify both runs produce identical image digests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant