You've already forked woodpecker
							
							
				mirror of
				https://github.com/woodpecker-ci/woodpecker.git
				synced 2025-10-30 23:27:39 +02:00 
			
		
		
		
	integrated plugin model for remotes
This commit is contained in:
		
							
								
								
									
										20
									
								
								plugin/remote/bitbucket/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								plugin/remote/bitbucket/init.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | package bitbucket | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/drone/drone/plugin/remote" | ||||||
|  | 	"github.com/drone/drone/shared/model" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func init() { | ||||||
|  | 	remote.Register(model.RemoteBitbucket, plugin) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func plugin(remote *model.Remote) remote.Remote { | ||||||
|  | 	return &Bitbucket{ | ||||||
|  | 		URL:     remote.URL, | ||||||
|  | 		API:     remote.API, | ||||||
|  | 		Client:  remote.Client, | ||||||
|  | 		Secret:  remote.Secret, | ||||||
|  | 		Enabled: remote.Open, | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								plugin/remote/github/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								plugin/remote/github/init.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | package github | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/drone/drone/plugin/remote" | ||||||
|  | 	"github.com/drone/drone/shared/model" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func init() { | ||||||
|  | 	remote.Register(model.RemoteGithub, plugin) | ||||||
|  | 	remote.Register(model.RemoteGithubEnterprise, plugin) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func plugin(remote *model.Remote) remote.Remote { | ||||||
|  | 	return &Github{ | ||||||
|  | 		URL:     remote.URL, | ||||||
|  | 		API:     remote.API, | ||||||
|  | 		Client:  remote.Client, | ||||||
|  | 		Secret:  remote.Secret, | ||||||
|  | 		Enabled: remote.Open, | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								plugin/remote/gitlab/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								plugin/remote/gitlab/init.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | package gitlab | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/drone/drone/plugin/remote" | ||||||
|  | 	"github.com/drone/drone/shared/model" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func init() { | ||||||
|  | 	remote.Register(model.RemoteGitlab, plugin) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func plugin(remote *model.Remote) remote.Remote { | ||||||
|  | 	return &Gitlab{ | ||||||
|  | 		URL:     remote.URL, | ||||||
|  | 		Enabled: remote.Open, | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -2,8 +2,27 @@ package remote | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
|  | 	"github.com/drone/drone/shared/model" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // Defines a model for integrating (or pluggin in) remote version | ||||||
|  | // control systems, such as GitHub and Bitbucket. | ||||||
|  | type Plugin func(*model.Remote) Remote | ||||||
|  |  | ||||||
|  | var plugins = map[string]Plugin{} | ||||||
|  |  | ||||||
|  | // Register registers a new plugin. | ||||||
|  | func Register(name string, plugin Plugin) { | ||||||
|  | 	plugins[name] = plugin | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Lookup retrieves the plugin for the remote. | ||||||
|  | func Lookup(name string) (Plugin, bool) { | ||||||
|  | 	plugin, ok := plugins[name] | ||||||
|  | 	return plugin, ok | ||||||
|  | } | ||||||
|  |  | ||||||
| type Remote interface { | type Remote interface { | ||||||
| 	// GetName returns the name of this remote system. | 	// GetName returns the name of this remote system. | ||||||
| 	GetName() string | 	GetName() string | ||||||
|   | |||||||
| @@ -42,11 +42,13 @@ | |||||||
| 		<script src="/scripts/controllers/setup.js"></script> | 		<script src="/scripts/controllers/setup.js"></script> | ||||||
| 		<script src="/scripts/controllers/sync.js"></script> | 		<script src="/scripts/controllers/sync.js"></script> | ||||||
| 		<script src="/scripts/controllers/main.js"></script> | 		<script src="/scripts/controllers/main.js"></script> | ||||||
|  | 		<script src="/scripts/controllers/login.js"></script> | ||||||
| 		<script src="/scripts/services/auth.js"></script> | 		<script src="/scripts/services/auth.js"></script> | ||||||
| 		<script src="/scripts/services/conf.js"></script> | 		<script src="/scripts/services/conf.js"></script> | ||||||
| 		<script src="/scripts/services/repo.js"></script> | 		<script src="/scripts/services/repo.js"></script> | ||||||
| 		<script src="/scripts/services/user.js"></script> | 		<script src="/scripts/services/user.js"></script> | ||||||
| 		<script src="/scripts/services/feed.js"></script> | 		<script src="/scripts/services/feed.js"></script> | ||||||
|  | 		<script src="/scripts/services/remote.js"></script> | ||||||
| 		<script src="/scripts/services/notify.js"></script> | 		<script src="/scripts/services/notify.js"></script> | ||||||
| 		<script src="/scripts/services/stdout.js"></script> | 		<script src="/scripts/services/stdout.js"></script> | ||||||
| 		<script src="/scripts/filters/filters.js"></script> | 		<script src="/scripts/filters/filters.js"></script> | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ app.config(['$routeProvider', '$locationProvider', function($routeProvider, $loc | |||||||
| 		}) | 		}) | ||||||
| 		.when('/login', { | 		.when('/login', { | ||||||
| 			templateUrl: '/views/login.html', | 			templateUrl: '/views/login.html', | ||||||
|  | 			controller: 'LoginController', | ||||||
| 			title: 'Login', | 			title: 'Login', | ||||||
| 		}) | 		}) | ||||||
| 		.when('/setup', { | 		.when('/setup', { | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								server/app/scripts/controllers/login.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								server/app/scripts/controllers/login.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | 'use strict'; | ||||||
|  |  | ||||||
|  | angular.module('app').controller("LoginController", function($scope, $http, remotes) { | ||||||
|  | 	$scope.state=0 | ||||||
|  | 	$scope.user = remotes.getLogins().success(function (data) { | ||||||
|  | 			$scope.remotes = (typeof data==="string")?[]:data; | ||||||
|  | 			$scope.state = 1; | ||||||
|  | 		}) | ||||||
|  | 		.error(function (error) { | ||||||
|  | 			$scope.remotes = []; | ||||||
|  | 			$scope.state = 1; | ||||||
|  | 		}); | ||||||
|  | }); | ||||||
| @@ -1,14 +1,18 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
| angular.module('app').controller("SetupController", function($scope, $http, $routeParams) { | angular.module('app').controller("SetupController", function($scope, $http, $routeParams, $window) { | ||||||
|  |  | ||||||
| 	// create a remote that will be populated | 	// create a remote that will be populated | ||||||
| 	// and persisted to the database. | 	// and persisted to the database. | ||||||
| 	$scope.remote = {}; | 	$scope.remote = {}; | ||||||
| 	$scope.remote.type = $routeParams.remote; | 	$scope.remote.type = $routeParams.remote; | ||||||
| 	$scope.remote.register = true; | 	$scope.remote.register = false; | ||||||
|  | 	$scope.window = $window | ||||||
|  |  | ||||||
|  | 	// pre-populate the form if the remote | ||||||
|  | 	// type is selected and is a cloud service | ||||||
|  | 	// with a known URL and standard configuration. | ||||||
| 	switch($scope.remote.type) { | 	switch($scope.remote.type) { | ||||||
| 	case undefined: |  | ||||||
| 	case 'github.com': | 	case 'github.com': | ||||||
| 		$scope.remote.type = "github.com" | 		$scope.remote.type = "github.com" | ||||||
| 		$scope.remote.url = "https://github.com"; | 		$scope.remote.url = "https://github.com"; | ||||||
| @@ -26,7 +30,7 @@ angular.module('app').controller("SetupController", function($scope, $http, $rou | |||||||
| 			success(function(data, status, headers, config) { | 			success(function(data, status, headers, config) { | ||||||
| 				delete $scope.failure; | 				delete $scope.failure; | ||||||
| 				$scope.remote = data; | 				$scope.remote = data; | ||||||
| 				console.log('success', $scope.remote); | 				$window.location.href="/login/"+data.type; | ||||||
| 			}). | 			}). | ||||||
| 			error(function(data, status, headers, config) { | 			error(function(data, status, headers, config) { | ||||||
| 				$scope.failure = data; | 				$scope.failure = data; | ||||||
|   | |||||||
| @@ -64,6 +64,31 @@ angular.module('app').filter('badgeMarkup', function() { | |||||||
|   } |   } | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | angular.module('app').filter('remoteName', function() { | ||||||
|  |   return function(name) { | ||||||
|  |     switch (name) { | ||||||
|  |     case 'gitlab.com'            : return 'GitLab'; | ||||||
|  |     case 'github.com'            : return 'GitHub'; | ||||||
|  |     case 'enterprise.github.com' : return 'GitHub Enterprise'; | ||||||
|  |     case 'bitbucket.org'         : return 'Bitbucket'; | ||||||
|  |     case 'stash.atlassian.com'   : return 'Atlassian Stash'; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | angular.module('app').filter('remoteIcon', function() { | ||||||
|  |   return function(name) { | ||||||
|  |     switch (name) { | ||||||
|  |     case 'gitlab.com'            : return 'fa-git-square'; | ||||||
|  |     case 'github.com'            : return 'fa-github-square'; | ||||||
|  |     case 'enterprise.github.com' : return 'fa-github-square'; | ||||||
|  |     case 'bitbucket.org'         : return 'fa-bitbucket-square'; | ||||||
|  |     case 'stash.atlassian.com'   : return 'fa-bitbucket-square'; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  |  | ||||||
| angular.module('app').filter('unique', function() { | angular.module('app').filter('unique', function() { | ||||||
|     return function(input, key) { |     return function(input, key) { | ||||||
|         var unique = {}; |         var unique = {}; | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								server/app/scripts/services/remote.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								server/app/scripts/services/remote.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | 'use strict'; | ||||||
|  |  | ||||||
|  | // Service facilitates interaction with the remote API. | ||||||
|  | angular.module('app').service('remotes', ['$http', function($http) { | ||||||
|  |  | ||||||
|  | 	this.get = function() { | ||||||
|  | 		return $http.get('/v1/remotes'); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	this.getLogins = function() { | ||||||
|  | 		return $http.get('/v1/logins'); | ||||||
|  | 	}; | ||||||
|  | }]); | ||||||
| @@ -650,6 +650,7 @@ nav div.options .pure-button i { | |||||||
|   -o-box-sizing: border-box; |   -o-box-sizing: border-box; | ||||||
|   box-sizing: border-box; |   box-sizing: border-box; | ||||||
| } | } | ||||||
|  | #setuppage .pure-g, | ||||||
| #loginpage .pure-g { | #loginpage .pure-g { | ||||||
|   padding: 30px; |   padding: 30px; | ||||||
|   border: 1px solid #DDD; |   border: 1px solid #DDD; | ||||||
| @@ -662,6 +663,7 @@ nav div.options .pure-button i { | |||||||
|   -o-box-sizing: border-box; |   -o-box-sizing: border-box; | ||||||
|   box-sizing: border-box; |   box-sizing: border-box; | ||||||
| } | } | ||||||
|  | #setuppage .pure-g a, | ||||||
| #loginpage .pure-g a { | #loginpage .pure-g a { | ||||||
|   display: block; |   display: block; | ||||||
|   background: #45494b; |   background: #45494b; | ||||||
| @@ -671,9 +673,11 @@ nav div.options .pure-button i { | |||||||
|   border-radius: 5px; |   border-radius: 5px; | ||||||
|   text-decoration: none; |   text-decoration: none; | ||||||
| } | } | ||||||
|  | #setuppage .pure-g a:hover, | ||||||
| #loginpage .pure-g a:hover { | #loginpage .pure-g a:hover { | ||||||
|   background: #262626; |   background: #262626; | ||||||
| } | } | ||||||
|  | #setuppage .pure-g [class*="fa-"], | ||||||
| #loginpage .pure-g [class*="fa-"] { | #loginpage .pure-g [class*="fa-"] { | ||||||
|   float: left; |   float: left; | ||||||
|   font-size: 20px; |   font-size: 20px; | ||||||
| @@ -684,12 +688,74 @@ nav div.options .pure-button i { | |||||||
|   min-width: 27px; |   min-width: 27px; | ||||||
|   min-height: 20px; |   min-height: 20px; | ||||||
| } | } | ||||||
|  | #setuppage .pure-g .pure-u-1 a, | ||||||
| #loginpage .pure-g .pure-u-1 a { | #loginpage .pure-g .pure-u-1 a { | ||||||
|   margin-bottom: 10px; |   margin-bottom: 10px; | ||||||
| } | } | ||||||
|  | #setuppage .pure-g .pure-u-1:last-child a, | ||||||
| #loginpage .pure-g .pure-u-1:last-child a { | #loginpage .pure-g .pure-u-1:last-child a { | ||||||
|   margin-bottom: 0px; |   margin-bottom: 0px; | ||||||
| } | } | ||||||
|  | #setuppage2 { | ||||||
|  |   margin-bottom: 50px; | ||||||
|  | } | ||||||
|  | #setuppage2 section { | ||||||
|  |   -webkit-box-sizing: border-box; | ||||||
|  |   -moz-box-sizing: border-box; | ||||||
|  |   -ms-box-sizing: border-box; | ||||||
|  |   -o-box-sizing: border-box; | ||||||
|  |   box-sizing: border-box; | ||||||
|  | } | ||||||
|  | #setuppage2 section .pure-g { | ||||||
|  |   padding: 30px; | ||||||
|  |   border: 1px solid #DDD; | ||||||
|  |   max-width: 400px; | ||||||
|  |   margin: 0px auto; | ||||||
|  |   margin-top: 50px; | ||||||
|  |   -webkit-box-sizing: border-box; | ||||||
|  |   -moz-box-sizing: border-box; | ||||||
|  |   -ms-box-sizing: border-box; | ||||||
|  |   -o-box-sizing: border-box; | ||||||
|  |   box-sizing: border-box; | ||||||
|  | } | ||||||
|  | #setuppage2 section label { | ||||||
|  |   display: inline-block; | ||||||
|  | } | ||||||
|  | #setuppage2 section input[type='text'] { | ||||||
|  |   margin-top: 5px; | ||||||
|  |   margin-bottom: 10px; | ||||||
|  |   box-shadow: none; | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  | #setuppage2 section .pure-button-primary { | ||||||
|  |   color: #FFF; | ||||||
|  |   background: #4ab1ce; | ||||||
|  |   padding: 10px 20px; | ||||||
|  |   margin-top: 20px; | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  | #setuppage2 section .tip h2 { | ||||||
|  |   font-size: 16px; | ||||||
|  |   margin-bottom: 20px; | ||||||
|  | } | ||||||
|  | #setuppage2 section .tip dd { | ||||||
|  |   font-weight: bold; | ||||||
|  |   color: #666; | ||||||
|  |   margin-top: 15px; | ||||||
|  |   margin-bottom: 5px; | ||||||
|  | } | ||||||
|  | #setuppage2 section .tip dt { | ||||||
|  |   padding: .5em .6em; | ||||||
|  |   display: inline-block; | ||||||
|  |   border: 1px solid #ccc; | ||||||
|  |   border-radius: 4px; | ||||||
|  |   -webkit-box-sizing: border-box; | ||||||
|  |   -moz-box-sizing: border-box; | ||||||
|  |   -ms-box-sizing: border-box; | ||||||
|  |   -o-box-sizing: border-box; | ||||||
|  |   box-sizing: border-box; | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
| #syncpage { | #syncpage { | ||||||
|   width: 100%; |   width: 100%; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -579,6 +579,7 @@ nav { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #setuppage, | ||||||
| #loginpage { | #loginpage { | ||||||
| 	.pure-g { | 	.pure-g { | ||||||
| 		padding: 30px; | 		padding: 30px; | ||||||
| @@ -622,6 +623,57 @@ nav { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #setuppage2  { | ||||||
|  | 	margin-bottom:50px; | ||||||
|  | 	section { | ||||||
|  | 		.border_box; | ||||||
|  | 		.pure-g { | ||||||
|  | 			padding: 30px; | ||||||
|  | 			border: 1px solid #DDD; | ||||||
|  | 			max-width:400px; | ||||||
|  | 			margin:0px auto; | ||||||
|  | 			margin-top:50px; | ||||||
|  | 			.border_box; | ||||||
|  | 		} | ||||||
|  | 		label { | ||||||
|  | 			display:inline-block; | ||||||
|  | 		} | ||||||
|  | 		input[type='text'] { | ||||||
|  | 			margin-top:5px; | ||||||
|  | 			margin-bottom:10px; | ||||||
|  | 			box-shadow:none; | ||||||
|  | 			width:100%; | ||||||
|  | 		} | ||||||
|  | 		.pure-button-primary { | ||||||
|  | 			color:#FFF; | ||||||
|  |             background: @link2; | ||||||
|  |             padding:10px 20px; | ||||||
|  |             margin-top:20px; | ||||||
|  |             width:100%; | ||||||
|  |         } | ||||||
|  |         .tip { | ||||||
|  |         	h2 { | ||||||
|  | 				font-size: 16px; | ||||||
|  | 				margin-bottom: 20px; | ||||||
|  | 			} | ||||||
|  |         	dd { | ||||||
|  |         		font-weight:bold; | ||||||
|  |         		color:#666; | ||||||
|  |         		margin-top:15px; | ||||||
|  |         		margin-bottom:5px; | ||||||
|  |         	} | ||||||
|  |         	dt { | ||||||
|  | 				padding: .5em .6em; | ||||||
|  | 				display: inline-block; | ||||||
|  | 				border: 1px solid #ccc; | ||||||
|  | 				border-radius: 4px; | ||||||
|  | 				.border_box; | ||||||
|  | 				width: 100%; | ||||||
|  |         	} | ||||||
|  |         } | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| #syncpage { | #syncpage { | ||||||
| 	width:100%; | 	width:100%; | ||||||
| 	section { | 	section { | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								server/app/styles/drone.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								server/app/styles/drone.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,28 +1,14 @@ | |||||||
| <article id="loginpage"> | <article id="loginpage"> | ||||||
| 	<div class="pure-g"> | 	<div class="pure-g"> | ||||||
| 		<div class="pure-u-1"> | 		<div class="pure-u-1" ng-if="state == 1 && remotes.length != 0" ng-repeat="remote in remotes"> | ||||||
| 			<a href="/login/github.com" target="_self"> | 			<a href="/login/{{ remote.type }}" target="_self"> | ||||||
| 				<i class="fa fa fa-github-square"></i> GitHub | 				<i class="fa {{ remote.type | remoteIcon }}"></i> {{ remote.type | remoteName }} | ||||||
| 			</a> | 			</a> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div class="pure-u-1"> |  | ||||||
| 			<a href="/login/enterprise.github.com" target="_self"> | 		<div class="pure-u-1" ng-if="state == 1 && remotes.length == 0"> | ||||||
| 				<i class="fa fa fa-github-square"></i> GitHub Enterprise | 			<a href="/setup"> | ||||||
| 			</a> | 				<i class="fa fa-rocket"></i> Launch Setup Wizard | ||||||
| 		</div> |  | ||||||
| 		<div class="pure-u-1"> |  | ||||||
| 			<a href="/login/bitbucket.org" target="_self"> |  | ||||||
| 				<i class="fa fa fa-bitbucket-square"></i> Bitbucket |  | ||||||
| 			</a> |  | ||||||
| 		</div> |  | ||||||
| 		<div class="pure-u-1"> |  | ||||||
| 			<a href="/login/stash.atlassian.com" target="_self"> |  | ||||||
| 				<i class="fa fa fa-bitbucket-square"></i> Stash |  | ||||||
| 			</a> |  | ||||||
| 		</div> |  | ||||||
| 		<div class="pure-u-1"> |  | ||||||
| 			<a href="/login/gitlab.com" target="_self"> |  | ||||||
| 				<i class="fa fa fa-sign-in"></i> Gitlab |  | ||||||
| 			</a> | 			</a> | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
|   | |||||||
| @@ -1,57 +1,105 @@ | |||||||
| <h1>First Time Setup</h1> | <article id="setuppage" ng-if="remote.type == undefined"> | ||||||
|  | 	<nav> | ||||||
|  | 		<a href="#"><span class="fa fa-th"></span></a> | ||||||
|  | 		<a href="#">Choose a Remote System</a> | ||||||
|  | 	</nav> | ||||||
|  |  | ||||||
| <div class="row"> | 	<section> | ||||||
| 	<div class="col-xs-6 col-sm-3"> | 		<div class="pure-g"> | ||||||
| 		<table border="1"> | 			<div class="pure-u-1"> | ||||||
| 			<tr> | 				<a href="/setup/github.com"> | ||||||
| 				<td><a href="/setup/github.com">GitHub</a></td> | 					<i class="fa fa-github-square"></i> GitHub | ||||||
| 				<td><a href="/setup/enterprise.github.com">GitHub Enterprise</a></td> | 				</a> | ||||||
| 				<td><a href="/setup/gitlab.com">Gitlab</a></td> | 			</div> | ||||||
| 				<td><a href="/setup/bitbucket.org">Bitbucket</a></td> | 			<div class="pure-u-1"> | ||||||
| 				<td><a href="/setup/stash.atlassian.com">Stash</a></td> | 				<a href="/setup/enterprise.github.com"> | ||||||
| 			</tr> | 					<i class="fa fa-github-square"></i> GitHub Enterprise | ||||||
| 		</table> | 				</a> | ||||||
| 	</div> | 			</div> | ||||||
|  | 			<div class="pure-u-1"> | ||||||
| 	<!-- primary column --> | 				<a href="/setup/bitbucket.org"> | ||||||
| 	<div class="col-xs-12 col-sm-9"> | 					<i class="fa fa-bitbucket-square"></i> Bitbucket | ||||||
|  | 				</a> | ||||||
| 		<div> | 			</div> | ||||||
| 			<label>Registration</label> | 			<div class="pure-u-1"> | ||||||
| 			<input type="radio" ng-model="remote.register" ng-value="true" /> | 				<a href="/setup/stash.atlassian.com"> | ||||||
| 			<input type="radio" ng-model="remote.register" ng-value="false" /> | 					<i class="fa fa-bitbucket-square"></i> Atlassian Stash | ||||||
| 		</div> | 				</a> | ||||||
|  | 			</div> | ||||||
| 		<div> | 			<div class="pure-u-1"> | ||||||
| 			<label>URL</label> | 				<a href="/setup/gitlab.com"> | ||||||
| 			<div ng-switch="remote.type"> | 					<i class="fa fa-git-square"></i> GitLab | ||||||
| 				<input ng-switch-when="github.com"    ng-model="remote.url" type="text" readonly /> | 				</a> | ||||||
| 				<input ng-switch-when="bitbucket.org" ng-model="remote.url" type="text" readonly /> |  | ||||||
| 				<input ng-switch-default              ng-model="remote.url" type="text" /> |  | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
|  | 	</section> | ||||||
|  | </article> | ||||||
|  |  | ||||||
| 		<div ng-if="remote.type != 'gitlab.com'"> | <article ng-if="remote.type != undefined" id="setuppage2"> | ||||||
| 			<label>API</label> | 	<nav> | ||||||
| 			<div ng-switch="remote.type"> | 		<a href="/setup"> | ||||||
| 				<input ng-switch-when="github.com"    ng-model="remote.api" type="text" readonly /> | 			<span class="fa fa-arrow-left"></span> | ||||||
| 				<input ng-switch-when="bitbucket.org" ng-model="remote.api" type="text" readonly /> | 		</a> | ||||||
| 				<input ng-switch-default              ng-model="remote.api" type="text" /> | 		<a href="/setup">Configure {{ remote.type | remoteName }}</a> | ||||||
|  | 	</nav> | ||||||
|  |  | ||||||
|  | 	<section ng-if-"remote.type == 'github.com' || remote.type == 'enterprise.github.com' "> | ||||||
|  | 		<div class="pure-g"> | ||||||
|  | 			<div class="pure-u-1 tip"> | ||||||
|  | 				<h2>Register with {{ remote.type | remoteName }}</h2> | ||||||
|  | 				<dl> | ||||||
|  | 					<dd>Homepage URL</dd> | ||||||
|  | 					<dt>{{ window.location.protocol }}//{{ window.location.host }}</dt> | ||||||
|  | 				</dl> | ||||||
|  | 				<dl> | ||||||
|  | 					<dd>Authorization callback URL</dd> | ||||||
|  | 					<dt>{{ window.location.protocol }}//{{ window.location.host }}/login/{{ remote.type }}</dt> | ||||||
|  | 				</dl> | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
|  | 	</section> | ||||||
|  |  | ||||||
| 		<div ng-if="remote.type != 'gitlab.com'"> | 	<section> | ||||||
| 			<label>Client</label> | 		<div class="pure-g"> | ||||||
| 			<input type="text" ng-model="remote.client" /> | 			<div class="pure-u-1"> | ||||||
| 		</div> | 				<div class="pure-form"> | ||||||
|  | 					<div ng-if="remote.type != 'github.com' && remote.type != 'bitbucket.org' "> | ||||||
|  | 						<label>URL</label> | ||||||
|  | 						<div ng-switch="remote.type"> | ||||||
|  | 							<input ng-switch-default ng-model="remote.url" type="text" placeholder="https://www.foo.com" /> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  |  | ||||||
| 		<div ng-if="remote.type != 'gitlab.com'"> | 					<div ng-if="remote.type != 'github.com' && remote.type != 'bitbucket.org' "> | ||||||
| 			<label>Secret</label> | 						<label>API URL</label> | ||||||
| 			<input type="text" ng-model="remote.secret" /> | 						<div ng-switch="remote.type"> | ||||||
| 		</div> | 							<input ng-switch-default ng-model="remote.api" type="text" placeholder="https://www.foo.com/api" /> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  |  | ||||||
| 		<div> | 					<div ng-if="remote.type != 'gitlab.com'"> | ||||||
| 			<button ng-click="save()">Save</button> | 						<label>OAuth Client</label> | ||||||
|  | 						<div> | ||||||
|  | 							<input type="text" ng-model="remote.client" /> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  |  | ||||||
|  | 					<div ng-if="remote.type != 'gitlab.com'"> | ||||||
|  | 						<label>OAuth Secret</label> | ||||||
|  | 						<div> | ||||||
|  | 							<input type="text" ng-model="remote.secret" /> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  |  | ||||||
|  | 					<div class="toggle"> | ||||||
|  | 						<input type="checkbox" ng-model="remote.register" id="register" /> | ||||||
|  | 						<label for="register"></label> | ||||||
|  | 						<span>Enable Self-Registration</span> | ||||||
|  | 					</div> | ||||||
|  |  | ||||||
|  | 					<button ng-click="save()" class="pure-button pure-button-primary">Save and Login</button> | ||||||
|  | 				</div> | ||||||
|  | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</section> | ||||||
| </div> | </article> | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| package database | package database | ||||||
|  |  | ||||||
|  | /* | ||||||
| import ( | import ( | ||||||
| 	"github.com/BurntSushi/toml" | 	"github.com/BurntSushi/toml" | ||||||
| 	"github.com/drone/drone/shared/model" | 	"github.com/drone/drone/shared/model" | ||||||
| @@ -33,3 +34,4 @@ func NewConfigManager(filename string) ConfigManager { | |||||||
| func (c *configManager) Find() *model.Config { | func (c *configManager) Find() *model.Config { | ||||||
| 	return c.conf | 	return c.conf | ||||||
| } | } | ||||||
|  | */ | ||||||
|   | |||||||
| @@ -14,6 +14,9 @@ type RemoteManager interface { | |||||||
| 	// FindHost finds the Remote by hostname. | 	// FindHost finds the Remote by hostname. | ||||||
| 	FindHost(name string) (*model.Remote, error) | 	FindHost(name string) (*model.Remote, error) | ||||||
|  |  | ||||||
|  | 	// FindHost finds the Remote by type. | ||||||
|  | 	FindType(t string) (*model.Remote, error) | ||||||
|  |  | ||||||
| 	// List finds all registered Remotes of the system. | 	// List finds all registered Remotes of the system. | ||||||
| 	List() ([]*model.Remote, error) | 	List() ([]*model.Remote, error) | ||||||
|  |  | ||||||
| @@ -40,10 +43,19 @@ WHERE remote_host=? | |||||||
| LIMIT 1 | LIMIT 1 | ||||||
| ` | ` | ||||||
|  |  | ||||||
|  | // SQL query to retrieve a Remote by remote login. | ||||||
|  | const findRemoteTypeQuery = ` | ||||||
|  | SELECT * | ||||||
|  | FROM remotes | ||||||
|  | WHERE remote_type=? | ||||||
|  | LIMIT 1 | ||||||
|  | ` | ||||||
|  |  | ||||||
| // SQL query to retrieve a list of all Remotes. | // SQL query to retrieve a list of all Remotes. | ||||||
| const listRemoteQuery = ` | const listRemoteQuery = ` | ||||||
| SELECT * | SELECT * | ||||||
| FROM remotes | FROM remotes | ||||||
|  | ORDER BY remote_type | ||||||
| ` | ` | ||||||
|  |  | ||||||
| // SQL statement to delete a Remote by ID. | // SQL statement to delete a Remote by ID. | ||||||
| @@ -69,6 +81,12 @@ func (db *remoteManager) FindHost(host string) (*model.Remote, error) { | |||||||
| 	return &dst, err | 	return &dst, err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (db *remoteManager) FindType(t string) (*model.Remote, error) { | ||||||
|  | 	dst := model.Remote{} | ||||||
|  | 	err := meddler.QueryRow(db, &dst, findRemoteTypeQuery, t) | ||||||
|  | 	return &dst, err | ||||||
|  | } | ||||||
|  |  | ||||||
| func (db *remoteManager) List() ([]*model.Remote, error) { | func (db *remoteManager) List() ([]*model.Remote, error) { | ||||||
| 	var dst []*model.Remote | 	var dst []*model.Remote | ||||||
| 	err := meddler.QueryAll(db, &dst, listRemoteQuery) | 	err := meddler.QueryAll(db, &dst, listRemoteQuery) | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/drone/drone/server/database" | 	"github.com/drone/drone/server/database" | ||||||
| 	"github.com/drone/drone/server/session" | 	"github.com/drone/drone/server/session" | ||||||
| 	"github.com/drone/drone/server/worker" | 	"github.com/drone/drone/shared/httputil" | ||||||
| 	"github.com/drone/drone/shared/model" | 	"github.com/drone/drone/shared/model" | ||||||
| 	"github.com/gorilla/pat" | 	"github.com/gorilla/pat" | ||||||
| ) | ) | ||||||
| @@ -16,10 +16,10 @@ type CommitHandler struct { | |||||||
| 	repos   database.RepoManager | 	repos   database.RepoManager | ||||||
| 	commits database.CommitManager | 	commits database.CommitManager | ||||||
| 	sess    session.Session | 	sess    session.Session | ||||||
| 	queue   chan *worker.Request | 	queue   chan *model.Request | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewCommitHandler(repos database.RepoManager, commits database.CommitManager, perms database.PermManager, sess session.Session, queue chan *worker.Request) *CommitHandler { | func NewCommitHandler(repos database.RepoManager, commits database.CommitManager, perms database.PermManager, sess session.Session, queue chan *model.Request) *CommitHandler { | ||||||
| 	return &CommitHandler{perms, repos, commits, sess, queue} | 	return &CommitHandler{perms, repos, commits, sess, queue} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -160,7 +160,8 @@ func (h *CommitHandler) PostCommit(w http.ResponseWriter, r *http.Request) error | |||||||
| 	// drop the items on the queue | 	// drop the items on the queue | ||||||
| 	// drop the items on the queue | 	// drop the items on the queue | ||||||
| 	go func() { | 	go func() { | ||||||
| 		h.queue <- &worker.Request{ | 		h.queue <- &model.Request{ | ||||||
|  | 			Host:   httputil.GetURL(r), | ||||||
| 			Repo:   repo, | 			Repo:   repo, | ||||||
| 			Commit: c, | 			Commit: c, | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -1,35 +0,0 @@ | |||||||
| package handler |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"encoding/json" |  | ||||||
| 	"net/http" |  | ||||||
|  |  | ||||||
| 	"github.com/drone/drone/server/database" |  | ||||||
| 	"github.com/drone/drone/server/session" |  | ||||||
| 	"github.com/gorilla/pat" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type ConfigHandler struct { |  | ||||||
| 	conf database.ConfigManager |  | ||||||
| 	sess session.Session |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewConfigHandler(conf database.ConfigManager, sess session.Session) *ConfigHandler { |  | ||||||
| 	return &ConfigHandler{conf, sess} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetConfig gets the system configuration details. |  | ||||||
| // GET /api/config |  | ||||||
| func (h *ConfigHandler) GetConfig(w http.ResponseWriter, r *http.Request) error { |  | ||||||
| 	// get the user form the session |  | ||||||
| 	user := h.sess.User(r) |  | ||||||
| 	if user == nil || !user.Admin { |  | ||||||
| 		return notAuthorized{} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return json.NewEncoder(w).Encode(h.conf.Find()) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *ConfigHandler) Register(r *pat.Router) { |  | ||||||
| 	r.Get("/v1/config", errorHandler(h.GetConfig)) |  | ||||||
| } |  | ||||||
| @@ -3,8 +3,9 @@ package handler | |||||||
| import ( | import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
|  | 	"github.com/drone/drone/plugin/remote" | ||||||
| 	"github.com/drone/drone/server/database" | 	"github.com/drone/drone/server/database" | ||||||
| 	"github.com/drone/drone/server/worker" | 	"github.com/drone/drone/shared/httputil" | ||||||
| 	"github.com/drone/drone/shared/model" | 	"github.com/drone/drone/shared/model" | ||||||
| 	"github.com/gorilla/pat" | 	"github.com/gorilla/pat" | ||||||
| ) | ) | ||||||
| @@ -13,12 +14,12 @@ type HookHandler struct { | |||||||
| 	users   database.UserManager | 	users   database.UserManager | ||||||
| 	repos   database.RepoManager | 	repos   database.RepoManager | ||||||
| 	commits database.CommitManager | 	commits database.CommitManager | ||||||
| 	conf    database.ConfigManager | 	remotes database.RemoteManager | ||||||
| 	queue   chan *worker.Request | 	queue   chan *model.Request | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewHookHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, conf database.ConfigManager, queue chan *worker.Request) *HookHandler { | func NewHookHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, remotes database.RemoteManager, queue chan *model.Request) *HookHandler { | ||||||
| 	return &HookHandler{users, repos, commits, conf, queue} | 	return &HookHandler{users, repos, commits, remotes, queue} | ||||||
| } | } | ||||||
|  |  | ||||||
| // PostHook receives a post-commit hook from GitHub, Bitbucket, etc | // PostHook receives a post-commit hook from GitHub, Bitbucket, etc | ||||||
| @@ -26,14 +27,21 @@ func NewHookHandler(users database.UserManager, repos database.RepoManager, comm | |||||||
| func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error { | func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error { | ||||||
| 	host := r.FormValue(":host") | 	host := r.FormValue(":host") | ||||||
|  |  | ||||||
| 	// get the remote system's client. | 	remoteServer, err := h.remotes.FindType(host) | ||||||
| 	remote := h.conf.Find().GetRemote(host) | 	if err != nil { | ||||||
| 	if remote == nil { | 		return notFound{err} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	remotePlugin, ok := remote.Lookup(remoteServer.Type) | ||||||
|  | 	if !ok { | ||||||
| 		return notFound{} | 		return notFound{} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// get the remote system's client. | ||||||
|  | 	plugin := remotePlugin(remoteServer) | ||||||
|  |  | ||||||
| 	// parse the hook payload | 	// parse the hook payload | ||||||
| 	hook, err := remote.GetHook(r) | 	hook, err := plugin.GetHook(r) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return badRequest{err} | 		return badRequest{err} | ||||||
| 	} | 	} | ||||||
| @@ -47,7 +55,7 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// fetch the repository from the database | 	// fetch the repository from the database | ||||||
| 	repo, err := h.repos.FindName(remote.GetHost(), hook.Owner, hook.Repo) | 	repo, err := h.repos.FindName(plugin.GetHost(), hook.Owner, hook.Repo) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return notFound{} | 		return notFound{} | ||||||
| 	} | 	} | ||||||
| @@ -66,7 +74,7 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// featch the .drone.yml file from the database | 	// featch the .drone.yml file from the database | ||||||
| 	client := remote.GetClient(user.Access, user.Secret) | 	client := plugin.GetClient(user.Access, user.Secret) | ||||||
| 	yml, err := client.GetScript(hook) | 	yml, err := client.GetScript(hook) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return badRequest{err} | 		return badRequest{err} | ||||||
| @@ -91,7 +99,8 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error { | |||||||
|  |  | ||||||
| 	// drop the items on the queue | 	// drop the items on the queue | ||||||
| 	go func() { | 	go func() { | ||||||
| 		h.queue <- &worker.Request{ | 		h.queue <- &model.Request{ | ||||||
|  | 			Host:   httputil.GetURL(r), | ||||||
| 			Repo:   repo, | 			Repo:   repo, | ||||||
| 			Commit: &c, | 			Commit: &c, | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/drone/drone/plugin/remote" | ||||||
| 	"github.com/drone/drone/server/database" | 	"github.com/drone/drone/server/database" | ||||||
| 	"github.com/drone/drone/server/session" | 	"github.com/drone/drone/server/session" | ||||||
| 	"github.com/drone/drone/shared/model" | 	"github.com/drone/drone/shared/model" | ||||||
| @@ -15,12 +16,13 @@ type LoginHandler struct { | |||||||
| 	users database.UserManager | 	users database.UserManager | ||||||
| 	repos database.RepoManager | 	repos database.RepoManager | ||||||
| 	perms database.PermManager | 	perms database.PermManager | ||||||
| 	conf  database.ConfigManager | 	//conf    database.ConfigManager | ||||||
| 	sess  session.Session | 	sess    session.Session | ||||||
|  | 	remotes database.RemoteManager | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewLoginHandler(users database.UserManager, repos database.RepoManager, perms database.PermManager, sess session.Session, conf database.ConfigManager) *LoginHandler { | func NewLoginHandler(users database.UserManager, repos database.RepoManager, perms database.PermManager, sess session.Session /*conf database.ConfigManager,*/, remotes database.RemoteManager) *LoginHandler { | ||||||
| 	return &LoginHandler{users, repos, perms, conf, sess} | 	return &LoginHandler{users, repos, perms /*conf,*/, sess, remotes} | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetLogin gets the login to the 3rd party remote system. | // GetLogin gets the login to the 3rd party remote system. | ||||||
| @@ -29,14 +31,21 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error { | |||||||
| 	host := r.FormValue(":host") | 	host := r.FormValue(":host") | ||||||
| 	redirect := "/" | 	redirect := "/" | ||||||
|  |  | ||||||
| 	// get the remote system's client. | 	remoteServer, err := h.remotes.FindType(host) | ||||||
| 	remote := h.conf.Find().GetRemote(host) | 	if err != nil { | ||||||
| 	if remote == nil { | 		return notFound{err} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	remotePlugin, ok := remote.Lookup(remoteServer.Type) | ||||||
|  | 	if !ok { | ||||||
| 		return notFound{} | 		return notFound{} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// get the remote system's client. | ||||||
|  | 	plugin := remotePlugin(remoteServer) | ||||||
|  |  | ||||||
| 	// authenticate the user | 	// authenticate the user | ||||||
| 	login, err := remote.GetLogin(w, r) | 	login, err := plugin.GetLogin(w, r) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return badRequest{err} | 		return badRequest{err} | ||||||
| 	} else if login == nil { | 	} else if login == nil { | ||||||
| @@ -51,12 +60,12 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error { | |||||||
| 		// if self-registration is disabled we should | 		// if self-registration is disabled we should | ||||||
| 		// return a notAuthorized error. the only exception | 		// return a notAuthorized error. the only exception | ||||||
| 		// is if no users exist yet in the system we'll proceed. | 		// is if no users exist yet in the system we'll proceed. | ||||||
| 		if h.conf.Find().Registration == false && h.users.Exist() { | 		if remoteServer.Open == false && h.users.Exist() { | ||||||
| 			return notAuthorized{} | 			return notAuthorized{} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// create the user account | 		// create the user account | ||||||
| 		u = model.NewUser(remote.GetName(), login.Login, login.Email) | 		u = model.NewUser(plugin.GetName(), login.Login, login.Email) | ||||||
| 		u.Name = login.Name | 		u.Name = login.Name | ||||||
| 		u.SetEmail(login.Email) | 		u.SetEmail(login.Email) | ||||||
|  |  | ||||||
| @@ -102,7 +111,7 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error { | |||||||
| 		// its own package / sync utility. | 		// its own package / sync utility. | ||||||
| 		go func() { | 		go func() { | ||||||
| 			// list all repositories | 			// list all repositories | ||||||
| 			client := remote.GetClient(u.Access, u.Secret) | 			client := plugin.GetClient(u.Access, u.Secret) | ||||||
| 			repos, err := client.GetRepos("") | 			repos, err := client.GetRepos("") | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Println("Error syncing user account, listing repositories", u.Login, err) | 				log.Println("Error syncing user account, listing repositories", u.Login, err) | ||||||
| @@ -111,7 +120,7 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error { | |||||||
|  |  | ||||||
| 			// insert all repositories | 			// insert all repositories | ||||||
| 			for _, remoteRepo := range repos { | 			for _, remoteRepo := range repos { | ||||||
| 				repo, _ := model.NewRepo(remote.GetName(), remoteRepo.Owner, remoteRepo.Name) | 				repo, _ := model.NewRepo(plugin.GetName(), remoteRepo.Owner, remoteRepo.Name) | ||||||
| 				repo.Private = remoteRepo.Private | 				repo.Private = remoteRepo.Private | ||||||
| 				repo.Host = remoteRepo.Host | 				repo.Host = remoteRepo.Host | ||||||
| 				repo.CloneURL = remoteRepo.Clone | 				repo.CloneURL = remoteRepo.Clone | ||||||
| @@ -131,13 +140,13 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error { | |||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				log.Println("Successfully syced repo.", u.Login+"/"+remoteRepo.Name) | 				log.Println("Successfully syced repo.", u.Login+"/"+remoteRepo.Name) | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 				u.Synced = time.Now().Unix() | 			u.Synced = time.Now().UTC().Unix() | ||||||
| 				u.Syncing = false | 			u.Syncing = false | ||||||
| 				if err := h.users.Update(u); err != nil { | 			if err := h.users.Update(u); err != nil { | ||||||
| 					log.Println("Error syncing user account, updating sync date", u.Login, err) | 				log.Println("Error syncing user account, updating sync date", u.Login, err) | ||||||
| 					return | 				return | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		}() | 		}() | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -38,6 +38,23 @@ func (h *RemoteHandler) GetRemotes(w http.ResponseWriter, r *http.Request) error | |||||||
| 	return json.NewEncoder(w).Encode(remotes) | 	return json.NewEncoder(w).Encode(remotes) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // GetRemoteLogins gets all remote logins. | ||||||
|  | // GET /api/remotes/logins | ||||||
|  | func (h *RemoteHandler) GetRemoteLogins(w http.ResponseWriter, r *http.Request) error { | ||||||
|  | 	remotes, err := h.remotes.List() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return internalServerError{err} | ||||||
|  | 	} | ||||||
|  | 	var logins []interface{} | ||||||
|  | 	for _, remote := range remotes { | ||||||
|  | 		logins = append(logins, struct { | ||||||
|  | 			Type string `json:"type"` | ||||||
|  | 			Host string `json:"host"` | ||||||
|  | 		}{remote.Type, remote.Host}) | ||||||
|  | 	} | ||||||
|  | 	return json.NewEncoder(w).Encode(&logins) | ||||||
|  | } | ||||||
|  |  | ||||||
| // PostRemote creates a new remote. | // PostRemote creates a new remote. | ||||||
| // POST /api/remotes | // POST /api/remotes | ||||||
| func (h *RemoteHandler) PostRemote(w http.ResponseWriter, r *http.Request) error { | func (h *RemoteHandler) PostRemote(w http.ResponseWriter, r *http.Request) error { | ||||||
| @@ -57,7 +74,6 @@ func (h *RemoteHandler) PostRemote(w http.ResponseWriter, r *http.Request) error | |||||||
| 	if err := json.NewDecoder(r.Body).Decode(&in); err != nil { | 	if err := json.NewDecoder(r.Body).Decode(&in); err != nil { | ||||||
| 		return badRequest{err} | 		return badRequest{err} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	uri, err := url.Parse(in.URL) | 	uri, err := url.Parse(in.URL) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return badRequest{err} | 		return badRequest{err} | ||||||
| @@ -65,7 +81,8 @@ func (h *RemoteHandler) PostRemote(w http.ResponseWriter, r *http.Request) error | |||||||
| 	in.Host = uri.Host | 	in.Host = uri.Host | ||||||
|  |  | ||||||
| 	// there is an edge case where, during installation, a user could attempt | 	// there is an edge case where, during installation, a user could attempt | ||||||
| 	// to add the same result multiple times. | 	// to add the same result multiple times. In this case we will delete | ||||||
|  | 	// the old remote prior to adding the new one. | ||||||
| 	if remote, err := h.remotes.FindHost(in.Host); err == nil && h.users.Exist() { | 	if remote, err := h.remotes.FindHost(in.Host); err == nil && h.users.Exist() { | ||||||
| 		h.remotes.Delete(remote) | 		h.remotes.Delete(remote) | ||||||
| 	} | 	} | ||||||
| @@ -78,31 +95,50 @@ func (h *RemoteHandler) PostRemote(w http.ResponseWriter, r *http.Request) error | |||||||
| 	return json.NewEncoder(w).Encode(&in) | 	return json.NewEncoder(w).Encode(&in) | ||||||
| } | } | ||||||
|  |  | ||||||
| // DeleteRemote delete the remote. | // PutRemote updates an existing remote. | ||||||
| // GET /api/remotes/:name | // PUT /api/remotes | ||||||
| func (h *RemoteHandler) DeleteRemote(w http.ResponseWriter, r *http.Request) error { | func (h *RemoteHandler) PutRemote(w http.ResponseWriter, r *http.Request) error { | ||||||
| 	host := r.FormValue(":host") |  | ||||||
|  |  | ||||||
| 	// get the user form the session | 	// get the user form the session | ||||||
| 	user := h.sess.User(r) | 	user := h.sess.User(r) | ||||||
| 	if user == nil || !user.Admin { | 	if user == nil || !user.Admin { | ||||||
| 		return notAuthorized{} | 		return notAuthorized{} | ||||||
| 	} | 	} | ||||||
| 	// get the remote | 	// unmarshal the remote from the payload | ||||||
| 	remote, err := h.remotes.FindHost(host) | 	defer r.Body.Close() | ||||||
|  | 	in := model.Remote{} | ||||||
|  | 	if err := json.NewDecoder(r.Body).Decode(&in); err != nil { | ||||||
|  | 		return badRequest{err} | ||||||
|  | 	} | ||||||
|  | 	uri, err := url.Parse(in.URL) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return badRequest{err} | ||||||
|  | 	} | ||||||
|  | 	in.Host = uri.Host | ||||||
|  |  | ||||||
|  | 	// retrieve the remote and return an error if not exists | ||||||
|  | 	remote, err := h.remotes.FindHost(in.Host) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return notFound{err} | 		return notFound{err} | ||||||
| 	} | 	} | ||||||
| 	if err := h.remotes.Delete(remote); err != nil { |  | ||||||
|  | 	// update the remote details | ||||||
|  | 	remote.API = in.API | ||||||
|  | 	remote.URL = in.URL | ||||||
|  | 	remote.Host = in.Host | ||||||
|  | 	remote.Client = in.Client | ||||||
|  | 	remote.Secret = in.Secret | ||||||
|  |  | ||||||
|  | 	// insert the remote in the database | ||||||
|  | 	if err := h.remotes.Update(remote); err != nil { | ||||||
| 		return internalServerError{err} | 		return internalServerError{err} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	w.WriteHeader(http.StatusNoContent) | 	return json.NewEncoder(w).Encode(remote) | ||||||
| 	return nil |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (h *RemoteHandler) Register(r *pat.Router) { | func (h *RemoteHandler) Register(r *pat.Router) { | ||||||
| 	r.Delete("/v1/remotes/:name", errorHandler(h.DeleteRemote)) | 	r.Get("/v1/logins", errorHandler(h.GetRemoteLogins)) | ||||||
| 	r.Post("/v1/remotes", errorHandler(h.PostRemote)) |  | ||||||
| 	r.Get("/v1/remotes", errorHandler(h.GetRemotes)) | 	r.Get("/v1/remotes", errorHandler(h.GetRemotes)) | ||||||
|  | 	r.Post("/v1/remotes", errorHandler(h.PostRemote)) | ||||||
|  | 	r.Put("/v1/remotes", errorHandler(h.PutRemote)) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
|  | 	"github.com/drone/drone/plugin/remote" | ||||||
| 	"github.com/drone/drone/server/database" | 	"github.com/drone/drone/server/database" | ||||||
| 	"github.com/drone/drone/server/session" | 	"github.com/drone/drone/server/session" | ||||||
| 	"github.com/drone/drone/shared/httputil" | 	"github.com/drone/drone/shared/httputil" | ||||||
| @@ -14,7 +15,7 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type RepoHandler struct { | type RepoHandler struct { | ||||||
| 	conf    database.ConfigManager | 	remotes database.RemoteManager | ||||||
| 	commits database.CommitManager | 	commits database.CommitManager | ||||||
| 	perms   database.PermManager | 	perms   database.PermManager | ||||||
| 	repos   database.RepoManager | 	repos   database.RepoManager | ||||||
| @@ -22,8 +23,8 @@ type RepoHandler struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| func NewRepoHandler(repos database.RepoManager, commits database.CommitManager, | func NewRepoHandler(repos database.RepoManager, commits database.CommitManager, | ||||||
| 	perms database.PermManager, sess session.Session, conf database.ConfigManager) *RepoHandler { | 	perms database.PermManager, sess session.Session, remotes database.RemoteManager) *RepoHandler { | ||||||
| 	return &RepoHandler{conf, commits, perms, repos, sess} | 	return &RepoHandler{remotes, commits, perms, repos, sess} | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetRepo gets the named repository. | // GetRepo gets the named repository. | ||||||
| @@ -105,16 +106,24 @@ func (h *RepoHandler) PostRepo(w http.ResponseWriter, r *http.Request) error { | |||||||
| 	repo.PrivateKey = sshutil.MarshalPrivateKey(key) | 	repo.PrivateKey = sshutil.MarshalPrivateKey(key) | ||||||
|  |  | ||||||
| 	// get the remote and client | 	// get the remote and client | ||||||
| 	remote := h.conf.Find().GetRemote(host) | 	remoteServer, err := h.remotes.FindType(repo.Remote) | ||||||
| 	if remote == nil { | 	if err != nil { | ||||||
|  | 		return notFound{err} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	remotePlugin, ok := remote.Lookup(remoteServer.Type) | ||||||
|  | 	if !ok { | ||||||
| 		return notFound{} | 		return notFound{} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// get the remote system's client. | ||||||
|  | 	plugin := remotePlugin(remoteServer) | ||||||
|  |  | ||||||
| 	// post commit hook url | 	// post commit hook url | ||||||
| 	hook := fmt.Sprintf("%s://%s/v1/hook/%s", httputil.GetScheme(r), httputil.GetHost(r), remote.GetName()) | 	hook := fmt.Sprintf("%s://%s/v1/hook/%s", httputil.GetScheme(r), httputil.GetHost(r), plugin.GetName()) | ||||||
|  |  | ||||||
| 	// activate the repository in the remote system | 	// activate the repository in the remote system | ||||||
| 	client := remote.GetClient(user.Access, user.Secret) | 	client := plugin.GetClient(user.Access, user.Secret) | ||||||
| 	if err := client.SetActive(owner, name, hook, repo.PublicKey); err != nil { | 	if err := client.SetActive(owner, name, hook, repo.PublicKey); err != nil { | ||||||
| 		return badRequest{err} | 		return badRequest{err} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,7 +9,6 @@ import ( | |||||||
| 	"github.com/drone/drone/server/database" | 	"github.com/drone/drone/server/database" | ||||||
| 	"github.com/drone/drone/server/pubsub" | 	"github.com/drone/drone/server/pubsub" | ||||||
| 	"github.com/drone/drone/server/session" | 	"github.com/drone/drone/server/session" | ||||||
| 	"github.com/drone/drone/server/worker" |  | ||||||
| 	"github.com/drone/drone/shared/model" | 	"github.com/drone/drone/shared/model" | ||||||
| 	"github.com/gorilla/pat" | 	"github.com/gorilla/pat" | ||||||
|  |  | ||||||
| @@ -72,7 +71,7 @@ func (h *WsHandler) WsUser(w http.ResponseWriter, r *http.Request) error { | |||||||
| 		for { | 		for { | ||||||
| 			select { | 			select { | ||||||
| 			case msg := <-sub.Read(): | 			case msg := <-sub.Read(): | ||||||
| 				work, ok := msg.(*worker.Request) | 				work, ok := msg.(*model.Request) | ||||||
| 				if !ok { | 				if !ok { | ||||||
| 					break | 					break | ||||||
| 				} | 				} | ||||||
| @@ -203,7 +202,7 @@ func readWebsocket(ws *websocket.Conn) { | |||||||
| // will be removed prior to release | // will be removed prior to release | ||||||
| func (h *WsHandler) Ping(w http.ResponseWriter, r *http.Request) error { | func (h *WsHandler) Ping(w http.ResponseWriter, r *http.Request) error { | ||||||
| 	channel := h.pubsub.Register("_global") | 	channel := h.pubsub.Register("_global") | ||||||
| 	msg := worker.Request{ | 	msg := model.Request{ | ||||||
| 		Repo:   &model.Repo{ID: 1, Private: false, Host: "github.com", Owner: "drone", Name: "drone"}, | 		Repo:   &model.Repo{ID: 1, Private: false, Host: "github.com", Owner: "drone", Name: "drone"}, | ||||||
| 		Commit: &model.Commit{ID: 1, Status: "Started", Branch: "master", Sha: "113f4917ff9174945388d86395f902cd154074cb", Message: "Remove branches by SCM hook", Author: "bradrydzewski", Gravatar: "8c58a0be77ee441bb8f8595b7f1b4e87"}, | 		Commit: &model.Commit{ID: 1, Status: "Started", Branch: "master", Sha: "113f4917ff9174945388d86395f902cd154074cb", Message: "Remove branches by SCM hook", Author: "bradrydzewski", Gravatar: "8c58a0be77ee441bb8f8595b7f1b4e87"}, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -25,6 +25,10 @@ import ( | |||||||
| 	"github.com/GeertJohan/go.rice" | 	"github.com/GeertJohan/go.rice" | ||||||
| 	_ "github.com/mattn/go-sqlite3" | 	_ "github.com/mattn/go-sqlite3" | ||||||
| 	"github.com/russross/meddler" | 	"github.com/russross/meddler" | ||||||
|  |  | ||||||
|  | 	_ "github.com/drone/drone/plugin/remote/bitbucket" | ||||||
|  | 	_ "github.com/drone/drone/plugin/remote/github" | ||||||
|  | 	_ "github.com/drone/drone/plugin/remote/gitlab" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| @@ -79,7 +83,7 @@ func main() { | |||||||
| 	commits := database.NewCommitManager(db) | 	commits := database.NewCommitManager(db) | ||||||
| 	servers := database.NewServerManager(db) | 	servers := database.NewServerManager(db) | ||||||
| 	remotes := database.NewRemoteManager(db) | 	remotes := database.NewRemoteManager(db) | ||||||
| 	configs := database.NewConfigManager(filepath.Join(home, "config.toml")) | 	//configs := database.NewConfigManager(filepath.Join(home, "config.toml")) | ||||||
|  |  | ||||||
| 	// message broker | 	// message broker | ||||||
| 	pubsub := pubsub.NewPubSub() | 	pubsub := pubsub.NewPubSub() | ||||||
| @@ -87,10 +91,10 @@ func main() { | |||||||
| 	// cancel all previously running builds | 	// cancel all previously running builds | ||||||
| 	go commits.CancelAll() | 	go commits.CancelAll() | ||||||
|  |  | ||||||
| 	queue := make(chan *worker.Request) | 	queue := make(chan *model.Request) | ||||||
| 	workers := make(chan chan *worker.Request) | 	workers := make(chan chan *model.Request) | ||||||
| 	worker.NewDispatch(queue, workers).Start() | 	worker.NewDispatch(queue, workers).Start() | ||||||
| 	worker.NewWorker(workers, users, repos, commits, configs, pubsub, &model.Server{}).Start() | 	worker.NewWorker(workers, users, repos, commits, pubsub, &model.Server{}).Start() | ||||||
|  |  | ||||||
| 	// setup the session managers | 	// setup the session managers | ||||||
| 	sess := session.NewSession(users) | 	sess := session.NewSession(users) | ||||||
| @@ -99,13 +103,13 @@ func main() { | |||||||
| 	router := pat.New() | 	router := pat.New() | ||||||
| 	handler.NewUsersHandler(users, sess).Register(router) | 	handler.NewUsersHandler(users, sess).Register(router) | ||||||
| 	handler.NewUserHandler(users, repos, commits, sess).Register(router) | 	handler.NewUserHandler(users, repos, commits, sess).Register(router) | ||||||
| 	handler.NewHookHandler(users, repos, commits, configs, queue).Register(router) | 	handler.NewHookHandler(users, repos, commits, remotes, queue).Register(router) | ||||||
| 	handler.NewLoginHandler(users, repos, perms, sess, configs).Register(router) | 	handler.NewLoginHandler(users, repos, perms, sess, remotes).Register(router) | ||||||
| 	handler.NewCommitHandler(repos, commits, perms, sess, queue).Register(router) | 	handler.NewCommitHandler(repos, commits, perms, sess, queue).Register(router) | ||||||
| 	handler.NewBranchHandler(repos, commits, perms, sess).Register(router) | 	handler.NewBranchHandler(repos, commits, perms, sess).Register(router) | ||||||
| 	handler.NewRepoHandler(repos, commits, perms, sess, configs).Register(router) | 	handler.NewRepoHandler(repos, commits, perms, sess, remotes).Register(router) | ||||||
| 	handler.NewBadgeHandler(repos, commits).Register(router) | 	handler.NewBadgeHandler(repos, commits).Register(router) | ||||||
| 	handler.NewConfigHandler(configs, sess).Register(router) | 	//handler.NewConfigHandler(configs, sess).Register(router) | ||||||
| 	handler.NewServerHandler(servers, sess).Register(router) | 	handler.NewServerHandler(servers, sess).Register(router) | ||||||
| 	handler.NewRemoteHandler(users, remotes, sess).Register(router) | 	handler.NewRemoteHandler(users, remotes, sess).Register(router) | ||||||
| 	handler.NewWsHandler(repos, commits, perms, sess, pubsub).Register(router) | 	handler.NewWsHandler(repos, commits, perms, sess, pubsub).Register(router) | ||||||
|   | |||||||
| @@ -1,14 +1,18 @@ | |||||||
| package worker | package worker | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/drone/drone/shared/model" | ||||||
|  | ) | ||||||
|  |  | ||||||
| // http://nesv.github.io/golang/2014/02/25/worker-queues-in-go.html | // http://nesv.github.io/golang/2014/02/25/worker-queues-in-go.html | ||||||
|  |  | ||||||
| type Dispatch struct { | type Dispatch struct { | ||||||
| 	requests chan *Request | 	requests chan *model.Request | ||||||
| 	workers  chan chan *Request | 	workers  chan chan *model.Request | ||||||
| 	quit     chan bool | 	quit     chan bool | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewDispatch(requests chan *Request, workers chan chan *Request) *Dispatch { | func NewDispatch(requests chan *model.Request, workers chan chan *model.Request) *Dispatch { | ||||||
| 	return &Dispatch{ | 	return &Dispatch{ | ||||||
| 		requests: requests, | 		requests: requests, | ||||||
| 		workers:  workers, | 		workers:  workers, | ||||||
|   | |||||||
| @@ -1,12 +0,0 @@ | |||||||
| package worker |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/drone/drone/shared/model" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type Request struct { |  | ||||||
| 	User   *model.User   `json:"-"` |  | ||||||
| 	Repo   *model.Repo   `json:"repo"` |  | ||||||
| 	Commit *model.Commit `json:"commit"` |  | ||||||
| 	server *model.Server |  | ||||||
| } |  | ||||||
| @@ -24,25 +24,25 @@ type worker struct { | |||||||
| 	users   database.UserManager | 	users   database.UserManager | ||||||
| 	repos   database.RepoManager | 	repos   database.RepoManager | ||||||
| 	commits database.CommitManager | 	commits database.CommitManager | ||||||
| 	config  database.ConfigManager | 	//config  database.ConfigManager | ||||||
| 	pubsub  *pubsub.PubSub | 	pubsub *pubsub.PubSub | ||||||
| 	server  *model.Server | 	server *model.Server | ||||||
|  |  | ||||||
| 	request  chan *Request | 	request  chan *model.Request | ||||||
| 	dispatch chan chan *Request | 	dispatch chan chan *model.Request | ||||||
| 	quit     chan bool | 	quit     chan bool | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewWorker(dispatch chan chan *Request, users database.UserManager, repos database.RepoManager, commits database.CommitManager, config database.ConfigManager, pubsub *pubsub.PubSub, server *model.Server) Worker { | func NewWorker(dispatch chan chan *model.Request, users database.UserManager, repos database.RepoManager, commits database.CommitManager /*config database.ConfigManager,*/, pubsub *pubsub.PubSub, server *model.Server) Worker { | ||||||
| 	return &worker{ | 	return &worker{ | ||||||
| 		users:    users, | 		users:   users, | ||||||
| 		repos:    repos, | 		repos:   repos, | ||||||
| 		commits:  commits, | 		commits: commits, | ||||||
| 		config:   config, | 		//config:   config, | ||||||
| 		pubsub:   pubsub, | 		pubsub:   pubsub, | ||||||
| 		server:   server, | 		server:   server, | ||||||
| 		dispatch: dispatch, | 		dispatch: dispatch, | ||||||
| 		request:  make(chan *Request), | 		request:  make(chan *model.Request), | ||||||
| 		quit:     make(chan bool), | 		quit:     make(chan bool), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -59,7 +59,7 @@ func (w *worker) Start() { | |||||||
| 			select { | 			select { | ||||||
| 			case r := <-w.request: | 			case r := <-w.request: | ||||||
| 				// handle the request | 				// handle the request | ||||||
| 				r.server = w.server | 				r.Server = w.server | ||||||
| 				w.Execute(r) | 				w.Execute(r) | ||||||
|  |  | ||||||
| 			case <-w.quit: | 			case <-w.quit: | ||||||
| @@ -78,7 +78,7 @@ func (w *worker) Stop() { | |||||||
| // Execute executes the work Request, persists the | // Execute executes the work Request, persists the | ||||||
| // results to the database, and sends event messages | // results to the database, and sends event messages | ||||||
| // to the pubsub (for websocket updates on the website). | // to the pubsub (for websocket updates on the website). | ||||||
| func (w *worker) Execute(r *Request) { | func (w *worker) Execute(r *model.Request) { | ||||||
| 	// mark the build as Started and update the database | 	// mark the build as Started and update the database | ||||||
| 	r.Commit.Status = model.StatusStarted | 	r.Commit.Status = model.StatusStarted | ||||||
| 	r.Commit.Started = time.Now().UTC().Unix() | 	r.Commit.Started = time.Now().UTC().Unix() | ||||||
| @@ -123,6 +123,11 @@ func (w *worker) Execute(r *Request) { | |||||||
| 		dockerClient = docker.NewHost(w.server.Host) | 		dockerClient = docker.NewHost(w.server.Host) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// send all "started" notifications | ||||||
|  | 	if script.Notifications != nil { | ||||||
|  | 		script.Notifications.Send(r) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// create an instance of the Docker builder | 	// create an instance of the Docker builder | ||||||
| 	builder := build.New(dockerClient) | 	builder := build.New(dockerClient) | ||||||
| 	builder.Build = script | 	builder.Build = script | ||||||
| @@ -162,5 +167,9 @@ func (w *worker) Execute(r *Request) { | |||||||
|  |  | ||||||
| 	// todo(bradrydzewski) update github status API | 	// todo(bradrydzewski) update github status API | ||||||
| 	// todo(bradrydzewski) send email notifications | 	// todo(bradrydzewski) send email notifications | ||||||
| 	// todo(bradrydzewski) send other notifications |  | ||||||
|  | 	// send all "finished" notifications | ||||||
|  | 	if script.Notifications != nil { | ||||||
|  | 		script.Notifications.Send(r) | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,94 +0,0 @@ | |||||||
| package model |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/drone/drone/plugin/remote" |  | ||||||
| 	"github.com/drone/drone/plugin/remote/bitbucket" |  | ||||||
| 	"github.com/drone/drone/plugin/remote/github" |  | ||||||
| 	"github.com/drone/drone/plugin/remote/gitlab" |  | ||||||
| 	"github.com/drone/drone/plugin/remote/stash" |  | ||||||
| 	"github.com/drone/drone/plugin/smtp" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type Config struct { |  | ||||||
| 	// Hostname of the server, eg drone.io |  | ||||||
| 	//Host string `json:"host"` |  | ||||||
|  |  | ||||||
| 	// Scheme of the server, eg https |  | ||||||
| 	//Scheme string `json:"scheme"` |  | ||||||
|  |  | ||||||
| 	// Registration with a value of True allows developers |  | ||||||
| 	// to register themselves. If false, must be approved |  | ||||||
| 	// or invited by the system administrator. |  | ||||||
| 	Registration bool `json:"registration"` |  | ||||||
|  |  | ||||||
| 	// SMTP stores configuration details for connecting with |  | ||||||
| 	// and smtp server to send email notifications. |  | ||||||
| 	SMTP *smtp.SMTP `json:"smtp"` |  | ||||||
|  |  | ||||||
| 	// Bitbucket stores configuration details for communicating |  | ||||||
| 	// with the bitbucket.org public cloud service. |  | ||||||
| 	Bitbucket *bitbucket.Bitbucket `json:"bitbucket"` |  | ||||||
|  |  | ||||||
| 	// Github stores configuration details for communicating |  | ||||||
| 	// with the github.com public cloud service. |  | ||||||
| 	Github *github.Github `json:"github"` |  | ||||||
|  |  | ||||||
| 	// GithubEnterprise stores configuration details for |  | ||||||
| 	// communicating with a private Github installation. |  | ||||||
| 	GithubEnterprise *github.Github `json:"githubEnterprise"` |  | ||||||
|  |  | ||||||
| 	// Gitlab stores configuration details for communicating |  | ||||||
| 	// with a private gitlab installation. |  | ||||||
| 	Gitlab *gitlab.Gitlab `json:"gitlab"` |  | ||||||
|  |  | ||||||
| 	// Stash stores configuration details for communicating |  | ||||||
| 	// with a private Atlassian Stash installation. |  | ||||||
| 	Stash *stash.Stash `json:"stash"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetRemote is a helper function that will return the |  | ||||||
| // remote plugin name based on the specified hostname. |  | ||||||
| func (c *Config) GetRemote(name string) remote.Remote { |  | ||||||
| 	// first attempt to get the remote instance |  | ||||||
| 	// by the unique plugin name (ie enterprise.github.com) |  | ||||||
| 	switch name { |  | ||||||
| 	case c.Github.GetName(): |  | ||||||
| 		return c.Github |  | ||||||
| 	case c.Bitbucket.GetName(): |  | ||||||
| 		return c.Bitbucket |  | ||||||
| 	case c.GithubEnterprise.GetName(): |  | ||||||
| 		return c.GithubEnterprise |  | ||||||
| 	case c.Gitlab.GetName(): |  | ||||||
| 		return c.Gitlab |  | ||||||
| 	case c.Stash.GetName(): |  | ||||||
| 		return c.Stash |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// else attempt to get the remote instance |  | ||||||
| 	// by the hostname (ie github.drone.io) |  | ||||||
| 	switch { |  | ||||||
| 	case c.Github.IsMatch(name): |  | ||||||
| 		return c.Github |  | ||||||
| 	case c.Bitbucket.IsMatch(name): |  | ||||||
| 		return c.Bitbucket |  | ||||||
| 	case c.GithubEnterprise.IsMatch(name): |  | ||||||
| 		return c.GithubEnterprise |  | ||||||
| 	case c.Gitlab.IsMatch(name): |  | ||||||
| 		return c.Gitlab |  | ||||||
| 	case c.Stash.IsMatch(name): |  | ||||||
| 		return c.Stash |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// else none found |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetClient is a helper function taht will return the named |  | ||||||
| // remote plugin client, used to interact with the remote system. |  | ||||||
| func (c *Config) GetClient(name, access, secret string) remote.Client { |  | ||||||
| 	remote := c.GetRemote(name) |  | ||||||
| 	if remote == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return remote.GetClient(access, secret) |  | ||||||
| } |  | ||||||
							
								
								
									
										9
									
								
								shared/model/request.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								shared/model/request.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | package model | ||||||
|  |  | ||||||
|  | type Request struct { | ||||||
|  | 	Host   string  `json:"-"` | ||||||
|  | 	User   *User   `json:"-"` | ||||||
|  | 	Repo   *Repo   `json:"repo"` | ||||||
|  | 	Commit *Commit `json:"commit"` | ||||||
|  | 	Server *Server `json:"-"` | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user