Skip to content

Commit af5bde7

Browse files
Add fork branch sync (#1898)
* Add fork branch sync * Remove check for fork sync and let the API rethrow exception * Add GHBranchSync model * Update src/main/java/org/kohsuke/github/GHBranchSync.java * Add missing javadoc --------- Co-authored-by: Liam Newman <[email protected]>
1 parent 3c4d80c commit af5bde7

File tree

19 files changed

+1360
-0
lines changed

19 files changed

+1360
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package org.kohsuke.github;
2+
3+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4+
5+
/**
6+
* The type Gh branch sync.
7+
*/
8+
public class GHBranchSync extends GitHubInteractiveObject {
9+
10+
/**
11+
* The Repository that this branch is in.
12+
*/
13+
private GHRepository owner;
14+
15+
/**
16+
* The message.
17+
*/
18+
private String message;
19+
20+
/**
21+
* The merge type.
22+
*/
23+
private String mergeType;
24+
25+
/**
26+
* The base branch.
27+
*/
28+
private String baseBranch;
29+
30+
/**
31+
* Gets owner.
32+
*
33+
* @return the repository that this branch is in.
34+
*/
35+
@SuppressFBWarnings(value = { "EI_EXPOSE_REP" }, justification = "Expected behavior")
36+
public GHRepository getOwner() {
37+
return owner;
38+
}
39+
40+
/**
41+
* Gets message.
42+
*
43+
* @return the message
44+
*/
45+
public String getMessage() {
46+
return message;
47+
}
48+
49+
/**
50+
* Gets merge type.
51+
*
52+
* @return the merge type
53+
*/
54+
public String getMergeType() {
55+
return mergeType;
56+
}
57+
58+
/**
59+
* Gets base branch.
60+
*
61+
* @return the base branch
62+
*/
63+
public String getBaseBranch() {
64+
return baseBranch;
65+
}
66+
67+
/**
68+
* To string.
69+
*
70+
* @return the string
71+
*/
72+
@Override
73+
public String toString() {
74+
return "GHBranchSync{" + "message='" + message + '\'' + ", mergeType='" + mergeType + '\'' + ", baseBranch='"
75+
+ baseBranch + '\'' + '}';
76+
}
77+
78+
/**
79+
* Wrap.
80+
*
81+
* @param repo
82+
* the repo
83+
* @return the GH branch sync
84+
*/
85+
GHBranchSync wrap(GHRepository repo) {
86+
this.owner = repo;
87+
return this;
88+
}
89+
90+
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,6 +1614,24 @@ public GHRepository fork() throws IOException {
16141614
throw new IOException(this + " was forked but can't find the new repository");
16151615
}
16161616

1617+
/**
1618+
* Sync this repository fork branch
1619+
*
1620+
* @param branch
1621+
* the branch to sync
1622+
* @return The current repository
1623+
* @throws IOException
1624+
* the io exception
1625+
*/
1626+
public GHBranchSync sync(String branch) throws IOException {
1627+
return root().createRequest()
1628+
.method("POST")
1629+
.with("branch", branch)
1630+
.withUrlPath(getApiTailUrl("merge-upstream"))
1631+
.fetch(GHBranchSync.class)
1632+
.wrap(this);
1633+
}
1634+
16171635
/**
16181636
* Forks this repository into an organization.
16191637
*

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,36 @@ private GHRepository getRepository(GitHub gitHub) throws IOException {
4747
return gitHub.getOrganization("hub4j-test-org").getRepository("github-api");
4848
}
4949

50+
/**
51+
* Test sync of fork
52+
*
53+
* @throws IOException
54+
* Signals that an I/O exception has occurred.
55+
*/
56+
@Test
57+
public void sync() throws IOException {
58+
GHRepository r = getRepository();
59+
GHBranchSync sync = r.sync("main");
60+
assertThat(sync.getOwner().getFullName(), equalTo("hub4j-test-org/github-api"));
61+
assertThat(sync.getMessage(), equalTo("Successfully fetched and fast-forwarded from upstream github-api:main"));
62+
assertThat(sync.getMergeType(), equalTo("fast-forward"));
63+
assertThat(sync.getBaseBranch(), equalTo("github-api:main"));
64+
}
65+
66+
/**
67+
* Test sync of repository not a fork
68+
*
69+
* @throws IOException
70+
* Signals that an I/O exception has occurred.
71+
*/
72+
@Test(expected = HttpException.class)
73+
public void syncNoFork() throws IOException {
74+
GHRepository r = getRepository();
75+
GHBranchSync sync = r.sync("main");
76+
fail("Should have thrown an exception");
77+
78+
}
79+
5080
/**
5181
* Test zipball.
5282
*
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"login": "bitwiseman",
3+
"id": 1958953,
4+
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
5+
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
6+
"gravatar_id": "",
7+
"url": "https://api.github.com/users/bitwiseman",
8+
"html_url": "https://github.com/bitwiseman",
9+
"followers_url": "https://api.github.com/users/bitwiseman/followers",
10+
"following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
11+
"gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
12+
"starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
13+
"subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
14+
"organizations_url": "https://api.github.com/users/bitwiseman/orgs",
15+
"repos_url": "https://api.github.com/users/bitwiseman/repos",
16+
"events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
17+
"received_events_url": "https://api.github.com/users/bitwiseman/received_events",
18+
"type": "User",
19+
"site_admin": false,
20+
"name": "Liam Newman",
21+
"company": "Cloudbees, Inc.",
22+
"blog": "",
23+
"location": "Seattle, WA, USA",
24+
"email": "[email protected]",
25+
"hireable": null,
26+
"bio": "https://twitter.com/bitwiseman",
27+
"public_repos": 166,
28+
"public_gists": 4,
29+
"followers": 135,
30+
"following": 9,
31+
"created_at": "2012-07-11T20:38:33Z",
32+
"updated_at": "2019-09-24T19:32:29Z"
33+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"login": "hub4j-test-org",
3+
"id": 7544739,
4+
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
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://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": 9,
18+
"public_gists": 0,
19+
"followers": 0,
20+
"following": 0,
21+
"html_url": "https://github.com/hub4j-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": "[email protected]",
31+
"default_repository_permission": "none",
32+
"members_can_create_repositories": false,
33+
"two_factor_requirement_enabled": false,
34+
"members_allowed_repository_creation_type": "none",
35+
"plan": {
36+
"name": "free",
37+
"space": 976562499,
38+
"private_repos": 0,
39+
"filled_seats": 3,
40+
"seats": 0
41+
}
42+
}

0 commit comments

Comments
 (0)