Skip to content
Snippets Groups Projects
Verified Commit f9a74562 authored by Jordi Gómez's avatar Jordi Gómez
Browse files

feat: migrating some Autovalue classes to records + small changes

parent 23e3f8b4
No related branches found
No related tags found
No related merge requests found
Pipeline #73412 failed
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!--
Copyright (c) 2020
2025 Eclipse Foundation
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.eclipsefoundation</groupId> <groupId>org.eclipsefoundation</groupId>
<artifactId>git-eca</artifactId> <artifactId>git-eca</artifactId>
...@@ -15,7 +28,7 @@ ...@@ -15,7 +28,7 @@
<quarkus.platform.version>3.15.4</quarkus.platform.version> <quarkus.platform.version>3.15.4</quarkus.platform.version>
<surefire-plugin.version>3.3.1</surefire-plugin.version> <surefire-plugin.version>3.3.1</surefire-plugin.version>
<maven.compiler.parameters>true</maven.compiler.parameters> <maven.compiler.parameters>true</maven.compiler.parameters>
<eclipse-api-version>1.2.3</eclipse-api-version> <eclipse-api-version>1.2.5</eclipse-api-version>
<auto-value.version>1.10.4</auto-value.version> <auto-value.version>1.10.4</auto-value.version>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version> <org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
<sonar.sources>src/main</sonar.sources> <sonar.sources>src/main</sonar.sources>
...@@ -75,8 +88,8 @@ ...@@ -75,8 +88,8 @@
<artifactId>quarkus-smallrye-jwt</artifactId> <artifactId>quarkus-smallrye-jwt</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.quarkus</groupId> <groupId>io.quarkus</groupId>
<artifactId>quarkus-mailer</artifactId> <artifactId>quarkus-mailer</artifactId>
</dependency> </dependency>
<!-- Annotation preprocessors - reduce all of the boiler plate --> <!-- Annotation preprocessors - reduce all of the boiler plate -->
...@@ -97,6 +110,12 @@ ...@@ -97,6 +110,12 @@
<version>${org.mapstruct.version}</version> <version>${org.mapstruct.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder-processor</artifactId>
<version>45</version>
<scope>provided</scope>
</dependency>
<!-- Test requirements --> <!-- Test requirements -->
<dependency> <dependency>
...@@ -168,6 +187,11 @@ ...@@ -168,6 +187,11 @@
<artifactId>mapstruct-processor</artifactId> <artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version> <version>${org.mapstruct.version}</version>
</path> </path>
<path>
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder-processor</artifactId>
<version>45</version>
</path>
</annotationProcessorPaths> </annotationProcessorPaths>
</configuration> </configuration>
</plugin> </plugin>
...@@ -184,4 +208,4 @@ ...@@ -184,4 +208,4 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
</project> </project>
\ No newline at end of file
...@@ -10,53 +10,24 @@ ...@@ -10,53 +10,24 @@
package org.eclipsefoundation.git.eca.api.models; package org.eclipsefoundation.git.eca.api.models;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.google.auto.value.AutoValue;
import io.soabase.recordbuilder.core.RecordBuilder;
/** /**
* Model response for repos/{org}/{repo}/issues/{issueNumber}/comments * Model response for repos/{org}/{repo}/issues/{issueNumber}/comments
*/ */
@AutoValue @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@JsonDeserialize(builder = AutoValue_GithubIssueComment.Builder.class) @RecordBuilder
public abstract class GithubIssueComment { public record GithubIssueComment(
public abstract String getBody(); String body,
Long id,
public abstract Long getId(); GithubUser user
) {
public abstract GithubUser getUser(); @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@RecordBuilder
@AutoValue public static record GithubUser(
@JsonDeserialize(builder = AutoValue_GithubIssueComment_GithubUser.Builder.class) Long id
public abstract static class GithubUser { ) {}
public abstract Long getId();
public static Builder builder() {
return new AutoValue_GithubIssueComment_GithubUser.Builder();
}
@AutoValue.Builder
@JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder {
public abstract Builder setId(Long id);
public abstract GithubUser build();
}
}
public static Builder builder() {
return new AutoValue_GithubIssueComment.Builder();
}
@AutoValue.Builder
@JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder {
public abstract Builder setBody(String body);
public abstract Builder setId(Long id);
public abstract Builder setUser(GithubUser user);
public abstract GithubIssueComment build();
}
} }
...@@ -10,51 +10,13 @@ ...@@ -10,51 +10,13 @@
package org.eclipsefoundation.git.eca.api.models; package org.eclipsefoundation.git.eca.api.models;
import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import io.soabase.recordbuilder.core.RecordBuilder;
import com.google.auto.value.AutoValue;
/** /**
* Model for creating a comment on a GitHub issue or pull request. * Model for creating a comment on a GitHub issue or pull request.
* Uses the issues API endpoint which works for both issues and PRs. * Uses the issues API endpoint which works for both issues and PRs.
*/ */
@AutoValue
@JsonDeserialize(builder = AutoValue_GithubIssueCommentRequest.Builder.class)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public abstract class GithubIssueCommentRequest { @RecordBuilder
/** public record GithubIssueCommentRequest(String body) {}
* Gets the comment body text. \ No newline at end of file
*
* @return the comment body text
*/
public abstract String getBody();
/**
* Creates a new builder for this class.
*
* @return a new builder instance
*/
public static Builder builder() {
return new AutoValue_GithubIssueCommentRequest.Builder();
}
@AutoValue.Builder
@JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder {
/**
* Sets the comment body text.
*
* @param body the comment text to set
* @return this builder instance
*/
public abstract Builder setBody(String body);
/**
* Builds a new GithubIssueCommentRequest instance.
*
* @return the built instance
*/
public abstract GithubIssueCommentRequest build();
}
}
\ No newline at end of file
...@@ -9,29 +9,14 @@ ...@@ -9,29 +9,14 @@
*/ */
package org.eclipsefoundation.git.eca.config; package org.eclipsefoundation.git.eca.config;
import io.smallrye.config.ConfigMapping;
import java.util.Optional; import java.util.Optional;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import jakarta.enterprise.context.ApplicationScoped;
/** /**
* The intention of this class is to provide an static bot ID, given that this app only supports one installation, this way we can avoid * The intention of this class is to provide an static bot ID, given that this app only supports one installation, this way we can avoid
* having to retrieve this information from the API on every start, or storing it in the DB. * having to retrieve this information from the API on every start, or storing it in the DB.
*/ */
@ApplicationScoped @ConfigMapping(prefix = "eclipse.github.bot")
public class GithubBotConfig { public interface GithubBotConfig {
Optional<Long> id();
@ConfigProperty(name = "eclipse.github.bot.id")
Optional<Integer> botId;
/**
* Gets the GitHub bot ID.
*
* @return the bot ID as an Optional Integer
*/
public Optional<Integer> getBotId() {
return botId;
}
} }
...@@ -35,6 +35,7 @@ import org.eclipsefoundation.git.eca.api.models.GithubCommit.ParentCommit; ...@@ -35,6 +35,7 @@ import org.eclipsefoundation.git.eca.api.models.GithubCommit.ParentCommit;
import org.eclipsefoundation.git.eca.api.models.GithubCommitStatusRequest; import org.eclipsefoundation.git.eca.api.models.GithubCommitStatusRequest;
import org.eclipsefoundation.git.eca.api.models.GithubIssueComment; import org.eclipsefoundation.git.eca.api.models.GithubIssueComment;
import org.eclipsefoundation.git.eca.api.models.GithubIssueCommentRequest; import org.eclipsefoundation.git.eca.api.models.GithubIssueCommentRequest;
import org.eclipsefoundation.git.eca.api.models.GithubIssueCommentRequestBuilder;
import org.eclipsefoundation.git.eca.api.models.GithubWebhookRequest; import org.eclipsefoundation.git.eca.api.models.GithubWebhookRequest;
import org.eclipsefoundation.git.eca.api.models.GithubWebhookRequest.PullRequest; import org.eclipsefoundation.git.eca.api.models.GithubWebhookRequest.PullRequest;
import org.eclipsefoundation.git.eca.config.GithubBotConfig; import org.eclipsefoundation.git.eca.config.GithubBotConfig;
...@@ -153,7 +154,7 @@ public class GithubHelper { ...@@ -153,7 +154,7 @@ public class GithubHelper {
} }
LOGGER.debug("Found {} commits for '{}#{}'", commitShas.size(), fullRepoName, prNo); LOGGER.debug("Found {} commits for '{}#{}'", commitShas.size(), fullRepoName, prNo);
// retrieve the webhook tracking info, or generate an entry to track this PR // retrieve the webhook tracking info, or generate an entry to track this PR if it's missing.
GithubWebhookTracking updatedTracking = retrieveAndUpdateTrackingInformation(wrapper, installationId, org, repoName, GithubWebhookTracking updatedTracking = retrieveAndUpdateTrackingInformation(wrapper, installationId, org, repoName,
prResponse.get()); prResponse.get());
if (updatedTracking == null) { if (updatedTracking == null) {
...@@ -472,9 +473,12 @@ public class GithubHelper { ...@@ -472,9 +473,12 @@ public class GithubHelper {
throw new IllegalStateException("Pull request should not be null when handling validation"); throw new IllegalStateException("Pull request should not be null when handling validation");
} }
LOGGER if (LOGGER.isTraceEnabled()) {
.trace("Generated access token for installation {}: {}", request.getInstallation().getId(), LOGGER
jwtHelper.getGithubAccessToken(request.getInstallation().getId()).getToken()); .trace("Generated access token for installation {}: {}", request.getInstallation().getId(),
jwtHelper.getGithubAccessToken(request.getInstallation().getId()).getToken());
}
ghApi ghApi
.updateStatus(jwtHelper.getGhBearerString(request.getInstallation().getId()), apiVersion, .updateStatus(jwtHelper.getGhBearerString(request.getInstallation().getId()), apiVersion,
request.getRepository().getOwner().getLogin(), request.getRepository().getName(), pr.getHead().getSha(), request.getRepository().getOwner().getLogin(), request.getRepository().getName(), pr.getHead().getSha(),
...@@ -499,24 +503,23 @@ public class GithubHelper { ...@@ -499,24 +503,23 @@ public class GithubHelper {
* @return List of all comments from the pull request * @return List of all comments from the pull request
*/ */
private List<GithubIssueComment> getAllPullRequestCommentsByUserId(String bearer, String apiVersion, String org, String repo, private List<GithubIssueComment> getAllPullRequestCommentsByUserId(String bearer, String apiVersion, String org, String repo,
int prNumber, int userId) { int prNumber, Long userId) {
int perPage = 100; // GitHub's maximum items per page int perPage = 100; // GitHub's maximum items per page
int page = 1; // Start from the first page int page = 1; // Start from the first page
List<GithubIssueComment> allComments = new ArrayList<>(); List<GithubIssueComment> allComments = new ArrayList<>();
// Given that there's no pagination in the response, we need to query until we get an empty response, that would mean that we've // Given that there's no pagination in the response, we need to query until we get an empty response, that would mean that we've
// reached the end // reached the end
while (true) { while (page < 50) {
RestResponse<List<GithubIssueComment>> response = ghApi RestResponse<List<GithubIssueComment>> response = ghApi.getComments(bearer, apiVersion, org, repo, prNumber, perPage, page);
.getComments(bearer, apiVersion, org, repo, prNumber, perPage, page);
List<GithubIssueComment> comments = response.getEntity(); List<GithubIssueComment> comments = response.getEntity();
if (Objects.isNull(comments) || comments.isEmpty()) { if (comments == null || comments.isEmpty()) {
break; break;
} }
// We only want the comments made by the bot user // We only want the comments made by the bot user
allComments.addAll(comments.stream().filter(comment -> comment.getUser().getId() == userId).collect(Collectors.toList())); allComments.addAll(comments.stream().filter(comment -> comment.user().id() == userId).collect(Collectors.toList()));
page++; page++;
} }
...@@ -546,17 +549,17 @@ public class GithubHelper { ...@@ -546,17 +549,17 @@ public class GithubHelper {
Set<String> nonMentionedUsers = Set.copyOf(usernames); Set<String> nonMentionedUsers = Set.copyOf(usernames);
if (botConfig.getBotId().isPresent()) { if (botConfig.id().isPresent()) {
// Get existing comments using pagination // Get existing comments using pagination
List<GithubIssueComment> comments = getAllPullRequestCommentsByUserId(ghBearerString, apiVersion, login, repositoryName, List<GithubIssueComment> comments = getAllPullRequestCommentsByUserId(ghBearerString, apiVersion, login, repositoryName,
pullRequestNumber, botConfig.getBotId().get()); pullRequestNumber, botConfig.id().get());
nonMentionedUsers = usernames nonMentionedUsers = usernames
.stream() .stream()
.filter(username -> comments .filter(username -> comments
.stream() .stream()
.noneMatch( .noneMatch(
comment -> Objects.requireNonNullElse(comment.getBody(), "").contains(String.format("@%s", username)))) comment -> Objects.requireNonNullElse(comment.body(), "").contains(String.format("@%s", username))))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
...@@ -566,18 +569,20 @@ public class GithubHelper { ...@@ -566,18 +569,20 @@ public class GithubHelper {
return; return;
} }
GithubIssueCommentRequest comment = GithubIssueCommentRequest GithubIssueCommentRequest comment = GithubIssueCommentRequestBuilder
.builder() .builder()
.setBody(failureMessage.data("reasons", errors).data("usernames", nonMentionedUsers).render()) .body(failureMessage.data("reasons", errors).data("usernames", nonMentionedUsers).render())
.build(); .build();
LOGGER if (LOGGER.isTraceEnabled()) {
.trace("Generated access token for installation {}: {}", request.getInstallation().getId(), LOGGER
jwtHelper.getGithubAccessToken(request.getInstallation().getId()).getToken()); .trace("Generated access token for installation {}: {}", request.getInstallation().getId(),
jwtHelper.getGithubAccessToken(request.getInstallation().getId()).getToken());
}
LOGGER LOGGER
.trace("Adding new comment to PR {} in repo {}/{}: {}", pullRequestNumber, TransformationHelper.formatLog(login), .trace("Adding new comment to PR {} in repo {}/{}: {}", pullRequestNumber, TransformationHelper.formatLog(login),
TransformationHelper.formatLog(repositoryName), comment.getBody()); TransformationHelper.formatLog(repositoryName), comment.body());
ghApi.addComment(ghBearerString, apiVersion, login, repositoryName, pullRequestNumber, comment); ghApi.addComment(ghBearerString, apiVersion, login, repositoryName, pullRequestNumber, comment);
} }
......
...@@ -301,7 +301,7 @@ class GithubHelperTest { ...@@ -301,7 +301,7 @@ class GithubHelperTest {
// Get the comments and verify content // Get the comments and verify content
List<GithubIssueComment> comments = ghApi.getComments("", "", orgName, repoName, prNumber, 30, 1).getEntity(); List<GithubIssueComment> comments = ghApi.getComments("", "", orgName, repoName, prNumber, 30, 1).getEntity();
assertEquals(1, comments.stream().filter(comment -> comment.getBody().equals(expectedBody)).toList().size(), assertEquals(1, comments.stream().filter(comment -> comment.body().equals(expectedBody)).toList().size(),
"Expected one comment with the expected body"); "Expected one comment with the expected body");
} }
......
...@@ -30,6 +30,8 @@ import org.eclipsefoundation.git.eca.api.models.GithubCommit.GitCommitUser; ...@@ -30,6 +30,8 @@ import org.eclipsefoundation.git.eca.api.models.GithubCommit.GitCommitUser;
import org.eclipsefoundation.git.eca.api.models.GithubCommit.GithubCommitUser; import org.eclipsefoundation.git.eca.api.models.GithubCommit.GithubCommitUser;
import org.eclipsefoundation.git.eca.api.models.GithubCommitStatusRequest; import org.eclipsefoundation.git.eca.api.models.GithubCommitStatusRequest;
import org.eclipsefoundation.git.eca.api.models.GithubIssueComment; import org.eclipsefoundation.git.eca.api.models.GithubIssueComment;
import org.eclipsefoundation.git.eca.api.models.GithubIssueCommentBuilder;
import org.eclipsefoundation.git.eca.api.models.GithubIssueCommentGithubUserBuilder;
import org.eclipsefoundation.git.eca.api.models.GithubIssueCommentRequest; import org.eclipsefoundation.git.eca.api.models.GithubIssueCommentRequest;
import org.eclipsefoundation.git.eca.api.models.GithubWebhookRequest.PullRequest; import org.eclipsefoundation.git.eca.api.models.GithubWebhookRequest.PullRequest;
import org.eclipsefoundation.git.eca.config.GithubBotConfig; import org.eclipsefoundation.git.eca.config.GithubBotConfig;
...@@ -139,11 +141,10 @@ public class MockGithubAPI implements GithubAPI { ...@@ -139,11 +141,10 @@ public class MockGithubAPI implements GithubAPI {
public Response addComment(String bearer, String apiVersion, String organization, String repo, int issueNumber, public Response addComment(String bearer, String apiVersion, String organization, String repo, int issueNumber,
GithubIssueCommentRequest commentRequest) { GithubIssueCommentRequest commentRequest) {
String repoFullName = organization + '/' + repo; String repoFullName = organization + '/' + repo;
GithubIssueComment comment = GithubIssueComment GithubIssueComment comment = GithubIssueCommentBuilder.builder()
.builder() .id(0L)
.setId(Long.valueOf(0)) .body(commentRequest.body())
.setBody(commentRequest.getBody()) .user(GithubIssueCommentGithubUserBuilder.builder().id(githubBotConfig.id().orElse(0L)).build())
.setUser(GithubIssueComment.GithubUser.builder().setId(Long.valueOf(githubBotConfig.getBotId().orElse(0))).build())
.build(); .build();
comments.computeIfAbsent(repoFullName, k -> new HashMap<>()).computeIfAbsent(issueNumber, k -> new ArrayList<>()).add(comment); comments.computeIfAbsent(repoFullName, k -> new HashMap<>()).computeIfAbsent(issueNumber, k -> new ArrayList<>()).add(comment);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment