Skip to content

Commit

Permalink
Use the "search issues" API instead of the "query issues" API
Browse files Browse the repository at this point in the history
Because it's (much) more flexible.
  • Loading branch information
yrodiere committed Dec 9, 2024
1 parent 713bee0 commit 373801a
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 283 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.kohsuke.github.GHIssueComment;
import org.kohsuke.github.GHIssueCommentQueryBuilder;
import org.kohsuke.github.GHIssueEvent;
import org.kohsuke.github.GHIssueQueryBuilder;
import org.kohsuke.github.GHIssueSearchBuilder;
import org.kohsuke.github.GHIssueState;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GHUser;
Expand Down Expand Up @@ -94,6 +94,12 @@ private GHRepository repository() throws IOException {
return repository;
}

private GHIssueSearchBuilder searchIssues() {
return client().searchIssues()
.q(GitHubSearchClauses.repo(ref))
.q(GitHubSearchClauses.isIssue());
}

private DynamicGraphQLClient graphQLClient() {
if (graphQLClient == null) {
graphQLClient = clientProvider.getInstallationGraphQLClient(ref.installationRef().installationId());
Expand All @@ -111,17 +117,15 @@ public Optional<LotteryConfig> fetchLotteryConfig() throws IOException {
*
* @param updatedBefore An instant; all returned issues must have been last updated before that instant.
* @return A lazily populated stream of matching issues.
* @throws IOException In case of I/O failure.
* @throws java.io.UncheckedIOException In case of I/O failure.
*/
public Stream<Issue> issuesLastUpdatedBefore(Instant updatedBefore) throws IOException {
return toStream(repository().queryIssues()
.state(GHIssueState.OPEN)
.sort(GHIssueQueryBuilder.Sort.UPDATED)
.direction(GHDirection.DESC)
public Stream<Issue> issuesLastUpdatedBefore(Instant updatedBefore) {
return toStream(searchIssues()
.isOpen()
.q(GitHubSearchClauses.updatedBefore(updatedBefore))
.sort(GHIssueSearchBuilder.Sort.UPDATED)
.order(GHDirection.DESC)
.list())
.filter(notPullRequest())
.filter(updatedBefore(updatedBefore))
.map(toIssueRecord());
}

Expand All @@ -131,17 +135,16 @@ public Stream<Issue> issuesLastUpdatedBefore(Instant updatedBefore) throws IOExc
* @param label A GitHub label; if non-null, all returned issues must have been assigned that label.
* @param updatedBefore An instant; all returned issues must have been last updated before that instant.
* @return A lazily populated stream of matching issues.
* @throws IOException In case of I/O failure.
* @throws java.io.UncheckedIOException In case of I/O failure.
*/
public Stream<Issue> issuesWithLabelLastUpdatedBefore(String label, Instant updatedBefore) throws IOException {
return toStream(repository().queryIssues().label(label)
.state(GHIssueState.OPEN)
.sort(GHIssueQueryBuilder.Sort.UPDATED)
.direction(GHDirection.DESC)
public Stream<Issue> issuesWithLabelLastUpdatedBefore(String label, Instant updatedBefore) {
return toStream(searchIssues()
.isOpen()
.q(GitHubSearchClauses.label(label))
.q(GitHubSearchClauses.updatedBefore(updatedBefore))
.sort(GHIssueSearchBuilder.Sort.UPDATED)
.order(GHDirection.DESC)
.list())
.filter(notPullRequest())
.filter(updatedBefore(updatedBefore))
.map(toIssueRecord());
}

Expand All @@ -155,35 +158,21 @@ public Stream<Issue> issuesWithLabelLastUpdatedBefore(String label, Instant upda
* This label is not relevant to determining the last action.
* @param updatedBefore An instant; all returned issues must have been last updated before that instant.
* @return A lazily populated stream of matching issues.
* @throws IOException In case of I/O failure.
* @throws java.io.UncheckedIOException In case of I/O failure.
*/
public Stream<Issue> issuesLastActedOnByAndLastUpdatedBefore(Set<String> initialActionLabels, String filterLabel,
IssueActionSide lastActionSide, Instant updatedBefore) throws IOException {
var theRepository = repository();
var streams = initialActionLabels.stream()
.map(initialActionLabel -> toStream(theRepository.queryIssues()
.label(initialActionLabel)
.label(filterLabel)
.state(GHIssueState.OPEN)
.sort(GHIssueQueryBuilder.Sort.UPDATED)
.direction(GHDirection.DESC)
.list())
.filter(notPullRequest())
.filter(updatedBefore(updatedBefore))
.filter(uncheckedIO((GHIssue ghIssue) -> lastActionSide
.equals(lastActionSide(ghIssue, initialActionLabels)))::apply)
.map(toIssueRecord()))
.toList();
return Streams.interleave(streams);
}

private Predicate<GHIssue> updatedBefore(Instant updatedBefore) {
return uncheckedIO((GHIssue ghIssue) -> ghIssue.getUpdatedAt().toInstant().isBefore(updatedBefore))::apply;
}

private Predicate<GHIssue> notPullRequest() {
return (GHIssue ghIssue) -> !ghIssue.isPullRequest();
IssueActionSide lastActionSide, Instant updatedBefore) {
return toStream(searchIssues()
.isOpen()
.q(GitHubSearchClauses.anyLabel(initialActionLabels))
.q(GitHubSearchClauses.label(filterLabel))
.q(GitHubSearchClauses.updatedBefore(updatedBefore))
.sort(GHIssueSearchBuilder.Sort.UPDATED)
.order(GHDirection.DESC)
.list())
.filter(uncheckedIO((GHIssue ghIssue) -> lastActionSide
.equals(lastActionSide(ghIssue, initialActionLabels)))::apply)
.map(toIssueRecord());
}

private IssueActionSide lastActionSide(GHIssue ghIssue, Set<String> initialActionLabels) throws IOException {
Expand Down Expand Up @@ -312,12 +301,12 @@ public void comment(String topicSuffix, String markdownBody)
}

private Stream<GHIssue> getDedicatedIssues() throws IOException {
var builder = repository().queryIssues().creator(appLogin());
var builder = searchIssues()
.q(GitHubSearchClauses.author(appLogin()));
if (ref.assignee() != null) {
builder.assignee(ref.assignee());
builder.q(GitHubSearchClauses.assignee(ref.assignee()));
}
builder.state(GHIssueState.ALL);
return Streams.toStream(builder.list())
return toStream(builder.list())
.filter(ref.expectedSuffixStart() != null
? issue -> issue.getTitle().startsWith(ref.topic() + ref.expectedSuffixStart())
// Try exact match in this case to avoid confusion if there are two issues and one is
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.quarkus.github.lottery.github;

import java.time.Instant;
import java.time.ZoneOffset;
import java.util.Set;

public final class GitHubSearchClauses {

private GitHubSearchClauses() {
}

public static String repo(GitHubRepositoryRef ref) {
return "repo:" + ref.repositoryName();
}

public static String isIssue() {
return "is:issue";
}

public static String anyLabel(Set<String> labels) {
return label(String.join(",", labels));
}

public static String label(String label) {
return "label:" + label;
}

public static String updatedBefore(Instant updatedBefore) {
return "updated:<" + updatedBefore.atOffset(ZoneOffset.UTC).toLocalDateTime().toString();
}

public static String author(String author) {
return "author:" + author;
}

public static String assignee(String assignee) {
return "assignee:" + assignee;
}
}
1 change: 1 addition & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ quarkus.info.enabled=true
%dev.quarkus.scheduler.enabled=false
%dev.quarkus.log.min-level=TRACE
%dev.quarkus.log.category."io.quarkus.github.lottery".level=TRACE
%dev.quarkus.log.category."org.kohsuke.github.GitHubClient".level=TRACE

%prod.quarkus.openshift.labels."app"=quarkus-github-lottery
# Renew the SSL certificate automatically
Expand Down
Loading

0 comments on commit 373801a

Please sign in to comment.