Skip to content

Reproducible chart archive builds#31323

Merged
mattfarina merged 2 commits intohelm:mainfrom
mattfarina:reproducible-chart-builds
Oct 29, 2025
Merged

Reproducible chart archive builds#31323
mattfarina merged 2 commits intohelm:mainfrom
mattfarina:reproducible-chart-builds

Conversation

@mattfarina
Copy link
Collaborator

Building the same chart into an archive multiple times will have the same sha256 hash.

Perviously, the time in the headers for a file was time.Now() which changed each time. The time is now collected from the operating system when the file is loaded and this time is used.

Fixes: #3612

What this PR does / why we need it:

Special notes for your reviewer:

If applicable:

  • this PR contains user facing changes (the docs needed label should be applied if so)
  • this PR contains unit tests
  • this PR has been tested for backwards compatibility

@pull-request-size pull-request-size bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Sep 24, 2025
@mattfarina mattfarina added the bug Categorizes issue or PR as related to a bug. label Sep 24, 2025
@mattfarina mattfarina added this to the 4.0.0 milestone Sep 24, 2025
@mattfarina
Copy link
Collaborator Author

Note, this is related to #10178. That PR has many commits and no longer cleanly applies. This updates for the changes that have happened to Helm and includes tests that were not previously updated.

@TerryHowe TerryHowe requested a review from Copilot September 24, 2025 15:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR modifies Helm chart archiving to enable reproducible builds by using consistent file modification times instead of the current timestamp. The change ensures that packaging the same chart multiple times produces archives with identical SHA256 hashes.

Key changes:

  • File modification times are now captured when charts are loaded from the filesystem
  • Archive creation uses these captured timestamps instead of time.Now()
  • New test coverage validates reproducible archive creation

Reviewed Changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/chart/common/file.go Added ModTime field to File struct
pkg/chart/v2/chart.go Added ModTime and SchemaModTime fields to Chart struct
pkg/chart/v2/util/save.go Modified writeToTar to accept modTime parameter
pkg/chart/v2/util/save_test.go Added tests for reproducible archive generation
pkg/chart/loader/archive/archive.go Updated BufferedFile to include ModTime
pkg/chart/v2/loader/load.go Set ModTime fields during chart loading
pkg/chart/v2/loader/directory.go Capture file ModTime from filesystem
Multiple test files Updated test fixtures to include ModTime fields

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@TerryHowe
Copy link
Contributor

With https://github.com/helm/helm/pull/31315/files merged, I get:

golangci-lint run ./...
pkg/chart/common/util/values_test.go:17:9: var-naming: avoid meaningless package names (revive)
package util
        ^
pkg/chart/common/values_test.go:17:9: var-naming: avoid meaningless package names (revive)
package common
        ^
pkg/release/v1/util/manifest_sorter_test.go:17:9: var-naming: avoid meaningless package names (revive)
package util
        ^
3 issues:
* revive: 3

Running what I'm pretty sure is in the v8 action

golangci-lint has version 2.5.0 built with go1.25.1 from ff63786c on 2025-09-21T19:04:05Z

@TerryHowe
Copy link
Contributor

Is this considered a breaking change?

@mattfarina
Copy link
Collaborator Author

@TerryHowe The lint rule that was recently removed is used. We have several package that have 'meaningless' names which trigger this rule on change. I created #31330 to restore the rule and left a code comment for context.

In the past we had considered this a breaking change but having written the change I wouldn't. It's been requested for a long time.

@mattfarina mattfarina force-pushed the reproducible-chart-builds branch from d536250 to 7facf29 Compare September 25, 2025 07:46
@hanikesn
Copy link

hanikesn commented Sep 25, 2025

It'd be nice to respect SOURCE_DATE_EPOCH in addition to relying on the file timestamp. This would allow for more easily reproducible builds. It's also what e.g. docker and most other tools use.

@mattfarina
Copy link
Collaborator Author

@hanikesn that's an interesting idea. We would need to set the ModTime for each file in the archive to this date/time. This is something we can do.

Building the same chart into an archive multiple times will have
the same sha256 hash.

Perviously, the time in the headers for a file was time.Now() which
changed each time. The time is now collected from the operating
system when the file is loaded and this time is used.

Fixes: helm#3612

Signed-off-by: Matt Farina <[email protected]>
Note, when time is not available, the builds are not reproducible.
This problem would only happen when an SDK user is using parts of
the API to build their own tooling. Helm will consistently inject
the dates through the higher level APIs.

Signed-off-by: Matt Farina <[email protected]>
Copy link
Member

@robertsirc robertsirc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Walked through the unit test, and this passed my local test suite as well.

@robertsirc robertsirc added the Has One Approval This PR has one approval. It still needs a second approval to be merged. label Oct 29, 2025
@mattfarina
Copy link
Collaborator Author

Per our policy, this needs 2 maintainers to look at it. For community that's 2 maintainers. For maintainer developed changes, the developer counts as one of the two. With that, merging this PR.

@mattfarina mattfarina merged commit 9bed143 into helm:main Oct 29, 2025
5 checks passed
@mattfarina mattfarina deleted the reproducible-chart-builds branch October 29, 2025 20:06
@gjenkins8 gjenkins8 removed the Has One Approval This PR has one approval. It still needs a second approval to be merged. label Oct 30, 2025
@scottrigby
Copy link
Member

I had reviewed privately with Matt, but didn't get back to formally give the LGTM this after the fixes. Just wanted to say NICE WORK on getting the fix in for this long standing and very frustrating issue! 👏👏

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

Labels

bug Categorizes issue or PR as related to a bug. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

helm package should produce bitwise-deterministic tar files

7 participants