Skip to content

Commit 49e833f

Browse files
authored
Merge pull request #300 from cognitedata/build-private-repos-only
Add an option to only build repositories that are private
2 parents 919f2b4 + 3a6deff commit 49e833f

File tree

14 files changed

+690
-5
lines changed

14 files changed

+690
-5
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package org.jenkinsci.plugins.github_branch_source;
2+
3+
import hudson.Extension;
4+
import jenkins.scm.api.trait.SCMNavigatorContext;
5+
import jenkins.scm.api.trait.SCMNavigatorTrait;
6+
import jenkins.scm.api.trait.SCMNavigatorTraitDescriptor;
7+
import jenkins.scm.impl.trait.Selection;
8+
import org.jenkinsci.Symbol;
9+
import org.kohsuke.stapler.DataBoundConstructor;
10+
11+
import javax.annotation.Nonnull;
12+
13+
/**
14+
* A {@link Selection} trait that will restrict the discovery of repositories that are public.
15+
*/
16+
public class ExcludePublicRepositoriesTrait extends SCMNavigatorTrait {
17+
18+
/**
19+
* Constructor for stapler.
20+
*/
21+
@DataBoundConstructor
22+
public ExcludePublicRepositoriesTrait() {
23+
}
24+
25+
/**
26+
* {@inheritDoc}
27+
*/
28+
@Override
29+
protected void decorateContext(SCMNavigatorContext<?, ?> context) {
30+
super.decorateContext(context);
31+
GitHubSCMNavigatorContext ctx = (GitHubSCMNavigatorContext) context;
32+
ctx.setExcludePublicRepositories(true);
33+
}
34+
35+
/**
36+
* Exclude archived repositories filter
37+
*/
38+
@Symbol("gitHubExcludePublicRepositories")
39+
@Extension
40+
@Selection
41+
public static class DescriptorImpl extends SCMNavigatorTraitDescriptor {
42+
43+
@Override
44+
public Class<? extends SCMNavigatorContext> getContextClass() {
45+
return GitHubSCMNavigatorContext.class;
46+
}
47+
48+
@Nonnull
49+
@Override
50+
public String getDisplayName() {
51+
return Messages.ExcludePublicRepositoriesTrait_displayName();
52+
}
53+
}
54+
}

