...
|
...
|
@@ -19,8 +19,10 @@ |
|
|
<div class="panel panel-default" data-env='{{deploy.env}}'>
|
|
|
<div class="panel-heading">
|
|
|
<div class="pull-right">
|
|
|
<a class="btn btn-info btn-rounded mr5 log-btn"><i class="fa fa-eye"></i> 查看构建日志</a>
|
|
|
<a class="btn btn-success btn-rounded mr20 build-btn"><i class="glyphicon glyphicon-plus"></i> 新增构建</a>
|
|
|
{{#if is_master}}
|
|
|
<a class="btn btn-info btn-rounded mr5 log-btn"><i class="fa fa-eye"></i> 查看构建日志</a>
|
|
|
<a class="btn btn-success btn-rounded mr20 build-btn"><i class="glyphicon glyphicon-plus"></i> 新增构建</a>
|
|
|
{{/if}}
|
|
|
<a href="" class="tooltips panel-minimize"><i class="fa fa-minus"></i></a>
|
|
|
</div>
|
|
|
<h4 class="panel-title">{{deploy.name}}</h4>
|
...
|
...
|
@@ -29,18 +31,18 @@ |
|
|
<div class="panel-body">
|
|
|
<table id="table-{{deploy.env}}" class="table table-striped table-bordered building-table">
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th>构建版本</th>
|
|
|
<th>分支名称</th>
|
|
|
<th>状态</th>
|
|
|
<th>构建时间</th>
|
|
|
<th>操作</th>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<th>构建版本</th>
|
|
|
<th>分支名称</th>
|
|
|
<th>状态</th>
|
|
|
<th>构建时间</th>
|
|
|
<th>操作</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
</table>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="panel panel-default">
|
|
|
<div class="panel-heading">
|
|
|
<h4>服务器信息</h4>
|
...
|
...
|
@@ -49,29 +51,32 @@ |
|
|
<div class="panel-body">
|
|
|
<div class="row">
|
|
|
{{#each targets}}
|
|
|
<div class="col-md-4" id="d-{{hostFm}}">
|
|
|
<div class="panel panel-info noborder">
|
|
|
<div class="panel-heading noborder">
|
|
|
<div class="panel-btns">
|
|
|
</div><!-- panel-btns -->
|
|
|
<div class="panel-icon"><i class="fa fa-cloud" style="padding-left:12px;"></i></div>
|
|
|
<div class="media-body">
|
|
|
<h2 class="nomargin">{{host}}</h2>
|
|
|
<h5 class="md-title mt5">当前运行版本: <code>{{#if info}}{{info.building}}{{^}}未知部署{{/if}}</code></h5>
|
|
|
</div><!-- media-body -->
|
|
|
<hr class="mt10 mb10">
|
|
|
<div class="clearfix mt5">
|
|
|
<div class="col-xs-6 project-env" data-env="test">
|
|
|
<h5 class="md-title mt10">当前状态</h5>
|
|
|
<span class="label label-success deploy-log-btn" data-host="{{host}}"><i class="fa fa-spinner fa-spin fa-fw margin-bottom"></i> <b>{{#if info}}{{info.state}}{{^}}未知部署{{/if}}</b></span>
|
|
|
</div>
|
|
|
<div class="col-xs-6">
|
|
|
|
|
|
<div class="col-md-4" id="d-{{hostFm}}">
|
|
|
<div class="panel panel-info noborder">
|
|
|
<div class="panel-heading noborder">
|
|
|
<div class="panel-btns">
|
|
|
</div><!-- panel-btns -->
|
|
|
<div class="panel-icon"><i class="fa fa-cloud" style="padding-left:12px;"></i></div>
|
|
|
<div class="media-body">
|
|
|
<h2 class="nomargin">{{host}}</h2>
|
|
|
<h5 class="md-title mt5">当前运行版本: <code>{{#if info}}{{info.building}}{{^}}
|
|
|
未知部署{{/if}}</code></h5>
|
|
|
</div><!-- media-body -->
|
|
|
<hr class="mt10 mb10">
|
|
|
<div class="clearfix mt5">
|
|
|
<div class="col-xs-6 project-env" data-env="test">
|
|
|
<h5 class="md-title mt10">当前状态</h5>
|
|
|
<span class="label label-success deploy-log-btn" data-host="{{host}}"><i
|
|
|
class="fa fa-spinner fa-spin fa-fw margin-bottom"></i> <b>{{#if info}}{{info.state}}{{^}}
|
|
|
未知部署{{/if}}</b></span>
|
|
|
</div>
|
|
|
<div class="col-xs-6">
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div><!-- panel-body -->
|
|
|
</div><!-- panel -->
|
|
|
</div>
|
|
|
</div><!-- panel-body -->
|
|
|
</div><!-- panel -->
|
|
|
</div>
|
|
|
{{/each}}
|
|
|
</div>
|
|
|
</div>
|
...
|
...
|
@@ -79,99 +84,103 @@ |
|
|
</div>
|
|
|
|
|
|
<div id="log-area" class="panel panel-default panel-alt" style="display:none;height: 100%;">
|
|
|
<div class="panel-body nopadding" style="height: 100%;">
|
|
|
<div class="panel-body nopadding" style="height: 100%;">
|
|
|
<textarea name="code" id="code" style="height: 100%;"></textarea>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<script>
|
|
|
|
|
|
$(function(){
|
|
|
|
|
|
|
|
|
$(function() {
|
|
|
|
|
|
var tables = {};
|
|
|
$('.building-table').each(function(){
|
|
|
$('.building-table').each(function() {
|
|
|
var env = $(this).parents('.panel').data('env');
|
|
|
tables[env] = $(this).DataTable({
|
|
|
responsive: true,
|
|
|
ajax: '/projects/{{project._id}}/buildings?env=' + env,
|
|
|
columns: [
|
|
|
{ data: "buildTime"},
|
|
|
{ data: "branch"},
|
|
|
{ data: "state"},
|
|
|
{ data: "updatedAt"},
|
|
|
{ data: "_id" }
|
|
|
{data: "buildTime"},
|
|
|
{data: "branch"},
|
|
|
{data: "state"},
|
|
|
{data: "updatedAt"},
|
|
|
{data: "_id"}
|
|
|
],
|
|
|
order: [[0, 'desc']],
|
|
|
columnDefs: [{
|
|
|
render: function(data, type, row){
|
|
|
render: function(data, type, row) {
|
|
|
var color = 'warning';
|
|
|
if(data == 'success'){
|
|
|
if (data == 'success') {
|
|
|
color = 'success';
|
|
|
}else if(data == 'fail'){
|
|
|
} else if (data == 'fail') {
|
|
|
color = 'danger';
|
|
|
}
|
|
|
var html = '<span id="b-'+row._id+'" class="label label-' + color + '">';
|
|
|
if(data != 'success' && data != 'fail'){
|
|
|
var html = '<span id="b-' + row._id + '" class="label label-' + color + '">';
|
|
|
if (data != 'success' && data != 'fail') {
|
|
|
html += '<i class="fa fa-spinner fa-spin fa-fw margin-bottom"></i>';
|
|
|
}
|
|
|
}
|
|
|
html += data + '</span>';
|
|
|
return html;
|
|
|
},
|
|
|
targets: 2
|
|
|
}, {
|
|
|
render: function(data, type, row){
|
|
|
render: function(data, type, row) {
|
|
|
var disabled = row.state !== 'success';
|
|
|
return '<button '+(disabled? 'disabled' : '')+' class="btn btn-success btn-xs deploy-btn" data-id="'+data+'" data-build='+row.buildTime+'>分发</button>';
|
|
|
{{#if is_master}}
|
|
|
return '<button ' + (disabled ? 'disabled' : '') + ' class="btn btn-success btn-xs deploy-btn" data-id="' + data + '" data-build=' + row.buildTime + '>分发</button>';
|
|
|
{{^}}
|
|
|
return '';
|
|
|
{{/if}}
|
|
|
},
|
|
|
targets: 4
|
|
|
}]
|
|
|
});
|
|
|
|
|
|
$(this).on( 'draw.dt', function () {
|
|
|
$('.deploy-btn').click(function(){
|
|
|
var id = $(this).data('id');
|
|
|
var build = $(this).data('build');
|
|
|
layer.confirm('确定发布版本<code>' + build + '</code>吗?', {
|
|
|
btn: ['确定', '取消']
|
|
|
}, function(){
|
|
|
doDeploy(id);
|
|
|
});
|
|
|
|
|
|
$(this).on('draw.dt', function() {
|
|
|
$('.deploy-btn').click(function() {
|
|
|
var id = $(this).data('id');
|
|
|
var build = $(this).data('build');
|
|
|
layer.confirm('确定发布版本<code>' + build + '</code>吗?', {
|
|
|
btn: ['确定', '取消']
|
|
|
}, function() {
|
|
|
doDeploy(id);
|
|
|
});
|
|
|
} );
|
|
|
});
|
|
|
});
|
|
|
});
|
|
|
|
|
|
function doDeploy(build){
|
|
|
|
|
|
function doDeploy(build) {
|
|
|
$.post('/projects/deploy/' + build, function(ret) {
|
|
|
if(ret.code == 200){
|
|
|
if (ret.code == 200) {
|
|
|
layer.msg('正在分发中');
|
|
|
}else{
|
|
|
} else {
|
|
|
layer.msg(ret.msg, {icon: 5});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
$('.build-btn').click(function(){
|
|
|
|
|
|
$('.build-btn').click(function() {
|
|
|
var env = $(this).parents('.panel').data('env');
|
|
|
var i = layer.prompt({
|
|
|
var i = layer.prompt({
|
|
|
title: '请输入需要构建的分支,默认为 {{deploy.branchName}}'
|
|
|
}, function(branch){
|
|
|
}, function(branch) {
|
|
|
branch = branch || '{{deploy.branchName}}';
|
|
|
$.post('/projects/build/{{project._id}}', {env: env, branch: branch}, function(ret){
|
|
|
if(ret.code == 200) {
|
|
|
$.post('/projects/build/{{project._id}}', {env: env, branch: branch}, function(ret) {
|
|
|
if (ret.code == 200) {
|
|
|
tables[env].ajax.reload();
|
|
|
layer.close(i);
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
$('.rollback-btn').click(function(){
|
|
|
|
|
|
|
|
|
$('.rollback-btn').click(function() {
|
|
|
layer.prompt({
|
|
|
title: '请输入回滚到哪个版本'
|
|
|
}, function(build){
|
|
|
doDeploy(build);
|
|
|
}, function(build) {
|
|
|
doDeploy(build);
|
|
|
});
|
|
|
});
|
|
|
|
...
|
...
|
@@ -181,17 +190,17 @@ |
|
|
});
|
|
|
|
|
|
var tag;
|
|
|
|
|
|
$('.log-btn').click(function(){
|
|
|
|
|
|
$('.log-btn').click(function() {
|
|
|
viewLog('');
|
|
|
});
|
|
|
|
|
|
$('.deploy-log-btn').click(function(){
|
|
|
$('.deploy-log-btn').click(function() {
|
|
|
var host = $(this).data('host');
|
|
|
viewLog(host);
|
|
|
});
|
|
|
|
|
|
function viewLog(tag){
|
|
|
function viewLog(tag) {
|
|
|
tag = tag;
|
|
|
$('#log-area').show();
|
|
|
cm.setValue("");
|
...
|
...
|
@@ -201,46 +210,46 @@ |
|
|
title: '实时日志',
|
|
|
content: $('#log-area'),
|
|
|
area: ['1000px', '600px'],
|
|
|
maxmin:true,
|
|
|
cancel: function(){
|
|
|
maxmin: true,
|
|
|
cancel: function() {
|
|
|
$('#log-area').hide();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
var ws = io();
|
|
|
ws.on('connect', function(){
|
|
|
ws.on('/building/{{project._id}}', function(data){
|
|
|
ws.on('connect', function() {
|
|
|
ws.on('/building/{{project._id}}', function(data) {
|
|
|
console.log(data);
|
|
|
$('#b-' + data.bid).text(data.state);
|
|
|
if(data.state == 'success'){
|
|
|
if (data.state == 'success') {
|
|
|
$('#b-' + data.bid).removeClass('label-warning').addClass('label-success')
|
|
|
$('#b-' + data.bid).parent().parent().find('.deploy-btn').removeAttr('disabled');
|
|
|
$('#b-' + data.bid).find('i').remove();
|
|
|
}else if(data.state == 'fail'){
|
|
|
} else if (data.state == 'fail') {
|
|
|
$('#b-' + data.bid).removeClass('label-warning').addClass('label-danger');
|
|
|
$('#b-' + data.bid).find('i').remove();
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// ws.on('/building/{{project._id}}/log', function(data){
|
|
|
// if(tag == '') {
|
|
|
// cm.replaceRange("> " + data + "\n", {line: Infinity});
|
|
|
// }
|
|
|
// });
|
|
|
|
|
|
ws.on('/deploy/{{project._id}}', function(data){
|
|
|
|
|
|
// ws.on('/building/{{project._id}}/log', function(data){
|
|
|
// if(tag == '') {
|
|
|
// cm.replaceRange("> " + data + "\n", {line: Infinity});
|
|
|
// }
|
|
|
// });
|
|
|
|
|
|
ws.on('/deploy/{{project._id}}', function(data) {
|
|
|
console.log(data);
|
|
|
$('#d-' + data.host.replace(/\./g, '-')).find('b').text(data.state);
|
|
|
});
|
|
|
|
|
|
// ws.on('/deploy/{{project._id}}/log', function(data){
|
|
|
// if(tag == data.host){
|
|
|
// cm.replaceRange("> " +data.msg+ "\n", {line: Infinity});
|
|
|
// }
|
|
|
// });
|
|
|
// ws.on('/deploy/{{project._id}}/log', function(data){
|
|
|
// if(tag == data.host){
|
|
|
// cm.replaceRange("> " +data.msg+ "\n", {line: Infinity});
|
|
|
// }
|
|
|
// });
|
|
|
});
|
|
|
ws.on('error', function(){
|
|
|
ws.on('error', function() {
|
|
|
console.log('connect fail');
|
|
|
});
|
|
|
});
|
...
|
...
|
|