diff --git a/src/main/java/org/kohsuke/github/GHCodeownersError.java b/src/main/java/org/kohsuke/github/GHCodeownersError.java
new file mode 100644
index 0000000000..8d5662700c
--- /dev/null
+++ b/src/main/java/org/kohsuke/github/GHCodeownersError.java
@@ -0,0 +1,77 @@
+package org.kohsuke.github;
+
+/**
+ * Represents an error in a {@code CODEOWNERS} file. See the
+ * relevant documentation.
+ *
+ * @author Michael Grant
+ */
+public class GHCodeownersError {
+ private int line, column;
+
+ private String kind, source, suggestion, message, path;
+
+ /**
+ * Gets line.
+ *
+ * @return the line
+ */
+ public int getLine() {
+ return line;
+ }
+
+ /**
+ * Gets column.
+ *
+ * @return the column
+ */
+ public int getColumn() {
+ return column;
+ }
+
+ /**
+ * Gets kind.
+ *
+ * @return the kind
+ */
+ public String getKind() {
+ return kind;
+ }
+
+ /**
+ * Gets source.
+ *
+ * @return the source
+ */
+ public String getSource() {
+ return source;
+ }
+
+ /**
+ * Gets suggestion.
+ *
+ * @return the suggestion
+ */
+ public String getSuggestion() {
+ return suggestion;
+ }
+
+ /**
+ * Gets message.
+ *
+ * @return the message
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * Gets path.
+ *
+ * @return the path
+ */
+ public String getPath() {
+ return path;
+ }
+}
diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java
index da6658fee2..5220a1b80b 100644
--- a/src/main/java/org/kohsuke/github/GHRepository.java
+++ b/src/main/java/org/kohsuke/github/GHRepository.java
@@ -2956,6 +2956,25 @@ public GHSubscription getSubscription() throws IOException {
}
}
+ // Only used within listCodeownersErrors().
+ private static class GHCodeownersErrors {
+ public List errors;
+ }
+
+ /**
+ * List errors in the {@code CODEOWNERS} file. Note that GitHub skips lines with incorrect syntax; these are
+ * reported in the web interface, but not in the API call which this library uses.
+ *
+ * @return the list of errors
+ * @throws IOException
+ * the io exception
+ */
+ public List listCodeownersErrors() throws IOException {
+ return root().createRequest()
+ .withUrlPath(getApiTailUrl("codeowners/errors"))
+ .fetch(GHCodeownersErrors.class).errors;
+ }
+
/**
* List contributors paged iterable.
*
diff --git a/src/test/java/org/kohsuke/github/GHCodeownersErrorTest.java b/src/test/java/org/kohsuke/github/GHCodeownersErrorTest.java
new file mode 100644
index 0000000000..b4294be64e
--- /dev/null
+++ b/src/test/java/org/kohsuke/github/GHCodeownersErrorTest.java
@@ -0,0 +1,55 @@
+package org.kohsuke.github;
+
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.hamcrest.Matchers.*;
+
+/**
+ * Test class for listing errors in CODEOWNERS files.
+ *
+ * @author Michael Grant
+ */
+public class GHCodeownersErrorTest extends AbstractGitHubWireMockTest {
+
+ /**
+ * Gets the {@code CODEOWNERS} errors.
+ *
+ * @throws IOException
+ * the exception
+ */
+ @Test
+ public void testGetCodeownersErrors() throws IOException {
+ final GHRepository repo = getRepository(gitHub);
+ final List codeownersErrors = repo.listCodeownersErrors();
+ assertThat(codeownersErrors.size(), is(1));
+ final GHCodeownersError firstError = codeownersErrors.get(0);
+ assertThat(firstError.getLine(), is(1));
+ assertThat(firstError.getColumn(), is(3));
+ assertThat(firstError.getKind(), is("Unknown owner"));
+ assertThat(firstError.getSource(),
+ is("* @nonexistent-user # Deliberate error to test response to repo.listCodeownersErrors()\n"));
+ assertThat(firstError.getSuggestion(),
+ is("make sure @nonexistent-user exists and has write access to the repository"));
+ assertThat(firstError.getMessage(),
+ is("Unknown owner on line 1: make sure @nonexistent-user exists and has write access to the repository\n\n * @nonexistent-user # Deliberate error to test response to repo.listCodeownersErrors()\n ^"));
+ assertThat(firstError.getPath(), is(".github/CODEOWNERS"));
+ }
+
+ /**
+ * Gets the repository.
+ *
+ * @return the repository
+ * @throws IOException
+ * Signals that an I/O exception has occurred.
+ */
+ protected GHRepository getRepository() throws IOException {
+ return getRepository(gitHub);
+ }
+
+ private GHRepository getRepository(GitHub gitHub) throws IOException {
+ return gitHub.getOrganization(GITHUB_API_TEST_ORG).getRepository("github-api");
+ }
+}
diff --git a/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/__files/orgs_hub4j-test-org-1.json b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/__files/orgs_hub4j-test-org-1.json
new file mode 100644
index 0000000000..3fee6b6ffd
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/__files/orgs_hub4j-test-org-1.json
@@ -0,0 +1,31 @@
+{
+ "login": "hub4j-test-org",
+ "id": 7544739,
+ "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
+ "url": "https://api.github.com/orgs/hub4j-test-org",
+ "repos_url": "https://api.github.com/orgs/hub4j-test-org/repos",
+ "events_url": "https://api.github.com/orgs/hub4j-test-org/events",
+ "hooks_url": "https://api.github.com/orgs/hub4j-test-org/hooks",
+ "issues_url": "https://api.github.com/orgs/hub4j-test-org/issues",
+ "members_url": "https://api.github.com/orgs/hub4j-test-org/members{/member}",
+ "public_members_url": "https://api.github.com/orgs/hub4j-test-org/public_members{/member}",
+ "avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
+ "description": "Hub4j Test Org Description (this could be null or blank too)",
+ "name": "Hub4j Test Org Name (this could be null or blank too)",
+ "company": null,
+ "blog": "https://hub4j.url.io/could/be/null",
+ "location": "Hub4j Test Org Location (this could be null or blank too)",
+ "email": "hub4jtestorgemail@could.be.null.com",
+ "twitter_username": null,
+ "is_verified": false,
+ "has_organization_projects": true,
+ "has_repository_projects": true,
+ "public_repos": 54,
+ "public_gists": 0,
+ "followers": 1,
+ "following": 0,
+ "html_url": "https://github.com/hub4j-test-org",
+ "created_at": "2014-05-10T19:39:11Z",
+ "updated_at": "2020-06-04T05:56:10Z",
+ "type": "Organization"
+}
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/__files/repos_hub4j-test-org_github-api-2.json b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/__files/repos_hub4j-test-org_github-api-2.json
new file mode 100644
index 0000000000..bf61dfac64
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/__files/repos_hub4j-test-org_github-api-2.json
@@ -0,0 +1,357 @@
+{
+ "id": 206888201,
+ "node_id": "MDEwOlJlcG9zaXRvcnkyMDY4ODgyMDE=",
+ "name": "github-api",
+ "full_name": "hub4j-test-org/github-api",
+ "private": false,
+ "owner": {
+ "login": "hub4j-test-org",
+ "id": 7544739,
+ "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
+ "avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/hub4j-test-org",
+ "html_url": "https://github.com/hub4j-test-org",
+ "followers_url": "https://api.github.com/users/hub4j-test-org/followers",
+ "following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
+ "gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
+ "organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
+ "repos_url": "https://api.github.com/users/hub4j-test-org/repos",
+ "events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
+ "type": "Organization",
+ "site_admin": false
+ },
+ "html_url": "https://github.com/hub4j-test-org/github-api",
+ "description": "Tricky",
+ "fork": true,
+ "url": "https://api.github.com/repos/hub4j-test-org/github-api",
+ "forks_url": "https://api.github.com/repos/hub4j-test-org/github-api/forks",
+ "keys_url": "https://api.github.com/repos/hub4j-test-org/github-api/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/hub4j-test-org/github-api/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/hub4j-test-org/github-api/teams",
+ "hooks_url": "https://api.github.com/repos/hub4j-test-org/github-api/hooks",
+ "issue_events_url": "https://api.github.com/repos/hub4j-test-org/github-api/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/hub4j-test-org/github-api/events",
+ "assignees_url": "https://api.github.com/repos/hub4j-test-org/github-api/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/hub4j-test-org/github-api/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/hub4j-test-org/github-api/tags",
+ "blobs_url": "https://api.github.com/repos/hub4j-test-org/github-api/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/hub4j-test-org/github-api/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/hub4j-test-org/github-api/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/hub4j-test-org/github-api/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/hub4j-test-org/github-api/languages",
+ "stargazers_url": "https://api.github.com/repos/hub4j-test-org/github-api/stargazers",
+ "contributors_url": "https://api.github.com/repos/hub4j-test-org/github-api/contributors",
+ "subscribers_url": "https://api.github.com/repos/hub4j-test-org/github-api/subscribers",
+ "subscription_url": "https://api.github.com/repos/hub4j-test-org/github-api/subscription",
+ "commits_url": "https://api.github.com/repos/hub4j-test-org/github-api/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/hub4j-test-org/github-api/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/hub4j-test-org/github-api/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/hub4j-test-org/github-api/issues/comments{/number}",
+ "contents_url": "https://api.github.com/repos/hub4j-test-org/github-api/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/hub4j-test-org/github-api/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/hub4j-test-org/github-api/merges",
+ "archive_url": "https://api.github.com/repos/hub4j-test-org/github-api/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/hub4j-test-org/github-api/downloads",
+ "issues_url": "https://api.github.com/repos/hub4j-test-org/github-api/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/hub4j-test-org/github-api/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/hub4j-test-org/github-api/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/hub4j-test-org/github-api/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/hub4j-test-org/github-api/labels{/name}",
+ "releases_url": "https://api.github.com/repos/hub4j-test-org/github-api/releases{/id}",
+ "deployments_url": "https://api.github.com/repos/hub4j-test-org/github-api/deployments",
+ "created_at": "2019-09-06T23:26:04Z",
+ "updated_at": "2023-01-31T10:03:44Z",
+ "pushed_at": "2023-02-01T12:37:22Z",
+ "git_url": "git://github.com/hub4j-test-org/github-api.git",
+ "ssh_url": "git@github.com:hub4j-test-org/github-api.git",
+ "clone_url": "https://github.com/hub4j-test-org/github-api.git",
+ "svn_url": "https://github.com/hub4j-test-org/github-api",
+ "homepage": "http://github-api.kohsuke.org/",
+ "size": 18977,
+ "stargazers_count": 1,
+ "watchers_count": 1,
+ "language": "Java",
+ "has_issues": true,
+ "has_projects": true,
+ "has_downloads": true,
+ "has_wiki": true,
+ "has_pages": false,
+ "has_discussions": false,
+ "forks_count": 0,
+ "mirror_url": null,
+ "archived": false,
+ "disabled": false,
+ "open_issues_count": 7,
+ "license": {
+ "key": "mit",
+ "name": "MIT License",
+ "spdx_id": "MIT",
+ "url": "https://api.github.com/licenses/mit",
+ "node_id": "MDc6TGljZW5zZTEz"
+ },
+ "allow_forking": true,
+ "is_template": false,
+ "web_commit_signoff_required": false,
+ "topics": [],
+ "visibility": "public",
+ "forks": 0,
+ "open_issues": 7,
+ "watchers": 1,
+ "default_branch": "main",
+ "temp_clone_token": null,
+ "organization": {
+ "login": "hub4j-test-org",
+ "id": 7544739,
+ "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
+ "avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/hub4j-test-org",
+ "html_url": "https://github.com/hub4j-test-org",
+ "followers_url": "https://api.github.com/users/hub4j-test-org/followers",
+ "following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
+ "gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
+ "organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
+ "repos_url": "https://api.github.com/users/hub4j-test-org/repos",
+ "events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
+ "type": "Organization",
+ "site_admin": false
+ },
+ "parent": {
+ "id": 617210,
+ "node_id": "MDEwOlJlcG9zaXRvcnk2MTcyMTA=",
+ "name": "github-api",
+ "full_name": "hub4j/github-api",
+ "private": false,
+ "owner": {
+ "login": "hub4j",
+ "id": 54909825,
+ "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0OTA5ODI1",
+ "avatar_url": "https://avatars.githubusercontent.com/u/54909825?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/hub4j",
+ "html_url": "https://github.com/hub4j",
+ "followers_url": "https://api.github.com/users/hub4j/followers",
+ "following_url": "https://api.github.com/users/hub4j/following{/other_user}",
+ "gists_url": "https://api.github.com/users/hub4j/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/hub4j/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/hub4j/subscriptions",
+ "organizations_url": "https://api.github.com/users/hub4j/orgs",
+ "repos_url": "https://api.github.com/users/hub4j/repos",
+ "events_url": "https://api.github.com/users/hub4j/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/hub4j/received_events",
+ "type": "Organization",
+ "site_admin": false
+ },
+ "html_url": "https://github.com/hub4j/github-api",
+ "description": "Java API for GitHub",
+ "fork": false,
+ "url": "https://api.github.com/repos/hub4j/github-api",
+ "forks_url": "https://api.github.com/repos/hub4j/github-api/forks",
+ "keys_url": "https://api.github.com/repos/hub4j/github-api/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/hub4j/github-api/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/hub4j/github-api/teams",
+ "hooks_url": "https://api.github.com/repos/hub4j/github-api/hooks",
+ "issue_events_url": "https://api.github.com/repos/hub4j/github-api/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/hub4j/github-api/events",
+ "assignees_url": "https://api.github.com/repos/hub4j/github-api/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/hub4j/github-api/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/hub4j/github-api/tags",
+ "blobs_url": "https://api.github.com/repos/hub4j/github-api/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/hub4j/github-api/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/hub4j/github-api/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/hub4j/github-api/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/hub4j/github-api/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/hub4j/github-api/languages",
+ "stargazers_url": "https://api.github.com/repos/hub4j/github-api/stargazers",
+ "contributors_url": "https://api.github.com/repos/hub4j/github-api/contributors",
+ "subscribers_url": "https://api.github.com/repos/hub4j/github-api/subscribers",
+ "subscription_url": "https://api.github.com/repos/hub4j/github-api/subscription",
+ "commits_url": "https://api.github.com/repos/hub4j/github-api/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/hub4j/github-api/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/hub4j/github-api/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/hub4j/github-api/issues/comments{/number}",
+ "contents_url": "https://api.github.com/repos/hub4j/github-api/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/hub4j/github-api/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/hub4j/github-api/merges",
+ "archive_url": "https://api.github.com/repos/hub4j/github-api/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/hub4j/github-api/downloads",
+ "issues_url": "https://api.github.com/repos/hub4j/github-api/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/hub4j/github-api/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/hub4j/github-api/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/hub4j/github-api/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/hub4j/github-api/labels{/name}",
+ "releases_url": "https://api.github.com/repos/hub4j/github-api/releases{/id}",
+ "deployments_url": "https://api.github.com/repos/hub4j/github-api/deployments",
+ "created_at": "2010-04-19T04:13:03Z",
+ "updated_at": "2023-01-30T18:28:31Z",
+ "pushed_at": "2023-02-01T11:03:02Z",
+ "git_url": "git://github.com/hub4j/github-api.git",
+ "ssh_url": "git@github.com:hub4j/github-api.git",
+ "clone_url": "https://github.com/hub4j/github-api.git",
+ "svn_url": "https://github.com/hub4j/github-api",
+ "homepage": "https://github-api.kohsuke.org/",
+ "size": 40829,
+ "stargazers_count": 972,
+ "watchers_count": 972,
+ "language": "Java",
+ "has_issues": true,
+ "has_projects": true,
+ "has_downloads": true,
+ "has_wiki": true,
+ "has_pages": true,
+ "has_discussions": true,
+ "forks_count": 651,
+ "mirror_url": null,
+ "archived": false,
+ "disabled": false,
+ "open_issues_count": 139,
+ "license": {
+ "key": "mit",
+ "name": "MIT License",
+ "spdx_id": "MIT",
+ "url": "https://api.github.com/licenses/mit",
+ "node_id": "MDc6TGljZW5zZTEz"
+ },
+ "allow_forking": true,
+ "is_template": false,
+ "web_commit_signoff_required": false,
+ "topics": [
+ "api",
+ "client-library",
+ "github",
+ "github-api",
+ "github-api-v3",
+ "java",
+ "java-api"
+ ],
+ "visibility": "public",
+ "forks": 651,
+ "open_issues": 139,
+ "watchers": 972,
+ "default_branch": "main"
+ },
+ "source": {
+ "id": 617210,
+ "node_id": "MDEwOlJlcG9zaXRvcnk2MTcyMTA=",
+ "name": "github-api",
+ "full_name": "hub4j/github-api",
+ "private": false,
+ "owner": {
+ "login": "hub4j",
+ "id": 54909825,
+ "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0OTA5ODI1",
+ "avatar_url": "https://avatars.githubusercontent.com/u/54909825?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/hub4j",
+ "html_url": "https://github.com/hub4j",
+ "followers_url": "https://api.github.com/users/hub4j/followers",
+ "following_url": "https://api.github.com/users/hub4j/following{/other_user}",
+ "gists_url": "https://api.github.com/users/hub4j/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/hub4j/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/hub4j/subscriptions",
+ "organizations_url": "https://api.github.com/users/hub4j/orgs",
+ "repos_url": "https://api.github.com/users/hub4j/repos",
+ "events_url": "https://api.github.com/users/hub4j/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/hub4j/received_events",
+ "type": "Organization",
+ "site_admin": false
+ },
+ "html_url": "https://github.com/hub4j/github-api",
+ "description": "Java API for GitHub",
+ "fork": false,
+ "url": "https://api.github.com/repos/hub4j/github-api",
+ "forks_url": "https://api.github.com/repos/hub4j/github-api/forks",
+ "keys_url": "https://api.github.com/repos/hub4j/github-api/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/hub4j/github-api/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/hub4j/github-api/teams",
+ "hooks_url": "https://api.github.com/repos/hub4j/github-api/hooks",
+ "issue_events_url": "https://api.github.com/repos/hub4j/github-api/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/hub4j/github-api/events",
+ "assignees_url": "https://api.github.com/repos/hub4j/github-api/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/hub4j/github-api/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/hub4j/github-api/tags",
+ "blobs_url": "https://api.github.com/repos/hub4j/github-api/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/hub4j/github-api/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/hub4j/github-api/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/hub4j/github-api/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/hub4j/github-api/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/hub4j/github-api/languages",
+ "stargazers_url": "https://api.github.com/repos/hub4j/github-api/stargazers",
+ "contributors_url": "https://api.github.com/repos/hub4j/github-api/contributors",
+ "subscribers_url": "https://api.github.com/repos/hub4j/github-api/subscribers",
+ "subscription_url": "https://api.github.com/repos/hub4j/github-api/subscription",
+ "commits_url": "https://api.github.com/repos/hub4j/github-api/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/hub4j/github-api/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/hub4j/github-api/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/hub4j/github-api/issues/comments{/number}",
+ "contents_url": "https://api.github.com/repos/hub4j/github-api/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/hub4j/github-api/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/hub4j/github-api/merges",
+ "archive_url": "https://api.github.com/repos/hub4j/github-api/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/hub4j/github-api/downloads",
+ "issues_url": "https://api.github.com/repos/hub4j/github-api/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/hub4j/github-api/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/hub4j/github-api/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/hub4j/github-api/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/hub4j/github-api/labels{/name}",
+ "releases_url": "https://api.github.com/repos/hub4j/github-api/releases{/id}",
+ "deployments_url": "https://api.github.com/repos/hub4j/github-api/deployments",
+ "created_at": "2010-04-19T04:13:03Z",
+ "updated_at": "2023-01-30T18:28:31Z",
+ "pushed_at": "2023-02-01T11:03:02Z",
+ "git_url": "git://github.com/hub4j/github-api.git",
+ "ssh_url": "git@github.com:hub4j/github-api.git",
+ "clone_url": "https://github.com/hub4j/github-api.git",
+ "svn_url": "https://github.com/hub4j/github-api",
+ "homepage": "https://github-api.kohsuke.org/",
+ "size": 40829,
+ "stargazers_count": 972,
+ "watchers_count": 972,
+ "language": "Java",
+ "has_issues": true,
+ "has_projects": true,
+ "has_downloads": true,
+ "has_wiki": true,
+ "has_pages": true,
+ "has_discussions": true,
+ "forks_count": 651,
+ "mirror_url": null,
+ "archived": false,
+ "disabled": false,
+ "open_issues_count": 139,
+ "license": {
+ "key": "mit",
+ "name": "MIT License",
+ "spdx_id": "MIT",
+ "url": "https://api.github.com/licenses/mit",
+ "node_id": "MDc6TGljZW5zZTEz"
+ },
+ "allow_forking": true,
+ "is_template": false,
+ "web_commit_signoff_required": false,
+ "topics": [
+ "api",
+ "client-library",
+ "github",
+ "github-api",
+ "github-api-v3",
+ "java",
+ "java-api"
+ ],
+ "visibility": "public",
+ "forks": 651,
+ "open_issues": 139,
+ "watchers": 972,
+ "default_branch": "main"
+ },
+ "network_count": 651,
+ "subscribers_count": 1
+}
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/__files/repos_hub4j-test-org_github-api_codeowners_errors-3.json b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/__files/repos_hub4j-test-org_github-api_codeowners_errors-3.json
new file mode 100644
index 0000000000..243321999f
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/__files/repos_hub4j-test-org_github-api_codeowners_errors-3.json
@@ -0,0 +1,13 @@
+{
+ "errors": [
+ {
+ "line": 1,
+ "column": 3,
+ "source": "* @nonexistent-user # Deliberate error to test response to repo.listCodeownersErrors()\n",
+ "kind": "Unknown owner",
+ "suggestion": "make sure @nonexistent-user exists and has write access to the repository",
+ "message": "Unknown owner on line 1: make sure @nonexistent-user exists and has write access to the repository\n\n * @nonexistent-user # Deliberate error to test response to repo.listCodeownersErrors()\n ^",
+ "path": ".github/CODEOWNERS"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/mappings/orgs_hub4j-test-org-1.json b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/mappings/orgs_hub4j-test-org-1.json
new file mode 100644
index 0000000000..d29d4588d3
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/mappings/orgs_hub4j-test-org-1.json
@@ -0,0 +1,46 @@
+{
+ "id": "fed03a9c-634b-4e3c-8423-11e978fcc80d",
+ "name": "orgs_hub4j-test-org",
+ "request": {
+ "url": "/orgs/hub4j-test-org",
+ "method": "GET",
+ "headers": {
+ "Accept": {
+ "equalTo": "application/vnd.github.v3+json"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "bodyFileName": "orgs_hub4j-test-org-1.json",
+ "headers": {
+ "Server": "GitHub.com",
+ "Date": "Wed, 01 Feb 2023 13:13:32 GMT",
+ "Content-Type": "application/json; charset=utf-8",
+ "Cache-Control": "public, max-age=60, s-maxage=60",
+ "Vary": "Accept, Accept-Encoding, Accept, X-Requested-With",
+ "ETag": "W/\"019b7739e9fbcde09b75c43c41ed21dbb8be92b33062c8544e40549543f07fc9\"",
+ "Last-Modified": "Thu, 04 Jun 2020 05:56:10 GMT",
+ "X-GitHub-Media-Type": "github.v3; format=json",
+ "x-github-api-version-selected": "2022-11-28",
+ "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset",
+ "Access-Control-Allow-Origin": "*",
+ "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
+ "X-Frame-Options": "deny",
+ "X-Content-Type-Options": "nosniff",
+ "X-XSS-Protection": "0",
+ "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
+ "Content-Security-Policy": "default-src 'none'",
+ "X-RateLimit-Limit": "60",
+ "X-RateLimit-Remaining": "12",
+ "X-RateLimit-Reset": "1675258706",
+ "X-RateLimit-Resource": "core",
+ "X-RateLimit-Used": "48",
+ "Accept-Ranges": "bytes",
+ "X-GitHub-Request-Id": "B77E:E756:54773C6:55FA2D7:63DA657C"
+ }
+ },
+ "uuid": "fed03a9c-634b-4e3c-8423-11e978fcc80d",
+ "persistent": true,
+ "insertionIndex": 1
+}
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/mappings/repos_hub4j-test-org_github-api-2.json b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/mappings/repos_hub4j-test-org_github-api-2.json
new file mode 100644
index 0000000000..f47d8f16e2
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/mappings/repos_hub4j-test-org_github-api-2.json
@@ -0,0 +1,46 @@
+{
+ "id": "83ae59b2-2fee-4b87-b9c5-d4c9df208df2",
+ "name": "repos_hub4j-test-org_github-api",
+ "request": {
+ "url": "/repos/hub4j-test-org/github-api",
+ "method": "GET",
+ "headers": {
+ "Accept": {
+ "equalTo": "application/vnd.github.v3+json"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "bodyFileName": "repos_hub4j-test-org_github-api-2.json",
+ "headers": {
+ "Server": "GitHub.com",
+ "Date": "Wed, 01 Feb 2023 13:13:33 GMT",
+ "Content-Type": "application/json; charset=utf-8",
+ "Cache-Control": "public, max-age=60, s-maxage=60",
+ "Vary": "Accept, Accept-Encoding, Accept, X-Requested-With",
+ "ETag": "W/\"764f0069b95f6b8021183ff5da0ff253c0aa150492ab6776e0bbbb19df38fd31\"",
+ "Last-Modified": "Tue, 31 Jan 2023 10:03:44 GMT",
+ "X-GitHub-Media-Type": "github.v3; format=json",
+ "x-github-api-version-selected": "2022-11-28",
+ "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset",
+ "Access-Control-Allow-Origin": "*",
+ "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
+ "X-Frame-Options": "deny",
+ "X-Content-Type-Options": "nosniff",
+ "X-XSS-Protection": "0",
+ "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
+ "Content-Security-Policy": "default-src 'none'",
+ "X-RateLimit-Limit": "60",
+ "X-RateLimit-Remaining": "11",
+ "X-RateLimit-Reset": "1675258706",
+ "X-RateLimit-Resource": "core",
+ "X-RateLimit-Used": "49",
+ "Accept-Ranges": "bytes",
+ "X-GitHub-Request-Id": "B77E:E756:54775D8:55FA4F1:63DA657D"
+ }
+ },
+ "uuid": "83ae59b2-2fee-4b87-b9c5-d4c9df208df2",
+ "persistent": true,
+ "insertionIndex": 2
+}
\ No newline at end of file
diff --git a/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/mappings/repos_hub4j-test-org_github-api_codeowners_errors-3.json b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/mappings/repos_hub4j-test-org_github-api_codeowners_errors-3.json
new file mode 100644
index 0000000000..d11d713046
--- /dev/null
+++ b/src/test/resources/org/kohsuke/github/GHCodeownersErrorTest/wiremock/testGetCodeownersErrors/mappings/repos_hub4j-test-org_github-api_codeowners_errors-3.json
@@ -0,0 +1,45 @@
+{
+ "id": "fa38407c-47c9-4eb9-88c1-fe025c83c5f7",
+ "name": "repos_hub4j-test-org_github-api_codeowners_errors",
+ "request": {
+ "url": "/repos/hub4j-test-org/github-api/codeowners/errors",
+ "method": "GET",
+ "headers": {
+ "Accept": {
+ "equalTo": "application/vnd.github.v3+json"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "bodyFileName": "repos_hub4j-test-org_github-api_codeowners_errors-3.json",
+ "headers": {
+ "Server": "GitHub.com",
+ "Date": "Wed, 01 Feb 2023 13:13:33 GMT",
+ "Content-Type": "application/json; charset=utf-8",
+ "Cache-Control": "public, max-age=60, s-maxage=60",
+ "Vary": "Accept, Accept-Encoding, Accept, X-Requested-With",
+ "ETag": "W/\"2429b2e50fda38535f58bfed72e523831eedca6b313cb9c6b660306c7d8e0452\"",
+ "X-GitHub-Media-Type": "github.v3; format=json",
+ "x-github-api-version-selected": "2022-11-28",
+ "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset",
+ "Access-Control-Allow-Origin": "*",
+ "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
+ "X-Frame-Options": "deny",
+ "X-Content-Type-Options": "nosniff",
+ "X-XSS-Protection": "0",
+ "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
+ "Content-Security-Policy": "default-src 'none'",
+ "X-RateLimit-Limit": "60",
+ "X-RateLimit-Remaining": "10",
+ "X-RateLimit-Reset": "1675258706",
+ "X-RateLimit-Resource": "core",
+ "X-RateLimit-Used": "50",
+ "Accept-Ranges": "bytes",
+ "X-GitHub-Request-Id": "B77E:E756:54777B2:55FA6C7:63DA657D"
+ }
+ },
+ "uuid": "fa38407c-47c9-4eb9-88c1-fe025c83c5f7",
+ "persistent": true,
+ "insertionIndex": 3
+}
\ No newline at end of file