Skip to content

Commit

Permalink
Support state reason for issues (#1793)
Browse files Browse the repository at this point in the history
* Support state reason for issues

Closes #1792

* Apply suggestions from code review

* Update src/main/java/org/kohsuke/github/GHIssueStateReason.java

---------

Co-authored-by: Liam Newman <[email protected]>
  • Loading branch information
stianst and bitwiseman authored Feb 20, 2024
1 parent 0af15ad commit 5c155dc
Show file tree
Hide file tree
Showing 19 changed files with 1,203 additions and 1 deletion.
34 changes: 34 additions & 0 deletions src/main/java/org/kohsuke/github/GHIssue.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.github.internal.EnumUtils;

import java.io.IOException;
import java.net.URL;
Expand All @@ -35,8 +36,10 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
Expand Down Expand Up @@ -67,6 +70,9 @@ public class GHIssue extends GHObject implements Reactable {
/** The state. */
protected String state;

/** The state reason. */
protected String state_reason;

/** The number. */
protected int number;

Expand Down Expand Up @@ -198,6 +204,15 @@ public GHIssueState getState() {
return Enum.valueOf(GHIssueState.class, state.toUpperCase(Locale.ENGLISH));
}

/**
* Gets state reason.
*
* @return the state reason
*/
public GHIssueStateReason getStateReason() {
return EnumUtils.getNullableEnumOrDefault(GHIssueStateReason.class, state_reason, GHIssueStateReason.UNKNOWN);
}

/**
* Gets labels.
*
Expand Down Expand Up @@ -273,6 +288,10 @@ private void edit(String key, Object value) throws IOException {
root().createRequest().with(key, value).method("PATCH").withUrlPath(getApiRoute()).send();
}

private void edit(Map<String, Object> map) throws IOException {
root().createRequest().with(map).method("PATCH").withUrlPath(getApiRoute()).send();
}

/**
* Identical to edit(), but allows null for the value.
*/
Expand All @@ -294,6 +313,21 @@ public void close() throws IOException {
edit("state", "closed");
}

/**
* Closes this issue.
*
* @param reason
* the reason the issue was closed
* @throws IOException
* the io exception
*/
public void close(GHIssueStateReason reason) throws IOException {
Map<String, Object> map = new HashMap<>();
map.put("state", "closed");
map.put("state_reason", reason.name().toLowerCase(Locale.ENGLISH));
edit(map);
}

/**
* Reopens this issue.
*
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/org/kohsuke/github/GHIssueStateReason.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.kohsuke.github;

/**
* The enum GHIssueStateReason.
*/
public enum GHIssueStateReason {

/** Completed **/
COMPLETED,

/** Closed as not planned **/
NOT_PLANNED,

/** Uknown **/
UNKNOWN
}
29 changes: 28 additions & 1 deletion src/test/java/org/kohsuke/github/GHIssueTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;

// TODO: Auto-generated Javadoc
/**
Expand Down Expand Up @@ -158,7 +159,33 @@ public void closeIssue() throws Exception {
assertThat(issue.getTitle(), equalTo(name));
assertThat(getRepository().getIssue(issue.getNumber()).getState(), equalTo(GHIssueState.OPEN));
issue.close();
assertThat(getRepository().getIssue(issue.getNumber()).getState(), equalTo(GHIssueState.CLOSED));
GHIssue closedIssued = getRepository().getIssue(issue.getNumber());
assertThat(closedIssued.getState(), equalTo(GHIssueState.CLOSED));
assertThat(closedIssued.getStateReason(), equalTo(GHIssueStateReason.COMPLETED));
}

/**
* Close issue as not planned.
*
* @throws Exception
* the exception
*/
@Test
public void closeIssueNotPlanned() throws Exception {
String name = "closeIssueNotPlanned";
GHIssue issue = getRepository().createIssue(name).body("## test").create();
assertThat(issue.getTitle(), equalTo(name));

GHIssue createdIssue = issue.getRepository().getIssue(issue.getNumber());

assertThat(createdIssue.getState(), equalTo(GHIssueState.OPEN));
assertThat(createdIssue.getStateReason(), nullValue());

issue.close(GHIssueStateReason.NOT_PLANNED);

GHIssue closedIssued = getRepository().getIssue(issue.getNumber());
assertThat(closedIssued.getState(), equalTo(GHIssueState.CLOSED));
assertThat(closedIssued.getStateReason(), equalTo(GHIssueStateReason.NOT_PLANNED));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"login": "stianst",
"id": 2271511,
"node_id": "MDQ6VXNlcjIyNzE1MTE=",
"avatar_url": "https://avatars.githubusercontent.com/u/2271511?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/stianst",
"html_url": "https://github.com/stianst",
"followers_url": "https://api.github.com/users/stianst/followers",
"following_url": "https://api.github.com/users/stianst/following{/other_user}",
"gists_url": "https://api.github.com/users/stianst/gists{/gist_id}",
"starred_url": "https://api.github.com/users/stianst/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/stianst/subscriptions",
"organizations_url": "https://api.github.com/users/stianst/orgs",
"repos_url": "https://api.github.com/users/stianst/repos",
"events_url": "https://api.github.com/users/stianst/events{/privacy}",
"received_events_url": "https://api.github.com/users/stianst/received_events",
"type": "User",
"site_admin": false,
"name": "Stian Thorgersen",
"company": "Red Hat",
"blog": "",
"location": null,
"email": "[email protected]",
"hireable": null,
"bio": "Keycloak Project Lead",
"twitter_username": null,
"public_repos": 39,
"public_gists": 20,
"followers": 454,
"following": 1,
"created_at": "2012-09-03T14:55:29Z",
"updated_at": "2023-11-20T07:52:25Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"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": "[email protected]",
"twitter_username": null,
"is_verified": false,
"has_organization_projects": true,
"has_repository_projects": true,
"public_repos": 26,
"public_gists": 0,
"followers": 2,
"following": 0,
"html_url": "https://github.com/hub4j-test-org",
"created_at": "2014-05-10T19:39:11Z",
"updated_at": "2020-06-04T05:56:10Z",
"archived_at": null,
"type": "Organization",
"total_private_repos": 6,
"owned_private_repos": 6,
"private_gists": 0,
"disk_usage": 12014,
"collaborators": 1,
"billing_email": "[email protected]",
"default_repository_permission": "none",
"members_can_create_repositories": false,
"two_factor_requirement_enabled": false,
"members_allowed_repository_creation_type": "none",
"members_can_create_public_repositories": false,
"members_can_create_private_repositories": false,
"members_can_create_internal_repositories": false,
"members_can_create_pages": true,
"members_can_fork_private_repositories": false,
"web_commit_signoff_required": false,
"members_can_create_public_pages": true,
"members_can_create_private_pages": true,
"plan": {
"name": "free",
"space": 976562499,
"private_repos": 10000,
"filled_seats": 49,
"seats": 3
},
"advanced_security_enabled_for_new_repositories": false,
"dependabot_alerts_enabled_for_new_repositories": false,
"dependabot_security_updates_enabled_for_new_repositories": false,
"dependency_graph_enabled_for_new_repositories": false,
"secret_scanning_enabled_for_new_repositories": false,
"secret_scanning_push_protection_enabled_for_new_repositories": false,
"secret_scanning_push_protection_custom_link_enabled": false,
"secret_scanning_push_protection_custom_link": null,
"secret_scanning_validity_checks_enabled": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
{
"id": 539903172,
"node_id": "R_kgDOIC5ExA",
"name": "GHIssueTest",
"full_name": "hub4j-test-org/GHIssueTest",
"private": true,
"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/GHIssueTest",
"description": "Repository used by GHIssueTest",
"fork": false,
"url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest",
"forks_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/forks",
"keys_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/teams",
"hooks_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/hooks",
"issue_events_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues/events{/number}",
"events_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/events",
"assignees_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/assignees{/user}",
"branches_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/branches{/branch}",
"tags_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/tags",
"blobs_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/statuses/{sha}",
"languages_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/languages",
"stargazers_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/stargazers",
"contributors_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/contributors",
"subscribers_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/subscribers",
"subscription_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/subscription",
"commits_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/contents/{+path}",
"compare_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/merges",
"archive_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/downloads",
"issues_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues{/number}",
"pulls_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/pulls{/number}",
"milestones_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/milestones{/number}",
"notifications_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/labels{/name}",
"releases_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/releases{/id}",
"deployments_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/deployments",
"created_at": "2022-09-22T09:33:05Z",
"updated_at": "2022-09-22T09:33:16Z",
"pushed_at": "2022-09-22T09:33:05Z",
"git_url": "git://github.com/hub4j-test-org/GHIssueTest.git",
"ssh_url": "[email protected]:hub4j-test-org/GHIssueTest.git",
"clone_url": "https://github.com/hub4j-test-org/GHIssueTest.git",
"svn_url": "https://github.com/hub4j-test-org/GHIssueTest",
"homepage": null,
"size": 0,
"stargazers_count": 0,
"watchers_count": 0,
"language": null,
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": false,
"has_pages": false,
"has_discussions": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 0,
"license": null,
"allow_forking": false,
"is_template": false,
"web_commit_signoff_required": false,
"topics": [],
"visibility": "private",
"forks": 0,
"open_issues": 0,
"watchers": 0,
"default_branch": "main",
"permissions": {
"admin": true,
"maintain": true,
"push": true,
"triage": true,
"pull": true
},
"temp_clone_token": "AARKSFYLQOBOSCZJCPGLQMTFZSKWQ",
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_rebase_merge": true,
"allow_auto_merge": false,
"delete_branch_on_merge": false,
"allow_update_branch": false,
"use_squash_pr_title_as_default": false,
"squash_merge_commit_message": "COMMIT_MESSAGES",
"squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
"merge_commit_message": "PR_TITLE",
"merge_commit_title": "MERGE_MESSAGE",
"custom_properties": {},
"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
},
"security_and_analysis": {
"secret_scanning": {
"status": "disabled"
},
"secret_scanning_push_protection": {
"status": "disabled"
},
"dependabot_security_updates": {
"status": "disabled"
},
"secret_scanning_validity_checks": {
"status": "disabled"
}
},
"network_count": 0,
"subscribers_count": 15
}
Loading

0 comments on commit 5c155dc

Please sign in to comment.