Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6956922

Browse filesBrowse files
authored
Merge pull request hub4j#579 from martinvanzijl/issue_512_methods_to_update_milestones
Add methods to update and delete milestones.
2 parents d4ddf45 + 03edacf commit 6956922
Copy full SHA for 6956922
Expand file treeCollapse file tree

20 files changed

+1119
-1
lines changed

‎src/main/java/org/kohsuke/github/GHMilestone.java

Copy file name to clipboardExpand all lines: src/main/java/org/kohsuke/github/GHMilestone.java
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,29 @@ public void reopen() throws IOException {
8585
edit("state", "open");
8686
}
8787

88+
/**
89+
* Deletes this milestone.
90+
*/
91+
public void delete() throws IOException {
92+
root.retrieve().method("DELETE").to(getApiRoute());
93+
}
94+
8895
private void edit(String key, Object value) throws IOException {
8996
new Requester(root)._with(key, value).method("PATCH").to(getApiRoute());
9097
}
9198

99+
public void setTitle(String title) throws IOException {
100+
edit("title", title);
101+
}
102+
103+
public void setDescription(String description) throws IOException {
104+
edit("description", description);
105+
}
106+
107+
public void setDueOn(Date dueOn) throws IOException {
108+
edit("due_on", GitHub.printDate(dueOn));
109+
}
110+
92111
protected String getApiRoute() {
93112
return "/repos/"+owner.getOwnerName()+"/"+owner.getName()+"/milestones/"+number;
94113
}

‎src/main/java/org/kohsuke/github/GitHub.java

Copy file name to clipboardExpand all lines: src/main/java/org/kohsuke/github/GitHub.java
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,9 @@ public Reader renderMarkdown(String text) throws IOException {
956956
}
957957

958958
/*package*/ static String printDate(Date dt) {
959-
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(dt);
959+
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
960+
df.setTimeZone(TimeZone.getTimeZone("GMT"));
961+
return df.format(dt);
960962
}
961963

