Skip to content
This repository has been archived by the owner on May 28, 2021. It is now read-only.

Commit

Permalink
Merge pull request #36 from retest/feature/github-support
Browse files Browse the repository at this point in the history
Feature/GitHub support (1/3)
  • Loading branch information
martin-v authored Aug 2, 2018
2 parents 2485515 + 4a769b4 commit 0dbc6b6
Show file tree
Hide file tree
Showing 19 changed files with 880 additions and 396 deletions.
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@

<name>rebazer</name>
<description>
Helper service to handle PullRequests on Bitbucket.
Helper service to handle PullRequests on GitHub/Bitbucket.
Rebase PullRequests against target to streamline commit history.
Merge the PullRequest if it's rebased, approved and the build is green.
</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<version>2.0.3.RELEASE</version>
<relativePath />
</parent>

Expand All @@ -42,7 +42,7 @@
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.11.0.201803080745-r</version>
<version>5.0.1.201806211838-r</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
Expand Down Expand Up @@ -80,8 +80,8 @@
</plugin>

<plugin>
<artifactId>jdeb</artifactId>
<groupId>org.vafer</groupId>
<artifactId>jdeb</artifactId>
<version>1.6</version>
<executions>
<execution>
Expand Down
86 changes: 86 additions & 0 deletions src/main/java/org/retest/rebazer/RebazerService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package org.retest.rebazer;

import static org.retest.rebazer.config.RebazerConfig.POLL_INTERVAL_DEFAULT;
import static org.retest.rebazer.config.RebazerConfig.POLL_INTERVAL_KEY;

import org.retest.rebazer.config.RebazerConfig;
import org.retest.rebazer.config.RebazerConfig.RepositoryConfig;
import org.retest.rebazer.config.RebazerConfig.RepositoryHost;
import org.retest.rebazer.config.RebazerConfig.RepositoryTeam;
import org.retest.rebazer.connector.RepositoryConnector;
import org.retest.rebazer.domain.PullRequest;
import org.retest.rebazer.service.PullRequestLastUpdateStore;
import org.retest.rebazer.service.RebaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor( onConstructor = @__( @Autowired ) )
public class RebazerService {

private static final String MSG_REBASE_FAILED = "Rebase failed, this pull request needs some manual love ...";

private final RebaseService rebaseService;
private final RebazerConfig rebazerConfig;
private final PullRequestLastUpdateStore pullRequestLastUpdateStore;

private final RestTemplateBuilder builder;

@Scheduled( fixedDelayString = "${" + POLL_INTERVAL_KEY + ":" + POLL_INTERVAL_DEFAULT + "}000" )
public void pollToHandleAllPullRequests() {
rebazerConfig.getHosts().forEach( repoHost -> {
repoHost.getTeams().forEach( repoTeam -> {
repoTeam.getRepos().forEach( repoConfig -> {
handleRepo( repoHost, repoTeam, repoConfig );
} );
} );
} );
}

private void handleRepo( final RepositoryHost repoHost, final RepositoryTeam repoTeam,
final RepositoryConfig repoConfig ) {
log.debug( "Processing {}.", repoConfig );
final RepositoryConnector repoConnector = repoHost.getType().getRepository( repoTeam, repoConfig, builder );
for ( final PullRequest pullRequest : repoConnector.getAllPullRequests() ) {
handlePullRequest( repoConnector, repoConfig, pullRequest );
}
log.debug( "Processing done for {}.", repoConfig );
}

public void handlePullRequest( final RepositoryConnector repoConnector, final RepositoryConfig repoConfig,
final PullRequest pullRequest ) {
log.debug( "Processing {}.", pullRequest );

if ( pullRequestLastUpdateStore.isHandled( repoConfig, pullRequest ) ) {
log.info( "{} is unchanged since last run (last change: {}).", pullRequest,
pullRequestLastUpdateStore.getLastDate( repoConfig, pullRequest ) );

} else if ( !repoConnector.greenBuildExists( pullRequest ) ) {
log.info( "Waiting for green build of {}.", pullRequest );
pullRequestLastUpdateStore.setHandled( repoConfig, pullRequest );

} else if ( repoConnector.rebaseNeeded( pullRequest ) ) {
if ( !rebaseService.rebase( repoConfig, pullRequest ) ) {
repoConnector.addComment( pullRequest, MSG_REBASE_FAILED );
}
// we need to update the "lastUpdate" of a PullRequest to counteract if addComment is called
pullRequestLastUpdateStore.setHandled( repoConfig, repoConnector.getLatestUpdate( pullRequest ) );

} else if ( !repoConnector.isApproved( pullRequest ) ) {
log.info( "Waiting for approval of {}.", pullRequest );
pullRequestLastUpdateStore.setHandled( repoConfig, pullRequest );

} else {
log.info( "Merging pull request " + pullRequest );
repoConnector.merge( pullRequest );
pullRequestLastUpdateStore.resetAllInThisRepo( repoConfig );
}
}

}
43 changes: 43 additions & 0 deletions src/main/java/org/retest/rebazer/RepositoryHostingTypes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.retest.rebazer;

