Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow constant modified time to support reproducibility #363

Merged
merged 2 commits into from
Jul 16, 2021

Conversation

michal-riha
Copy link
Contributor

Hi,

This change allows users to specify 'modified time' that will be used for all files/folders. This is required to achieve reproducible builds (https://reproducible-builds.org/) of debian packages using this plugin, since there isn't another way how to control the time.

It adds new parameter 'modifiedTimeMs' to the plugin configuration, which (if not left empty) should contain epoch time in milliseconds that will be used as 'modified time'.

Looking forward to hearing from you

@codecov-commenter
Copy link

codecov-commenter commented Jun 23, 2021

Codecov Report

Merging #363 (98af964) into master (14b505b) will increase coverage by 0.33%.
The diff coverage is 100.00%.

❗ Current head 98af964 differs from pull request most recent head aa1839f. Consider uploading reports for the commit aa1839f to get more accurate results
Impacted file tree graph

@@             Coverage Diff              @@
##             master     #363      +/-   ##
============================================
+ Coverage     68.13%   68.46%   +0.33%     
- Complexity       93       97       +4     
============================================
  Files             7        7              
  Lines           568      593      +25     
  Branches         78       82       +4     
============================================
+ Hits            387      406      +19     
- Misses          128      137       +9     
+ Partials         53       50       -3     
Impacted Files Coverage Δ
src/main/java/org/vafer/jdeb/ControlBuilder.java 56.81% <100.00%> (+1.52%) ⬆️
src/main/java/org/vafer/jdeb/DataBuilder.java 90.00% <100.00%> (+0.56%) ⬆️
src/main/java/org/vafer/jdeb/DebMaker.java 60.60% <100.00%> (-0.04%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 14b505b...aa1839f. Read the comment docs.

@tcurdt
Copy link
Owner

tcurdt commented Jun 23, 2021

Thanks for the contribution, @michal-riha
I will have another closer look tomorrow - but this looks already pretty good. Thanks!

@ebourg
Copy link
Collaborator

ebourg commented Jun 23, 2021

We could also support the SOURCE_DATE_EPOCH environment variable, that's the standard to set the build timestamp and that would be probably less intrusive.

@tcurdt
Copy link
Owner

tcurdt commented Jun 23, 2021

@ebourg you mean on top of the config or as another option?

@ebourg
Copy link
Collaborator

ebourg commented Jun 23, 2021

I was thinking about the variable as the only configuration mechanism. The developer sets the variable and all the build tools involved are supposed to handle it. That's how the reproducible builds work usually, the developer doesn't have to configure each tool specifically, it just works.

@tcurdt
Copy link
Owner

tcurdt commented Jun 23, 2021

@michal-riha what are your thoughts on that? would that also work for you?

@michal-riha
Copy link
Contributor Author

I don't mind supporting the env variable.

However it doesn't seem very maven-like: everything about the project and how to build it should be in pom.xml. This will make the build result dependent on build environment. (From practical point of view, consider local builds - you'd probably need extra script to wrap the maven build and set the env variable before running it, which seems like a bit of pain).

But the agrument about not having to configure the setting everywhere is also a good one. Maybe it is worth to support both?

Anyway, I don't really follow any discussions about this topic, maybe all of this was already considered. If you think supporting only the env variable is the way to go, I can change it.

@ebourg
Copy link
Collaborator

ebourg commented Jun 24, 2021

If we do it the Maven way we should support the project.build.outputTimestamp property:

https://maven.apache.org/guides/mini/guide-reproducible-builds.html

@michal-riha
Copy link
Contributor Author

I agree, I'll change it to use the common property.

@tcurdt
Copy link
Owner

tcurdt commented Jun 24, 2021

Env (which should also work with ant) plus official maven property sounds like a good plan then. Thanks!

@@ -140,6 +140,11 @@
<artifactId>xz</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-archiver</artifactId>
Copy link
Owner

Choose a reason for hiding this comment

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

This is only needed for the test case, right?
Any reason for not using <scope>test</scope> ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's 'needed' to resolve the property - see OutputTimestampResolver#24, where MavenArchiver is created.

Date outputDate = new MavenArchiver().parseOutputTimestamp(paramValue);

But to be fair the functionality can be recreated, so if you don't want to add new dependency, it can be removed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Might be worth asking @hboutemy if the property could be exposed in the core Maven API.

* @since 1.9
*/
@Parameter(defaultValue = "${project.build.outputTimestamp}")
private String outputTimestamp;
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we parse project.build.outputTimestamp and SOURCE_DATE_EPOCH I don't think it's necessary to keep a mojo property, nobody is going to configure jdeb specifically if it's possible to do it at a higher level.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry I don't follow. I thought this is the way how to read the properties from pom.xml. Is there another way how to get the specified value?

Copy link
Collaborator

Choose a reason for hiding this comment

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

If you add the project to the mojo with:

@Component
private MavenProject project;

you can then call project.getProperties() to get the properties defined in the pom.xml file:

project.getProperties().get("project.build.outputTimestamp");

Copy link
Contributor

@hboutemy hboutemy Jun 29, 2021

Choose a reason for hiding this comment

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

see https://maven.apache.org/guides/mini/guide-reproducible-builds.html for user documentation

the property is defined globally, then available globally, and it is read by maven-archiver in archiver.configureReproducible( outputTimestamp );

see for example how maven-jar plugin has integrated the feature: https://github.com/apache/maven-jar-plugin/commit/64c5e6530b4712cd95501fffb2de6bb1a202cd89/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since this follows the example given above, I'd prefer to leave it as is.

@hboutemy
Copy link
Contributor

notice: one way to discover how reproducible builds is expected to be used by Maven builds is to make jdeb build reproducible, applying https://maven.apache.org/guides/mini/guide-reproducible-builds.html

@ebourg
Copy link
Collaborator

ebourg commented Jun 29, 2021

@hboutemy Thank you, I was actually wondering if it was possible to have a method somewhere in the core API (in MavenProject maybe?) that provides the reproducible timestamp to be used by the plugins. For example a MavenProject.getReproducibleTimestamp() or getOutputTimestamp() method that takes care of parsing the project.build.outputTimestamp property and the SOURCE_DATE_EPOCH variable.

@hboutemy
Copy link
Contributor

@ebourg reproducible build is a bout plugins, not core, which permits to have reproducible builds whatever Maven core version you use, even Maven 2
maven-archiver has been updated to provide such an API, it is way more flexible than putting something in core

@ebourg
Copy link
Collaborator

ebourg commented Jun 30, 2021

Maybe there is a common plugin dependency that could expose such a method if it's not in the core API then? It's a bit suboptimal and error prone to let every plugin reimplement the same logic to compute the output timestamp.

@hboutemy
Copy link
Contributor

it's available as archiver.configureReproducible( outputTimestamp ); in maven-archiver: what is not matching your needs in this API? I don't see anything error prone
https://maven.apache.org/shared/maven-archiver/apidocs/org/apache/maven/archiver/MavenArchiver.html#configureReproducible(java.lang.String)

@ebourg
Copy link
Collaborator

ebourg commented Jun 30, 2021

Yes but it adds a dependency that wasn't otherwise necessary for this plugin. Maybe it doesn't matter after all since Maven always pulls this dependency.

@hboutemy
Copy link
Contributor

in fact, sharing code will require a dependency
and not a core one, or there will be a Maven version prerequisite

@tcurdt
Copy link
Owner

tcurdt commented Jul 3, 2021

So - what do we do about the dependency?

IIUC I see 3 options:

  1. copy code to recreated the functionality (not sure how much code we are talking about)
  2. just add the dependency
  3. inline the dependency with the shade plugin and let minimizeJar do it's magic

Unless the code is trivial 3. might give is us the best of 1) and 2). Just might need some testing.

@ebourg
Copy link
Collaborator

ebourg commented Jul 3, 2021

Let's just add the dependency, maven-archiver is already pulled by the maven-jar-plugin anyway.

@michal-riha
Copy link
Contributor Author

Hi,
What is the state of this? Are there some more changes you want to make?

@tcurdt
Copy link
Owner

tcurdt commented Jul 15, 2021

What is the state of this? Are there some more changes you want to make?

Sorry, I was semi-offline the past few days.
I think I am OK to merge as is. Any objections, @ebourg?

If I find time I might try inlining the deb.

Thanks for your contribution!

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.

None yet

5 participants