Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/default-tests.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,7 +31,7 @@ jobs:
needs: checkstyle
strategy:
matrix:
java_version: ['11', '12', '13', '14', '15', '16', '17', '18', '19', '20']
java_version: ['11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21']

steps:
- uses: actions/checkout@v4
Expand DownExpand Up@@ -59,7 +59,7 @@ jobs:
strategy:
matrix:
java_version: ['11']
maven_version: ['3.2.5', '3.3.9', '3.5.4', '3.6.3', '3.8.8', '3.9.1', '3.9.2', '4.0.0-alpha-7']
maven_version: ['3.2.5', '3.3.9', '3.5.4', '3.6.3', '3.8.8', '3.9.6', '4.0.0-alpha-12']

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -397,7 +397,7 @@
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<generateGitPropertiesFilename>target/testing.properties</generateGitPropertiesFilename>
<dateFormat>yyyy-MM-dd'T'HH:mm:ssZ</dateFormat>
<!-- <dateFormat>yyyy-MM-dd'T'HH:mm:ssXXX</dateFormat> -->
<dateFormatTimeZone>GMT-08:00</dateFormatTimeZone>
<useNativeGit>false</useNativeGit>
<abbrevLength>7</abbrevLength>
Expand Down
41 changes: 22 additions & 19 deletions src/main/java/pl/project13/maven/git/GitCommitIdMojo.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,12 +18,12 @@

package pl.project13.maven.git;

