diff --git a/src/main/java/org/eclipsefoundation/git/eca/config/EclipseQuteTemplateExtensions.java b/src/main/java/org/eclipsefoundation/git/eca/config/EclipseQuteTemplateExtensions.java index 0413b4249a7a2856b84c4440e4d8d9e091740503..3387e3b8d0b51cb7253d78e12bfa720e92cff256 100644 --- a/src/main/java/org/eclipsefoundation/git/eca/config/EclipseQuteTemplateExtensions.java +++ b/src/main/java/org/eclipsefoundation/git/eca/config/EclipseQuteTemplateExtensions.java @@ -11,6 +11,7 @@ **********************************************************************/ package org.eclipsefoundation.git.eca.config; +import java.time.format.DateTimeFormatter; import java.util.List; import org.apache.commons.lang3.StringUtils; @@ -49,6 +50,24 @@ public class EclipseQuteTemplateExtensions { return statuses.stream().flatMap(s -> s.getErrors().stream()).toList(); } + /** + * Sorts list and retrieves the most recently modified status, and returns a human readable format of the time. + * + * @param statuses a list of commit validation statuses to retrieve a modification time from + * @return the most recent modification time for any of the passed statuses. + */ + static String getLastKnownValidationTime(List<CommitValidationStatus> statuses) { + CommitValidationStatus latestStatus = statuses + .stream() + .sorted((o1, o2) -> o2.getLastModified().compareTo(o1.getLastModified())) + .findFirst() + .orElse(null); + if (latestStatus == null) { + return "Unknown"; + } + return latestStatus.getLastModified().format(DateTimeFormatter.RFC_1123_DATE_TIME); + } + /** * Converts the status list to a list of email addresses that were associated with validated commits. * diff --git a/src/main/java/org/eclipsefoundation/git/eca/resource/StatusResource.java b/src/main/java/org/eclipsefoundation/git/eca/resource/StatusResource.java index 2625fa163f4ef8edcebddaaa313e7d2f67f72dba..c864c251838766c1b5faa43db2f344b310dc3204 100644 --- a/src/main/java/org/eclipsefoundation/git/eca/resource/StatusResource.java +++ b/src/main/java/org/eclipsefoundation/git/eca/resource/StatusResource.java @@ -12,9 +12,11 @@ package org.eclipsefoundation.git.eca.resource; import java.util.List; +import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.eclipsefoundation.efservices.api.models.Project; +import org.eclipsefoundation.git.eca.api.models.GithubWebhookRequest.PullRequest; import org.eclipsefoundation.git.eca.config.EclipseQuteTemplateExtensions; import org.eclipsefoundation.git.eca.dto.CommitValidationStatus; import org.eclipsefoundation.git.eca.helper.GithubValidationHelper; @@ -187,7 +189,13 @@ public class StatusResource extends CommonResource { // retrieve the status of the commits to display on the status page statuses = validationStatus.getHistoricValidationStatusByShas(wrapper, r.getCommits().keySet().stream().toList()); } - + // fetch the PR so we can indicate whether it's closed, open, or merged + String lastKnownStatus = "unknown"; + Optional<PullRequest> pr = ghAppService.getPullRequest(installationId, org, repoName, prNo); + if (pr.isPresent()) { + lastKnownStatus = pr.get().getState(); + } + // get projects for use in queries + UI List<Project> ps = projects.retrieveProjectsForRepoURL(repoUrl, ProviderType.GITHUB); // render and return the status UI @@ -203,6 +211,7 @@ public class StatusResource extends CommonResource { .data("installationId", installationId) .data("currentUser", getUserForLoggedInAccount()) .data("redirectUri", info.getPath()) + .data("lastKnownStatus", lastKnownStatus) .render()) .build(); } catch (BadRequestException e) { diff --git a/src/main/resources/templates/simple_fingerprint_ui.html b/src/main/resources/templates/simple_fingerprint_ui.html index 4bc08da854c4363359037871e75fb5216f360113..f5a64b5b1dd4b423b7cbe05e119b63bfb7f80bed 100644 --- a/src/main/resources/templates/simple_fingerprint_ui.html +++ b/src/main/resources/templates/simple_fingerprint_ui.html @@ -76,6 +76,9 @@ <strong>Pull request:</strong> <a class="underline" href="https://github.com/{orgName}/{repoName}/pull/{pullRequestNumber}" target="_blank" >#{pullRequestNumber}</a> </li> {/if} + <li><strong>Last Validation Time:</strong> + {statuses.getLastKnownValidationTime} + </li> </ul> <a href="{repoUrl}" target="_blank" rel="noopener" class="btn btn-primary margin-top-10">Project repository</a> </div> @@ -163,13 +166,18 @@ </div> {/if} {#if statuses.0.provider == ProviderType:GITHUB && pullRequestNumber != null && repoName != null && orgName != null} - <div> + <div data-state="{lastKnownStatus}"> + {#if lastKnownStatus ne null && lastKnownStatus ne 'open'} + <button class="btn-success margin-top-10 btn form-submit" type="submit" disabled>Revalidate</button> + <p class="small">Revalidation is disabled as the Pull Request is in a non-open state</p> + {#else} <form id="git-eca-hook-revalidation" data-request-number="{pullRequestNumber}" data-request-repo="{repoName}" data-request-org="{orgName}" data-request-installation="{installationId}"> <div class="captcha"> <div class="h-captcha" data-sitekey="{config:['eclipse.hcaptcha.site-key']}"></div> </div> - <button class="btn-success margin-top-10 btn form-submit" type="submit">Revalidate</button> + <button class="btn-success margin-top-10 btn form-submit" type="submit" { lastKnownStatus ne null && lastKnownStatus ne 'open' ? 'disabled' : '' }>Revalidate</button> </form> + {/if} </div> {/if} </section> diff --git a/src/test/java/org/eclipsefoundation/git/eca/config/EclipseQuteTemplateExtensionsTest.java b/src/test/java/org/eclipsefoundation/git/eca/config/EclipseQuteTemplateExtensionsTest.java index 988fc6b190010e1caeb0930585b6e9f692a85c51..76899e3c5c3112ebc1eade0c6c05120ba6f3a07d 100644 --- a/src/test/java/org/eclipsefoundation/git/eca/config/EclipseQuteTemplateExtensionsTest.java +++ b/src/test/java/org/eclipsefoundation/git/eca/config/EclipseQuteTemplateExtensionsTest.java @@ -11,7 +11,17 @@ */ package org.eclipsefoundation.git.eca.config; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.eclipsefoundation.git.eca.dto.CommitValidationStatus; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -64,4 +74,32 @@ class EclipseQuteTemplateExtensionsTest { void obfuscateEmail_failure_invalidAddress(String input, String expected) { Assertions.assertEquals(expected, EclipseQuteTemplateExtensions.obfuscateEmail(input)); } + + @Test + void getLastKnownValidationTime_success() { + ZonedDateTime timeOne = ZonedDateTime.now().minus(3, ChronoUnit.DAYS); + ZonedDateTime timeTwo = ZonedDateTime.now().minus(5, ChronoUnit.DAYS); + ZonedDateTime timeThree = ZonedDateTime.now().minus(1, ChronoUnit.DAYS); + List<CommitValidationStatus> statuses = Arrays + .asList(createStatus(Optional.of(timeOne)), createStatus(Optional.of(timeTwo)), createStatus(Optional.of(timeThree))); + // should return time three in RFC 1123 format, as it is the most recent time. + Assertions + .assertEquals(timeThree.format(DateTimeFormatter.RFC_1123_DATE_TIME), + EclipseQuteTemplateExtensions.getLastKnownValidationTime(statuses)); + } + + @Test + void getLastKnownValidationTime_noCommits() { + // should return "Unknown" if we can't find an associated modification time at all + Assertions + .assertEquals("Unknown", + EclipseQuteTemplateExtensions.getLastKnownValidationTime(new ArrayList<>())); + } + + private CommitValidationStatus createStatus(Optional<ZonedDateTime> date) { + CommitValidationStatus status = new CommitValidationStatus(); + status.setCreationDate(ZonedDateTime.now()); + status.setLastModified(date.orElse(ZonedDateTime.now())); + return status; + } }