Skip to content

Add a way to ignore a check for a GitHub team #338

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
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ jira:
titlePattern: ".*\\bmaven\\b.*\\bplugin\\b.*" # will ignore build dependency upgrades i.e. maven plugin version upgrades.
- user: all-contributors[bot]
titlePattern: ".*"
# ignore check rule can also be performed against a GH team within an org.
# in such case the username is ignored and only team/title are considered:
- team:
# A team name within the organization:
name: team-name
# Organization name, i.e. hibernate
organization: org-name
titlePattern: ".*"
# To skip commits that contain only irrelevant files for JIRA-related checks (commit includes JIRA issue key),
# a list of ignored files rules can be configured:
ignoreFiles:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHPullRequestCommitDetail;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GHTeam;
import org.kohsuke.github.GHUser;
import org.kohsuke.github.GitHub;

public class CheckPullRequestContributionRules {

Expand All @@ -58,35 +60,36 @@ void pullRequestChanged(
@PullRequest.Opened @PullRequest.Reopened @PullRequest.Edited @PullRequest.Synchronize
GHEventPayload.PullRequest payload,
@ConfigFile("hibernate-github-bot.yml") RepositoryConfig repositoryConfig,
@ConfigFile("PULL_REQUEST_TEMPLATE.md") String pullRequestTemplate) throws IOException {
checkPullRequestContributionRules( payload.getRepository(), repositoryConfig, pullRequestTemplate, payload.getPullRequest() );
@ConfigFile("PULL_REQUEST_TEMPLATE.md") String pullRequestTemplate,
GitHub gitHub) throws IOException {
checkPullRequestContributionRules( payload.getRepository(), gitHub, repositoryConfig, pullRequestTemplate, payload.getPullRequest() );
}

void checkRunRequested(@CheckRun.Rerequested GHEventPayload.CheckRun payload,
@ConfigFile("hibernate-github-bot.yml") RepositoryConfig repositoryConfig,
@ConfigFile("PULL_REQUEST_TEMPLATE.md") String pullRequestTemplate) throws IOException {
@ConfigFile("PULL_REQUEST_TEMPLATE.md") String pullRequestTemplate,
GitHub gitHub) throws IOException {
for ( GHPullRequest pullRequest : payload.getCheckRun().getPullRequests() ) {
checkPullRequestContributionRules( payload.getRepository(), repositoryConfig, pullRequestTemplate, pullRequest );
checkPullRequestContributionRules( payload.getRepository(), gitHub, repositoryConfig, pullRequestTemplate, pullRequest );
}
}

void checkSuiteRequested(@CheckSuite.Requested @CheckSuite.Rerequested GHEventPayload.CheckSuite payload,
@ConfigFile("hibernate-github-bot.yml") RepositoryConfig repositoryConfig,
@ConfigFile("PULL_REQUEST_TEMPLATE.md") String pullRequestTemplate) throws IOException {
@ConfigFile("PULL_REQUEST_TEMPLATE.md") String pullRequestTemplate,
GitHub gitHub) throws IOException {
for ( GHPullRequest pullRequest : payload.getCheckSuite().getPullRequests() ) {
checkPullRequestContributionRules( payload.getRepository(), repositoryConfig, pullRequestTemplate, pullRequest );
checkPullRequestContributionRules( payload.getRepository(), gitHub, repositoryConfig, pullRequestTemplate, pullRequest );
}
}

private void checkPullRequestContributionRules(GHRepository repository, RepositoryConfig repositoryConfig,
String pullRequestTemplate,
GHPullRequest pullRequest)
throws IOException {
private void checkPullRequestContributionRules(GHRepository repository, GitHub gitHub, RepositoryConfig repositoryConfig,
String pullRequestTemplate, GHPullRequest pullRequest) throws IOException {
if ( !shouldCheck( repository, pullRequest ) ) {
return;
}

PullRequestCheckRunContext context = new PullRequestCheckRunContext( deploymentConfig, repository, repositoryConfig, pullRequest );
PullRequestCheckRunContext context = new PullRequestCheckRunContext( deploymentConfig, gitHub, repository, repositoryConfig, pullRequest );
List<PullRequestCheck> checks = createChecks( repositoryConfig, pullRequestTemplate );
List<PullRequestCheckRunOutput> outputs = new ArrayList<>();
for ( PullRequestCheck check : checks ) {
Expand Down Expand Up @@ -323,8 +326,21 @@ protected boolean shouldCheckPullRequest(PullRequestCheckRunContext context) thr
GHUser author = context.pullRequest.getUser();
String title = context.pullRequest.getTitle();
for ( RepositoryConfig.IgnoreConfiguration ignore : ignoredPRConfigurations ) {
if ( ignore.getUser().equals( author.getLogin() )
&& ignore.getTitlePattern().matcher( title ).matches() ) {
if ( ignore.getTeam().isPresent() ) {
boolean userTeamCanSkip = false;
var teamToFind = ignore.getTeam().get();
GHTeam team = context.gitHub.getOrganization( teamToFind.getOrganization() ).getTeamByName( teamToFind.getName() );
for ( GHUser user : team.listMembers() ) {
if ( user.getLogin().equals( author.getLogin() ) ) {
userTeamCanSkip = true;
break;
}
}
if ( userTeamCanSkip && ignore.getTitlePattern().matcher( title ).matches() ) {
return false;
}
}
else if ( ignore.getUser().equals( author.getLogin() ) && ignore.getTitlePattern().matcher( title ).matches() ) {
return false;
}
}
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/org/hibernate/infra/bot/config/RepositoryConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public static class IgnoreConfiguration {

private String user;
private Pattern titlePattern;
private Optional<GitHubTeam> team = Optional.empty();

public String getUser() {
return user;
Expand All @@ -91,6 +92,35 @@ public Pattern getTitlePattern() {
public void setTitlePattern(String titlePattern) {
this.titlePattern = Patterns.compile( titlePattern );
}

public Optional<GitHubTeam> getTeam() {
return team;
}

public void setTeam(GitHubTeam team) {
this.team = Optional.of( team );
}

public static class GitHubTeam {
private String name;
private String organization;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getOrganization() {
return organization;
}

public void setOrganization(String organization) {
this.organization = organization;
}
}
}

public static class Develocity {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@

import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;

public final class PullRequestCheckRunContext {

public final DeploymentConfig deploymentConfig;
public final GitHub gitHub;
public final GHRepository repository;
public final GHPullRequest pullRequest;
public final RepositoryConfig repositoryConfig;

public PullRequestCheckRunContext(DeploymentConfig deploymentConfig, GHRepository repository,
RepositoryConfig repositoryConfig, GHPullRequest pullRequest) {
public PullRequestCheckRunContext(DeploymentConfig deploymentConfig, GitHub gitHub, GHRepository repository,
RepositoryConfig repositoryConfig, GHPullRequest pullRequest) {
this.deploymentConfig = deploymentConfig;
this.gitHub = gitHub;
this.repository = repository;
this.repositoryConfig = repositoryConfig;
this.pullRequest = pullRequest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import static io.quarkiverse.githubapp.testing.GitHubAppTesting.given;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hibernate.infra.bot.tests.PullRequestMockHelper.mockPagedIterable;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.util.List;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -17,9 +20,15 @@
import org.kohsuke.github.GHCheckRun;
import org.kohsuke.github.GHCheckRunBuilder;
import org.kohsuke.github.GHEvent;
import org.kohsuke.github.GHOrganization;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GHTeam;
import org.kohsuke.github.GHUser;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.PagedIterable;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.junit.jupiter.MockitoExtension;

@QuarkusTest
Expand Down Expand Up @@ -208,4 +217,67 @@ void licenseCheckIgnored() throws IOException {
} );
}

@Test
void licenseCheckIgnoredByTeam() throws IOException {
long repoId = 344815557L;
long prId = 585627026L;
given()
.github( mocks -> {
mocks.configFile( "hibernate-github-bot.yml" )
.fromString( """
jira:
projectKey: "HSEARCH"
# We also ignore jira keys check as dependabot PRs won't have them anyways:
ignore:
- user: dependabot[bot]
titlePattern: ".*\\\\bmaven\\\\b.*\\\\bplugin\\\\b.*"
licenseAgreement:
enabled: true
ignore:
- team:
name: skippable
organization: hibernate
titlePattern: ".*+"
""" );
mocks.configFile( "PULL_REQUEST_TEMPLATE.md" )
.fromString( """
[Please describe here what your change is about]

<!--
Please read and do not remove the following lines:
-->
----------------------
By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0.txt)
and can be relicensed under the terms of the [LGPL v2.1 license](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt) in the future at the maintainers' discretion.
For more information on licensing, please check [here](https://github.com/hibernate/hibernate-search/blob/main/CONTRIBUTING.md#legal).

----------------------
""" );

GHRepository repoMock = mocks.repository( "yrodiere/hibernate-github-bot-playground" );
when( repoMock.getId() ).thenReturn( repoId );
GitHub gitHubMock = mocks.installationClient( 15144501L ); // see the submitted JSON file for this value
GHOrganization organization = mock( GHOrganization.class );
GHTeam team = mock( GHTeam.class );
GHUser user = mock( GHUser.class );
when( user.getLogin() ).thenReturn( "dependabot[bot]" );
PagedIterable<GHUser> page = mockPagedIterable( List.of( user ) );
when( team.listMembers() ).thenReturn( page );
when( organization.getTeamByName( ArgumentMatchers.eq( "skippable" ) ) ).thenReturn( team );
when( gitHubMock.getOrganization( ( anyString() ) ) ).thenReturn( organization );

PullRequestMockHelper.start( mocks, prId, repoMock )
.noComments();

mockCheckRuns( repoMock, "6e9f11a1e2946b207c6eb245ec942f2b5a3ea156" );
} )
.when()
.payloadFromClasspath( "/pullrequest-opened-hsearch-1111-skippable-team-member.json" )
.event( GHEvent.PULL_REQUEST )
.then()
.github( mocks -> {
verifyNoMoreInteractions( mocks.ghObjects() );
} );
}

}
Loading