962964
/*package*/ static final ObjectMapper MAPPER = new ObjectMapper();
+64Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package org.kohsuke.github;
2+
3+
import org.junit.After;
4+
import org.junit.Before;
5+
import org.junit.Test;
6+
7+
import java.io.IOException;
8+
import java.util.Date;
9+
10+
/**
11+
* @author Martin van Zijl
12+
*/
13+
public class GHMilestoneTest extends AbstractGitHubWireMockTest {
14+
15+
@Before
16+
@After
17+
public void cleanUp() throws Exception {
18+
// Cleanup is only needed when proxying
19+
if (!mockGitHub.isUseProxy()) {
20+
return;
21+
}
22+
23+
for (GHMilestone milestone : getRepository(gitHubBeforeAfter).listMilestones(GHIssueState.ALL)) {
24+
if ("Original Title".equals(milestone.getTitle()) ||
25+
"Updated Title".equals(milestone.getTitle())) {
26+
milestone.delete();
27+
}
28+
}
29+
}
30+
31+
@Test
32+
public void testUpdateMilestone() throws Exception {
33+
GHRepository repo = getRepository();
34+
GHMilestone milestone = repo.createMilestone("Original Title",
35+
"To test the update methods");
36+
37+
String NEW_TITLE = "Updated Title";
38+
String NEW_DESCRIPTION = "Updated Description";
39+
Date NEW_DUE_DATE = GitHub.parseDate("2020-10-05T13:00:00Z");
40+
Date OUTPUT_DUE_DATE = GitHub.parseDate("2020-10-05T07:00:00Z");
41+
42+
milestone.setTitle(NEW_TITLE);
43+
milestone.setDescription(NEW_DESCRIPTION);
44+
milestone.setDueOn(NEW_DUE_DATE);
45+
46+
// Force reload.
47+
milestone = repo.getMilestone(milestone.getNumber());
48+
49+
assertEquals(NEW_TITLE, milestone.getTitle());
50+
assertEquals(NEW_DESCRIPTION, milestone.getDescription());
51+
52+
// The time is truncated when sent to the server, but still part of the returned value
53+
// 07:00 midnight PDT
54+
assertEquals(OUTPUT_DUE_DATE, milestone.getDueOn());
55+
}
56+
57+
protected GHRepository getRepository() throws IOException {
58+
return getRepository(gitHub);
59+
}
60+
61+
private GHRepository getRepository(GitHub gitHub) throws IOException {
62+
return gitHub.getOrganization("github-api-test-org").getRepository("github-api");
63+
}
64+
}
+72Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package org.kohsuke.github;
2+
3+
import org.junit.Assert;
4+
import org.junit.Test;
5+
6+
import java.text.SimpleDateFormat;
7+
import java.time.Instant;
8+
import java.time.temporal.ChronoUnit;
9+
import java.util.Date;
10+
import java.util.TimeZone;
11+
12+
import static org.hamcrest.CoreMatchers.equalTo;
13+
import static org.hamcrest.CoreMatchers.not;
14+
15+
/**
16+
* Unit test for {@link GitHub} static helpers.
17+
*
18+
* @author Liam Newman
19+
*/
20+
public class GitHubStaticTest extends Assert {
21+
22+
@Test
23+
public void timeRoundTrip() throws Exception {
24+
Instant instantNow = Instant.now();
25+
26+
Date instantSeconds = Date.from(instantNow.truncatedTo(ChronoUnit.SECONDS));
27+
Date instantMillis = Date.from(instantNow.truncatedTo(ChronoUnit.MILLIS));
28+
29+
// TODO: other formats
30+
String instantFormatSlash = formatDate(instantMillis, "yyyy/MM/dd HH:mm:ss ZZZZ");
31+
String instantFormatDash = formatDate(instantMillis, "yyyy-MM-dd'T'HH:mm:ss'Z'");
32+
String instantFormatMillis = formatDate(instantMillis, "yyyy-MM-dd'T'HH:mm:ss.S'Z'");
33+
String instantSecondsFormatMillis = formatDate(instantSeconds, "yyyy-MM-dd'T'HH:mm:ss.S'Z'");
34+
String instantBadFormat = formatDate(instantMillis, "yy-MM-dd'T'HH:mm'Z'");
35+
36+
37+
assertThat(GitHub.parseDate(GitHub.printDate(instantSeconds)),
38+
equalTo(GitHub.parseDate(GitHub.printDate(instantMillis))));
39+
40+
assertThat(instantSeconds,
41+
equalTo(GitHub.parseDate(GitHub.printDate(instantSeconds))));
42+
43+
assertThat(instantMillis,
44+
not(equalTo(GitHub.parseDate(GitHub.printDate(instantMillis)))));
45+
46+
assertThat(instantSeconds,
47+
equalTo(GitHub.parseDate(instantFormatSlash)));
48+
49+
assertThat(instantSeconds,
50+
equalTo(GitHub.parseDate(instantFormatDash)));
51+
52+
assertThat(instantMillis,
53+
equalTo(GitHub.parseDate(instantFormatMillis)));
54+
55+
assertThat(instantSeconds,
56+
equalTo(GitHub.parseDate(instantSecondsFormatMillis)));
57+
58+
try {
59+
GitHub.parseDate(instantBadFormat);
60+
fail("Bad time format should throw.");
61+
} catch (IllegalStateException e) {
62+
assertThat(e.getMessage(), equalTo("Unable to parse the timestamp: " + instantBadFormat));
63+
}
64+
}
65+
66+
static String formatDate(Date dt, String format) {
67+
SimpleDateFormat df = new SimpleDateFormat(format);
68+
df.setTimeZone(TimeZone.getTimeZone("GMT"));
69+
return df.format(dt);
70+
}
71+
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"login": "github-api-test-org",
3+
"id": 7544739,
4+
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
5+
"url": "https://api.github.com/orgs/github-api-test-org",
6+
"repos_url": "https://api.github.com/orgs/github-api-test-org/repos",
7+
"events_url": "https://api.github.com/orgs/github-api-test-org/events",
8+
"hooks_url": "https://api.github.com/orgs/github-api-test-org/hooks",
9+
"issues_url": "https://api.github.com/orgs/github-api-test-org/issues",
10+
"members_url": "https://api.github.com/orgs/github-api-test-org/members{/member}",
11+
"public_members_url": "https://api.github.com/orgs/github-api-test-org/public_members{/member}",
12+
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
13+
"description": null,
14+
"is_verified": false,
15+
"has_organization_projects": true,
16+
"has_repository_projects": true,
17+
"public_repos": 10,
18+
"public_gists": 0,
19+
"followers": 0,
20+
"following": 0,
21+
"html_url": "https://github.com/github-api-test-org",
22+
"created_at": "2014-05-10T19:39:11Z",
23+
"updated_at": "2015-04-20T00:42:30Z",
24+
"type": "Organization",
25+
"total_private_repos": 0,
26+
"owned_private_repos": 0,
27+
"private_gists": 0,
28+
"disk_usage": 132,
29+
"collaborators": 0,
30+
"billing_email": "kk@kohsuke.org",
31+
"default_repository_permission": "none",
32+
"members_can_create_repositories": false,
33+
"two_factor_requirement_enabled": false,
34+
"plan": {
35+
"name": "free",
36+
"space": 976562499,
37+
"private_repos": 0,
38+
"filled_seats": 7,
39+
"seats": 0
40+
}
41+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.