diff --git a/deployment/pom.xml b/deployment/pom.xml
index 3779ec1..b74ee10 100644
--- a/deployment/pom.xml
+++ b/deployment/pom.xml
@@ -21,6 +21,12 @@
quarkus-github-api
${project.version}
+
+
+ org.assertj
+ assertj-core
+ test
+
diff --git a/deployment/src/main/java/io/quarkiverse/githubapi/deployment/GitHubApiDotNames.java b/deployment/src/main/java/io/quarkiverse/githubapi/deployment/GitHubApiDotNames.java
index f405d7a..54259fa 100644
--- a/deployment/src/main/java/io/quarkiverse/githubapi/deployment/GitHubApiDotNames.java
+++ b/deployment/src/main/java/io/quarkiverse/githubapi/deployment/GitHubApiDotNames.java
@@ -6,6 +6,7 @@
import org.jboss.jandex.DotName;
import org.kohsuke.github.GHAppInstallation;
import org.kohsuke.github.GHAppInstallationToken;
+import org.kohsuke.github.GHAuthenticatedAppInstallation;
import org.kohsuke.github.GHAuthorization;
import org.kohsuke.github.GHBlob;
import org.kohsuke.github.GHBranch;
@@ -27,6 +28,7 @@
import org.kohsuke.github.GHIssue;
import org.kohsuke.github.GHIssueChanges;
import org.kohsuke.github.GHIssueEvent;
+import org.kohsuke.github.GHIssueRename;
import org.kohsuke.github.GHKey;
import org.kohsuke.github.GHLabel;
import org.kohsuke.github.GHLabelChanges;
@@ -38,6 +40,7 @@
import org.kohsuke.github.GHMembership;
import org.kohsuke.github.GHMeta;
import org.kohsuke.github.GHNotificationStream;
+import org.kohsuke.github.GHObject;
import org.kohsuke.github.GHOrganization;
import org.kohsuke.github.GHProjectsV2ItemChanges;
import org.kohsuke.github.GHPullRequest;
@@ -62,7 +65,6 @@
import org.kohsuke.github.GHWorkflowRun;
import org.kohsuke.github.GitCommit;
import org.kohsuke.github.GitUser;
-import org.kohsuke.github.PagedIterable;
final class GitHubApiDotNames {
@@ -71,7 +73,7 @@ final class GitHubApiDotNames {
private static final DotName GH_MARKETPLACE_ACCOUNT = DotName.createSimple(GHMarketplaceAccount.class.getName());
private static final DotName GH_CONTENT = DotName.createSimple(GHContent.class.getName());
private static final DotName GITHUB_INTERACTIVE_OBJECT = DotName.createSimple("org.kohsuke.github.GitHubInteractiveObject");
- private static final DotName PAGED_ITERABLE = DotName.createSimple(PagedIterable.class.getName());
+ private static final DotName GH_OBJECT = DotName.createSimple(GHObject.class.getName());
private static final DotName GH_HOOK = DotName.createSimple(GHHook.class.getName());
private static final DotName GH_REPOSITORY_TRAFFIC = DotName.createSimple(GHRepositoryTraffic.class.getName());
private static final DotName GH_REPOSITORY_TRAFFIC_DAILY_INFO = DotName
@@ -82,20 +84,27 @@ final class GitHubApiDotNames {
private static final DotName GH_COMMIT = DotName.createSimple(GHCommit.class.getName());
static final List GH_ROOT_OBJECTS = Arrays.asList(GH_EVENT_PAYLOAD, GH_MARKETPLACE_ACCOUNT, GH_CONTENT,
- GITHUB_INTERACTIVE_OBJECT,
- PAGED_ITERABLE, GH_HOOK, GH_REPOSITORY_TRAFFIC, GH_REPOSITORY_TRAFFIC_DAILY_INFO, GH_KEY, SEARCH_RESULT, GIT_USER,
+ GH_OBJECT,
+ GH_HOOK, GH_REPOSITORY_TRAFFIC, GH_REPOSITORY_TRAFFIC_DAILY_INFO, GH_KEY, SEARCH_RESULT, GIT_USER,
GH_COMMIT);
// Simple objects
private static final DotName GH_APP_INSTALLATION_GH_APP_INSTALLATION_REPOSITORY_RESULT = DotName
.createSimple(GHAppInstallation.class.getName() + "$GHAppInstallationRepositoryResult");
+ private static final DotName GH_APP_INSTALLATION_PAGE = DotName.createSimple("org.kohsuke.github.GHAppInstallationsPage");
private static final DotName GH_APP_INSTALLATION_TOKEN = DotName.createSimple(GHAppInstallationToken.class.getName());
private static final DotName GH_APP_AUTHORIZATION_APP = DotName.createSimple(GHAuthorization.class.getName() + "$App");
private static final DotName GH_ARTIFACTS_PAGE = DotName.createSimple("org.kohsuke.github.GHArtifactsPage");
+ private static final DotName GH_AUTHENTICATED_APP_INSTALLATION = DotName
+ .createSimple(GHAuthenticatedAppInstallation.class.getName());
private static final DotName GH_BLOB = DotName.createSimple(GHBlob.class.getName());
private static final DotName GH_BRANCH = DotName.createSimple(GHBranch.class.getName());
private static final DotName GH_BRANCH_COMMIT = DotName.createSimple(GHBranch.Commit.class.getName());
private static final DotName GH_BRANCH_PROTECTION = DotName.createSimple(GHBranchProtection.class.getName());
+ private static final DotName GH_BRANCH_PROTECTION_BUILDER_RESTRICTIONS = DotName
+ .createSimple("org.kohsuke.github.GHBranchProtectionBuilder$Restrictions");
+ private static final DotName GH_BRANCH_PROTECTION_BUILDER_STATUS_CHECKS = DotName
+ .createSimple("org.kohsuke.github.GHBranchProtectionBuilder$StatusChecks");
private static final DotName GH_BRANCH_PROTECTION_ENFORCE_ADMINS = DotName
.createSimple(GHBranchProtection.EnforceAdmins.class.getName());
private static final DotName GH_BRANCH_PROTECTION_REQUIRED_REVIEWS = DotName
@@ -114,6 +123,8 @@ final class GitHubApiDotNames {
private static final DotName GH_CHECK_RUN_OUTPUT = DotName.createSimple(GHCheckRun.Output.class.getName());
private static final DotName GH_CHECK_RUNS_PAGE = DotName.createSimple("org.kohsuke.github.GHCheckRunsPage");
private static final DotName GH_CHECK_SUITE_HEAD_COMMIT = DotName.createSimple(GHCheckSuite.HeadCommit.class.getName());
+ private static final DotName GH_COMMIT_BUILDER_USER_INFO = DotName
+ .createSimple("org.kohsuke.github.GHCommitBuilder$UserInfo");
private static final DotName GH_COMMIT_FILE = DotName.createSimple(GHCommit.File.class.getName());
private static final DotName GH_COMMIT_PARENT = DotName.createSimple(GHCommit.Parent.class.getName());
private static final DotName GH_COMMIT_SHORT_INFO = DotName.createSimple(GHCommit.ShortInfo.class.getName());
@@ -142,6 +153,7 @@ final class GitHubApiDotNames {
private static final DotName GH_ISSUE_CHANGES = DotName.createSimple(GHIssueChanges.class.getName());
private static final DotName GH_ISSUE_CHANGES_GH_FROM = DotName
.createSimple(GHIssueChanges.GHFrom.class.getName());
+ private static final DotName GH_ISSUE_RENAME = DotName.createSimple(GHIssueRename.class.getName());
private static final DotName GH_ISSUE_PULL_REQUEST = DotName.createSimple(GHIssue.PullRequest.class.getName());
private static final DotName GH_ISSUE_EVENT = DotName.createSimple(GHIssueEvent.class.getName());
private static final DotName GH_LABEL = DotName.createSimple(GHLabel.class.getName());
@@ -181,6 +193,8 @@ final class GitHubApiDotNames {
private static final DotName GH_PULL_REQUEST_COMMIT_DETAIL_TREE = DotName
.createSimple(GHPullRequestCommitDetail.Tree.class.getName());
private static final DotName GH_PULL_REQUEST_FILE_DETAIL = DotName.createSimple(GHPullRequestFileDetail.class.getName());
+ private static final DotName GH_PULL_REQUEST_REVIEW_BUILDER_DRAFT_REVIEW_COMMENT = DotName
+ .createSimple("org.kohsuke.github.GHPullRequestReviewBuilder$DraftReviewComment");
private static final DotName GH_RATE_LIMIT = DotName.createSimple(GHRateLimit.class.getName());
private static final DotName GH_RATE_LIMIT_RECORD = DotName.createSimple(GHRateLimit.Record.class.getName());
private static final DotName GH_RATE_LIMIT_UNKNOWN_LIMIT_RECORD = DotName
@@ -205,6 +219,8 @@ final class GitHubApiDotNames {
private static final DotName GH_TAG_OBJECT = DotName.createSimple(GHTagObject.class.getName());
private static final DotName GH_THREAD_SUBJECT = DotName.createSimple(GHThread.class.getName() + "$Subject");
private static final DotName GH_TREE = DotName.createSimple(GHTree.class.getName());
+ private static final DotName GH_TREE_BUILDER_TREE_ENTRY = DotName
+ .createSimple("org.kohsuke.github.GHTreeBuilder$TreeEntry");
private static final DotName GH_TREE_ENTRY = DotName.createSimple(GHTreeEntry.class.getName());
private static final DotName GH_VERIFICATION = DotName.createSimple(GHVerification.class.getName());
private static final DotName GH_WORKFLOW_JOB_STEP = DotName.createSimple(GHWorkflowJob.Step.class.getName());
@@ -219,15 +235,22 @@ final class GitHubApiDotNames {
private static final DotName GITHUB_RESPONSE = DotName.createSimple("org.kohsuke.github.GitHubResponse");
private static final DotName JSON_RATE_LIMIT = DotName.createSimple("org.kohsuke.github.JsonRateLimit");
- static final List GH_SIMPLE_OBJECTS = Arrays.asList(GH_APP_INSTALLATION_GH_APP_INSTALLATION_REPOSITORY_RESULT,
- GH_APP_INSTALLATION_TOKEN, GH_APP_AUTHORIZATION_APP, GH_ARTIFACTS_PAGE, GH_BLOB,
+ static final List GH_SIMPLE_OBJECTS = Arrays.asList(
+ GITHUB_INTERACTIVE_OBJECT, // Must be registered for reflection, but not all of its subclasses.
+ GH_APP_INSTALLATION_GH_APP_INSTALLATION_REPOSITORY_RESULT,
+ GH_APP_INSTALLATION_PAGE,
+ GH_APP_INSTALLATION_TOKEN, GH_APP_AUTHORIZATION_APP, GH_ARTIFACTS_PAGE,
+ GH_AUTHENTICATED_APP_INSTALLATION, GH_BLOB,
GH_BRANCH,
- GH_BRANCH_COMMIT, GH_BRANCH_PROTECTION, GH_BRANCH_PROTECTION_ENFORCE_ADMINS, GH_BRANCH_PROTECTION_REQUIRED_REVIEWS,
+ GH_BRANCH_COMMIT, GH_BRANCH_PROTECTION, GH_BRANCH_PROTECTION_BUILDER_RESTRICTIONS,
+ GH_BRANCH_PROTECTION_BUILDER_STATUS_CHECKS,
+ GH_BRANCH_PROTECTION_ENFORCE_ADMINS, GH_BRANCH_PROTECTION_REQUIRED_REVIEWS,
GH_BRANCH_PROTECTION_REQUIRED_SIGNATURES, GH_BRANCH_PROTECTION_REQUIRED_STATUS_CHECKS,
GH_BRANCH_PROTECTION_RESTRICTIONS,
GH_CHECK_RUN_BUILDER_ACTION, GH_CHECK_RUN_BUILDER_ANNOTATION, GH_CHECK_RUN_BUILDER_IMAGE,
GH_CHECK_RUN_BUILDER_OUTPUT,
GH_CHECK_RUN_OUTPUT, GH_CHECK_RUNS_PAGE, GH_CHECK_SUITE_HEAD_COMMIT,
+ GH_COMMIT_BUILDER_USER_INFO,
GH_COMMIT_FILE, GH_COMMIT_PARENT, GH_COMMIT_SHORT_INFO,
GH_COMMIT_STATS, GH_COMMIT_TREE, GH_COMMIT_USER,
GH_COMMIT_POINTER, GH_COMPARE, GH_COMPARE_INNER_COMMIT, GH_COMPARE_TREE, GH_CONTENT_UPDATE_RESPONSE,
@@ -236,7 +259,7 @@ final class GitHubApiDotNames {
GH_EVENT_PAYLOAD_COMMENT_CHANGES, GH_EVENT_PAYLOAD_COMMENT_CHANGES_GH_FROM,
GH_EVENT_PAYLOAD_PUSH_PUSHER, GH_EVENT_PAYLOAD_PUSH_PUSH_COMMIT,
GH_GIST_FILE, GH_ISSUE_CHANGES, GH_ISSUE_CHANGES_GH_FROM,
- GH_ISSUE_PULL_REQUEST, GH_ISSUE_EVENT,
+ GH_ISSUE_RENAME, GH_ISSUE_PULL_REQUEST, GH_ISSUE_EVENT,
GH_LABEL, GH_LABEL_CHANGES, GH_LABEL_CHANGES_GH_FROM,
GH_MARKETPLACE_PENDING_CHANGE, GH_MARKETPLACE_PLAN,
GH_MARKETPLACE_PURCHASE, GH_MARKETPLACE_USER_PURCHASE, GH_MEMBERSHIP, GH_META, GH_NOTIFICATION_STREAM,
@@ -247,11 +270,12 @@ final class GitHubApiDotNames {
GH_PULL_REQUEST_CHANGES_GH_COMMIT_POINTER,
GH_PULL_REQUEST_COMMIT_DETAIL, GH_PULL_REQUEST_COMMIT_DETAIL_COMMIT,
GH_PULL_REQUEST_COMMIT_DETAIL_COMMIT_POINTER, GH_PULL_REQUEST_COMMIT_DETAIL_TREE,
- GH_PULL_REQUEST_FILE_DETAIL, GH_RATE_LIMIT, GH_RATE_LIMIT_RECORD, GH_RATE_LIMIT_UNKNOWN_LIMIT_RECORD, GH_REF,
+ GH_PULL_REQUEST_FILE_DETAIL, GH_PULL_REQUEST_REVIEW_BUILDER_DRAFT_REVIEW_COMMENT,
+ GH_RATE_LIMIT, GH_RATE_LIMIT_RECORD, GH_RATE_LIMIT_UNKNOWN_LIMIT_RECORD, GH_REF,
GH_REF_GH_OBJECT, GH_REPOSITORY_DISCUSSION_CATEGORY, GH_REPOSITORY_GH_REPO_PERMISSION, GH_REPOSITORY_TOPICS,
GH_REPOSITORY_STATISTICS, GH_REPOSITORY_STATISTICS_CONTRIBUTOR_STATS_WEEK, GH_REPOSITORY_STATISTICS_CODE_FREQUENCY,
GH_REPOSITORY_STATISTICS_PUNCH_CARD_ITEM, GH_STARGAZER, GH_SUBSCRIPTION, GH_TAG, GH_TAG_OBJECT, GH_THREAD_SUBJECT,
- GH_TREE, GH_TREE_ENTRY, GH_VERIFICATION,
+ GH_TREE, GH_TREE_BUILDER_TREE_ENTRY, GH_TREE_ENTRY, GH_VERIFICATION,
GH_WORKFLOW_JOB_STEP, GH_WORKFLOW_JOBS_PAGE, GH_WORKFLOW_RUN_HEAD_COMMIT, GH_WORKFLOW_RUNS_PAGE, GH_WORKFLOWS_PAGE,
GIT_COMMIT, GIT_COMMIT_TREE,
GITHUB_REQUEST, GITHUB_REQUEST_ENTRY, GITHUB_RESPONSE,
diff --git a/deployment/src/test/java/io/quarkiverse/githubapi/deployment/GitHubApiDotNamesTest.java b/deployment/src/test/java/io/quarkiverse/githubapi/deployment/GitHubApiDotNamesTest.java
new file mode 100644
index 0000000..e845d1c
--- /dev/null
+++ b/deployment/src/test/java/io/quarkiverse/githubapi/deployment/GitHubApiDotNamesTest.java
@@ -0,0 +1,140 @@
+package io.quarkiverse.githubapi.deployment;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import org.jboss.jandex.ClassInfo;
+import org.jboss.jandex.DotName;
+import org.jboss.jandex.Index;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.kohsuke.github.GitHub;
+
+import io.quarkus.deployment.index.IndexingUtil;
+
+class GitHubApiDotNamesTest {
+
+ // These types will be expected NOT to be registered for reflection, as well as their subtypes.
+ // Their inner types, however, won't be affected by the exclusion.
+ // Useful for "helper" types, such as clients, or builders in all but name.
+ private static final Set EXCLUDED_TYPES = Set.of(
+ "org.kohsuke.github.AbuseLimitHandler",
+ "org.kohsuke.github.GHDiscussion$Creator",
+ "org.kohsuke.github.GHDiscussion$Setter",
+ "org.kohsuke.github.GHDiscussion$Updater",
+ "org.kohsuke.github.GHException",
+ "org.kohsuke.github.GHFileNotFoundException",
+ "org.kohsuke.github.GHGistUpdater",
+ "org.kohsuke.github.GHHooks",
+ "org.kohsuke.github.GHHooks$Context",
+ "org.kohsuke.github.GHHooks$OrgContext",
+ "org.kohsuke.github.GHHooks$RepoContext",
+ "org.kohsuke.github.GHIOException",
+ "org.kohsuke.github.GHPersonSet",
+ "org.kohsuke.github.GHReleaseUpdater",
+ "org.kohsuke.github.GitHub",
+ "org.kohsuke.github.GitHub$DependentAuthorizationProvider",
+ "org.kohsuke.github.GitHub$LoginLoadingUserAuthorizationProvider",
+ "org.kohsuke.github.GitHubAbuseLimitHandler",
+ "org.kohsuke.github.GitHubClient",
+ "org.kohsuke.github.GitHubClient$BodyHandler",
+ "org.kohsuke.github.GitHubClient$GHApiInfo",
+ "org.kohsuke.github.GitHubClient$RetryRequestException",
+ "org.kohsuke.github.GitHubConnectorResponseErrorHandler",
+ "org.kohsuke.github.GitHubPageIterator",
+ "org.kohsuke.github.GitHubRateLimitChecker",
+ "org.kohsuke.github.GitHubRateLimitHandler",
+ "org.kohsuke.github.HttpConnector",
+ "org.kohsuke.github.HttpException",
+ "org.kohsuke.github.PagedIterator",
+ "org.kohsuke.github.RateLimitChecker",
+ "org.kohsuke.github.RateLimitHandler",
+ "org.kohsuke.github.Reactable",
+ "org.kohsuke.github.Refreshable",
+ "org.kohsuke.github.Requester",
+ "org.kohsuke.github.TrafficInfo",
+ "org.kohsuke.github.authorization",
+ "org.kohsuke.github.connector",
+ "org.kohsuke.github.example.dataobject",
+ "org.kohsuke.github.extras",
+ "org.kohsuke.github.extras.authorization",
+ "org.kohsuke.github.extras.okhttp3",
+ "org.kohsuke.github.function",
+ "org.kohsuke.github.internal");
+
+ private static Index ghApiIndex;
+
+ @BeforeAll
+ public static void index() throws IOException {
+ ghApiIndex = IndexingUtil.indexJar(determineJarLocation(GitHub.class, "github-api"));
+ }
+
+ @Test
+ public void testNoMissingGitHubClasses() {
+ Set expectedClasses = new TreeSet<>();
+ for (ClassInfo clazz : ghApiIndex.getKnownClasses()) {
+ if (shouldBeRegisteredForReflection(clazz)) {
+ expectedClasses.add(clazz.name());
+ }
+ }
+
+ // Simulate what happens when we create build items to register classes for reflection
+ Set actualClasses = new TreeSet<>();
+ actualClasses.addAll(GitHubApiDotNames.GH_SIMPLE_OBJECTS);
+ for (DotName clazz : GitHubApiDotNames.GH_ROOT_OBJECTS) {
+ actualClasses.add(clazz);
+ actualClasses.addAll(ghApiIndex.getAllKnownSubclasses(clazz).stream()
+ .map(ClassInfo::name).collect(Collectors.toList()));
+ }
+
+ // No idea why this appears in the result, since the class doesn't event exist;
+ // that's probably a bug in Jandex?
+ actualClasses.remove(DotName.createSimple("org.kohsuke.github.GHCommit$ShortInfo$Tree"));
+
+ assertThat(expectedClasses).isNotEmpty();
+ assertThat(actualClasses).containsExactlyInAnyOrderElementsOf(expectedClasses);
+ }
+
+ private boolean shouldBeRegisteredForReflection(ClassInfo clazz) {
+ return !clazz.isAnnotation() && !clazz.isEnum() && !clazz.isSynthetic()
+ && !ClassInfo.NestingType.ANONYMOUS.equals(clazz.nestingType())
+ && !ClassInfo.NestingType.LOCAL.equals(clazz.nestingType())
+ && !isExcluded(clazz);
+ }
+
+ private boolean isExcluded(ClassInfo clazz) {
+ if (clazz.simpleName().endsWith("Builder") || clazz.simpleName().endsWith("PagedIterable")) {
+ return true;
+ }
+ if (EXCLUDED_TYPES.contains(clazz.name().toString())
+ || EXCLUDED_TYPES.contains(clazz.name().packagePrefix())) {
+ return true;
+ }
+ var superClass = ghApiIndex.getClassByName(clazz.superName());
+ if (superClass != null) {
+ return isExcluded(superClass);
+ }
+ return false;
+ }
+
+ private static Path determineJarLocation(Class> classFromJar, String jarName) {
+ URL url = classFromJar.getProtectionDomain().getCodeSource().getLocation();
+ if (!url.getProtocol().equals("file")) {
+ throw new IllegalStateException(jarName + " JAR is not a local file? " + url);
+ }
+ try {
+ return Paths.get(url.toURI());
+ } catch (URISyntaxException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 7cb27d2..2cc9151 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,6 +26,7 @@
3.0.0-M7
1.313
+ 3.23.1
@@ -49,6 +50,11 @@
github-api
${github-api.version}
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+