diff --git a/.gitignore b/.gitignore
index 6d49b95354..8f164d2f9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ target
.project
*.iml
.idea
+/.factorypath
diff --git a/src/it/it-set-019-outputTimestamp/invoker.properties b/src/it/it-set-019-outputTimestamp/invoker.properties
new file mode 100644
index 0000000000..414e361403
--- /dev/null
+++ b/src/it/it-set-019-outputTimestamp/invoker.properties
@@ -0,0 +1 @@
+invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:set -DnewVersion=2.0
diff --git a/src/it/it-set-019-outputTimestamp/pom.xml b/src/it/it-set-019-outputTimestamp/pom.xml
new file mode 100644
index 0000000000..9029e8a2b1
--- /dev/null
+++ b/src/it/it-set-019-outputTimestamp/pom.xml
@@ -0,0 +1,14 @@
+
+ 4.0.0
+
+ localhost
+ it-set-019
+ 1.0
+ pom
+ set
+
+
+ 10
+
+
diff --git a/src/it/it-set-019-outputTimestamp/verify.groovy b/src/it/it-set-019-outputTimestamp/verify.groovy
new file mode 100644
index 0000000000..e854a85867
--- /dev/null
+++ b/src/it/it-set-019-outputTimestamp/verify.groovy
@@ -0,0 +1,3 @@
+pom = new File( basedir, "pom.xml" ).text;
+
+assert pom =~ /\d\d\d\d+<.project.build.outputTimestamp>/
diff --git a/src/main/java/org/codehaus/mojo/versions/SetMojo.java b/src/main/java/org/codehaus/mojo/versions/SetMojo.java
index 65ce2a01cd..3f823b428b 100644
--- a/src/main/java/org/codehaus/mojo/versions/SetMojo.java
+++ b/src/main/java/org/codehaus/mojo/versions/SetMojo.java
@@ -21,14 +21,18 @@
import java.io.File;
import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Date;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
+import java.util.TimeZone;
import java.util.TreeMap;
import java.util.regex.Pattern;
@@ -485,6 +489,9 @@ protected synchronized void update( ModifiedPomXMLEventReader pom )
for ( VersionChange versionChange : sourceChanges )
{
changer.apply( versionChange );
+
+ // also update project.build.outputTimestamp
+ updateBuildOutputTimestamp( pom, model );
}
}
catch ( IOException e )
@@ -494,4 +501,36 @@ protected synchronized void update( ModifiedPomXMLEventReader pom )
log.clearContext();
}
+ private void updateBuildOutputTimestamp( ModifiedPomXMLEventReader pom, Model model )
+ throws XMLStreamException
+ {
+ String buildOutputTimestamp = model.getProperties().getProperty( "project.build.outputTimestamp" );
+
+ if ( buildOutputTimestamp == null || StringUtils.isEmpty( buildOutputTimestamp ) )
+ {
+ // no Reproducible Builds output timestamp defined
+ return;
+ }
+
+ if ( StringUtils.isNumeric( buildOutputTimestamp ) )
+ {
+ // int representing seconds since the epoch, like SOURCE_DATE_EPOCH
+ buildOutputTimestamp = String.valueOf( System.currentTimeMillis() / 1000 );
+ }
+ else if ( buildOutputTimestamp.length() <= 1 )
+ {
+ // value length == 1 means disable Reproducible Builds
+ return;
+ }
+ else
+ {
+ // ISO-8601
+ DateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss'Z'" );
+ df.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
+ buildOutputTimestamp = df.format( new Date() );
+ }
+
+ PomHelper.setPropertyVersion( pom, null, "project.build.outputTimestamp", buildOutputTimestamp );
+ }
+
}