Skip to content

Commit 0c41dd7

Browse files
committed
Support state reason for issues
Closes #1792
1 parent be00e51 commit 0c41dd7

File tree

19 files changed

+1088
-1
lines changed

19 files changed

+1088
-1
lines changed

src/main/java/org/kohsuke/github/GHIssue.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
2828
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
2929
import org.apache.commons.lang3.StringUtils;
30+
import org.kohsuke.github.internal.EnumUtils;
3031

3132
import java.io.IOException;
3233
import java.net.URL;
@@ -35,8 +36,10 @@
3536
import java.util.Collection;
3637
import java.util.Collections;
3738
import java.util.Date;
39+
import java.util.HashMap;
3840
import java.util.List;
3941
import java.util.Locale;
42+
import java.util.Map;
4043
import java.util.Objects;
4144

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

73+
/** The state. */
74+
protected String state_reason;
75+
7076
/** The number. */
7177
protected int number;
7278

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

207+
/**
208+
* Gets state reason.
209+
*
210+
* @return the state reason
211+
*/
212+
public GHIssueStateReason getStateReason() {
213+
return EnumUtils.getEnumOrDefault(GHIssueStateReason.class, state_reason, GHIssueStateReason.UNKNOWN);
214+
}
215+
201216
/**
202217
* Gets labels.
203218
*
@@ -273,6 +288,10 @@ private void edit(String key, Object value) throws IOException {
273288
root().createRequest().with(key, value).method("PATCH").withUrlPath(getApiRoute()).send();
274289
}
275290

291+
private void edit(Map<String, Object> map) throws IOException {
292+
root().createRequest().with(map).method("PATCH").withUrlPath(getApiRoute()).send();
293+
}
294+
276295
/**
277296
* Identical to edit(), but allows null for the value.
278297
*/
@@ -294,6 +313,19 @@ public void close() throws IOException {
294313
edit("state", "closed");
295314
}
296315

316+
/**
317+
* Closes this issue.
318+
*
319+
* @throws IOException
320+
* the io exception
321+
*/
322+
public void close(GHIssueStateReason reason) throws IOException {
323+
Map<String, Object> map = new HashMap<>();
324+
map.put("state", "closed");
325+
map.put("state_reason", reason.name().toLowerCase(Locale.ENGLISH));
326+
edit(map);
327+
}
328+
297329
/**
298330
* Reopens this issue.
299331
*
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.kohsuke.github;
2+
3+
public enum GHIssueStateReason {
4+
5+
COMPLETED, NOT_PLANNED, UNKNOWN
6+
}

src/test/java/org/kohsuke/github/GHIssueTest.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,33 @@ public void closeIssue() throws Exception {
158158
assertThat(issue.getTitle(), equalTo(name));
159159
assertThat(getRepository().getIssue(issue.getNumber()).getState(), equalTo(GHIssueState.OPEN));
160160
issue.close();
161-
assertThat(getRepository().getIssue(issue.getNumber()).getState(), equalTo(GHIssueState.CLOSED));
161+
GHIssue closedIssued = getRepository().getIssue(issue.getNumber());
162+
assertThat(closedIssued.getState(), equalTo(GHIssueState.CLOSED));
163+
assertThat(closedIssued.getStateReason(), equalTo(GHIssueStateReason.COMPLETED));
164+
}
165+
166+
/**
167+
* Close issue as not planned.
168+
*
169+
* @throws Exception
170+
* the exception
171+
*/
172+
@Test
173+
public void closeIssueNotPlanned() throws Exception {
174+
String name = "closeIssueNotPlanned";
175+
GHIssue issue = getRepository().createIssue(name).body("## test").create();
176+
assertThat(issue.getTitle(), equalTo(name));
177+
178+
GHIssue createdIssue = issue.getRepository().getIssue(issue.getNumber());
179+
180+
assertThat(createdIssue.getState(), equalTo(GHIssueState.OPEN));
181+
assertThat(createdIssue.getStateReason(), equalTo(GHIssueStateReason.UNKNOWN));
182+
183+
issue.close(GHIssueStateReason.NOT_PLANNED);
184+
185+
GHIssue closedIssued = getRepository().getIssue(issue.getNumber());
186+
assertThat(closedIssued.getState(), equalTo(GHIssueState.CLOSED));
187+
assertThat(closedIssued.getStateReason(), equalTo(GHIssueStateReason.NOT_PLANNED));
162188
}
163189

