Merge remote-tracking branch 'origin/0.4-database' into 0.4-database
This commit is contained in:
commit
fba4362e61
40 changed files with 2444 additions and 2397 deletions
|
@ -118,10 +118,10 @@ func createClone(c *Context) error {
|
|||
|
||||
c.Clone.Origin = c.Repo.Clone
|
||||
c.Clone.Remote = c.Repo.Clone
|
||||
c.Clone.Sha = c.Commit.Sha
|
||||
c.Clone.Ref = c.Commit.Ref
|
||||
c.Clone.Branch = c.Commit.Branch
|
||||
// TODO move this to the main app (github package)
|
||||
c.Clone.Sha = c.Build.Commit.Sha
|
||||
c.Clone.Ref = c.Build.Commit.Ref
|
||||
c.Clone.Branch = c.Build.Commit.Branch
|
||||
// TODO do we still need this? it should be set by the remote
|
||||
if strings.HasPrefix(c.Clone.Branch, "refs/heads/") {
|
||||
c.Clone.Branch = c.Clone.Branch[11:]
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ type Context struct {
|
|||
// Links *common.Link
|
||||
Clone *common.Clone `json:"clone"`
|
||||
Repo *common.Repo `json:"repo"`
|
||||
Commit *common.Commit `json:"commit"`
|
||||
Build *common.Build `json:"build"`
|
||||
Job *common.Job `json:"job"`
|
||||
Keys *common.Keypair `json:"keys"`
|
||||
Netrc *common.Netrc `json:"netrc"`
|
||||
|
|
|
@ -6,12 +6,12 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/samalba/dockerclient"
|
||||
common "github.com/drone/drone/pkg/types"
|
||||
"github.com/drone/drone/pkg/types"
|
||||
)
|
||||
|
||||
// helper function that converts the build step to
|
||||
// a containerConfig for use with the dockerclient
|
||||
func toContainerConfig(step *common.Step) *dockerclient.ContainerConfig {
|
||||
func toContainerConfig(step *types.Step) *dockerclient.ContainerConfig {
|
||||
config := &dockerclient.ContainerConfig{
|
||||
Image: step.Image,
|
||||
Env: step.Environment,
|
||||
|
@ -47,8 +47,8 @@ func toEnv(c *Context) map[string]string {
|
|||
return map[string]string{
|
||||
"CI": "true",
|
||||
"BUILD_DIR": c.Clone.Dir,
|
||||
"BUILD_ID": strconv.Itoa(c.Commit.Sequence),
|
||||
"BUILD_NUMBER": strconv.Itoa(c.Commit.Sequence),
|
||||
"BUILD_ID": strconv.Itoa(c.Build.Number),
|
||||
"BUILD_NUMBER": strconv.Itoa(c.Build.Number),
|
||||
"JOB_NAME": c.Repo.FullName,
|
||||
"WORKSPACE": c.Clone.Dir,
|
||||
"GIT_BRANCH": c.Clone.Branch,
|
||||
|
@ -56,7 +56,7 @@ func toEnv(c *Context) map[string]string {
|
|||
|
||||
"DRONE": "true",
|
||||
"DRONE_REPO": c.Repo.FullName,
|
||||
"DRONE_BUILD": strconv.Itoa(c.Commit.Sequence),
|
||||
"DRONE_BUILD": strconv.Itoa(c.Build.Number),
|
||||
"DRONE_BRANCH": c.Clone.Branch,
|
||||
"DRONE_COMMIT": c.Clone.Sha,
|
||||
"DRONE_DIR": c.Clone.Dir,
|
||||
|
@ -66,10 +66,10 @@ func toEnv(c *Context) map[string]string {
|
|||
// helper function to encode the build step to
|
||||
// a json string. Primarily used for plugins, which
|
||||
// expect a json encoded string in stdin or arg[1].
|
||||
func toCommand(c *Context, step *common.Step) []string {
|
||||
func toCommand(c *Context, step *types.Step) []string {
|
||||
p := payload{
|
||||
c.Repo,
|
||||
c.Commit,
|
||||
c.Build,
|
||||
c.Job,
|
||||
c.Clone,
|
||||
step.Config,
|
||||
|
@ -81,10 +81,10 @@ func toCommand(c *Context, step *common.Step) []string {
|
|||
// that is serialized and sent to the plugin in JSON
|
||||
// format via stdin or arg[1].
|
||||
type payload struct {
|
||||
Repo *common.Repo `json:"repo"`
|
||||
Commit *common.Commit `json:"commit"`
|
||||
Job *common.Job `json:"job"`
|
||||
Clone *common.Clone `json:"clone"`
|
||||
Repo *types.Repo `json:"repo"`
|
||||
Build *types.Build `json:"build"`
|
||||
Job *types.Job `json:"job"`
|
||||
Clone *types.Clone `json:"clone"`
|
||||
|
||||
Config map[string]interface{} `json:"vargs"`
|
||||
}
|
||||
|
|
BIN
cmd/drone-server/drone-server
Executable file
BIN
cmd/drone-server/drone-server
Executable file
Binary file not shown.
|
@ -1,45 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
<html ng-app="drone" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<base href="/"/>
|
||||
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<link href='//fonts.googleapis.com/css?family=Open+Sans:400,600,300' rel='stylesheet' type='text/css'>
|
||||
<link href='//fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
|
||||
<link href='//cdn.rawgit.com/zavoloklom/material-design-iconic-font/master/css/material-design-iconic-font.min.css' rel='stylesheet' type='text/css'>
|
||||
<link href='//cdnjs.cloudflare.com/ajax/libs/octicons/2.1.2/octicons.min.css' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Droid+Sans+Mono" />
|
||||
<link href='/static/styles/drone.css' rel='stylesheet' type='text/css'>
|
||||
<link rel="icon" href="/static/favicon.png">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<base href="/"/>
|
||||
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<link href='//fonts.googleapis.com/css?family=Open+Sans:400,600,300' rel='stylesheet' type='text/css'>
|
||||
<link href='//fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
|
||||
<link href='//fonts.googleapis.com/icon?family=Material+Icons' rel='stylesheet' type='text/css'>
|
||||
<link href='//cdnjs.cloudflare.com/ajax/libs/octicons/2.1.2/octicons.min.css' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Droid+Sans+Mono"/>
|
||||
<link href='/static/styles/drone.css' rel='stylesheet' type='text/css'>
|
||||
<link rel="icon" href="/static/favicon.png">
|
||||
</head>
|
||||
<body>
|
||||
<div role="main" ng-view ng-cloak></div>
|
||||
<div ui-view="layout"></div>
|
||||
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-route.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-resource.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.6.0/moment.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-route.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-resource.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.6.0/moment.min.js"></script>
|
||||
|
||||
<!-- main javascript application -->
|
||||
<script src="/static/scripts/term.js"></script>
|
||||
<script src="/static/scripts/drone.js"></script>
|
||||
<script src="/static/scripts/controllers/repos.js"></script>
|
||||
<script src="/static/scripts/controllers/builds.js"></script>
|
||||
<script src="/static/scripts/controllers/users.js"></script>
|
||||
<!-- main javascript application -->
|
||||
<script src="/static/scripts/term.js"></script>
|
||||
<script src="/static/scripts/drone.js"></script>
|
||||
<script src="/static/scripts/controllers/repos.js"></script>
|
||||
<script src="/static/scripts/controllers/builds.js"></script>
|
||||
<script src="/static/scripts/controllers/users.js"></script>
|
||||
|
||||
<script src="/static/scripts/services/repos.js"></script>
|
||||
<script src="/static/scripts/services/builds.js"></script>
|
||||
<script src="/static/scripts/services/users.js"></script>
|
||||
<script src="/static/scripts/services/logs.js"></script>
|
||||
<script src="/static/scripts/services/tokens.js"></script>
|
||||
<script src="/static/scripts/services/feed.js"></script>
|
||||
<script src="/static/scripts/services/repos.js"></script>
|
||||
<script src="/static/scripts/services/builds.js"></script>
|
||||
<script src="/static/scripts/services/users.js"></script>
|
||||
<script src="/static/scripts/services/logs.js"></script>
|
||||
<script src="/static/scripts/services/tokens.js"></script>
|
||||
<script src="/static/scripts/services/feed.js"></script>
|
||||
|
||||
<script src="/static/scripts/filters/filter.js"></script>
|
||||
<script src="/static/scripts/filters/gravatar.js"></script>
|
||||
<script src="/static/scripts/filters/time.js"></script>
|
||||
<script src="/static/scripts/filters/filter.js"></script>
|
||||
<script src="/static/scripts/filters/gravatar.js"></script>
|
||||
<script src="/static/scripts/filters/time.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,222 +1,240 @@
|
|||
(function () {
|
||||
|
||||
/**
|
||||
* BuildsCtrl responsible for rendering the repo's
|
||||
* recent build history.
|
||||
*/
|
||||
function BuildsCtrl($scope, $routeParams, builds, repos, users, logs) {
|
||||
/**
|
||||
* BuildsCtrl responsible for rendering the repo's
|
||||
* recent build history.
|
||||
*/
|
||||
function BuildsCtrl($scope, $stateParams, builds, repos, users, logs) {
|
||||
var owner = $stateParams.owner;
|
||||
var name = $stateParams.name;
|
||||
var fullName = owner + '/' + name;
|
||||
|
||||
var owner = $routeParams.owner;
|
||||
var name = $routeParams.name;
|
||||
var fullName = owner+'/'+name;
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function (payload) {
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function(payload){
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
// Gets a repository
|
||||
repos.get(fullName).then(function (payload) {
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
|
||||
// Gets a repository
|
||||
repos.get(fullName).then(function(payload){
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
// Gets a list of builds
|
||||
builds.list(fullName).then(function (payload) {
|
||||
$scope.builds = angular.isArray(payload.data) ? payload.data : [];
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
|
||||
// Gets a list of builds
|
||||
builds.list(fullName).then(function(payload){
|
||||
$scope.builds = angular.isArray(payload.data) ? payload.data : [];
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
$scope.watch = function (repo) {
|
||||
repos.watch(repo.full_name).then(function (payload) {
|
||||
$scope.repo.starred = true;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.watch = function(repo) {
|
||||
repos.watch(repo.full_name).then(function(payload) {
|
||||
$scope.repo.starred = true;
|
||||
});
|
||||
}
|
||||
$scope.unwatch = function (repo) {
|
||||
repos.unwatch(repo.full_name).then(function () {
|
||||
$scope.repo.starred = false;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.unwatch = function(repo) {
|
||||
repos.unwatch(repo.full_name).then(function() {
|
||||
$scope.repo.starred = false;
|
||||
});
|
||||
}
|
||||
repos.subscribe(fullName, function (event) {
|
||||
var added = false;
|
||||
for (var i = 0; i < $scope.builds.length; i++) {
|
||||
var build = $scope.builds[i];
|
||||
if (event.number !== build.number) {
|
||||
continue; // ignore
|
||||
}
|
||||
// update the build status
|
||||
$scope.builds[i] = event;
|
||||
$scope.$apply();
|
||||
added = true;
|
||||
}
|
||||
|
||||
repos.subscribe(fullName, function(event) {
|
||||
var added = false;
|
||||
for (var i=0;i<$scope.builds.length;i++) {
|
||||
var build = $scope.builds[i];
|
||||
if (event.number !== build.number) {
|
||||
continue; // ignore
|
||||
}
|
||||
// update the build status
|
||||
$scope.builds[i] = event;
|
||||
$scope.$apply();
|
||||
added = true;
|
||||
}
|
||||
if (!added) {
|
||||
$scope.builds.push(event);
|
||||
$scope.$apply();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!added) {
|
||||
$scope.builds.push(event);
|
||||
$scope.$apply();
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* BuildCtrl responsible for rendering a build.
|
||||
*/
|
||||
function BuildCtrl($scope, $stateParams, $window, logs, builds, repos, users) {
|
||||
var number = $stateParams.number;
|
||||
var owner = $stateParams.owner;
|
||||
var name = $stateParams.name;
|
||||
var fullName = owner + '/' + name;
|
||||
|
||||
/**
|
||||
* BuildCtrl responsible for rendering a build.
|
||||
*/
|
||||
function BuildCtrl($scope, $routeParams, $window, logs, builds, repos, users) {
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function (payload) {
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
|
||||
var number = $routeParams.number;
|
||||
var owner = $routeParams.owner;
|
||||
var name = $routeParams.name;
|
||||
var fullName = owner+'/'+name;
|
||||
// Gets a repository
|
||||
repos.get(fullName).then(function (payload) {
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function(payload){
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
// Gets the build
|
||||
builds.get(fullName, number).then(function (payload) {
|
||||
$scope.build = payload.data;
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
|
||||
// Gets a repository
|
||||
repos.get(fullName).then(function(payload){
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
repos.subscribe(fullName, function (event) {
|
||||
if (event.number !== parseInt(number)) {
|
||||
return; // ignore
|
||||
}
|
||||
// update the build
|
||||
$scope.build = event;
|
||||
$scope.$apply();
|
||||
});
|
||||
|
||||
// Gets the build
|
||||
builds.get(fullName, number).then(function(payload){
|
||||
$scope.build = payload.data;
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
$scope.restart = function () {
|
||||
builds.restart(fullName, number).then(function (payload) {
|
||||
$scope.build = payload.data;
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
};
|
||||
|
||||
repos.subscribe(fullName, function(event) {
|
||||
if (event.number !== parseInt(number)) {
|
||||
return; // ignore
|
||||
}
|
||||
// update the build
|
||||
$scope.build = event;
|
||||
$scope.$apply();
|
||||
});
|
||||
}
|
||||
$scope.cancel = function () {
|
||||
builds.cancel(fullName, number).then(function (payload) {
|
||||
$scope.build = payload.data;
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.tail = function () {
|
||||
tail = !tail;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* BuildOutCtrl responsible for rendering a build output.
|
||||
*/
|
||||
function BuildOutCtrl($scope, $routeParams, $window, logs, builds, repos, users) {
|
||||
/**
|
||||
* BuildOutCtrl responsible for rendering a build output.
|
||||
*/
|
||||
function BuildOutCtrl($scope, $stateParams, $window, logs, builds, repos, users) {
|
||||
|
||||
var step = parseInt($routeParams.step) || 1;
|
||||
var number = $routeParams.number;
|
||||
var owner = $routeParams.owner;
|
||||
var name = $routeParams.name;
|
||||
var fullName = owner+'/'+name;
|
||||
var streaming = false;
|
||||
var tail = false;
|
||||
var step = parseInt($stateParams.step) || 1;
|
||||
var number = $stateParams.number;
|
||||
var owner = $stateParams.owner;
|
||||
var name = $stateParams.name;
|
||||
var fullName = owner + '/' + name;
|
||||
var streaming = false;
|
||||
var tail = false;
|
||||
|
||||
// Initiates streaming a build.
|
||||
var stream = function() {
|
||||
if (streaming) {
|
||||
return;
|
||||
}
|
||||
streaming = true;
|
||||
// Initiates streaming a build.
|
||||
var stream = function () {
|
||||
if (streaming) {
|
||||
return;
|
||||
}
|
||||
streaming = true;
|
||||
|
||||
var convert = new Filter({stream:true,newline:false});
|
||||
var term = document.getElementById("term");
|
||||
term.innerHTML = "";
|
||||
var convert = new Filter({stream: true, newline: false});
|
||||
var term = document.getElementById("term");
|
||||
term.innerHTML = "";
|
||||
|
||||
// subscribes to the build otuput.
|
||||
logs.subscribe(fullName, number, step, function(data){
|
||||
term.innerHTML += convert.toHtml(data.replace("\\n","\n"));
|
||||
if (tail) {
|
||||
// scrolls to the bottom of the page if enabled
|
||||
$window.scrollTo(0, $window.document.body.scrollHeight);
|
||||
}
|
||||
});
|
||||
}
|
||||
// subscribes to the build otuput.
|
||||
logs.subscribe(fullName, number, step, function (data) {
|
||||
term.innerHTML += convert.toHtml(data.replace("\\n", "\n"));
|
||||
if (tail) {
|
||||
// scrolls to the bottom of the page if enabled
|
||||
$window.scrollTo(0, $window.document.body.scrollHeight);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function(payload){
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function (payload) {
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
|
||||
// Gets a repository
|
||||
repos.get(fullName).then(function(payload){
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
// Gets a repository
|
||||
repos.get(fullName).then(function (payload) {
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
|
||||
// Gets the build
|
||||
builds.get(fullName, number).then(function(payload){
|
||||
$scope.build = payload.data;
|
||||
$scope.task = payload.data.jobs[step-1];
|
||||
// Gets the build
|
||||
builds.get(fullName, number).then(function (payload) {
|
||||
$scope.build = payload.data;
|
||||
$scope.task = payload.data.jobs[step - 1];
|
||||
|
||||
if (['pending', 'killed'].indexOf($scope.task.status) !== -1) {
|
||||
// do nothing
|
||||
} else if ($scope.task.status === 'running') {
|
||||
// stream the build
|
||||
stream();
|
||||
} else {
|
||||
if (['pending', 'killed'].indexOf($scope.task.status) !== -1) {
|
||||
// do nothing
|
||||
} else if ($scope.task.status === 'running') {
|
||||
// stream the build
|
||||
stream();
|
||||
} else {
|
||||
|
||||
// fetch the logs for the finished build.
|
||||
logs.get(fullName, number, step).then(function(payload){
|
||||
var convert = new Filter({stream:false,newline:false});
|
||||
var term = document.getElementById("term")
|
||||
term.innerHTML = convert.toHtml(payload.data);
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
// fetch the logs for the finished build.
|
||||
logs.get(fullName, number, step).then(function (payload) {
|
||||
var convert = new Filter({stream: false, newline: false});
|
||||
var term = document.getElementById("term")
|
||||
term.innerHTML = convert.toHtml(payload.data);
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
|
||||
$scope.restart = function() {
|
||||
builds.restart(fullName, number).then(function(payload){
|
||||
$scope.build = payload.data;
|
||||
$scope.task = payload.data.builds[step-1];
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
};
|
||||
repos.subscribe(fullName, function (event) {
|
||||
if (event.number !== parseInt(number)) {
|
||||
return; // ignore
|
||||
}
|
||||
// update the build
|
||||
$scope.build = event;
|
||||
console.log(event.builds);
|
||||
$scope.task = event.builds[step - 1];
|
||||
$scope.$apply();
|
||||
|
||||
$scope.cancel = function() {
|
||||
builds.cancel(fullName, number).then(function(payload){
|
||||
$scope.build = payload.data;
|
||||
$scope.task = payload.data.builds[step-1];
|
||||
}).catch(function(err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
};
|
||||
// start streaming the current build
|
||||
if ($scope.task.status === 'running') {
|
||||
stream();
|
||||
} else {
|
||||
// resets our streaming state
|
||||
streaming = false;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.tail = function() {
|
||||
tail = !tail;
|
||||
};
|
||||
$scope.restart = function () {
|
||||
builds.restart(fullName, number).then(function (payload) {
|
||||
$scope.build = payload.data;
|
||||
$scope.task = payload.data.builds[step - 1];
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
};
|
||||
|
||||
repos.subscribe(fullName, function(event) {
|
||||
if (event.number !== parseInt(number)) {
|
||||
return; // ignore
|
||||
}
|
||||
// update the build
|
||||
$scope.build = event;
|
||||
$scope.task = event.builds[step-1];
|
||||
$scope.$apply();
|
||||
$scope.cancel = function () {
|
||||
builds.cancel(fullName, number).then(function (payload) {
|
||||
$scope.build = payload.data;
|
||||
$scope.task = payload.data.builds[step - 1];
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
};
|
||||
|
||||
// start streaming the current build
|
||||
if ($scope.task.status === 'running') {
|
||||
stream();
|
||||
} else {
|
||||
// resets our streaming state
|
||||
streaming = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
$scope.tail = function () {
|
||||
tail = !tail;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
angular
|
||||
.module('drone')
|
||||
.controller('BuildOutCtrl', BuildOutCtrl)
|
||||
.controller('BuildCtrl', BuildCtrl)
|
||||
.controller('BuildsCtrl', BuildsCtrl);
|
||||
angular
|
||||
.module('drone')
|
||||
.controller('BuildOutCtrl', BuildOutCtrl)
|
||||
.controller('BuildCtrl', BuildCtrl)
|
||||
.controller('BuildsCtrl', BuildsCtrl);
|
||||
})();
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
* CommitsCtrl responsible for rendering the repo's
|
||||
* recent commit history.
|
||||
*/
|
||||
function CommitsCtrl($scope, $routeParams, builds, repos, users, logs) {
|
||||
function CommitsCtrl($scope, $stateParams, builds, repos, users, logs) {
|
||||
|
||||
var owner = $routeParams.owner;
|
||||
var name = $routeParams.name;
|
||||
var owner = $stateParams.owner;
|
||||
var name = $stateParams.name;
|
||||
var fullName = owner+'/'+name;
|
||||
|
||||
// Gets the currently authenticated user
|
||||
|
|
|
@ -1,116 +1,115 @@
|
|||
(function () {
|
||||
|
||||
/**
|
||||
* ReposCtrl responsible for rendering the user's
|
||||
* repository home screen.
|
||||
*/
|
||||
function ReposCtrl($scope, $routeParams, repos, users) {
|
||||
/**
|
||||
* ReposCtrl responsible for rendering the user's
|
||||
* repository home screen.
|
||||
*/
|
||||
function ReposCtrl($scope, $stateParams, repos, users) {
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function (payload) {
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function(payload){
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
// Gets a list of repos to display in the
|
||||
// dropdown.
|
||||
repos.list().then(function (payload) {
|
||||
$scope.repos = angular.isArray(payload.data) ? payload.data : [];
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
|
||||
// Gets a list of repos to display in the
|
||||
// dropdown.
|
||||
repos.list().then(function(payload){
|
||||
$scope.repos = angular.isArray(payload.data) ? payload.data : [];
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* RepoAddCtrl responsible for activaing a new
|
||||
* repository.
|
||||
*/
|
||||
function RepoAddCtrl($scope, $location, repos, users) {
|
||||
|
||||
/**
|
||||
* RepoAddCtrl responsible for activaing a new
|
||||
* repository.
|
||||
*/
|
||||
function RepoAddCtrl($scope, $location, repos, users) {
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function (payload) {
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function(payload){
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
$scope.add = function (slug) {
|
||||
repos.post(slug).then(function (payload) {
|
||||
$location.path('/' + slug);
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$scope.add = function(slug) {
|
||||
repos.post(slug).then(function(payload) {
|
||||
$location.path('/'+slug);
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* RepoEditCtrl responsible for editing a repository.
|
||||
*/
|
||||
function RepoEditCtrl($scope, $window, $location, $stateParams, repos, users) {
|
||||
var owner = $stateParams.owner;
|
||||
var name = $stateParams.name;
|
||||
var fullName = owner + '/' + name;
|
||||
|
||||
/**
|
||||
* RepoEditCtrl responsible for editing a repository.
|
||||
*/
|
||||
function RepoEditCtrl($scope, $window, $location, $routeParams, repos, users) {
|
||||
var owner = $routeParams.owner;
|
||||
var name = $routeParams.name;
|
||||
var fullName = owner+'/'+name;
|
||||
// Inject window for composing url
|
||||
$scope.window = $window;
|
||||
|
||||
// Inject window for composing url
|
||||
$scope.window = $window;
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function (payload) {
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
|
||||
// Gets the currently authenticated user
|
||||
users.getCached().then(function(payload){
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
// Gets a repository
|
||||
repos.get(fullName).then(function (payload) {
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
|
||||
// Gets a repository
|
||||
repos.get(fullName).then(function(payload){
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
$scope.save = function (repo) {
|
||||
repo.timeout = parseInt(repo.timeout);
|
||||
repos.update(repo).then(function (payload) {
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.save = function(repo) {
|
||||
repo.timeout = parseInt(repo.timeout);
|
||||
repos.update(repo).then(function(payload) {
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
$scope.delete = function (repo) {
|
||||
repos.delete(repo).then(function (payload) {
|
||||
$location.path('/');
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.delete = function(repo) {
|
||||
repos.delete(repo).then(function(payload) {
|
||||
$location.path('/');
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
$scope.param = {};
|
||||
$scope.addParam = function (param) {
|
||||
if (!$scope.repo.params) {
|
||||
$scope.repo.params = {}
|
||||
}
|
||||
$scope.repo.params[param.key] = param.value;
|
||||
$scope.param = {};
|
||||
|
||||
$scope.param={}
|
||||
$scope.addParam = function(param) {
|
||||
if (!$scope.repo.params) {
|
||||
$scope.repo.params = {}
|
||||
}
|
||||
$scope.repo.params[param.key]=param.value;
|
||||
$scope.param={}
|
||||
// auto-update
|
||||
repos.update($scope.repo).then(function (payload) {
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
};
|
||||
|
||||
// auto-update
|
||||
repos.update($scope.repo).then(function(payload) {
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
$scope.deleteParam = function (key) {
|
||||
delete $scope.repo.params[key];
|
||||
|
||||
$scope.deleteParam = function(key) {
|
||||
delete $scope.repo.params[key];
|
||||
// auto-update
|
||||
repos.update($scope.repo).then(function (payload) {
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function (err) {
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// auto-update
|
||||
repos.update($scope.repo).then(function(payload) {
|
||||
$scope.repo = payload.data;
|
||||
}).catch(function(err){
|
||||
$scope.error = err;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
angular
|
||||
.module('drone')
|
||||
.controller('ReposCtrl', ReposCtrl)
|
||||
.controller('RepoAddCtrl', RepoAddCtrl)
|
||||
.controller('RepoEditCtrl', RepoEditCtrl);
|
||||
angular
|
||||
.module('drone')
|
||||
.controller('ReposCtrl', ReposCtrl)
|
||||
.controller('RepoAddCtrl', RepoAddCtrl)
|
||||
.controller('RepoEditCtrl', RepoEditCtrl);
|
||||
})();
|
||||
|
|
|
@ -2,150 +2,251 @@
|
|||
|
||||
(function () {
|
||||
|
||||
/**
|
||||
* Creates the angular application.
|
||||
*/
|
||||
angular.module('drone', [
|
||||
'ngRoute',
|
||||
'ui.filters'
|
||||
]);
|
||||
/**
|
||||
* Creates the angular application.
|
||||
*/
|
||||
angular.module('drone', [
|
||||
'ngRoute',
|
||||
'ui.filters',
|
||||
'ui.router'
|
||||
]);
|
||||
|
||||
/**
|
||||
* Bootstraps the application and retrieves the
|
||||
* token from the
|
||||
*/
|
||||
function Authorize() {
|
||||
// First, parse the query string
|
||||
var params = {}, queryString = location.hash.substring(1),
|
||||
regex = /([^&=]+)=([^&]*)/g, m;
|
||||
/**
|
||||
* Bootstraps the application and retrieves the
|
||||
* token from the
|
||||
*/
|
||||
function Authorize() {
|
||||
// First, parse the query string
|
||||
var params = {}, queryString = location.hash.substring(1),
|
||||
regex = /([^&=]+)=([^&]*)/g, m;
|
||||
|
||||
// Loop through and retrieve the token
|
||||
while (m = regex.exec(queryString)) {
|
||||
params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
|
||||
}
|
||||
// Loop through and retrieve the token
|
||||
while (m = regex.exec(queryString)) {
|
||||
params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
|
||||
}
|
||||
|
||||
// if the user has just received an auth token we
|
||||
// should extract from the URL, save to local storage
|
||||
// and then remove from the URL for good measure.
|
||||
if (params.access_token) {
|
||||
localStorage.setItem("access_token", params.access_token);
|
||||
history.replaceState({}, document.title, location.pathname);
|
||||
}
|
||||
}
|
||||
// if the user has just received an auth token we
|
||||
// should extract from the URL, save to local storage
|
||||
// and then remove from the URL for good measure.
|
||||
if (params.access_token) {
|
||||
localStorage.setItem("access_token", params.access_token);
|
||||
history.replaceState({}, document.title, location.pathname);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the route configuration for the
|
||||
* main application.
|
||||
*/
|
||||
function Config ($routeProvider, $httpProvider, $locationProvider) {
|
||||
/**
|
||||
* Defines the route configuration for the
|
||||
* main application.
|
||||
*/
|
||||
function Config($stateProvider, $httpProvider, $locationProvider) {
|
||||
|
||||
// Resolver that will attempt to load the currently
|
||||
// authenticated user prior to loading the page.
|
||||
var resolveUser = {
|
||||
user: function(users) {
|
||||
return users.getCached();
|
||||
}
|
||||
}
|
||||
// Resolver that will attempt to load the currently
|
||||
// authenticated user prior to loading the page.
|
||||
var resolveUser = {
|
||||
user: function (users) {
|
||||
return users.getCached();
|
||||
}
|
||||
};
|
||||
|
||||
$routeProvider
|
||||
.when('/', {
|
||||
templateUrl: '/static/scripts/views/repos.html',
|
||||
controller: 'ReposCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.when('/login', {
|
||||
templateUrl: '/static/scripts/views/login.html',
|
||||
controller: 'UserLoginCtrl'
|
||||
})
|
||||
.when('/profile', {
|
||||
templateUrl: '/static/scripts/views/user.html',
|
||||
controller: 'UserCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.when('/users', {
|
||||
templateUrl: '/static/scripts/views/users.html',
|
||||
controller: 'UsersCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.when('/new', {
|
||||
templateUrl: '/static/scripts/views/repos_add.html',
|
||||
controller: 'RepoAddCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.when('/:owner/:name', {
|
||||
templateUrl: '/static/scripts/views/builds.html',
|
||||
controller: 'BuildsCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.when('/:owner/:name/edit', {
|
||||
templateUrl: '/static/scripts/views/repos_edit.html',
|
||||
controller: 'RepoEditCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.when('/:owner/:name/edit/env', {
|
||||
templateUrl: '/static/scripts/views/repos_env.html',
|
||||
controller: 'RepoEditCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.when('/:owner/:name/delete', {
|
||||
templateUrl: '/static/scripts/views/repos_del.html',
|
||||
controller: 'RepoEditCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.when('/:owner/:name/:number', {
|
||||
templateUrl: '/static/scripts/views/build.html',
|
||||
controller: 'BuildCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.when('/:owner/:name/:number/:step', {
|
||||
templateUrl: '/static/scripts/views/build_out.html',
|
||||
controller: 'BuildOutCtrl',
|
||||
resolve: resolveUser
|
||||
});
|
||||
$stateProvider
|
||||
.state('app', {
|
||||
abstract: true,
|
||||
views: {
|
||||
'layout': {
|
||||
templateUrl: '/static/scripts/views/layout.html',
|
||||
controller: function ($scope, $routeParams, repos, users) {
|
||||
users.getCached().then(function (payload) {
|
||||
$scope.user = payload.data;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.state('app.index', {
|
||||
url: '/',
|
||||
views: {
|
||||
'toolbar': {
|
||||
templateUrl: '/static/scripts/views/repos/index/toolbar.html'
|
||||
},
|
||||
'content': {
|
||||
templateUrl: '/static/scripts/views/repos/index/content.html',
|
||||
controller: 'ReposCtrl',
|
||||
resolve: resolveUser
|
||||
}
|
||||
},
|
||||
title: 'Dashboard'
|
||||
})
|
||||
.state('login', {
|
||||
url: '/login',
|
||||
views: {
|
||||
'layout': {
|
||||
templateUrl: '/static/scripts/views/login.html',
|
||||
controller: 'UserLoginCtrl',
|
||||
resolve: resolveUser
|
||||
}
|
||||
},
|
||||
title: 'Login'
|
||||
})
|
||||
.state('app.profile', {
|
||||
url: '/profile',
|
||||
views: {
|
||||
'toolbar': {templateUrl: '/static/scripts/views/profile/toolbar.html'},
|
||||
'content': {
|
||||
templateUrl: '/static/scripts/views/profile/content.html',
|
||||
controller: 'UserCtrl',
|
||||
resolve: resolveUser
|
||||
}
|
||||
},
|
||||
title: 'Profile'
|
||||
})
|
||||
.state('app.users', {
|
||||
url: '/users',
|
||||
views: {
|
||||
'toolbar': {templateUrl: '/static/scripts/views/users/toolbar.html'},
|
||||
'content': {
|
||||
templateUrl: '/static/scripts/views/users/content.html',
|
||||
controller: 'UsersCtrl',
|
||||
resolve: resolveUser
|
||||
}
|
||||
},
|
||||
title: 'Users'
|
||||
})
|
||||
.state('app.new_repo', {
|
||||
url: '/new',
|
||||
views: {
|
||||
'toolbar': {templateUrl: '/static/scripts/views/repos/add/toolbar.html'},
|
||||
'content': {
|
||||
templateUrl: '/static/scripts/views/repos/add/content.html',
|
||||
controller: 'RepoAddCtrl',
|
||||
resolve: resolveUser
|
||||
}
|
||||
},
|
||||
title: 'Add Repository'
|
||||
})
|
||||
.state('app.builds', {
|
||||
url: '/:owner/:name',
|
||||
views: {
|
||||
'toolbar': {
|
||||
templateUrl: '/static/scripts/views/builds/index/toolbar.html',
|
||||
controller: 'RepoEditCtrl',
|
||||
resolve: resolveUser
|
||||
},
|
||||
'content': {
|
||||
templateUrl: '/static/scripts/views/builds/index/content.html',
|
||||
controller: 'BuildsCtrl'
|
||||
}
|
||||
},
|
||||
title: 'Builds'
|
||||
})
|
||||
.state('app.repo_edit', {
|
||||
url: '/:owner/:name/edit',
|
||||
views: {
|
||||
'toolbar': {
|
||||
templateUrl: '/static/scripts/views/repos/toolbar.html',
|
||||
controller: 'RepoEditCtrl',
|
||||
resolve: resolveUser
|
||||
},
|
||||
'content': {
|
||||
templateUrl: '/static/scripts/views/repos/edit.html',
|
||||
controller: 'RepoEditCtrl',
|
||||
resolve: resolveUser
|
||||
}
|
||||
},
|
||||
title: 'Edit Repository'
|
||||
})
|
||||
.state('app.repo.env', {
|
||||
url: '/:owner/:name/edit/env',
|
||||
views: {
|
||||
'toolbar': {templateUrl: '/static/scripts/views/repos/toolbar.html'},
|
||||
'content': {templateUrl: '/static/scripts/views/repos/env.html'}
|
||||
},
|
||||
controller: 'RepoEditCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.state('app.repo.del', {
|
||||
url: '/:owner/:name/delete',
|
||||
views: {
|
||||
'toolbar': {templateUrl: '/static/scripts/views/repos/toolbar.html'},
|
||||
'content': {templateUrl: '/static/scripts/views/repos/del.html'}
|
||||
},
|
||||
controller: 'RepoEditCtrl',
|
||||
resolve: resolveUser
|
||||
})
|
||||
.state('app.build', {
|
||||
url: '/:owner/:name/:number',
|
||||
views: {
|
||||
'toolbar': {
|
||||
templateUrl: '/static/scripts/views/builds/show/toolbar.html',
|
||||
controller: 'BuildCtrl',
|
||||
resolve: resolveUser
|
||||
},
|
||||
'content': {
|
||||
templateUrl: '/static/scripts/views/builds/show/content.html',
|
||||
controller: 'BuildCtrl',
|
||||
resolve: resolveUser
|
||||
}
|
||||
},
|
||||
title: 'Build'
|
||||
})
|
||||
.state('app.job', {
|
||||
url: '/:owner/:name/:number/:step',
|
||||
views: {
|
||||
'toolbar': {
|
||||
templateUrl: '/static/scripts/views/builds/step/toolbar.html',
|
||||
controller: 'BuildOutCtrl',
|
||||
resolve: resolveUser
|
||||
},
|
||||
'content': {
|
||||
templateUrl: '/static/scripts/views/builds/step/content.html',
|
||||
controller: 'BuildOutCtrl',
|
||||
resolve: resolveUser
|
||||
},
|
||||
title: 'Build Job'
|
||||
}
|
||||
});
|
||||
|
||||
// Enables html5 mode
|
||||
$locationProvider.html5Mode(true)
|
||||
// Enables html5 mode
|
||||
$locationProvider.html5Mode(true);
|
||||
|
||||
// Appends the Bearer token to authorize every
|
||||
// outbound http request.
|
||||
$httpProvider.defaults.headers.common.Authorization = 'Bearer '+localStorage.getItem('access_token');
|
||||
// Appends the Bearer token to authorize every
|
||||
// outbound http request.
|
||||
$httpProvider.defaults.headers.common.Authorization = 'Bearer ' + localStorage.getItem('access_token');
|
||||
|
||||
// Intercepts every oubput http response and redirects
|
||||
// the user to the logic screen if the request was rejected.
|
||||
$httpProvider.interceptors.push(function($q, $location) {
|
||||
return {
|
||||
'responseError': function(rejection) {
|
||||
if (rejection.status === 401 && rejection.config.url !== "/api/user") {
|
||||
$location.path('/login');
|
||||
}
|
||||
if (rejection.status === 0) {
|
||||
// this happens when the app is down or
|
||||
// the browser loses internet connectivity.
|
||||
}
|
||||
return $q.reject(rejection);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
// Intercepts every oubput http response and redirects
|
||||
// the user to the logic screen if the request was rejected.
|
||||
$httpProvider.interceptors.push(function ($q, $location) {
|
||||
return {
|
||||
'responseError': function (rejection) {
|
||||
if (rejection.status === 401 && rejection.config.url !== "/api/user") {
|
||||
$location.path('/login');
|
||||
}
|
||||
if (rejection.status === 0) {
|
||||
// this happens when the app is down or
|
||||
// the browser loses internet connectivity.
|
||||
}
|
||||
return $q.reject(rejection);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function RouteChange($rootScope, repos, logs) {
|
||||
$rootScope.$on('$stateChangeStart', function () {
|
||||
repos.unsubscribe();
|
||||
logs.unsubscribe();
|
||||
});
|
||||
|
||||
function RouteChange($rootScope, repos, logs) {
|
||||
$rootScope.$on('$routeChangeStart', function (event, next) {
|
||||
repos.unsubscribe();
|
||||
logs.unsubscribe();
|
||||
});
|
||||
$rootScope.$on('$stateChangeSuccess', function (event, current) {
|
||||
if (current.title) {
|
||||
document.title = current.title + ' · drone';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
|
||||
if (current.$$route.title) {
|
||||
document.title = current.$$route.title + ' · drone';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
angular
|
||||
.module('drone')
|
||||
.config(Authorize)
|
||||
.config(Config)
|
||||
.run(RouteChange);
|
||||
angular
|
||||
.module('drone')
|
||||
.config(Authorize)
|
||||
.config(Config)
|
||||
.run(RouteChange);
|
||||
|
||||
})();
|
||||
|
|
|
@ -2,116 +2,116 @@
|
|||
|
||||
(function () {
|
||||
|
||||
/**
|
||||
* The RepoService provides access to repository
|
||||
* data using REST API calls.
|
||||
*/
|
||||
function RepoService($http, $window) {
|
||||
/**
|
||||
* The RepoService provides access to repository
|
||||
* data using REST API calls.
|
||||
*/
|
||||
function RepoService($http, $window) {
|
||||
|
||||
var callback,
|
||||
websocket,
|
||||
token = localStorage.getItem('access_token');
|
||||
var callback,
|
||||
websocket,
|
||||
token = localStorage.getItem('access_token');
|
||||
|
||||
/**
|
||||
* Gets a list of all repositories.
|
||||
*/
|
||||
this.list = function() {
|
||||
return $http.get('/api/user/repos');
|
||||
};
|
||||
/**
|
||||
* Gets a list of all repositories.
|
||||
*/
|
||||
this.list = function () {
|
||||
return $http.get('/api/user/repos');
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a repository by name.
|
||||
*
|
||||
* @param {string} Name of the repository.
|
||||
*/
|
||||
this.get = function(repoName) {
|
||||
return $http.get('/api/repos/'+repoName);
|
||||
};
|
||||
/**
|
||||
* Gets a repository by name.
|
||||
*
|
||||
* @param {string} Name of the repository.
|
||||
*/
|
||||
this.get = function (repoName) {
|
||||
return $http.get('/api/repos/' + repoName);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new repository.
|
||||
*
|
||||
* @param {object} JSON representation of a repository.
|
||||
*/
|
||||
this.post = function(repoName) {
|
||||
return $http.post('/api/repos/' + repoName);
|
||||
};
|
||||
/**
|
||||
* Creates a new repository.
|
||||
*
|
||||
* @param {object} JSON representation of a repository.
|
||||
*/
|
||||
this.post = function (repoName) {
|
||||
return $http.post('/api/repos/' + repoName);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates an existing repository.
|
||||
*
|
||||
* @param {object} JSON representation of a repository.
|
||||
*/
|
||||
this.update = function(repo) {
|
||||
return $http.patch('/api/repos/'+repo.full_name, repo);
|
||||
};
|
||||
/**
|
||||
* Updates an existing repository.
|
||||
*
|
||||
* @param {object} JSON representation of a repository.
|
||||
*/
|
||||
this.update = function (repo) {
|
||||
return $http.patch('/api/repos/' + repo.full_name, repo);
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a repository.
|
||||
*
|
||||
* @param {string} Name of the repository.
|
||||
*/
|
||||
this.delete = function(repoName) {
|
||||
return $http.delete('/api/repos/'+repoName);
|
||||
};
|
||||
/**
|
||||
* Deletes a repository.
|
||||
*
|
||||
* @param {string} Name of the repository.
|
||||
*/
|
||||
this.delete = function (repoName) {
|
||||
return $http.delete('/api/repos/' + repoName);
|
||||
};
|
||||
|
||||
/**
|
||||
* Watch a repository.
|
||||
*
|
||||
* @param {string} Name of the repository.
|
||||
*/
|
||||
this.watch = function(repoName) {
|
||||
return $http.post('/api/repos/'+repoName+'/watch');
|
||||
};
|
||||
/**
|
||||
* Watch a repository.
|
||||
*
|
||||
* @param {string} Name of the repository.
|
||||
*/
|
||||
this.watch = function (repoName) {
|
||||
return $http.post('/api/repos/' + repoName + '/watch');
|
||||
};
|
||||
|
||||
/**
|
||||
* Unwatch a repository.
|
||||
*
|
||||
* @param {string} Name of the repository.
|
||||
*/
|
||||
this.unwatch = function(repoName) {
|
||||
return $http.delete('/api/repos/'+repoName+'/unwatch');
|
||||
};
|
||||
/**
|
||||
* Unwatch a repository.
|
||||
*
|
||||
* @param {string} Name of the repository.
|
||||
*/
|
||||
this.unwatch = function (repoName) {
|
||||
return $http.delete('/api/repos/' + repoName + '/unwatch');
|
||||
};
|
||||
|
||||
|
||||
var callback,
|
||||
events,
|
||||
token = localStorage.getItem('access_token');
|
||||
var callback,
|
||||
events,
|
||||
token = localStorage.getItem('access_token');
|
||||
|
||||
/**
|
||||
* Subscribes to a live update feed for a repository
|
||||
*
|
||||
* @param {string} Name of the repository.
|
||||
*/
|
||||
this.subscribe = function(repo, _callback) {
|
||||
callback = _callback;
|
||||
/**
|
||||
* Subscribes to a live update feed for a repository
|
||||
*
|
||||
* @param {string} Name of the repository.
|
||||
*/
|
||||
this.subscribe = function (repo, _callback) {
|
||||
callback = _callback;
|
||||
|
||||
events = new EventSource("/api/stream/" + repo + "?access_token=" + token, { withCredentials: true });
|
||||
events.onmessage = function (event) {
|
||||
if (callback !== undefined) {
|
||||
callback(angular.fromJson(event.data));
|
||||
}
|
||||
};
|
||||
events.onerror = function (event) {
|
||||
callback = undefined;
|
||||
if (events !== undefined) {
|
||||
events.close();
|
||||
events = undefined;
|
||||
}
|
||||
console.log('user event stream closed due to error.', event);
|
||||
};
|
||||
};
|
||||
events = new EventSource("/api/stream/" + repo + "?access_token=" + token, {withCredentials: true});
|
||||
events.onmessage = function (event) {
|
||||
if (callback !== undefined) {
|
||||
callback(angular.fromJson(event.data));
|
||||
}
|
||||
};
|
||||
events.onerror = function (event) {
|
||||
callback = undefined;
|
||||
if (events !== undefined) {
|
||||
events.close();
|
||||
events = undefined;
|
||||
}
|
||||
console.log('user event stream closed due to error.', event);
|
||||
};
|
||||
};
|
||||
|
||||
this.unsubscribe = function() {
|
||||
callback = undefined;
|
||||
if (events !== undefined) {
|
||||
events.close();
|
||||
events = undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
this.unsubscribe = function () {
|
||||
callback = undefined;
|
||||
if (events !== undefined) {
|
||||
events.close();
|
||||
events = undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
angular
|
||||
.module('drone')
|
||||
.service('repos', RepoService);
|
||||
angular
|
||||
.module('drone')
|
||||
.service('repos', RepoService);
|
||||
})();
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item settings float-right" href="/profile"></a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank"></a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
|
||||
<div class="toolbar">
|
||||
|
||||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a ng-href="/{{ repo.full_name }}" class="icon icon-home"></a>
|
||||
<a ng-href="/{{ repo.full_name }}">{{ repo.owner }} / {{ repo.name }}</a>
|
||||
<span class="spacer"></span>
|
||||
<a ng-href="#">{{ build.number }}</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a href="settings.html" class="icon icon-settings"></a>
|
||||
<a ng-href="/{{ repo.full_name }}/edit" class="nav-item settings float-right"></a>
|
||||
<button ng-click="watch(repo)" ng-if="!repo.starred" class="nav-item star float-right"></button>
|
||||
<button ng-click="unwatch(repo)" ng-if="repo.starred" class="nav-item unstar float-right"></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<article>
|
||||
|
||||
<section class="commit-section">
|
||||
<div class="row build-row">
|
||||
<div>
|
||||
<div ng-class="[ 'build-num', build.status ]"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ build.head_commit.message }}</h3>
|
||||
<p><strong>{{ build.head_commit.author.login }}</strong> pushed to <strong>{{ build.head_commit.branch }}</strong> {{ build.started_at | fromNow }}</p>
|
||||
<div style="position:absolute;top:30px;right:30px;color:#CCC;"># {{build.number}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<a class="row build-row sub-build-row" ng-repeat="job in build.jobs" ng-href="{{ repo.full_name }}/{{ build.number }}/{{ job.number }}">
|
||||
<div>
|
||||
<div ng-class="[ 'build-num', build.status ]"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>
|
||||
<div ng-repeat="(key, value) in job.environment">
|
||||
{{ key.toUpperCase() }}={{ value }}
|
||||
</div>
|
||||
</h3>
|
||||
<div style="position:absolute;top:30px;right:30px;color:#CCC;"># {{job.number}}</div>
|
||||
</div>
|
||||
</a>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
<button ng-if="build.status !== 'pending' && build.status !== 'running'" ng-click="restart()">Restart</button>
|
||||
<button ng-if="build.status === 'pending' || build.status === 'running'" ng-click="cancel()">Cancel</button>
|
|
@ -1,68 +0,0 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item settings float-right" href="/profile"></a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank"></a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
|
||||
<div class="toolbar">
|
||||
|
||||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a ng-href="/{{ repo.full_name }}/{{ build.sequence }}" class="icon icon-home"></a>
|
||||
<a ng-href="/{{ repo.full_name }}">{{ repo.owner }} / {{ repo.name }}</a>
|
||||
<span class="spacer"></span>
|
||||
<a ng-href="/{{ repo.full_name }}/{{ build.sequence }}">{{ build.sequence }}</a>
|
||||
<span class="spacer"></span>
|
||||
<a href="#">{{ task.sequence }}</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a ng-href="/{{ repo.full_name }}/edit" class="nav-item settings float-right"></a>
|
||||
<button ng-click="watch(repo)" ng-if="!repo.starred" class="nav-item star float-right"></button>
|
||||
<button ng-click="unwatch(repo)" ng-if="repo.starred" class="nav-item unstar float-right"></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<article>
|
||||
|
||||
<section class="commit-section">
|
||||
<div class="row build-row">
|
||||
<div>
|
||||
<div ng-class="[ 'build-num', task.status ]" ng-if="task"></div>
|
||||
<div ng-class="[ 'build-num', build.status ]" ng-if="!task"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ build.head_commit.message }}</h3>
|
||||
<p><strong>{{ build.head_commit.author.login }}</strong> pushed to <strong>{{ build.head_commit.branch }}</strong> {{ build.started_at | fromNow }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row build-row sub-build-row" ng-if="build.jobs.length > 1">
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<h3 style="margin-top:0px">
|
||||
<div ng-repeat="(key, value) in task.environment">
|
||||
{{ key.toUpperCase() }}={{ value }}
|
||||
</div>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<pre id="term" ng-if="task && task.status !== 'pending'"></pre>
|
||||
<button class="fab" ng-if="build.status === 'running'" ng-click="tail()"></button>
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
<button ng-if="build.status !== 'pending' && build.status !== 'running'" ng-click="restart()">Restart</button>
|
||||
<button ng-if="build.status === 'pending' || build.status === 'running'" ng-click="cancel()">Cancel</button>
|
|
@ -1,39 +0,0 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item settings float-right" href="/profile"></a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank"></a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
|
||||
<div class="toolbar">
|
||||
|
||||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/" class="icon icon-home"></a>
|
||||
<a href="#">{{ repo.owner }} / {{ repo.name }}</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a ng-href="/{{ repo.full_name }}/edit" class="nav-item settings float-right" ng-if="repo.permissions.pull"></a>
|
||||
<button ng-click="watch(repo)" ng-if="!repo.starred && user" class="nav-item star float-right"></button>
|
||||
<button ng-click="unwatch(repo)" ng-if="repo.starred && user" class="nav-item unstar float-right"></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<a class="row build-row" ng-repeat="build in builds | orderBy:'-number'" ng-href="/{{ repo.full_name }}/{{ build.number }}">
|
||||
<div>
|
||||
<div ng-class="[ 'build-num', build.status ]"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ build.head_commit.message }}</h3>
|
||||
<p><strong>{{ build.head_commit.author.login }}</strong> pushed to <strong>{{ build.head_commit.branch }}</strong> {{ build.started_at | fromNow }}</p>
|
||||
<div style="position:absolute;top:30px;right:30px;color:#CCC;"># {{build.number}}</div>
|
||||
</div>
|
||||
</a>
|
||||
</section>
|
||||
</article>
|
|
@ -0,0 +1,18 @@
|
|||
<article>
|
||||
<section>
|
||||
<a class="row build-row" ng-repeat="build in builds | orderBy:'-number'" ng-href="/{{ repo.full_name }}/{{ build.number }}">
|
||||
<div>
|
||||
<div ng-class="[ 'build-num', build.status ]"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ build.head_commit.message }}</h3>
|
||||
|
||||
<p>
|
||||
<strong>{{ build.head_commit.author.login }}</strong> pushed to <strong>{{ build.head_commit.branch}}</strong> {{ build.started_at | fromNow }}
|
||||
</p>
|
||||
|
||||
<div style="position:absolute;top:30px;right:30px;color:#CCC;"># {{build.number}}</div>
|
||||
</div>
|
||||
</a>
|
||||
</section>
|
||||
</article>
|
|
@ -0,0 +1,18 @@
|
|||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/" class="icon icon-home">
|
||||
<i class="material-icons md-18">home</i>
|
||||
</a>
|
||||
<a href="#">{{ repo.owner }} / {{ repo.name }}</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a ng-href="/{{ repo.full_name }}/edit" class="nav-item settings float-right" ng-if="repo.permissions.pull">
|
||||
<i class="material-icons md-18">edit</i>
|
||||
</a>
|
||||
<button ng-click="watch(repo)" ng-if="!repo.starred && user" class="nav-item star float-right">
|
||||
<i class="material-icons md-18">star_border</i>
|
||||
</button>
|
||||
<button ng-click="unwatch(repo)" ng-if="repo.starred && user" class="nav-item unstar float-right">
|
||||
<i class="material-icons md-18">star</i>
|
||||
</button>
|
||||
</div>
|
|
@ -0,0 +1,40 @@
|
|||
<article>
|
||||
|
||||
<section class="commit-section">
|
||||
<div class="row build-row">
|
||||
<div>
|
||||
<div ng-class="[ 'build-num', build.status ]"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ build.head_commit.message }}</h3>
|
||||
|
||||
<p><strong>{{ build.head_commit.author.login }}</strong> pushed to <strong>{{ build.head_commit.branch}}</strong> {{ build.started_at | fromNow }}</p>
|
||||
|
||||
<div style="position:absolute;top:30px;right:30px;color:#CCC;"># {{build.number}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<p style="padding-top: 20px;">
|
||||
<h3><strong>Build jobs</strong></h3>
|
||||
</p>
|
||||
<section>
|
||||
<a class="row build-row sub-build-row" ng-repeat="job in build.jobs" ng-href="{{ repo.full_name }}/{{ build.number }}/{{ job.number }}">
|
||||
<div>
|
||||
<div ng-class="[ 'build-num', build.status ]"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>
|
||||
<div ng-repeat="(key, value) in job.environment">
|
||||
{{ key.toUpperCase() }}={{ value }}
|
||||
</div>
|
||||
</h3>
|
||||
<div style="position:absolute;top:30px;right:30px;color:#CCC;"># {{job.number}}</div>
|
||||
</div>
|
||||
</a>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
<div style="padding-left: 20px;">
|
||||
<button ng-if="build.status !== 'pending' && build.status !== 'running'" ng-click="restart()">Restart</button>
|
||||
<button ng-if="build.status === 'pending' || build.status === 'running'" ng-click="cancel()">Cancel</button>
|
||||
</div>
|
|
@ -0,0 +1,20 @@
|
|||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a ng-href="/{{ repo.full_name }}" class="icon icon-home">
|
||||
<i class="material-icons md-18">home</i>
|
||||
</a>
|
||||
<a ng-href="/{{ repo.full_name }}">{{ repo.owner }} / {{ repo.name }}</a>
|
||||
<span class="spacer"></span>
|
||||
<a ng-href="#">#{{ build.number }}</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a ng-href="/{{ repo.full_name }}/edit" class="nav-item settings float-right" ng-if="repo.permissions.pull">
|
||||
<i class="material-icons md-18">edit</i>
|
||||
</a>
|
||||
<button ng-click="watch(repo)" ng-if="!repo.starred && user" class="nav-item star float-right">
|
||||
<i class="material-icons md-18">star_border</i>
|
||||
</button>
|
||||
<button ng-click="unwatch(repo)" ng-if="repo.starred && user" class="nav-item unstar float-right">
|
||||
<i class="material-icons md-18">star</i>
|
||||
</button>
|
||||
</div>
|
|
@ -0,0 +1,37 @@
|
|||
<article>
|
||||
|
||||
<section class="commit-section">
|
||||
<div class="row build-row">
|
||||
<div>
|
||||
<div ng-class="[ 'build-num', task.status ]" ng-if="task"></div>
|
||||
<div ng-class="[ 'build-num', build.status ]" ng-if="!task"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ build.head_commit.message }}</h3>
|
||||
|
||||
<p><strong>{{ build.head_commit.author.login }}</strong> pushed to <strong>{{ build.head_commit.branch}}</strong> {{ build.started_at | fromNow }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row build-row sub-build-row" ng-if="build.jobs.length > 1">
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<h3 style="margin-top:0px">
|
||||
<div ng-repeat="(key, value) in task.environment">
|
||||
{{ key.toUpperCase() }}={{ value }}
|
||||
</div>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<pre id="term" ng-if="task && task.status !== 'pending'"></pre>
|
||||
<button class="fab" ng-if="build.status === 'running'" ng-click="tail()"></button>
|
||||
</article>
|
||||
|
||||
|
||||
<button ng-if="build.status !== 'pending' && build.status !== 'running'" ng-click="restart()">Restart</button>
|
||||
<button ng-if="build.status === 'pending' || build.status === 'running'" ng-click="cancel()">Cancel</button>
|
|
@ -0,0 +1,22 @@
|
|||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a ng-href="/{{ repo.full_name }}/{{ build.sequence }}" class="icon icon-home">
|
||||
<i class="material-icons md-18">home</i>
|
||||
</a>
|
||||
<a ng-href="/{{ repo.full_name }}">{{ repo.owner }} / {{ repo.name }}</a>
|
||||
<span class="spacer"> </span>
|
||||
<a ng-href="/{{ repo.full_name }}/{{ build.number }}">Build # {{ build.number }}</a>
|
||||
<span class="spacer"></span>
|
||||
<a href="#">Job #{{ task.number }}</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a ng-href="/{{ repo.full_name }}/edit" class="nav-item settings float-right" ng-if="repo.permissions.pull">
|
||||
<i class="material-icons md-18">edit</i>
|
||||
</a>
|
||||
<button ng-click="watch(repo)" ng-if="!repo.starred && user" class="nav-item star float-right">
|
||||
<i class="material-icons md-18">star_border</i>
|
||||
</button>
|
||||
<button ng-click="unwatch(repo)" ng-if="repo.starred && user" class="nav-item unstar float-right">
|
||||
<i class="material-icons md-18">star</i>
|
||||
</button>
|
||||
</div>
|
15
cmd/drone-server/static/scripts/views/layout.html
Normal file
15
cmd/drone-server/static/scripts/views/layout.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank">
|
||||
<i class="material-icons md-18">help</i>
|
||||
</a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin">
|
||||
<i class="material-icons md-18">supervisor_account</i>
|
||||
</a>
|
||||
<a class="menu-item settings float-right" href="/profile">
|
||||
<i class="material-icons md-18">settings</i>
|
||||
</a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
<div class="toolbar" ui-view="toolbar"></div>
|
||||
<div ui-view="content"></div>
|
|
@ -1,67 +1,74 @@
|
|||
<style>
|
||||
html, body {
|
||||
background:#EEEEEE;
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
font-family:"Roboto";
|
||||
font-size:15px;
|
||||
text-transform:uppercase;
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
a.box {
|
||||
background:#FFF;
|
||||
width:250px;
|
||||
padding:20px;
|
||||
box-shadow: 0px 0px 0 rgba(255,255,255,0.05);
|
||||
-webkit-transition: all .5s;
|
||||
-webkit-box-flex: 0;
|
||||
display:block;
|
||||
text-decoration:none;
|
||||
border-radius:3px;
|
||||
}
|
||||
a.box:hover {
|
||||
box-shadow: 7px 7px 0 rgba(255,255,255,0.05);
|
||||
}
|
||||
div.logo {
|
||||
background: url(/static/images/logo.svg) no-repeat center center;;
|
||||
background-size:72px;
|
||||
height:150px;
|
||||
-webkit-transition: all .5s;
|
||||
}
|
||||
div.login {
|
||||
text-align: center;
|
||||
padding: 15px;
|
||||
color: #424242;
|
||||
font-size: 18px;
|
||||
text-transform: uppercase;
|
||||
border-radius: 3px;
|
||||
-webkit-transition: all .5s;
|
||||
background: #424242;
|
||||
color: rgba(255,255,255,0.7);
|
||||
}
|
||||
body > div {
|
||||
width:100%;
|
||||
height:100%;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
html, body {
|
||||
background: #EEEEEE;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
font-family: "Roboto";
|
||||
font-size: 15px;
|
||||
text-transform: uppercase;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
a.box {
|
||||
background: #FFF;
|
||||
width: 250px;
|
||||
padding: 20px;
|
||||
box-shadow: 0px 0px 0 rgba(255, 255, 255, 0.05);
|
||||
-webkit-transition: all .5s;
|
||||
-webkit-box-flex: 0;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
a.box:hover {
|
||||
box-shadow: 7px 7px 0 rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
div.logo {
|
||||
background: url(/static/images/logo.svg) no-repeat center center;
|
||||
background-size: 72px;
|
||||
height: 150px;
|
||||
-webkit-transition: all .5s;
|
||||
}
|
||||
|
||||
div.login {
|
||||
text-align: center;
|
||||
padding: 15px;
|
||||
color: #424242;
|
||||
font-size: 18px;
|
||||
text-transform: uppercase;
|
||||
border-radius: 3px;
|
||||
-webkit-transition: all .5s;
|
||||
background: #424242;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
body > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<a href="/authorize" target="_self" class="box">
|
||||
<div class="logo"></div>
|
||||
<div ng-switch="error" class="alert alert-error" ng-if="error">
|
||||
<div ng-switch-when="internal_error">Oops. There was an unexpected error. Please try again.</div>
|
||||
<div ng-switch-when="user_not_found">There was an error authorizing your account.</div>
|
||||
<div ng-switch-when="access_denied_org">Login is restricted to approved organization members only</div>
|
||||
<div ng-switch-when="access_denied">Self-registration is disabled. Please contact the system admin to grant access.</div>
|
||||
</div>
|
||||
<div class="login">Login</div>
|
||||
<div class="logo"></div>
|
||||
<div ng-switch="error" class="alert alert-error" ng-if="error">
|
||||
<div ng-switch-when="internal_error">Oops. There was an unexpected error. Please try again.</div>
|
||||
<div ng-switch-when="user_not_found">There was an error authorizing your account.</div>
|
||||
<div ng-switch-when="access_denied_org">Login is restricted to approved organization members only</div>
|
||||
<div ng-switch-when="access_denied">Self-registration is disabled. Please contact the system admin to grant
|
||||
access.
|
||||
</div>
|
||||
</div>
|
||||
<div class="login">Login</div>
|
||||
</a>
|
||||
|
|
|
@ -1,19 +1,3 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item settings float-right" href="/profile"></a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank"></a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
|
||||
<div class="toolbar">
|
||||
|
||||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/" class="icon icon-home"></a>
|
||||
<a href="#">Profile</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Login info</h2>
|
||||
|
@ -34,8 +18,12 @@
|
|||
<section>
|
||||
<h2>Tokens</h2>
|
||||
<form>
|
||||
<input type="label" ng-model="newToken.label" />
|
||||
<div style="padding-left: 20px; float: left;">
|
||||
<input type="label" ng-model="newToken.label" />
|
||||
</div>
|
||||
<div style="padding-top: 20px; padding-left: 20px; float: left;">
|
||||
<button ng-click="createToken(newToken)">Create</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="alert" ng-if="tokens && tokens.length === 0">No Personal Tokens Exist</div>
|
|
@ -0,0 +1,6 @@
|
|||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/" class="icon icon-home">
|
||||
<i class="material-icons md-18">home</i>
|
||||
</a>
|
||||
<a href="#">Profile</a>
|
||||
</div>
|
|
@ -1,34 +0,0 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item settings float-right" href="/profile"></a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank"></a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
|
||||
<div class="toolbar">
|
||||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="#">Dashboard</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a ng-href="/new" class="nav-item add float-right"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
|
||||
|
||||
<section>
|
||||
<a class="row build-row" ng-repeat="repo in repos | orderBy:'full_name'" ng-href="/{{ repo.full_name }}">
|
||||
<div>
|
||||
<div class="icon icon-repo"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ repo.owner }} / {{ repo.name }}</h3>
|
||||
<p>{{ repo.clone_url }}</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</section>
|
||||
</article>
|
|
@ -1,18 +1,3 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item settings float-right" href="/profile"></a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank"></a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
|
||||
<div class="toolbar">
|
||||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/" class="icon icon-home"></a>
|
||||
<a href="#">Add Repository</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<section style="background:transparent !important;">
|
||||
<p style="color:#9E9E9E;font-size:15px;line-height:22px;">Register your repository with Drone to enable automated testing. Note that Drone
|
|
@ -0,0 +1,6 @@
|
|||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/" class="icon icon-home">
|
||||
<i class="material-icons md-18">home</i>
|
||||
</a>
|
||||
<a href="#">Add Repository</a>
|
||||
</div>
|
17
cmd/drone-server/static/scripts/views/repos/del.html
Normal file
17
cmd/drone-server/static/scripts/views/repos/del.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<article>
|
||||
|
||||
|
||||
<section style="padding:30px; background-color:#EF5350;">
|
||||
<button ng-click="delete(repo.full_name)" style="color:rgba(255,255,255,0.9);
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
border: 1px solid rgba(255,255,255,0.9);
|
||||
padding: 10px;
|
||||
background:transparent;
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
margin-right: 10px;">Delete</button>
|
||||
<span style="color:rgba(255,255,255,0.9);font-size:16px;">Warning: this action cannot be undone.</span>
|
||||
</section>
|
||||
|
||||
</article>
|
75
cmd/drone-server/static/scripts/views/repos/edit.html
Normal file
75
cmd/drone-server/static/scripts/views/repos/edit.html
Normal file
|
@ -0,0 +1,75 @@
|
|||
<article>
|
||||
<section>
|
||||
<h2>Settings</h2>
|
||||
|
||||
<div class="row">
|
||||
<div>Post Commit Hooks</div>
|
||||
<div>
|
||||
<input id="post_commits" type="checkbox" hidden="hidden" ng-model="repo.hooks.push" ng-change="save(repo)"/>
|
||||
<label for="post_commits" class="switch"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>Pull Request Hooks</div>
|
||||
<div>
|
||||
<input id="pull_requests" type="checkbox" hidden="hidden" ng-model="repo.hooks.pull_request"
|
||||
ng-change="save(repo)"/>
|
||||
<label for="pull_requests" class="switch"></label>
|
||||
</div>
|
||||
</div>
|
||||
<a class="row" ng-href="{{ repo.full_name }}/edit/env">
|
||||
<div>Private Variables</div>
|
||||
<div>
|
||||
Inject private variables into your build environment
|
||||
</div>
|
||||
</a>
|
||||
<a class="row" ng-href="{{ repo.full_name }}/delete">
|
||||
<div>Delete</div>
|
||||
<div>Delete this repository and its build history</div>
|
||||
</a>
|
||||
</section>
|
||||
|
||||
<section ng-if="user.admin">
|
||||
<h2>Admin settings</h2>
|
||||
|
||||
<div class="row">
|
||||
<div>Trusted (Evelvate Privilege)</div>
|
||||
<div>
|
||||
<input id="trusted" type="checkbox" hidden="hidden" ng-model="repo.trusted" ng-change="save(repo)"/>
|
||||
<label for="trusted" class="switch"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>Timeout in minutes</div>
|
||||
<div>
|
||||
<input type="range" ng-model="repo.timeout" min="0" max="900" ng-blur="save(repo)"/>
|
||||
<span class="slider-label">{{ repo.timeout }} minutes</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Badges</h2>
|
||||
|
||||
<div class="row">
|
||||
<div>Markdown</div>
|
||||
<div>
|
||||
<pre class="snippet">[![Build Status]({{ window.location.origin }}/api/badges/{{ repo.full_name }}/status.svg)]({{ window.location.origin }}/{{ repo.full_name }})</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>CCMenu</div>
|
||||
<div>
|
||||
<pre class="snippet">{{ window.location.origin }}/api/badges/{{ repo.full_name }}/cc.xml</pre>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Public Key</h2>
|
||||
|
||||
<div>
|
||||
<pre class="snippet snippet-padding">{{ repo.keypair.public }}</pre>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
|
@ -1,25 +1,3 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item settings float-right" href="/profile"></a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank"></a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
|
||||
<div class="toolbar">
|
||||
|
||||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/{{ repo.full_name }}/edit" class="icon icon-home"></a>
|
||||
<a ng-href="/{{ repo.full_name }}">{{ repo.owner }} / {{ repo.name }}</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a ng-href="/{{ repo.full_name }}/edit" class="nav-item settings float-right"></a>
|
||||
<button ng-click="watch(repo)" ng-if="!repo.starred" class="nav-item star float-right"></button>
|
||||
<button ng-click="unwatch(repo)" ng-if="repo.starred" class="nav-item unstar float-right"></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<article>
|
||||
<section style="padding:30px;">
|
||||
<h2 style=" padding-left: 0px;
|
||||
|
@ -42,4 +20,4 @@ font-family: Roboto;
|
|||
text-transform: uppercase;">add</button>
|
||||
</form>
|
||||
</section>
|
||||
</article>
|
||||
</article>
|
|
@ -0,0 +1,14 @@
|
|||
<article>
|
||||
<section>
|
||||
<a class="row build-row" ng-repeat="repo in repos | orderBy:'full_name'" ng-href="/{{ repo.full_name }}">
|
||||
<div>
|
||||
<div class="icon icon-repo"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ repo.owner }} / {{ repo.name }}</h3>
|
||||
<p>{{ repo.clone_url }}</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</section>
|
||||
</article>
|
|
@ -0,0 +1,9 @@
|
|||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="#">Dashboard</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a ng-href="/new" class="nav-item add float-right">
|
||||
<i class="material-icons">add</i>
|
||||
</a>
|
||||
</div>
|
18
cmd/drone-server/static/scripts/views/repos/toolbar.html
Normal file
18
cmd/drone-server/static/scripts/views/repos/toolbar.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<div class="breadcrumb">
|
||||
<a href="/{{ repo.full_name }}/edit" class="icon icon-home">
|
||||
<i class="material-icons md-18">home</i>
|
||||
</a>
|
||||
<a ng-href="/{{ repo.full_name }}">{{ repo.owner }} / {{ repo.name }}</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a ng-href="/{{ repo.full_name }}/edit" class="nav-item settings float-right" ng-if="repo.permissions.pull">
|
||||
<i class="material-icons md-18">edit</i>
|
||||
</a>
|
||||
<button ng-click="watch(repo)" ng-if="!repo.starred && user" class="nav-item star float-right">
|
||||
<i class="material-icons md-18">star_border</i>
|
||||
</button>
|
||||
<button ng-click="unwatch(repo)" ng-if="repo.starred && user" class="nav-item unstar float-right">
|
||||
<i class="material-icons md-18">star</i>
|
||||
</button>
|
||||
</div>
|
|
@ -1,42 +0,0 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item settings float-right" href="/profile"></a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank"></a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
|
||||
<div class="toolbar">
|
||||
|
||||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/{{ repo.full_name }}/edit" class="icon icon-home"></a>
|
||||
<a ng-href="/{{ repo.full_name }}">{{ repo.owner }} / {{ repo.name }}</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a ng-href="/{{ repo.full_name }}/edit" class="nav-item settings float-right"></a>
|
||||
<button ng-click="watch(repo)" ng-if="!repo.starred" class="nav-item star float-right"></button>
|
||||
<button ng-click="unwatch(repo)" ng-if="repo.starred" class="nav-item unstar float-right"></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<article>
|
||||
|
||||
|
||||
<section style="padding:30px; background-color:#EF5350;">
|
||||
<button ng-click="delete(repo.full_name)" style="color:rgba(255,255,255,0.9);
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
border: 1px solid rgba(255,255,255,0.9);
|
||||
padding: 10px;
|
||||
background:transparent;
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
margin-right: 10px;">Delete</button>
|
||||
<span style="color:rgba(255,255,255,0.9);font-size:16px;">Warning: this action cannot be undone.</span>
|
||||
</section>
|
||||
|
||||
|
||||
</article>
|
|
@ -1,95 +0,0 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item settings float-right" href="/profile"></a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank"></a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
|
||||
<div class="toolbar">
|
||||
|
||||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/{{ repo.full_name }}" class="icon icon-home"></a>
|
||||
<a ng-href="/{{ repo.full_name }}">{{ repo.owner }} / {{ repo.name }}</a>
|
||||
</div>
|
||||
|
||||
<div class="menu">
|
||||
<a href="settings.html" class="icon icon-settings"></a>
|
||||
<a ng-href="/{{ repo.full_name }}/edit" class="nav-item settings float-right"></a>
|
||||
<button ng-click="watch(repo)" ng-if="!repo.starred" class="nav-item star float-right"></button>
|
||||
<button ng-click="unwatch(repo)" ng-if="repo.starred" class="nav-item unstar float-right"></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Settings</h2>
|
||||
<div class="row">
|
||||
<div>Post Commit Hooks</div>
|
||||
<div>
|
||||
<input id="post_commits" type="checkbox" hidden="hidden" ng-model="repo.hooks.push" ng-change="save(repo)" />
|
||||
<label for="post_commits" class="switch"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>Pull Request Hooks</div>
|
||||
<div>
|
||||
<input id="pull_requests" type="checkbox" hidden="hidden" ng-model="repo.hooks.pull_request" ng-change="save(repo)" />
|
||||
<label for="pull_requests" class="switch"></label>
|
||||
</div>
|
||||
</div>
|
||||
<a class="row" ng-href="{{ repo.full_name }}/edit/env">
|
||||
<div>Private Variables</div>
|
||||
<div>
|
||||
Inject private variables into your build environment
|
||||
</div>
|
||||
</a>
|
||||
<a class="row" ng-href="{{ repo.full_name }}/delete">
|
||||
<div>Delete</div>
|
||||
<div>Delete this repository and its build history</div>
|
||||
</a>
|
||||
</section>
|
||||
|
||||
<section ng-if="user.admin">
|
||||
<h2>Admin settings</h2>
|
||||
<div class="row">
|
||||
<div>Trusted (Evelvate Privilege)</div>
|
||||
<div>
|
||||
<input id="trusted" type="checkbox" hidden="hidden" ng-model="repo.trusted" ng-change="save(repo)" />
|
||||
<label for="trusted" class="switch"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>Timeout in minutes</div>
|
||||
<div>
|
||||
<input type="range" ng-model="repo.timeout" min="0" max="900" ng-blur="save(repo)" />
|
||||
<span class="slider-label">{{ repo.timeout }} minutes</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Badges</h2>
|
||||
<div class="row">
|
||||
<div>Markdown</div>
|
||||
<div>
|
||||
<pre class="snippet">[![Build Status]({{ window.location.origin }}/api/badges/{{ repo.full_name }}/status.svg)]({{ window.location.origin }}/{{ repo.full_name }})</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>CCMenu</div>
|
||||
<div>
|
||||
<pre class="snippet">{{ window.location.origin }}/api/badges/{{ repo.full_name }}/cc.xml</pre>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Public Key</h2>
|
||||
<div>
|
||||
<pre class="snippet snippet-padding">{{ repo.keypair.public }}</pre>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
|
@ -1,41 +0,0 @@
|
|||
<header>
|
||||
<a class="logo float-left" href="/"></a>
|
||||
<a class="menu-item settings float-right" href="/profile"></a>
|
||||
<a class="menu-item users float-right" href="/users" ng-if="user.admin"></a>
|
||||
<a class="menu-item help float-right" href="http://readme.drone.io" target="_blank"></a>
|
||||
<a class="menu-item user-name float-right" href="/profile">{{ "+"+user.login }}</a>
|
||||
</header>
|
||||
|
||||
<div class="toolbar">
|
||||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/" class="icon icon-home"></a>
|
||||
<a href="#">Users</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
|
||||
<section>
|
||||
<form style="padding:30px">
|
||||
<input type="text" ng-model="login" placeholder="i.e. octocat" style="font-size:14px;padding:10px 20px;width:400px;border: 1px solid #d9d9d9;outline:none;"/>
|
||||
<button ng-click="add(login)" style="display: inline-block;background:#EEE;font-size:14px; padding:0px 20px;text-transform:uppercase;cursor:pointer;color:#616161;height:39px;line-height:41px;margin-left:10px;">Add User</button>
|
||||
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="row row-user" ng-repeat="user in users">
|
||||
<div>
|
||||
<img ng-src="{{ user.gravatar_id | gravatar }}" />
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ user.login }} <small ng-if="user.admin">Admin</small></h3>
|
||||
<p>{{ user.email }}</p>
|
||||
<button ng-click="toggle(user)" ng-class="{'btn-admin':true, 'btn-checked': user.admin}"></button>
|
||||
<button ng-click="remove(user)" class="btn-remove"></button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
</article>
|
36
cmd/drone-server/static/scripts/views/users/content.html
Normal file
36
cmd/drone-server/static/scripts/views/users/content.html
Normal file
|
@ -0,0 +1,36 @@
|
|||
<article>
|
||||
|
||||
<section>
|
||||
<form style="padding:30px">
|
||||
<input type="text" ng-model="login" placeholder="i.e. octocat"
|
||||
style="font-size:14px;padding:10px 20px;width:400px;border: 1px solid #d9d9d9;outline:none;"/>
|
||||
<button ng-click="add(login)"
|
||||
style="display: inline-block;background:#EEE;font-size:14px; padding:0px 20px;text-transform:uppercase;cursor:pointer;color:#616161;height:39px;line-height:41px;margin-left:10px;">
|
||||
Add User
|
||||
</button>
|
||||
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="row row-user" ng-repeat="user in users">
|
||||
<div>
|
||||
<img ng-src="{{ user.gravatar_id | gravatar }}"/>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ user.login }}
|
||||
<small ng-if="user.admin">Admin</small>
|
||||
</h3>
|
||||
<p>{{ user.email }}</p>
|
||||
<button ng-click="toggle(user)" ng-class="{'btn-admin':true, 'btn-checked': user.admin}">
|
||||
<i class="material-icons md-18">account_circle</i>
|
||||
</button>
|
||||
<button ng-click="remove(user)" class="btn-remove">
|
||||
<i class="material-icons md-18">delete</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
</article>
|
6
cmd/drone-server/static/scripts/views/users/toolbar.html
Normal file
6
cmd/drone-server/static/scripts/views/users/toolbar.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<div class="breadcrumb" style="position:relative;top:0px;">
|
||||
<a href="/" class="icon icon-home">
|
||||
<i class="material-icons md-18">home</i>
|
||||
</a>
|
||||
<a href="#">Users</a>
|
||||
</div>
|
File diff suppressed because it is too large
Load diff
|
@ -8,6 +8,8 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
|
||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/samalba/dockerclient"
|
||||
"github.com/drone/drone/pkg/docker"
|
||||
|
@ -23,6 +25,11 @@ var (
|
|||
|
||||
// Docker host address from environment variable
|
||||
DockerHost = os.Getenv("DOCKER_HOST")
|
||||
|
||||
// Docker TLS variables
|
||||
DockerHostCa = os.Getenv("DOCKER_CA")
|
||||
DockerHostKey = os.Getenv("DOCKER_KEY")
|
||||
DockerHostCert = os.Getenv("DOCKER_CERT")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -40,6 +47,7 @@ type Runner struct {
|
|||
func (r *Runner) Run(w *queue.Work) error {
|
||||
var workers []*worker
|
||||
var client dockerclient.Client
|
||||
var tlc *tls.Config
|
||||
|
||||
defer func() {
|
||||
recover()
|
||||
|
@ -86,14 +94,34 @@ func (r *Runner) Run(w *queue.Work) error {
|
|||
w.Build.Status = types.StateRunning
|
||||
err := r.SetBuild(w.User, w.Repo, w.Build)
|
||||
if err != nil {
|
||||
log.Errorf("failure to set build. %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// create the Docket client TLS config
|
||||
if len(DockerHostCert) > 0 && len(DockerHostKey) > 0 && len(DockerHostCa) > 0 {
|
||||
cert, err := tls.LoadX509KeyPair(DockerHostCert, DockerHostKey)
|
||||
if err != nil {
|
||||
log.Errorf("failure to load SSL cert and key. %s", err)
|
||||
}
|
||||
caCert, err := ioutil.ReadFile(DockerHostCa)
|
||||
if err != nil {
|
||||
log.Errorf("failure to load SSL CA cert. %s", err)
|
||||
}
|
||||
caCertPool := x509.NewCertPool()
|
||||
caCertPool.AppendCertsFromPEM(caCert)
|
||||
tlc = &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
RootCAs: caCertPool,
|
||||
}
|
||||
}
|
||||
|
||||
// create the Docker client. In this version of Drone (alpha)
|
||||
// we do not spread builds across clients, but this can and
|
||||
// (probably) will change in the future.
|
||||
client, err = dockerclient.NewDockerClient(DockerHost, nil)
|
||||
client, err = dockerclient.NewDockerClient(DockerHost, tlc)
|
||||
if err != nil {
|
||||
log.Errorf("failure to connect to docker. %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -106,6 +134,7 @@ func (r *Runner) Run(w *queue.Work) error {
|
|||
job.Started = time.Now().UTC().Unix()
|
||||
err = r.SetJob(w.Repo, w.Build, job)
|
||||
if err != nil {
|
||||
log.Errorf("failure to set job. %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -121,6 +150,7 @@ func (r *Runner) Run(w *queue.Work) error {
|
|||
}
|
||||
in, err := json.Marshal(work)
|
||||
if err != nil {
|
||||
log.Errorf("failure to marshalise work. %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ func PostHook(c *gin.Context) {
|
|||
build.Status = common.StatePending
|
||||
build.RepoID = repo.ID
|
||||
|
||||
// featch the .drone.yml file from the database
|
||||
// fetch the .drone.yml file from the database
|
||||
raw, err := remote.Script(user, repo, build)
|
||||
if err != nil {
|
||||
log.Errorf("failure to get .drone.yml for %s. %s", repo.FullName, err)
|
||||
|
|
Loading…
Reference in a new issue