#59672 closed enhancement (fixed)
Set SOURCE_DATE_EPOCH
Reported by: | ryandesign (Ryan Carsten Schmidt) | Owned by: | jmroot (Joshua Root) |
---|---|---|---|
Priority: | Normal | Milestone: | MacPorts 2.10.0 |
Component: | base | Version: | |
Keywords: | haspatch | Cc: | kurthindenburg (Kurt Hindenburg), harens (Haren S), tenzap, mascguy (Christopher Nielsen), jmroot (Joshua Root) |
Port: |
Description
MacPorts base could set the SOURCE_DATE_EPOCH environment variable.
Change History (16)
comment:1 Changed 5 years ago by kurthindenburg (Kurt Hindenburg)
Cc: | kurthindenburg added |
---|
comment:2 Changed 5 years ago by ryandesign (Ryan Carsten Schmidt)
As far as I know builds of base are already reproducible, at least insofar as we don't deliberately use the build date/time anywhere.
I intended this ticket to suggest that MacPorts could add SOURCE_DATE_EPOCH
to the environment when it builds ports so that ports' build systems that make use of this variable will be more reproducible. (Per the link in the ticket description: "SOURCE_DATE_EPOCH
is a standardised environment variable that distributions can set centrally and have build tools consume this in order to produce reproducible output.") When I filed this ticket, I had just encountered a port that had such build system and I had been unaware of this variable.
comment:3 Changed 4 years ago by ryandesign (Ryan Carsten Schmidt)
In the wordgrinder port I have implemented it this way:
post-extract { set latest 0 fs-traverse i [list ${worksrcpath}] { if {[file isfile ${i}]} { set t [file mtime ${i}] if {${t} > ${latest}} { set latest ${t} } } } set fp [open $env(TMPDIR)/SOURCE_DATE_EPOCH w] puts -nonewline ${fp} ${latest} close ${fp} }
pre-build { set fp [open $env(TMPDIR)/SOURCE_DATE_EPOCH r] set latest [read ${fp}] close ${fp} build.env-append \ SOURCE_DATE_EPOCH=${latest} }
The value needs to be determined right after extraction so that it is not affected by any changes made in the patch or configure phases and it needs to be saved to disk between phases in case the user is running the phases independently.
Maybe something similar can be done in base. The base version should include error-checking code that skips setting the environment variable if the file doesn't exist. (Users might have existing work directories that don't have the file.)
comment:4 Changed 4 years ago by ryandesign (Ryan Carsten Schmidt)
The base version should also set the environment variable in all relevant phases (patch, configure, build, destroot). It should be stored in memory so that it only needs to be read from disk once. We might store it in a new option that portfiles could even override if needed.
comment:5 Changed 3 years ago by harens (Haren S)
Cc: | harens added |
---|
comment:6 follow-up: 9 Changed 3 years ago by tenzap
@ryandesign, do you think setting this variable can be managed directly in the tool that calls the various phases of the portfile. This would make SOURCE_DATE_EPOCH available for every port ?
May I suggest to add the revision number of the port (the value in the Portfile) to the timestamp in SOURCE_DATE_EPOCH? This would be like adding a few seconds to it and permit to represent in SOURCE_DATE_EPOCH that the Portfile changed. This is sort of analogous to the way debian does it (Debian uses the timestamp of the debian/changelog file).
comment:7 Changed 3 years ago by tenzap
Cc: | tenzap added |
---|
comment:8 Changed 2 years ago by mascguy (Christopher Nielsen)
Cc: | mascguy added |
---|
comment:9 follow-up: 12 Changed 18 months ago by ryandesign (Ryan Carsten Schmidt)
Keywords: | haspatch added |
---|
Replying to tenzap:
do you think setting this variable can be managed directly in the tool that calls the various phases of the portfile. This would make SOURCE_DATE_EPOCH available for every port ?
What "tool" do you mean? The phases are run by MacPorts base. I am proposing that MacPorts base should set SOURCE_DATE_EPOCH
in all phases of all ports.
Haren has provided a PR implementing this:
https://github.com/macports/macports-base/pull/274
May I suggest to add the revision number of the port (the value in the Portfile) to the timestamp in SOURCE_DATE_EPOCH? This would be like adding a few seconds to it and permit to represent in SOURCE_DATE_EPOCH that the Portfile changed. This is sort of analogous to the way debian does it (Debian uses the timestamp of the debian/changelog file).
I don't know if that's a good idea. I don't see anything recommending doing that in the documentation link I posted at the top. I am not familiar with what Debian does or why it does it.
comment:10 Changed 18 months ago by tenzap
I didn't know which tool processes the Portfile, now I know it's macports-base. While reading the ticket again, I probably didn't understand well. Now my comment seems actually inaccurate since SOURCE_DATE_EPOCH is apparently set to the last commit date of a port.
comment:11 Changed 6 months ago by jmroot (Joshua Root)
Cc: | jmroot added |
---|
Would there be any serious drawback to simply setting SOURCE_DATE_EPOCH
to a fixed value, at least to start with? The only one I can think of is that users might be slightly confused if the recorded timestamps are visible somewhere.
To use it the way Debian does, we would need to determine the timestamp of the last change to the port's directory in the macports-ports repo. That's not hard when using a git repo, but we would have to somehow add that information to the ports trees we serve via rsync and http, maybe in a metadata file.
comment:12 Changed 6 months ago by jmroot (Joshua Root)
Replying to ryandesign:
Replying to tenzap:
May I suggest to add the revision number of the port (the value in the Portfile) to the timestamp in SOURCE_DATE_EPOCH? This would be like adding a few seconds to it and permit to represent in SOURCE_DATE_EPOCH that the Portfile changed. This is sort of analogous to the way debian does it (Debian uses the timestamp of the debian/changelog file).
I don't know if that's a good idea. I don't see anything recommending doing that in the documentation link I posted at the top. I am not familiar with what Debian does or why it does it.
Debian increments the value only in the case of a Binary Non-Maintainer Upload. We don't have the problem that that solves for them. The equivalent of a Portfile change normally results in a new entry in debian/changelog
which has a new timestamp.
comment:13 Changed 6 months ago by jmroot (Joshua Root)
comment:14 Changed 6 months ago by jmroot (Joshua Root)
Owner: | set to jmroot |
---|---|
Resolution: | → fixed |
Status: | new → closed |
comment:15 Changed 6 months ago by jmroot (Joshua Root)
Milestone: | → MacPorts Future |
---|
comment:16 Changed 4 months ago by jmroot (Joshua Root)
Milestone: | MacPorts Future → MacPorts 2.10.0 |
---|
I've been looking at this. is the goal to have base have reproducible builds? or that the ports should be reproducible builds?
If I understand who this would workl, it would be use SOURCE_DATE_EPOCH in place of the current time in the logs/etc to allow all builds to be the same. This would require another option somewhere to do this.
SOURCE_DATE_EPOCH could/would be set to the last commit change. SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD)