Opened 4 years ago

Last modified 11 months ago

#59672 new enhancement

Set SOURCE_DATE_EPOCH

Reported by: ryandesign (Ryan Carsten Schmidt) Owned by:
Priority: Normal Milestone:
Component: base Version:
Keywords: haspatch Cc: kurthindenburg (Kurt Hindenburg), harens (Haren S), tenzap, mascguy (Christopher Nielsen)
Port:

Description

MacPorts base could set the SOURCE_DATE_EPOCH environment variable.

Change History (10)

comment:1 Changed 4 years ago by kurthindenburg (Kurt Hindenburg)

Cc: kurthindenburg added

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)

comment:2 Changed 4 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 3 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.)

Last edited 3 years ago by ryandesign (Ryan Carsten Schmidt) (previous) (diff)

comment:4 Changed 3 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 Changed 2 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 2 years ago by tenzap

Cc: tenzap added

comment:8 Changed 22 months ago by mascguy (Christopher Nielsen)

Cc: mascguy added

comment:9 in reply to:  6 Changed 11 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 11 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.

Note: See TracTickets for help on using tickets.