164190
/**
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"login": "stianst",
3+
"id": 2271511,
4+
"node_id": "MDQ6VXNlcjIyNzE1MTE=",
5+
"avatar_url": "https://avatars.githubusercontent.com/u/2271511?v=4",
6+
"gravatar_id": "",
7+
"url": "https://api.github.com/users/stianst",
8+
"html_url": "https://github.com/stianst",
9+
"followers_url": "https://api.github.com/users/stianst/followers",
10+
"following_url": "https://api.github.com/users/stianst/following{/other_user}",
11+
"gists_url": "https://api.github.com/users/stianst/gists{/gist_id}",
12+
"starred_url": "https://api.github.com/users/stianst/starred{/owner}{/repo}",
13+
"subscriptions_url": "https://api.github.com/users/stianst/subscriptions",
14+
"organizations_url": "https://api.github.com/users/stianst/orgs",
15+
"repos_url": "https://api.github.com/users/stianst/repos",
16+
"events_url": "https://api.github.com/users/stianst/events{/privacy}",
17+
"received_events_url": "https://api.github.com/users/stianst/received_events",
18+
"type": "User",
19+
"site_admin": false,
20+
"name": "Stian Thorgersen",
21+
"company": "Red Hat",
22+
"blog": "",
23+
"location": null,
24+
"email": "stian@redhat.com",
25+
"hireable": null,
26+
"bio": "Keycloak Project Lead",
27+
"twitter_username": null,
28+
"public_repos": 39,
29+
"public_gists": 20,
30+
"followers": 454,
31+
"following": 1,
32+
"created_at": "2012-09-03T14:55:29Z",
33+
"updated_at": "2023-11-20T07:52:25Z"
34+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"login": "hub4j-test-org",
3+
"id": 160007886,
4+
"node_id": "O_kgDOCYmGzg",
5+
"url": "https://api.github.com/orgs/hub4j-test-org",
6+
"repos_url": "https://api.github.com/orgs/hub4j-test-org/repos",
7+
"events_url": "https://api.github.com/orgs/hub4j-test-org/events",
8+
"hooks_url": "https://api.github.com/orgs/hub4j-test-org/hooks",
9+
"issues_url": "https://api.github.com/orgs/hub4j-test-org/issues",
10+
"members_url": "https://api.github.com/orgs/hub4j-test-org/members{/member}",
11+
"public_members_url": "https://api.github.com/orgs/hub4j-test-org/public_members{/member}",
12+
"avatar_url": "https://avatars.githubusercontent.com/u/160007886?v=4",
13+
"description": null,
14+
"is_verified": false,
15+
"has_organization_projects": true,
16+
"has_repository_projects": true,
17+
"public_repos": 1,
18+
"public_gists": 0,
19+
"followers": 0,
20+
"following": 0,
21+
"html_url": "https://github.com/hub4j-test-org",
22+
"created_at": "2024-02-14T08:57:43Z",
23+
"updated_at": "2024-02-14T08:57:43Z",
24+
"archived_at": null,
25+
"type": "Organization"
26+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
{
2+
"id": 757320982,
3+
"node_id": "R_kgDOLSPNFg",
4+
"name": "GHIssueTest",
5+
"full_name": "hub4j-test-org/GHIssueTest",
6+
"private": false,
7+
"owner": {
8+
"login": "hub4j-test-org",
9+
"id": 160007886,
10+
"node_id": "O_kgDOCYmGzg",
11+
"avatar_url": "https://avatars.githubusercontent.com/u/160007886?v=4",
12+
"gravatar_id": "",
13+
"url": "https://api.github.com/users/hub4j-test-org",
14+
"html_url": "https://github.com/hub4j-test-org",
15+
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
16+
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
17+
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
18+
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
19+
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
20+
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
21+
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
22+
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
23+
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
24+
"type": "Organization",
25+
"site_admin": false
26+
},
27+
"html_url": "https://github.com/hub4j-test-org/GHIssueTest",
28+
"description": null,
29+
"fork": false,
30+
"url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest",
31+
"forks_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/forks",
32+
"keys_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/keys{/key_id}",
33+
"collaborators_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/collaborators{/collaborator}",
34+
"teams_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/teams",
35+
"hooks_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/hooks",
36+
"issue_events_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues/events{/number}",
37+
"events_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/events",
38+
"assignees_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/assignees{/user}",
39+
"branches_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/branches{/branch}",
40+
"tags_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/tags",
41+
"blobs_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/git/blobs{/sha}",
42+
"git_tags_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/git/tags{/sha}",
43+
"git_refs_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/git/refs{/sha}",
44+
"trees_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/git/trees{/sha}",
45+
"statuses_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/statuses/{sha}",
46+
"languages_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/languages",
47+
"stargazers_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/stargazers",
48+
"contributors_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/contributors",
49+
"subscribers_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/subscribers",
50+
"subscription_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/subscription",
51+
"commits_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/commits{/sha}",
52+
"git_commits_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/git/commits{/sha}",
53+
"comments_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/comments{/number}",
54+
"issue_comment_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues/comments{/number}",
55+
"contents_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/contents/{+path}",
56+
"compare_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/compare/{base}...{head}",
57+
"merges_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/merges",
58+
"archive_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/{archive_format}{/ref}",
59+
"downloads_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/downloads",
60+
"issues_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues{/number}",
61+
"pulls_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/pulls{/number}",
62+
"milestones_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/milestones{/number}",
63+
"notifications_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/notifications{?since,all,participating}",
64+
"labels_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/labels{/name}",
65+
"releases_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/releases{/id}",
66+
"deployments_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/deployments",
67+
"created_at": "2024-02-14T08:58:05Z",
68+
"updated_at": "2024-02-14T08:58:05Z",
69+
"pushed_at": "2024-02-14T08:58:05Z",
70+
"git_url": "git://github.com/hub4j-test-org/GHIssueTest.git",
71+
"ssh_url": "git@github.com:hub4j-test-org/GHIssueTest.git",
72+
"clone_url": "https://github.com/hub4j-test-org/GHIssueTest.git",
73+
"svn_url": "https://github.com/hub4j-test-org/GHIssueTest",
74+
"homepage": null,
75+
"size": 0,
76+
"stargazers_count": 0,
77+
"watchers_count": 0,
78+
"language": null,
79+
"has_issues": true,
80+
"has_projects": true,
81+
"has_downloads": true,
82+
"has_wiki": true,
83+
"has_pages": false,
84+
"has_discussions": false,
85+
"forks_count": 0,
86+
"mirror_url": null,
87+
"archived": false,
88+
"disabled": false,
89+
"open_issues_count": 0,
90+
"license": null,
91+
"allow_forking": true,
92+
"is_template": false,
93+
"web_commit_signoff_required": false,
94+
"topics": [],
95+
"visibility": "public",
96+
"forks": 0,
97+
"open_issues": 0,
98+
"watchers": 0,
99+
"default_branch": "main",
100+
"permissions": {
101+
"admin": true,
102+
"maintain": true,
103+
"push": true,
104+
"triage": true,
105+
"pull": true
106+
},
107+
"custom_properties": {},
108+
"organization": {
109+
"login": "hub4j-test-org",
110+
"id": 160007886,
111+
"node_id": "O_kgDOCYmGzg",
112+
"avatar_url": "https://avatars.githubusercontent.com/u/160007886?v=4",
113+
"gravatar_id": "",
114+
"url": "https://api.github.com/users/hub4j-test-org",
115+
"html_url": "https://github.com/hub4j-test-org",
116+
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
117+
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
118+
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
119+
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
120+
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
121+
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
122+
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
123+
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
124+
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
125+
"type": "Organization",
126+
"site_admin": false
127+
},
128+
"network_count": 0,
129+
"subscribers_count": 0
130+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues/7",
3+
"repository_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest",
4+
"labels_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues/7/labels{/name}",
5+
"comments_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues/7/comments",
6+
"events_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues/7/events",
7+
"html_url": "https://github.com/hub4j-test-org/GHIssueTest/issues/7",
8+
"id": 2133869595,
9+
"node_id": "I_kwDOLSPNFs5_MEQb",
10+
"number": 7,
11+
"title": "closeIssueNotPlanned",
12+
"user": {
13+
"login": "stianst",
14+
"id": 2271511,
15+
"node_id": "MDQ6VXNlcjIyNzE1MTE=",
16+
"avatar_url": "https://avatars.githubusercontent.com/u/2271511?v=4",
17+
"gravatar_id": "",
18+
"url": "https://api.github.com/users/stianst",
19+
"html_url": "https://github.com/stianst",
20+
"followers_url": "https://api.github.com/users/stianst/followers",
21+
"following_url": "https://api.github.com/users/stianst/following{/other_user}",
22+
"gists_url": "https://api.github.com/users/stianst/gists{/gist_id}",
23+
"starred_url": "https://api.github.com/users/stianst/starred{/owner}{/repo}",
24+
"subscriptions_url": "https://api.github.com/users/stianst/subscriptions",
25+
"organizations_url": "https://api.github.com/users/stianst/orgs",
26+
"repos_url": "https://api.github.com/users/stianst/repos",
27+
"events_url": "https://api.github.com/users/stianst/events{/privacy}",
28+
"received_events_url": "https://api.github.com/users/stianst/received_events",
29+
"type": "User",
30+
"site_admin": false
31+
},
32+
"labels": [],
33+
"state": "open",
34+
"locked": false,
35+
"assignee": null,
36+
"assignees": [],
37+
"milestone": null,
38+
"comments": 0,
39+
"created_at": "2024-02-14T09:08:53Z",
40+
"updated_at": "2024-02-14T09:08:53Z",
41+
"closed_at": null,
42+
"author_association": "MEMBER",
43+
"active_lock_reason": null,
44+
"body": "## test",
45+
"closed_by": null,
46+
"reactions": {
47+
"url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues/7/reactions",
48+
"total_count": 0,
49+
"+1": 0,
50+
"-1": 0,
51+
"laugh": 0,
52+
"hooray": 0,
53+
"confused": 0,
54+
"heart": 0,
55+
"rocket": 0,
56+
"eyes": 0
57+
},
58+
"timeline_url": "https://api.github.com/repos/hub4j-test-org/GHIssueTest/issues/7/timeline",
59+
"performed_via_github_app": null,
60+
"state_reason": null
61+
}

0 commit comments

Comments
 (0)