Skip to content

feat: add ability to add checks with app ids #1844

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/main/java/org/kohsuke/github/GHBranchProtection.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.kohsuke.github;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

Expand Down Expand Up @@ -221,6 +222,55 @@ public boolean isEnabled() {
}
}

/**
* The type Check.
*/
public static class Check {
private String context;

@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer appId;

/**
* no-arg constructor for the serializer
*/
public Check() {
}

/**
* Regular constructor for use in user business logic
*
* @param context
* the context string of the check
* @param appId
* the application ID the check is supposed to come from. Pass "-1" to explicitly allow any app to
* set the status. Pass "null" to automatically select the GitHub App that has recently provided this
* check.
*/
public Check(String context, Integer appId) {
this.context = context;
this.appId = appId;
}

/**
* The context string of the check
*
* @return the string
*/
public String getContext() {
return context;
}

/**
* The application ID the check is supposed to come from. The value "-1" indicates "any source".
*
* @return the integer
*/
public Integer getAppId() {
return appId;
}
}

/**
* The type AllowForcePushes.
*/
Expand Down Expand Up @@ -462,6 +512,9 @@ public static class RequiredStatusChecks {
@JsonProperty
private Collection<String> contexts;

@JsonProperty
private Collection<Check> checks;

@JsonProperty
private boolean strict;

Expand All @@ -477,6 +530,15 @@ public Collection<String> getContexts() {
return Collections.unmodifiableCollection(contexts);
}

/**
* Gets checks.
*
* @return the checks
*/
public Collection<Check> getChecks() {
return Collections.unmodifiableCollection(checks);
}

/**
* Gets url.
*
Expand Down
33 changes: 31 additions & 2 deletions src/main/java/org/kohsuke/github/GHBranchProtectionBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static org.kohsuke.github.internal.Previews.LUKE_CAGE;

Expand Down Expand Up @@ -50,8 +51,23 @@ public class GHBranchProtectionBuilder {
* the checks
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder addRequiredStatusChecks(Collection<GHBranchProtection.Check> checks) {
getStatusChecks().checks.addAll(checks);
return this;
}

/**
* Add required checks gh branch protection builder.
*
* @param checks
* the checks
* @return the gh branch protection builder
*/
@Deprecated
public GHBranchProtectionBuilder addRequiredChecks(Collection<String> checks) {
getStatusChecks().contexts.addAll(checks);
getStatusChecks().checks.addAll(checks.stream()
.map(context -> new GHBranchProtection.Check(context, null))
.collect(Collectors.toList()));
return this;
}

Expand All @@ -62,11 +78,24 @@ public GHBranchProtectionBuilder addRequiredChecks(Collection<String> checks) {
* the checks
* @return the gh branch protection builder
*/
@Deprecated
public GHBranchProtectionBuilder addRequiredChecks(String... checks) {
addRequiredChecks(Arrays.asList(checks));
return this;
}

/**
* Add required checks gh branch protection builder.
*
* @param checks
* the checks
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder addRequiredChecks(GHBranchProtection.Check... checks) {
addRequiredStatusChecks(Arrays.asList(checks));
return this;
}

/**
* Allow deletion of the protected branch.
*
Expand Down Expand Up @@ -547,7 +576,7 @@ private static class Restrictions {
}

private static class StatusChecks {
final List<String> contexts = new ArrayList<String>();
final List<GHBranchProtection.Check> checks = new ArrayList<>();
boolean strict;
}
}
27 changes: 27 additions & 0 deletions src/test/java/org/kohsuke/github/GHBranchProtectionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import org.kohsuke.github.GHBranchProtection.RequiredReviews;
import org.kohsuke.github.GHBranchProtection.RequiredStatusChecks;

import java.util.ArrayList;

import static org.hamcrest.Matchers.*;

// TODO: Auto-generated Javadoc
Expand Down Expand Up @@ -189,6 +191,31 @@ public void testSignedCommits() throws Exception {
assertThat(protection.getRequiredSignatures(), is(false));
}

/**
* Checks with app ids are being populated
*
* @throws Exception
* the exception
*/
@Test
public void testChecksWithAppIds() throws Exception {
GHBranchProtection protection = branch.enableProtection()
.addRequiredChecks(new GHBranchProtection.Check("context", -1),
new GHBranchProtection.Check("context2", 123),
new GHBranchProtection.Check("context3", null))
.enable();

ArrayList<GHBranchProtection.Check> resultChecks = new ArrayList<>(
protection.getRequiredStatusChecks().getChecks());

assertThat(resultChecks.size(), is(3));
assertThat(resultChecks.get(0).getContext(), is("context"));
assertThat(resultChecks.get(0).getAppId(), nullValue());
assertThat(resultChecks.get(1).getContext(), is("context2"));
assertThat(resultChecks.get(1).getAppId(), is(123));
assertThat(resultChecks.get(2).getContext(), is("context3"));
}

/**
* Test get protection.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"login": "tginiotis-at-work",
"id": 61763026,
"node_id": "MDQ6VXNlcjYxNzYzMDI2",
"avatar_url": "https://avatars.githubusercontent.com/u/61763026?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tginiotis-at-work",
"html_url": "https://github.com/tginiotis-at-work",
"followers_url": "https://api.github.com/users/tginiotis-at-work/followers",
"following_url": "https://api.github.com/users/tginiotis-at-work/following{/other_user}",
"gists_url": "https://api.github.com/users/tginiotis-at-work/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tginiotis-at-work/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tginiotis-at-work/subscriptions",
"organizations_url": "https://api.github.com/users/tginiotis-at-work/orgs",
"repos_url": "https://api.github.com/users/tginiotis-at-work/repos",
"events_url": "https://api.github.com/users/tginiotis-at-work/events{/privacy}",
"received_events_url": "https://api.github.com/users/tginiotis-at-work/received_events",
"type": "User",
"site_admin": false,
"name": "Tadas Giniotis",
"company": "IBM Lietuva",
"blog": "",
"location": null,
"email": null,
"hireable": null,
"bio": null,
"twitter_username": null,
"public_repos": 12,
"public_gists": 0,
"followers": 0,
"following": 0,
"created_at": "2020-03-03T23:04:00Z",
"updated_at": "2024-05-15T15:03:51Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
{
"id": 802086844,
"node_id": "R_kgDOL87fvA",
"name": "temp-testChecksWithAppIds",
"full_name": "hub4j-test-org/temp-testChecksWithAppIds",
"private": false,
"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/temp-testChecksWithAppIds",
"description": "A test repository for testing the github-api project: temp-testChecksWithAppIds",
"fork": false,
"url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds",
"forks_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/forks",
"keys_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/teams",
"hooks_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/hooks",
"issue_events_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/issues/events{/number}",
"events_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/events",
"assignees_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/assignees{/user}",
"branches_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/branches{/branch}",
"tags_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/tags",
"blobs_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/statuses/{sha}",
"languages_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/languages",
"stargazers_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/stargazers",
"contributors_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/contributors",
"subscribers_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/subscribers",
"subscription_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/subscription",
"commits_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/contents/{+path}",
"compare_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/merges",
"archive_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/downloads",
"issues_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/issues{/number}",
"pulls_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/pulls{/number}",
"milestones_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/milestones{/number}",
"notifications_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/labels{/name}",
"releases_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/releases{/id}",
"deployments_url": "https://api.github.com/repos/hub4j-test-org/temp-testChecksWithAppIds/deployments",
"created_at": "2024-05-17T13:51:56Z",
"updated_at": "2024-05-17T13:52:00Z",
"pushed_at": "2024-05-17T13:51:57Z",
"git_url": "git://github.com/hub4j-test-org/temp-testChecksWithAppIds.git",
"ssh_url": "git@github.com:hub4j-test-org/temp-testChecksWithAppIds.git",
"clone_url": "https://github.com/hub4j-test-org/temp-testChecksWithAppIds.git",
"svn_url": "https://github.com/hub4j-test-org/temp-testChecksWithAppIds",
"homepage": "http://github-api.kohsuke.org/",
"size": 0,
"stargazers_count": 0,
"watchers_count": 0,
"language": null,
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"has_discussions": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 0,
"license": null,
"allow_forking": true,
"is_template": false,
"web_commit_signoff_required": false,
"topics": [],
"visibility": "public",
"forks": 0,
"open_issues": 0,
"watchers": 0,
"default_branch": "main",
"permissions": {
"admin": true,
"maintain": true,
"push": true,
"triage": true,
"pull": true
},
"temp_clone_token": "",
"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": 22
}
Loading