import java.net.MalformedURLException;
import java.net.URL;

import org.retest.rebazer.config.RebazerConfig.RepositoryConfig;
import org.retest.rebazer.config.RebazerConfig.RepositoryTeam;
import org.retest.rebazer.connector.BitbucketConnector;
import org.retest.rebazer.connector.GithubConnector;
import org.retest.rebazer.connector.RepositoryConnector;
import org.springframework.boot.web.client.RestTemplateBuilder;

import lombok.Getter;
import lombok.SneakyThrows;

public enum RepositoryHostingTypes {

BITBUCKET( "https://bitbucket.org/" ),
GITHUB( "https://github.com/" ),

;

@Getter
final URL defaultUrl;

@SneakyThrows( MalformedURLException.class )
private RepositoryHostingTypes( final String defaultUrl ) {
this.defaultUrl = new URL( defaultUrl );
}

public RepositoryConnector getRepository( final RepositoryTeam repoTeam, final RepositoryConfig repoConfig,
final RestTemplateBuilder templateBuilder ) {
switch ( this ) {
case BITBUCKET:
return new BitbucketConnector( repoTeam, repoConfig, templateBuilder );
case GITHUB:
return new GithubConnector( repoTeam, repoConfig, templateBuilder );
default:
throw new RuntimeException( "No Repository defined for provider: " + this );
}
}

}
2 changes: 1 addition & 1 deletion src/main/java/org/retest/rebazer/config/AppConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
public class AppConfig {

@Bean
public TaskScheduler taskScheduler() {
public static TaskScheduler taskScheduler() {
return new ThreadPoolTaskScheduler();
}

Expand Down
28 changes: 0 additions & 28 deletions src/main/java/org/retest/rebazer/config/BitbucketConfig.java

This file was deleted.

60 changes: 45 additions & 15 deletions src/main/java/org/retest/rebazer/config/RebazerConfig.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.retest.rebazer.config;

import java.net.URL;
import java.util.List;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.retest.rebazer.RepositoryHostingTypes;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

Expand All @@ -13,24 +13,54 @@
@Configuration
@ConfigurationProperties( "rebazer" )
public class RebazerConfig {
private String team;
private String user;
private String pass;

/**
* Values used for {@link org.retest.rebazer.RebazerService#pollToHandleAllPullRequests()}
*/
public final static String POLL_INTERVAL_KEY = "rebazer.pollInterval";
public final static int POLL_INTERVAL_DEFAULT = 60;
private long pollInterval = POLL_INTERVAL_DEFAULT;

private String workspace = "./rebazer-workspace";
private List<Repository> repos;
private int garbageCollectionCountdown = 20;

private List<RepositoryHost> hosts;

@Data
public static class RepositoryHost {
private RepositoryHostingTypes type;
private URL url;
private List<RepositoryTeam> teams;

public URL getUrl() {
if ( url != null ) {
return url;
} else {
return type.getDefaultUrl();
}
}
}

@Data
public static class Repository {
public static class RepositoryTeam {
private String name;
private String branch;
private String url;
private CredentialsProvider credentials;
private Git git;

@Override
public String toString() {
return "Repo " + name + " (" + url + ")";
private String user;
private String pass;
private List<RepositoryConfig> repos;

public String getUser() {
if ( user != null && !user.isEmpty() ) {
return user;
} else {
return name;
}
}
}

@Data
public static class RepositoryConfig {
private String name;
private String masterBranch = "master";
}

}
Loading

0 comments on commit 0dbc6b6

Please sign in to comment.