import com.google.common.annotations.VisibleForTesting;
import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Collections;
import java.util.Date;
import java.util.List;
Expand All@@ -44,6 +44,7 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.joda.time.DateTime;
import org.sonatype.plexus.build.incremental.BuildContext;
import pl.project13.core.CommitIdGenerationMode;
import pl.project13.core.CommitIdPropertiesOutputFormat;
Expand DownExpand Up@@ -497,20 +498,28 @@ public class GitCommitIdMojo extends AbstractMojo {
* represents dates or times exported by this plugin (e.g. {@code git.commit.time}, {@code
* git.build.time}). It should be a valid {@link SimpleDateFormat} string.
*
* <p>The current dateFormat is set to match maven's default {@code yyyy-MM-dd'T'HH:mm:ssZ}.
* Please note that in previous versions (2.2.0 - 2.2.2) the default dateFormat was set to: {@code
* dd.MM.yyyy '@' HH:mm:ss z}. However the {@code RFC 822 time zone} seems to give a more reliable
* option in parsing the date and it's being used in maven as default.
* <p>The current dateFormat will be formatted as ISO 8601
* {@code yyyy-MM-dd'T'HH:mm:ssXXX} and therefore can be used as input to maven's
* <a href="https://maven.apache.org/guides/mini/guide-reproducible-builds.html">
* reproducible build</a> feature.
*
* Please note that in previous versions
* (2.2.2 - 7.0.1) the default format was set to {@code yyyy-MM-dd'T'HH:mm:ssZ}
* which produces a {@code RFC 822 time zone}. While such format gives reliable
* options in parsing the date, it does not comply with the requirements of
* the reproducible build feature.
* (2.2.0 - 2.2.2) the default dateFormat was set to: {@code
* dd.MM.yyyy '@' HH:mm:ss z}.
*
* <p>Example:
*
* <pre>{@code
* <dateFormat>yyyy-MM-dd'T'HH:mm:ssZ</dateFormat>
* <dateFormat>yyyy-MM-dd'T'HH:mm:ssXXX</dateFormat>
* }</pre>
*
* @since 2.2.0
*/
@Parameter(defaultValue = "yyyy-MM-dd'T'HH:mm:ssZ")
@Parameter(defaultValue = "yyyy-MM-dd'T'HH:mm:ssXXX")
String dateFormat;

/**
Expand DownExpand Up@@ -1454,32 +1463,26 @@ private Properties getContextProperties(MavenProject project) {
* href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>.
*
* <p>Inspired by
* https://github.com/apache/maven-archiver/blob/a3103d99396cd8d3440b907ef932a33563225265/src/main/java/org/apache/maven/archiver/MavenArchiver.java#L765
* https://github.com/apache/maven-archiver/blob/7acb1db4a9754beacde3f21a69e5523ee901abd5/src/main/java/org/apache/maven/archiver/MavenArchiver.java#L755
*
* @param outputTimestamp the value of <code>${project.build.outputTimestamp}</code> (may be
* <code>null</code>)
* @return the parsed timestamp, may be <code>null</code> if <code>null</code> input or input
* contains only 1 character
*/
private Date parseOutputTimestamp(String outputTimestamp) throws GitCommitIdExecutionException {
@VisibleForTesting
protected static Date parseOutputTimestamp(String outputTimestamp) {
if (outputTimestamp != null
&& !outputTimestamp.trim().isEmpty()
&& outputTimestamp.chars().allMatch(Character::isDigit)) {
return new Date(Long.parseLong(outputTimestamp) * 1000);
return Date.from(Instant.ofEpochSecond(Long.parseLong(outputTimestamp)));
}

if ((outputTimestamp == null) || (outputTimestamp.length() < 2)) {
// no timestamp configured
return null;
}

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
try {
return df.parse(outputTimestamp);
} catch (ParseException pe) {
throw new GitCommitIdExecutionException(
"Invalid 'project.build.outputTimestamp' value '" + outputTimestamp + "'", pe);
}
return new DateTime(outputTimestamp).toDate();
}

private void publishPropertiesInto(Properties propertiesToPublish, Properties propertiesTarget) {
Expand Down
69 changes: 69 additions & 0 deletions src/test/java/pl/project13/maven/git/GitCommitIdMojoTest.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,12 +22,19 @@

import java.io.File;
import java.io.IOException;
import java.time.Instant;
import java.util.Date;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.joda.time.DateTime;
import org.junit.Test;
import org.junit.runner.RunWith;
import pl.project13.core.PropertiesFileGenerator;

/**
* Testcases to verify that the git-commit-id works properly.
*/
@RunWith(JUnitParamsRunner.class)
public class GitCommitIdMojoTest {
@Test
public void testCraftPropertiesOutputFileWithRelativePath() throws IOException {
Expand DownExpand Up@@ -66,4 +73,66 @@ public void testCraftPropertiesOutputFileWithFullPath() throws IOException {
.toFile()
.getCanonicalPath());
}

/**
* test cases for output timestamp parsing.
* This timestamp is configured for Reproducible Builds' archive entries
* (https://maven.apache.org/guides/mini/guide-reproducible-builds.html). The value from <code>
* ${project.build.outputTimestamp}</code> is either formatted as ISO 8601 <code>
* yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like <a
* href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>.
* When using ISO 8601 formatting please note that the entire expression must be entirely either
* in the basic format (20240215T135459+0100) or in the
* extended format (e.g. 2024-02-15T13:54:59+01:00).
* The maven plugin only supports the extended format.
*/
private Object[] parametersParseOutputTimestamp() {
return new Object[] {
// long since epoch
new Object[] {
"1644689403"
},
// Date and time with timezone:
new Object[] {
"2022-02-12T15:30+00:00"
},
new Object[] {
"2022-02-12T15:30:45-05:00"
},
new Object[] {
"2022-02-12T15:30:00+00:00"
},
new Object[] {
"2023-11-30T09:17:06+05:30"
},
new Object[] {
"2024-08-15T20:45:30-03:00"
},
new Object[] {
"2022-02-12T15:30:00Z"
},
new Object[] {
"2023-11-30T09:17:06+0100"
},
// Lowercase time designator
new Object[] {
"2019-03-26t14:00Z"
},
// Lowercase UTC designator
new Object[] {
"2019-03-26T14:00z"
},
// Hours-only offset
new Object[] {
"2019-03-26T10:00-04"
},
};
}

@Test
@Parameters(method = "parametersParseOutputTimestamp")
public void testParseOutputTimestamp(String input) {
Date actual = GitCommitIdMojo.parseOutputTimestamp(input);

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Tests fail with:

TimeZone.setDefault(TimeZone.getTimeZone("America/Sao_Paulo"));

assertThat(actual).isNotNull();
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,8 +56,8 @@ public class NativeAndJGitProviderTest extends GitIntegrationTest {
"git.local.branch.behind",
};

private static final String DEFAULT_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssZ";
private static final String ISO8601_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssZZ";
private static final String DEFAULT_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssXXX";
private static final String ISO8601_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssXXX";

@Test
public void testCompareBasic() throws Exception {
Expand Down