src/main/java/org/jenkinsci/plugins/github_branch_source/GitHubSCMNavigator.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,11 @@ public void visitSources(SCMSourceObserver observer) throws IOException, Interru
967967
listener.getLogger()
968968
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
969969
"Skipping repository %s because it is missing one or more of the following topics: '%s'", repo.getName(), gitHubSCMNavigatorContext.getTopics())));
970+
} else if (!repo.isPrivate() && gitHubSCMNavigatorContext.isExcludePublicRepositories()) {
971+
witness.record(repo.getName(), false);
972+
listener.getLogger()
973+
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
974+
"Skipping repository %s because it is public", repo.getName())));
970975
} else if (request.process(repo.getName(), sourceFactory, null, witness)) {
971976
listener.getLogger()
972977
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
@@ -1009,7 +1014,14 @@ public void visitSources(SCMSourceObserver observer) throws IOException, Interru
10091014
listener.getLogger()
10101015
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
10111016
"Skipping repository %s because it is missing one or more of the following topics: '%s'", repo.getName(), gitHubSCMNavigatorContext.getTopics())));
1012-
} else if (request.process(repo.getName(), sourceFactory, null, witness)) {
1017+
1018+
} else if (!repo.isPrivate() && gitHubSCMNavigatorContext.isExcludePublicRepositories()) {
1019+
witness.record(repo.getName(), false);
1020+
listener.getLogger()
1021+
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
1022+
"Skipping repository %s because it is public", repo.getName())));
1023+
1024+
} else if (request.process(repo.getName(), sourceFactory, null, witness)) {
10131025
listener.getLogger().println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
10141026
"%d repositories were processed (query completed)", witness.getCount())));
10151027
}
@@ -1150,6 +1162,12 @@ public void visitSource(String sourceName, SCMSourceObserver observer)
11501162
listener.getLogger()
11511163
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
11521164
"Skipping repository %s because it is missing one or more of the following topics: '%s'", repo.getName(), gitHubSCMNavigatorContext.getTopics())));
1165+
} else if (!repo.isPrivate() && gitHubSCMNavigatorContext.isExcludePublicRepositories()) {
1166+
witness.record(repo.getName(), false);
1167+
listener.getLogger()
1168+
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
1169+
"Skipping repository %s because it is public", repo.getName())));
1170+
11531171
} else if (request.process(repo.getName(), sourceFactory, null, witness)) {
11541172
listener.getLogger()
11551173
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
@@ -1190,6 +1208,12 @@ public void visitSource(String sourceName, SCMSourceObserver observer)
11901208
"Skipping repository %s because it is not in team %s",
11911209
repo.getName(),
11921210
gitHubSCMNavigatorContext.getTeamSlug())));
1211+
} else if (!repo.isPrivate() && gitHubSCMNavigatorContext.isExcludePublicRepositories()) {
1212+
witness.record(repo.getName(), false);
1213+
listener.getLogger()
1214+
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
1215+
"Skipping repository %s because it is public", repo.getName())));
1216+
11931217
} else if (request.process(repo.getName(), sourceFactory, null, witness)) {
11941218
listener.getLogger()
11951219
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
@@ -1228,6 +1252,12 @@ public void visitSource(String sourceName, SCMSourceObserver observer)
12281252
listener.getLogger()
12291253
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
12301254
"Skipping repository %s because it is missing one or more of the following topics: '%s'", repo.getName(), gitHubSCMNavigatorContext.getTopics())));
1255+
} else if (!repo.isPrivate() && gitHubSCMNavigatorContext.isExcludePublicRepositories()) {
1256+
witness.record(repo.getName(), false);
1257+
listener.getLogger()
1258+
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(
1259+
"Skipping repository %s because it is public", repo.getName())));
1260+
12311261
} else if (request.process(repo.getName(), sourceFactory, null, witness)) {
12321262
listener.getLogger()
12331263
.println(GitHubConsoleNote.create(System.currentTimeMillis(), String.format(

src/main/java/org/jenkinsci/plugins/github_branch_source/GitHubSCMNavigatorContext.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ public class GitHubSCMNavigatorContext extends SCMNavigatorContext<GitHubSCMNavi
5353
*/
5454
private boolean excludeArchivedRepositories;
5555

56+
/**
57+
* If true, public repositories will be ignored.
58+
*/
59+
private boolean excludePublicRepositories;
60+
5661
/**
5762
* {@inheritDoc}
5863
*/
@@ -99,10 +104,24 @@ public boolean isExcludeArchivedRepositories() {
99104
return excludeArchivedRepositories;
100105
}
101106

107+
/**
108+
* @return True if public repositories should be ignored, false if they should be included.
109+
*/
110+
public boolean isExcludePublicRepositories() {
111+
return excludePublicRepositories;
112+
}
113+
102114
/**
103115
* @param excludeArchivedRepositories Set true to exclude archived repositories
104116
*/
105117
public void setExcludeArchivedRepositories(boolean excludeArchivedRepositories) {
106118
this.excludeArchivedRepositories = excludeArchivedRepositories;
107119
}
120+
121+
/**
122+
* @param excludePublicRepositories Set true to exclude public repositories
123+
*/
124+
public void setExcludePublicRepositories(boolean excludePublicRepositories) {
125+
this.excludePublicRepositories = excludePublicRepositories;
126+
}
108127
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?jelly escape-by-default='true'?>
2+
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:c="/lib/credentials"
3+
xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"
4+
xmlns:f2="/org/jenkinsci/plugins/github_branch_source/form">
5+
</j:jelly>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
Exclude GitHub repositories that are public. If set, no jobs will be created for public repositories.
3+
</div>

src/main/resources/org/jenkinsci/plugins/github_branch_source/Messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ SSHCheckoutTrait.useAgentKey=- use build agent''s key -
6464
TagDiscoveryTrait.authorityDisplayName=Trust origin tags
6565
TagDiscoveryTrait.displayName=Discover tags
6666
ExcludeArchivedRepositoriesTrait.displayName=Exclude archived repositories
67+
ExcludePublicRepositoriesTrait.displayName=Exclude public repositories
6768

6869
GitHubSCMNavigator.general=General
6970
GitHubSCMNavigator.withinRepository=Within repository

src/test/java/org/jenkinsci/plugins/github_branch_source/GitHubSCMNavigatorTest.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,19 @@ public void fetchOneRepo_BelongingToAuthenticatedUser_ExcludingArchived() throws
221221
assertThat(projectNames, empty());
222222
}
223223

224+
@Test
225+
public void fetchOneRepo_ExcludingPublic() throws Exception {
226+
setCredentials(Collections.singletonList(credentials));
227+
navigator = navigatorForRepoOwner("stephenc", credentials.getId());
228+
navigator.setTraits(Collections.singletonList(new ExcludePublicRepositoriesTrait()));
229+
final Set<String> projectNames = new HashSet<>();
230+
final SCMSourceObserver observer = getObserver(projectNames);
231+
232+
navigator.visitSources(SCMSourceObserver.filter(observer, "yolo-private"));
233+
234+
assertThat(projectNames, containsInAnyOrder("yolo-private"));
235+
}
236+
224237
@Test
225238
public void fetchOneRepo_BelongingToOrg() throws Exception {
226239
final Set<String> projectNames = new HashSet<>();
@@ -313,6 +326,18 @@ public void fetchRepos_BelongingToOrg_ExcludingArchived() throws Exception {
313326
assertThat(projectNames, containsInAnyOrder("basic", "yolo"));
314327
}
315328

329+
@Test
330+
public void fetchRepos_BelongingToOrg_ExcludingPublic() throws Exception {
331+
navigator.setTraits(Collections.singletonList(new ExcludePublicRepositoriesTrait()));
332+
final Set<String> projectNames = new HashSet<>();
333+
final SCMSourceObserver observer = getObserver(projectNames);
334+
335+
navigator.visitSources(
336+
SCMSourceObserver.filter(observer, "Hello-World", "github-branch-source-plugin", "yolo-private"));
337+
338+
assertThat(projectNames, containsInAnyOrder("yolo-private"));
339+
}
340+
316341
@Test
317342
public void fetchRepos_BelongingToUser() throws Exception {
318343
navigator = navigatorForRepoOwner("stephenc", null);
@@ -321,7 +346,7 @@ public void fetchRepos_BelongingToUser() throws Exception {
321346

322347
navigator.visitSources(observer);
323348

324-
assertThat(projectNames, containsInAnyOrder("yolo", "yolo-archived"));
349+
assertThat(projectNames, containsInAnyOrder("yolo", "yolo-archived", "yolo-private"));
325350
}
326351

327352
@Test

src/test/resources/api/__files/body-cloudbeers-repos-v3FBW.json

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,99 @@
742742
"push": false,
743743
"pull": true
744744
}
745+
}, {
746+
"id": 43041241,
747+
"name": "yolo-private",
748+
"full_name": "cloudbeers/yolo-private",
749+
"owner": {
750+
"login": "cloudbeers",
751+
"id": 4181899,
752+
"avatar_url": "https://avatars.githubusercontent.com/u/4181899?v=3",
753+
"gravatar_id": "",
754+
"url": "https://api.github.com/users/cloudbeers",
755+
"html_url": "https://github.com/cloudbeers",
756+
"followers_url": "https://api.github.com/users/cloudbeers/followers",
757+
"following_url": "https://api.github.com/users/cloudbeers/following{/other_user}",
758+
"gists_url": "https://api.github.com/users/cloudbeers/gists{/gist_id}",
759+
"starred_url": "https://api.github.com/users/cloudbeers/starred{/owner}{/repo}",
760+
"subscriptions_url": "https://api.github.com/users/cloudbeers/subscriptions",
761+
"organizations_url": "https://api.github.com/users/cloudbeers/orgs",
762+
"repos_url": "https://api.github.com/users/cloudbeers/repos",
763+
"events_url": "https://api.github.com/users/cloudbeers/events{/privacy}",
764+
"received_events_url": "https://api.github.com/users/cloudbeers/received_events",
765+
"type": "Organization",
766+
"site_admin": false
767+
},
768+
"private": true,
769+
"html_url": "https://github.com/cloudbeers/yolo-private",
770+
"description": "It lived once, and then it was archived",
771+
"fork": false,
772+
"url": "https://api.github.com/repos/cloudbeers/yolo-private",
773+
"forks_url": "https://api.github.com/repos/cloudbeers/yolo-private/forks",
774+
"keys_url": "https://api.github.com/repos/cloudbeers/yolo-private/keys{/key_id}",
775+
"collaborators_url": "https://api.github.com/repos/cloudbeers/yolo-private/collaborators{/collaborator}",
776+
"teams_url": "https://api.github.com/repos/cloudbeers/yolo-private/teams",
777+
"hooks_url": "https://api.github.com/repos/cloudbeers/yolo-private/hooks",
778+
"issue_events_url": "https://api.github.com/repos/cloudbeers/yolo-private/issues/events{/number}",
779+
"events_url": "https://api.github.com/repos/cloudbeers/yolo-private/events",
780+
"assignees_url": "https://api.github.com/repos/cloudbeers/yolo-private/assignees{/user}",
781+
"branches_url": "https://api.github.com/repos/cloudbeers/yolo-private/branches{/branch}",
782+
"tags_url": "https://api.github.com/repos/cloudbeers/yolo-private/tags",
783+
"blobs_url": "https://api.github.com/repos/cloudbeers/yolo-private/git/blobs{/sha}",
784+
"git_tags_url": "https://api.github.com/repos/cloudbeers/yolo-private/git/tags{/sha}",
785+
"git_refs_url": "https://api.github.com/repos/cloudbeers/yolo-private/git/refs{/sha}",
786+
"trees_url": "https://api.github.com/repos/cloudbeers/yolo-private/git/trees{/sha}",
787+
"statuses_url": "https://api.github.com/repos/cloudbeers/yolo-private/statuses/{sha}",
788+
"languages_url": "https://api.github.com/repos/cloudbeers/yolo-private/languages",
789+
"stargazers_url": "https://api.github.com/repos/cloudbeers/yolo-private/stargazers",
790+
"contributors_url": "https://api.github.com/repos/cloudbeers/yolo-private/contributors",
791+
"subscribers_url": "https://api.github.com/repos/cloudbeers/yolo-private/subscribers",
792+
"subscription_url": "https://api.github.com/repos/cloudbeers/yolo-private/subscription",
793+
"commits_url": "https://api.github.com/repos/cloudbeers/yolo-private/commits{/sha}",
794+
"git_commits_url": "https://api.github.com/repos/cloudbeers/yolo-private/git/commits{/sha}",
795+
"comments_url": "https://api.github.com/repos/cloudbeers/yolo-private/comments{/number}",
796+
"issue_comment_url": "https://api.github.com/repos/cloudbeers/yolo-private/issues/comments{/number}",
797+
"contents_url": "https://api.github.com/repos/cloudbeers/yolo-private/contents/{+path}",
798+
"compare_url": "https://api.github.com/repos/cloudbeers/yolo-private/compare/{base}...{head}",
799+
"merges_url": "https://api.github.com/repos/cloudbeers/yolo-private/merges",
800+
"archive_url": "https://api.github.com/repos/cloudbeers/yolo-private/{archive_format}{/ref}",
801+
"downloads_url": "https://api.github.com/repos/cloudbeers/yolo-private/downloads",
802+
"issues_url": "https://api.github.com/repos/cloudbeers/yolo-private/issues{/number}",
803+
"pulls_url": "https://api.github.com/repos/cloudbeers/yolo-private/pulls{/number}",
804+
"milestones_url": "https://api.github.com/repos/cloudbeers/yolo-private/milestones{/number}",
805+
"notifications_url": "https://api.github.com/repos/cloudbeers/yolo-private/notifications{?since,all,participating}",
806+
"labels_url": "https://api.github.com/repos/cloudbeers/yolo-private/labels{/name}",
807+
"releases_url": "https://api.github.com/repos/cloudbeers/yolo-private/releases{/id}",
808+
"deployments_url": "https://api.github.com/repos/cloudbeers/yolo-private/deployments",
809+
"created_at": "2015-09-24T02:58:30Z",
810+
"updated_at": "2016-12-07T23:55:35Z",
811+
"pushed_at": "2016-12-01T16:07:01Z",
812+
"git_url": "git://github.com/cloudbeers/yolo-private.git",
813+
"ssh_url": "git@github.com:cloudbeers/yolo-private.git",
814+
"clone_url": "https://github.com/cloudbeers/yolo-private.git",
815+
"svn_url": "https://github.com/cloudbeers/yolo-private",
816+
"homepage": "http://yolo-private.example.com",
817+
"size": 3,
818+
"stargazers_count": 0,
819+
"watchers_count": 0,
820+
"language": null,
821+
"has_issues": true,
822+
"has_downloads": true,
823+
"archived": false,
824+
"has_wiki": true,
825+
"has_pages": false,
826+
"forks_count": 3,
827+
"mirror_url": null,
828+
"open_issues_count": 1,
829+
"forks": 3,
830+
"open_issues": 1,
831+
"watchers": 0,
832+
"default_branch": "master",
833+
"permissions": {
834+
"admin": false,
835+
"push": false,
836+
"pull": true
837+
}
745838
}, {
746839
"id": 63128175,
747840
"name": "blueocean-demo-project",
@@ -1300,4 +1393,4 @@
13001393
"push": false,
13011394
"pull": true
13021395
}
1303-
}]
1396+
}]

0 commit comments

Comments
 (0)