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

Feature/GitHub support (1/3) #36

Merged
merged 86 commits into from
Aug 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
6aeaca7
First draft create GithubConfig
jakobherdt Jan 8, 2018
02cc880
Change repoUrl to support github
jakobherdt Jan 8, 2018
028476e
Add GithubService to handle PR conditions
jakobherdt Jan 8, 2018
049ccd4
Edit method to parse PullRequests as ArrayList
jakobherdt Jan 8, 2018
d1de03b
Add condition to handle approved PullRequests
jakobherdt Jan 8, 2018
00f799a
Add methods to check if rebaseNeeded(PullRequest)
jakobherdt Jan 8, 2018
1cc50bf
Call method to rebase a repo
jakobherdt Jan 8, 2018
de55565
Add method to merge(PullRequest) into destination
jakobherdt Jan 9, 2018
84ae057
Add comment if a merge conflict happens
jakobherdt Jan 9, 2018
1ff00c8
Add GithubServiceTest and change visibilty of methods
jakobherdt Jan 9, 2018
9f93728
Add greenBuildExists(PullRequest) and add test
jakobherdt Jan 9, 2018
bc1481e
Edit addComment and add pullRequestLastUpdateStore
jakobherdt Jan 16, 2018
67f4025
Add getLatestUpdate and test after rebase
jakobherdt Jan 24, 2018
e1ebae1
Adapt yml.example for multiple services
jakobherdt Jan 24, 2018
5445e13
Extend RebazerConfig to match yaml
jakobherdt Jan 24, 2018
f048322
Extract polling and edit interface
jakobherdt Jan 24, 2018
4df9276
Change repoUrl to get it from RebazerConfig
jakobherdt Jan 24, 2018
609e626
Add Team to Provider methods
jakobherdt Jan 24, 2018
5510b65
Change templates to support multiple user
jakobherdt Jan 24, 2018
d7bd76c
Add restTemplates to support multiple teams
jakobherdt Jan 24, 2018
cb4c6bf
Adapt service tests for new configuration
jakobherdt Jan 24, 2018
b7e6f47
Rename Services to its functionality
jakobherdt Jan 25, 2018
40f9b89
Add List<Team> to support different teams
jakobherdt Jan 25, 2018
ec44014
Rename Repository to its funcionality
jakobherdt Jan 25, 2018
45c4dc5
Add ctor and remove obsolete methods parameter
jakobherdt Jan 25, 2018
106bc78
Adapt RebazerConfig to improve readability
jakobherdt Jan 25, 2018
e079bc4
Use for-loop to uniform loop style
jakobherdt Jan 25, 2018
a40eea0
Add Type as Enum to distinguish supported Provider
jakobherdt Jan 25, 2018
eab91d1
Add parameterized delay value
jakobherdt Jan 25, 2018
9bb2f67
Extract provider from RebazerConfig
jakobherdt Jan 26, 2018
3c96dd5
Remove obsolete code from getLastCommonCommitId
jakobherdt Jan 26, 2018
5a334ab
Change for-loop to Java 8 forEach-loop
jakobherdt Jan 26, 2018
d7a6f99
Rename hosts to host to use Singular form
jakobherdt Jan 26, 2018
a1b3755
Exract unused methods from interface
jakobherdt Jan 26, 2018
8cbc222
Extract methods to improve readability
jakobherdt Jan 26, 2018
a059d08
Change String url to java URL url
jakobherdt Jan 26, 2018
021df28
Change String type to Enum type
jakobherdt Jan 26, 2018
eb3aee2
Extract attributes from RebazerConfig
jakobherdt Jan 29, 2018
0bde742
Refactoring, there can be multiple team*s*
martin-v Jun 7, 2018
bab4bea
Update maven project description
martin-v Jul 11, 2018
14a9e72
Update dependencies
martin-v Jul 11, 2018
7a6b4b4
Fix tests after dependencies updates
martin-v Jul 11, 2018
883f2d1
Document pollInterval config default and rename poll method
martin-v Jul 18, 2018
4c3415d
Rename Provider to Repository, to what it actual represents
martin-v Jul 18, 2018
a8f3ed4
Move rebase method to HandleServices
martin-v Jul 18, 2018
292ed91
Inline restTemplates, because they aren't beans
martin-v Jul 18, 2018
98d145e
Move pollInterval config default to RebazerConfig
martin-v Jul 19, 2018
2eadbf2
Refactore pollToHandleAllPullRequests
martin-v Jul 19, 2018
8de8179
Set sane default in application.yml.example for pollInterval
martin-v Jul 19, 2018
ea096a2
Refactore extract RebaseService.setupRepo()
martin-v Jul 19, 2018
a0e42c8
Remove dupplicate variable
martin-v Jul 19, 2018
b193128
Remove obsolete RebaseService.repoUrl
martin-v Jul 19, 2018
3f7df38
RebaseService refactoring
martin-v Jul 19, 2018
717a717
Extract GitRepoCleaner code in seperate class
martin-v Jul 19, 2018
aa008c2
Improve code readability in GitRepoCleaner.removeAllLocalBranches()
martin-v Jul 19, 2018
15f203e
Refactore RebaseService
martin-v Jul 19, 2018
9b73323
Better name for classes and better package structure
martin-v Jul 19, 2018
6175ce5
Use @Service where it makes sense
martin-v Jul 19, 2018
fdfdadf
Refactoring: Sort methods in RepositoryConnector
martin-v Jul 19, 2018
e2760ec
Centralise url handling in BitbucketConnector
martin-v Jul 19, 2018
15bee35
Better variable names and RepositoryConnector selction to KnownProvider
martin-v Jul 19, 2018
8eab324
Rename RepositoryTeam equal to other configs
martin-v Jul 20, 2018
37ad3c3
Use better consistent variable names
martin-v Jul 20, 2018
247179c
Fix bug that GitRepoCleaner don't handle multiple repos correctly
martin-v Jul 20, 2018
0b0658d
Centralise url handling in GithubConnector
martin-v Jul 20, 2018
2180ca4
Remove repo und url from PullRequest
martin-v Jul 20, 2018
47e1318
Remove obsolete repoConfig in RepositoryConnector.getAllPullRequests
martin-v Jul 20, 2018
cd9614f
Reduce code in PullRequestLastUpdateStore
martin-v Jul 20, 2018
54e7c3e
lastUpdate isn't a usefull criteria to identify a PullRequest
martin-v Jul 20, 2018
3165f4d
Make RepositoryHost.url optional
martin-v Jul 20, 2018
c32732d
Make RepositoryTeam.user optional
martin-v Jul 20, 2018
b448fae
Make RepositoryConfig.branch optional, defaults to "master"
martin-v Jul 20, 2018
f220407
Change RepositoryConfig.masterBranch name and update application.yml.…
martin-v Jul 24, 2018
27d945d
Make methods static which can be static
martin-v Jul 25, 2018
183e43a
Rename KnownProvider to RepositoryHostingTypes
martin-v Jul 25, 2018
e1eb057
Remove dupplicate logger
martin-v Jul 25, 2018
6a24f94
Add param message to addComment
martin-v Aug 2, 2018
4af8bda
Remove unnessary cast
martin-v Aug 2, 2018
cd3ae0c
Use FileUtils.getFile() for multiple combined new File()
martin-v Aug 2, 2018
31bc1e7
Simplify size lookup in parsePullRequestsJson
martin-v Aug 2, 2018
123a819
Make RebaseService.originIsRepoUrl more readable
martin-v Aug 2, 2018
15d4e3a
Simplify GithubConnector.isApproved()
martin-v Aug 2, 2018
1d6190c
Use underscore_style for all demo variables in application.yml.example
martin-v Aug 2, 2018
a7a4633
Remove obsolete / in baseUrl
martin-v Aug 2, 2018
2e00971
Merge dupplicate mergeCommitMessage code
martin-v Aug 2, 2018
4a769b4
Prevent NPE when using string literals
martin-v Aug 2, 2018
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: 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