Merge branch 'devops19_caoyanyi_47221' into devops19
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `zt_job` ADD `sonarqubeServer` mediumint(8) unsigned NOT NULL AFTER `triggerType`;
|
||||
ALTER TABLE `zt_job` ADD `projectKey` varchar(255) NOT NULL AFTER `sonarqubeServer`;
|
||||
@@ -329,6 +329,7 @@ $lang->action->label->finishedbychild = 'finished';
|
||||
$lang->action->label->closedbychild = 'closed';
|
||||
$lang->action->label->activatedbychild = 'activated';
|
||||
$lang->action->label->createchild = 'activated';
|
||||
$lang->action->label->executed = 'executed';
|
||||
|
||||
/* Dynamic information is grouped by object. */
|
||||
$lang->action->dynamicAction = new stdclass;
|
||||
|
||||
@@ -329,6 +329,7 @@ $lang->action->label->finishedbychild = '完成了';
|
||||
$lang->action->label->closedbychild = '关闭了';
|
||||
$lang->action->label->activatedbychild = '激活了';
|
||||
$lang->action->label->createchild = '激活了';
|
||||
$lang->action->label->executed = '执行了';
|
||||
|
||||
/* 动态信息按照对象分组 */
|
||||
$lang->action->dynamicAction = new stdclass();
|
||||
|
||||
@@ -1389,12 +1389,14 @@ $lang->resource->sonarqube->create = 'create';
|
||||
$lang->resource->sonarqube->edit = 'edit';
|
||||
$lang->resource->sonarqube->delete = 'delete';
|
||||
$lang->resource->sonarqube->browseProject = 'browseProject';
|
||||
$lang->resource->sonarqube->execJob = 'execJob';
|
||||
|
||||
$lang->sonarqube->methodOrder[5] = 'browse';
|
||||
$lang->sonarqube->methodOrder[10] = 'create';
|
||||
$lang->sonarqube->methodOrder[15] = 'edit';
|
||||
$lang->sonarqube->methodOrder[20] = 'delete';
|
||||
$lang->sonarqube->methodOrder[25] = 'browseProject';
|
||||
$lang->sonarqube->methodOrder[5] = 'browse';
|
||||
$lang->sonarqube->methodOrder[10] = 'create';
|
||||
$lang->sonarqube->methodOrder[15] = 'edit';
|
||||
$lang->sonarqube->methodOrder[20] = 'delete';
|
||||
$lang->sonarqube->methodOrder[25] = 'browseProject';
|
||||
$lang->sonarqube->methodOrder[30] = 'execJob';
|
||||
|
||||
/* merge request. */
|
||||
$lang->resource->mr = new stdclass();
|
||||
@@ -1740,12 +1742,12 @@ $lang->backup->methodOrder[25] = 'setting';
|
||||
$lang->backup->methodOrder[30] = 'rmPHPHeader';
|
||||
|
||||
$lang->resource->cron = new stdclass();
|
||||
$lang->resource->cron->index = 'index';
|
||||
$lang->resource->cron->turnon = 'turnon';
|
||||
$lang->resource->cron->create = 'createAction';
|
||||
$lang->resource->cron->edit = 'edit';
|
||||
$lang->resource->cron->toggle = 'toggle';
|
||||
$lang->resource->cron->delete = 'delete';
|
||||
$lang->resource->cron->index = 'index';
|
||||
$lang->resource->cron->turnon = 'turnon';
|
||||
$lang->resource->cron->create = 'createAction';
|
||||
$lang->resource->cron->edit = 'edit';
|
||||
$lang->resource->cron->toggle = 'toggle';
|
||||
$lang->resource->cron->delete = 'delete';
|
||||
$lang->resource->cron->openProcess = 'restart';
|
||||
|
||||
$lang->cron->methodOrder[5] = 'index';
|
||||
|
||||
+32
-12
@@ -120,7 +120,8 @@ class job extends control
|
||||
$this->view->repoTypes = $repoTypes;
|
||||
$this->view->products = array(0 => '') + $this->loadModel('product')->getProductPairsByProject($this->projectID);
|
||||
|
||||
$this->view->jenkinsServerList = array('' => '') + $this->loadModel('jenkins')->getPairs();
|
||||
$this->view->jenkinsServerList = array('' => '') + $this->loadModel('jenkins')->getPairs();
|
||||
$this->view->sonarqubeServerList = array('' => '') + $this->loadModel('sonarqube')->getPairs();
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -189,17 +190,18 @@ class job extends control
|
||||
if($jobProduct and $jobProduct->deleted == 0) $products += array($job->product => $jobProduct->name);
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->job->edit;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->job);
|
||||
$this->view->position[] = $this->lang->job->edit;
|
||||
$this->view->repoPairs = $repoPairs;
|
||||
$this->view->gitlabRepos = $gitlabRepos;
|
||||
$this->view->repoTypes = $repoTypes;
|
||||
$this->view->repoType = zget($repoTypes, $job->repo, 'Git');
|
||||
$this->view->job = $job;
|
||||
$this->view->products = array(0 => '') + $products;
|
||||
$this->view->jenkinsServerList = $this->loadModel('jenkins')->getPairs();
|
||||
$this->view->pipelines = $this->jenkins->getTasks($job->server);
|
||||
$this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->job->edit;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->job);
|
||||
$this->view->position[] = $this->lang->job->edit;
|
||||
$this->view->repoPairs = $repoPairs;
|
||||
$this->view->gitlabRepos = $gitlabRepos;
|
||||
$this->view->repoTypes = $repoTypes;
|
||||
$this->view->repoType = zget($repoTypes, $job->repo, 'Git');
|
||||
$this->view->job = $job;
|
||||
$this->view->products = array(0 => '') + $products;
|
||||
$this->view->jenkinsServerList = $this->loadModel('jenkins')->getPairs();
|
||||
$this->view->sonarqubeServerList = array('' => '') + $this->loadModel('sonarqube')->getPairs();
|
||||
$this->view->pipelines = $this->jenkins->getTasks($job->server);
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -323,6 +325,7 @@ class job extends control
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->app->loadLang('compile');
|
||||
$this->loadModel('action')->create('job', $id, 'executed');
|
||||
return $this->send(array('result' => 'success', 'message' => sprintf($this->lang->job->sendExec, zget($this->lang->compile->statusList, $compile->status))));
|
||||
}
|
||||
|
||||
@@ -414,4 +417,21 @@ class job extends control
|
||||
$this->send(array('result' => 'success', 'type' => strtolower($repo->SCM)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax check SonarQube linked by repoID.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxCheckSonarqubeLink($repoID, $jobID = 0)
|
||||
{
|
||||
$repo = $this->loadModel('job')->getSonarqubeByRepo(array($repoID), $jobID);
|
||||
if(!empty($repo))
|
||||
{
|
||||
$message = sprintf($this->lang->job->repoExists, $repo[$repoID]->id . '-' . $repo[$repoID]->name);
|
||||
$this->send(array('result' => 'fail', 'message' => $message));
|
||||
}
|
||||
$this->send(array('result' => 'success', 'message' => ''));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,49 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
/*
|
||||
* Get frame select.
|
||||
* param string engine eg. jenkins|gitlab
|
||||
*/
|
||||
function getFrameSelect(engine)
|
||||
{
|
||||
$('#frameBox .input-group').empty();
|
||||
$('#frameBox .input-group').append("<div class='load-indicator loading'></div>");
|
||||
var html = "<select id='frame' name='frame' class='form-control chosen'>";
|
||||
for(frame in frameList)
|
||||
{
|
||||
if(engine == 'jenkins' || frame != 'sonarqube') html += "<option value='" + frame + "'>" + frameList[frame] + "</option>";
|
||||
}
|
||||
html += '</select>';
|
||||
|
||||
$('#frameBox .loading').remove();
|
||||
$('#frameBox .input-group').append(html);
|
||||
$('#frameBox #frame').chosen();
|
||||
}
|
||||
getFrameSelect('');
|
||||
|
||||
/*
|
||||
* Check sonarqube linked.
|
||||
*/
|
||||
function checkSonarquebLink()
|
||||
{
|
||||
var repoID = $('#repo').val();
|
||||
var frame = $('#frame').val();
|
||||
|
||||
if(frame != 'sonarqube' || repoID == 0) return false;
|
||||
|
||||
$.getJSON(createLink('job', 'ajaxCheckSonarqubeLink', 'repoID=' + repoID), function(result)
|
||||
{
|
||||
if(result.result != 'success')
|
||||
{
|
||||
alert(result.message);
|
||||
$('#repo').val(0).trigger('chosen:updated');
|
||||
$('#reference').val('').trigger('chosen:updated');
|
||||
$('.reference').hide();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
$(document).on('change', '#repo', function()
|
||||
{
|
||||
var repoID = $(this).val();
|
||||
@@ -63,6 +107,9 @@ $(document).ready(function()
|
||||
$('#triggerggerType option[value=tag]').html(data.type == 'gitlab' ? buildTag : dirChange).trigger('chosen:updated');
|
||||
}
|
||||
});
|
||||
|
||||
/* Check exists sonarqube data. */
|
||||
checkSonarquebLink();
|
||||
});
|
||||
|
||||
$(document).on('change', '[name^=svnDir]', function()
|
||||
@@ -139,6 +186,39 @@ $(document).ready(function()
|
||||
|
||||
$('#jenkinsServerTR #jkTask').chosen({drop_direction: 'auto'});
|
||||
})
|
||||
|
||||
/* There has been a problem with handling the prompt label. */
|
||||
$('#jkTaskLabel').remove();
|
||||
})
|
||||
|
||||
$(document).on('change', '#frame', function()
|
||||
{
|
||||
var frame = $(this).val();
|
||||
if(frame == 'sonarqube')
|
||||
{
|
||||
$('tr.sonarqube').removeClass('hide');
|
||||
|
||||
/* Check exists sonarqube data. */
|
||||
checkSonarquebLink();
|
||||
}
|
||||
else
|
||||
{
|
||||
$('tr.sonarqube').addClass('hide');
|
||||
}
|
||||
})
|
||||
|
||||
$(document).on('change', '#sonarqubeServer', function()
|
||||
{
|
||||
var sonarqubeID = $(this).val();
|
||||
$('#sonarProject #projectKey').remove();
|
||||
$('#sonarProject #projectKey_chosen').remove();
|
||||
$('#sonarProject .input-group').append("<div class='load-indicator loading'></div>");
|
||||
$.getJSON(createLink('sonarqube', 'ajaxGetProjectList', 'sonarqubeID=' + sonarqubeID), function(html)
|
||||
{
|
||||
$('#sonarProject .loading').remove();
|
||||
$('#sonarProject .input-group').append(html);
|
||||
$('#sonarProject #projectKey').chosen({drop_direction: 'auto'});
|
||||
})
|
||||
})
|
||||
|
||||
var scheduleOption = "<option value='schedule'>" + $('#triggerType').find('[value=schedule]').text() + "</option>";
|
||||
@@ -161,6 +241,7 @@ $(document).ready(function()
|
||||
$('tr.gitlabRepo').hide();
|
||||
$('tr.commonRepo').show();
|
||||
}
|
||||
getFrameSelect(engine);
|
||||
});
|
||||
|
||||
$('#engine').change();
|
||||
|
||||
@@ -1,5 +1,52 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
/*
|
||||
* Get frame select.
|
||||
* param string engine eg. jenkins|gitlab
|
||||
*/
|
||||
function getFrameSelect()
|
||||
{
|
||||
$('#frameBox .input-group').empty();
|
||||
$('#frameBox .input-group').append("<div class='load-indicator loading'></div>");
|
||||
var html = "<select id='frame' name='frame' class='form-control chosen'>";
|
||||
for(frame in frameList)
|
||||
{
|
||||
if(job.engine == 'jenkins' || frame != 'sonarqube')
|
||||
{
|
||||
html += "<option value='" + frame + "'";
|
||||
if(frame == job.frame) html += " selected";
|
||||
html += ">" + frameList[frame] + "</option>";
|
||||
}
|
||||
}
|
||||
html += '</select>';
|
||||
|
||||
$('#frameBox .loading').remove();
|
||||
$('#frameBox .input-group').append(html);
|
||||
$('#frameBox #frame').chosen();
|
||||
}
|
||||
getFrameSelect();
|
||||
|
||||
/* Check sonarqube linked. */
|
||||
function checkSonarquebLink()
|
||||
{
|
||||
var repoID = $('#repo').val();
|
||||
var frame = $('#frame').val();
|
||||
|
||||
if(frame != 'sonarqube' || repoID == 0) return false;
|
||||
|
||||
$.getJSON(createLink('job', 'ajaxCheckSonarqubeLink', 'repoID=' + repoID + '&jobID=' + job.id), function(result)
|
||||
{
|
||||
if(result.result != 'success')
|
||||
{
|
||||
alert(result.message);
|
||||
$('#repo').val(0).trigger('chosen:updated');
|
||||
$('#reference').val('').trigger('chosen:updated');
|
||||
$('.reference').hide();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
$('#gitlabRepo').change(function()
|
||||
{
|
||||
$('#repo').val($(this).val()).change();
|
||||
@@ -45,6 +92,9 @@ $(document).ready(function()
|
||||
$('#svnDirBox #svnDir').chosen();
|
||||
})
|
||||
}
|
||||
|
||||
/* Check exists sonarqube data. */
|
||||
checkSonarquebLink();
|
||||
})
|
||||
|
||||
$(document).on('change', '[name^=svnDir]', function()
|
||||
@@ -124,6 +174,39 @@ $(document).ready(function()
|
||||
|
||||
$('#jenkinsServerTR #jkTask').val(jkTask).chosen();
|
||||
})
|
||||
|
||||
/* There has been a problem with handling the prompt label. */
|
||||
$('#jkTaskLabel').remove();
|
||||
})
|
||||
|
||||
$(document).on('change', '#frame', function()
|
||||
{
|
||||
var frame = $(this).val();
|
||||
if(frame == 'sonarqube')
|
||||
{
|
||||
$('tr.sonarqube').removeClass('hide');
|
||||
|
||||
/* Check exists sonarqube data. */
|
||||
checkSonarquebLink();
|
||||
}
|
||||
else
|
||||
{
|
||||
$('tr.sonarqube').addClass('hide');
|
||||
}
|
||||
})
|
||||
|
||||
$(document).on('change', '#sonarqubeServer', function()
|
||||
{
|
||||
var sonarqubeID = $(this).val();
|
||||
$('#sonarProject #projectKey').remove();
|
||||
$('#sonarProject #projectKey_chosen').remove();
|
||||
$('#sonarProject .input-group').append("<div class='load-indicator loading'></div>");
|
||||
$.getJSON(createLink('sonarqube', 'ajaxGetProjectList', 'sonarqubeID=' + sonarqubeID), function(html)
|
||||
{
|
||||
$('#sonarProject .loading').remove();
|
||||
$('#sonarProject .input-group').append(html);
|
||||
$('#sonarProject #projectKey').chosen({drop_direction: 'auto'});
|
||||
})
|
||||
})
|
||||
|
||||
var scheduleOption = "<option value='schedule'>" + $('#triggerType').find('[value=schedule]').text() + "</option>";
|
||||
@@ -169,6 +252,7 @@ $(document).ready(function()
|
||||
|
||||
$('#engine').change();
|
||||
$('#jkServer').change();
|
||||
$('#frame').change();
|
||||
|
||||
$('#triggerType').change();
|
||||
});
|
||||
|
||||
+51
-46
@@ -14,46 +14,50 @@ $lang->job->execSuccess = 'Build success';
|
||||
|
||||
$lang->job->browseAction = 'Job List';
|
||||
|
||||
$lang->job->id = 'ID';
|
||||
$lang->job->name = 'Name';
|
||||
$lang->job->repo = 'Repo';
|
||||
$lang->job->product = $lang->productCommon;
|
||||
$lang->job->svnDir = 'SVN Tag Watch Path';
|
||||
$lang->job->jenkins = 'Jenkins';
|
||||
$lang->job->jkHost = 'Jenkins Server';
|
||||
$lang->job->jkJob = 'Jenkins Task';
|
||||
$lang->job->buildSpec = 'Build Target'; // 'pipeline@server'
|
||||
$lang->job->engine = 'Engine';
|
||||
$lang->job->server = 'Server';
|
||||
$lang->job->pipeline = 'Pipeline';
|
||||
$lang->job->buildType = 'Build Type';
|
||||
$lang->job->frame = 'Frame';
|
||||
$lang->job->triggerType = 'Trigger';
|
||||
$lang->job->atDay = 'Custom Days';
|
||||
$lang->job->atTime = 'At Time';
|
||||
$lang->job->lastStatus = 'Last Status';
|
||||
$lang->job->lastExec = 'Last Executed';
|
||||
$lang->job->comment = 'Match Keywords';
|
||||
$lang->job->customParam = 'Custom build parameters';
|
||||
$lang->job->paramName = 'Name';
|
||||
$lang->job->paramValue = 'Value';
|
||||
$lang->job->custom = 'Custom';
|
||||
$lang->job->createdBy = 'Created By';
|
||||
$lang->job->createdDate = 'Created Date';
|
||||
$lang->job->editedBy = 'Edited By';
|
||||
$lang->job->editedDate = 'Edited Date';
|
||||
$lang->job->lastTag = 'Last Tag';
|
||||
$lang->job->deleted = 'Deleted';
|
||||
$lang->job->repoServer = 'Repo Server';
|
||||
$lang->job->id = 'ID';
|
||||
$lang->job->name = 'Name';
|
||||
$lang->job->repo = 'Repo';
|
||||
$lang->job->product = $lang->productCommon;
|
||||
$lang->job->svnDir = 'SVN Tag Watch Path';
|
||||
$lang->job->jenkins = 'Jenkins';
|
||||
$lang->job->jkHost = 'Jenkins Server';
|
||||
$lang->job->jkJob = 'Jenkins Task';
|
||||
$lang->job->buildSpec = 'Build Target'; // 'pipeline@server'
|
||||
$lang->job->engine = 'Engine';
|
||||
$lang->job->server = 'Server';
|
||||
$lang->job->pipeline = 'Pipeline';
|
||||
$lang->job->buildType = 'Build Type';
|
||||
$lang->job->frame = 'Frame';
|
||||
$lang->job->triggerType = 'Trigger';
|
||||
$lang->job->atDay = 'Custom Days';
|
||||
$lang->job->atTime = 'At Time';
|
||||
$lang->job->lastStatus = 'Last Status';
|
||||
$lang->job->lastExec = 'Last Executed';
|
||||
$lang->job->comment = 'Match Keywords';
|
||||
$lang->job->customParam = 'Custom build parameters';
|
||||
$lang->job->paramName = 'Name';
|
||||
$lang->job->paramValue = 'Value';
|
||||
$lang->job->custom = 'Custom';
|
||||
$lang->job->createdBy = 'Created By';
|
||||
$lang->job->createdDate = 'Created Date';
|
||||
$lang->job->editedBy = 'Edited By';
|
||||
$lang->job->editedDate = 'Edited Date';
|
||||
$lang->job->lastTag = 'Last Tag';
|
||||
$lang->job->deleted = 'Deleted';
|
||||
$lang->job->repoServer = 'Repo Server';
|
||||
$lang->job->sonarqubeServer = 'SonarQube Server';
|
||||
$lang->job->projectKey = 'SonarQube Project';
|
||||
|
||||
$lang->job->lblBasic = 'Basic Info';
|
||||
|
||||
$lang->job->example = 'e.g.';
|
||||
$lang->job->commitEx = "Used to match the keywords used to create a compile. Multiple keywords are separated by ','";
|
||||
$lang->job->cronSample = 'e.g. 0 0 2 * * 2-6/1 means 2:00 a.m. every weekday.';
|
||||
$lang->job->sendExec = 'Send execute request success.';
|
||||
$lang->job->inputName = 'Please enter parameter name.';
|
||||
$lang->job->invalidName = 'The parameter name should be letters, numbers or underlines.';
|
||||
$lang->job->example = 'e.g.';
|
||||
$lang->job->commitEx = "Used to match the keywords used to create a compile. Multiple keywords are separated by ','";
|
||||
$lang->job->cronSample = 'e.g. 0 0 2 * * 2-6/1 means 2:00 a.m. every weekday.';
|
||||
$lang->job->sendExec = 'Send execute request success.';
|
||||
$lang->job->inputName = 'Please enter parameter name.';
|
||||
$lang->job->invalidName = 'The parameter name should be letters, numbers or underlines.';
|
||||
$lang->job->repoExists = 'This repository has a build task associated with it『%s』';
|
||||
$lang->job->mustUseJenkins = 'SonarQube frame is only used if the build engine is JenKins.';
|
||||
|
||||
$lang->job->buildTypeList['build'] = 'Only Build';
|
||||
$lang->job->buildTypeList['buildAndDeploy'] = 'Build And Deploy';
|
||||
@@ -63,15 +67,16 @@ $lang->job->triggerTypeList['tag'] = 'Tag';
|
||||
$lang->job->triggerTypeList['commit'] = 'Code Commit';
|
||||
$lang->job->triggerTypeList['schedule'] = 'Schedule';
|
||||
|
||||
$lang->job->frameList[''] = '';
|
||||
$lang->job->frameList['junit'] = 'JUnit';
|
||||
$lang->job->frameList['testng'] = 'TestNG';
|
||||
$lang->job->frameList['phpunit'] = 'PHPUnit';
|
||||
$lang->job->frameList['pytest'] = 'Pytest';
|
||||
$lang->job->frameList['jtest'] = 'JTest';
|
||||
$lang->job->frameList['cppunit'] = 'CppUnit';
|
||||
$lang->job->frameList['gtest'] = 'GTest';
|
||||
$lang->job->frameList['qtest'] = 'QTest';
|
||||
$lang->job->frameList[''] = '';
|
||||
$lang->job->frameList['junit'] = 'JUnit';
|
||||
$lang->job->frameList['testng'] = 'TestNG';
|
||||
$lang->job->frameList['phpunit'] = 'PHPUnit';
|
||||
$lang->job->frameList['pytest'] = 'Pytest';
|
||||
$lang->job->frameList['jtest'] = 'JTest';
|
||||
$lang->job->frameList['cppunit'] = 'CppUnit';
|
||||
$lang->job->frameList['gtest'] = 'GTest';
|
||||
$lang->job->frameList['qtest'] = 'QTest';
|
||||
$lang->job->frameList['sonarqube'] = 'SonarQube';
|
||||
|
||||
$lang->job->paramValueList[''] = '';
|
||||
$lang->job->paramValueList['$zentao_version'] = 'Current version';
|
||||
|
||||
+51
-46
@@ -14,46 +14,50 @@ $lang->job->execSuccess = '执行成功';
|
||||
|
||||
$lang->job->browseAction = '构建任务列表';
|
||||
|
||||
$lang->job->id = 'ID';
|
||||
$lang->job->name = '名称';
|
||||
$lang->job->repo = '代码库';
|
||||
$lang->job->product = '关联' . $lang->productCommon;
|
||||
$lang->job->svnDir = 'SVN监控路径';
|
||||
$lang->job->jenkins = 'Jenkins';
|
||||
$lang->job->jkHost = 'Jenkins服务器';
|
||||
$lang->job->jkJob = 'Jenkins任务';
|
||||
$lang->job->buildSpec = '构建对象'; // 'pipeline@server'
|
||||
$lang->job->engine = '构建引擎';
|
||||
$lang->job->server = '服务器';
|
||||
$lang->job->pipeline = '流水线';
|
||||
$lang->job->buildType = '构建类型';
|
||||
$lang->job->frame = '工具/框架';
|
||||
$lang->job->triggerType = '触发方式';
|
||||
$lang->job->atDay = '自定义日期';
|
||||
$lang->job->atTime = '执行时间';
|
||||
$lang->job->lastStatus = '最后执行状态';
|
||||
$lang->job->lastExec = '最后执行时间';
|
||||
$lang->job->comment = '匹配关键字';
|
||||
$lang->job->customParam = '自定义构建参数';
|
||||
$lang->job->paramName = '名称';
|
||||
$lang->job->paramValue = '值';
|
||||
$lang->job->custom = '自定义';
|
||||
$lang->job->createdBy = '由谁创建';
|
||||
$lang->job->createdDate = '创建日期';
|
||||
$lang->job->editedBy = '由谁编辑';
|
||||
$lang->job->editedDate = '编辑日期';
|
||||
$lang->job->lastTag = '最后标签';
|
||||
$lang->job->deleted = '已删除';
|
||||
$lang->job->repoServer = '版本库服务器';
|
||||
$lang->job->id = 'ID';
|
||||
$lang->job->name = '名称';
|
||||
$lang->job->repo = '代码库';
|
||||
$lang->job->product = '关联' . $lang->productCommon;
|
||||
$lang->job->svnDir = 'SVN监控路径';
|
||||
$lang->job->jenkins = 'Jenkins';
|
||||
$lang->job->jkHost = 'Jenkins服务器';
|
||||
$lang->job->jkJob = 'Jenkins任务';
|
||||
$lang->job->buildSpec = '构建对象'; // 'pipeline@server'
|
||||
$lang->job->engine = '构建引擎';
|
||||
$lang->job->server = '服务器';
|
||||
$lang->job->pipeline = '流水线';
|
||||
$lang->job->buildType = '构建类型';
|
||||
$lang->job->frame = '工具/框架';
|
||||
$lang->job->triggerType = '触发方式';
|
||||
$lang->job->atDay = '自定义日期';
|
||||
$lang->job->atTime = '执行时间';
|
||||
$lang->job->lastStatus = '最后执行状态';
|
||||
$lang->job->lastExec = '最后执行时间';
|
||||
$lang->job->comment = '匹配关键字';
|
||||
$lang->job->customParam = '自定义构建参数';
|
||||
$lang->job->paramName = '名称';
|
||||
$lang->job->paramValue = '值';
|
||||
$lang->job->custom = '自定义';
|
||||
$lang->job->createdBy = '由谁创建';
|
||||
$lang->job->createdDate = '创建日期';
|
||||
$lang->job->editedBy = '由谁编辑';
|
||||
$lang->job->editedDate = '编辑日期';
|
||||
$lang->job->lastTag = '最后标签';
|
||||
$lang->job->deleted = '已删除';
|
||||
$lang->job->repoServer = '版本库服务器';
|
||||
$lang->job->sonarqubeServer = 'SonarQube服务器';
|
||||
$lang->job->projectKey = 'SonarQube项目';
|
||||
|
||||
$lang->job->lblBasic = '基本信息';
|
||||
|
||||
$lang->job->example = '举例';
|
||||
$lang->job->commitEx = "用于匹配创建构建任务的关键字,多个关键字用','分割";
|
||||
$lang->job->cronSample = '如 0 0 2 * * 2-6/1 表示每个工作日凌晨2点';
|
||||
$lang->job->sendExec = '发送执行请求成功!执行结果:%s';
|
||||
$lang->job->inputName = '请输入参数名称。';
|
||||
$lang->job->invalidName = '参数名称应该是英文字母、数字或下划线的组合。';
|
||||
$lang->job->example = '举例';
|
||||
$lang->job->commitEx = "用于匹配创建构建任务的关键字,多个关键字用','分割";
|
||||
$lang->job->cronSample = '如 0 0 2 * * 2-6/1 表示每个工作日凌晨2点';
|
||||
$lang->job->sendExec = '发送执行请求成功!执行结果:%s';
|
||||
$lang->job->inputName = '请输入参数名称。';
|
||||
$lang->job->invalidName = '参数名称应该是英文字母、数字或下划线的组合。';
|
||||
$lang->job->repoExists = '此版本库已关联构建任务『%s』';
|
||||
$lang->job->mustUseJenkins = 'SonarQube工具/框架仅在构建引擎为JenKins的情况下使用';
|
||||
|
||||
$lang->job->buildTypeList['build'] = '仅构建';
|
||||
$lang->job->buildTypeList['buildAndDeploy'] = '构建部署';
|
||||
@@ -63,15 +67,16 @@ $lang->job->triggerTypeList['tag'] = '打标签';
|
||||
$lang->job->triggerTypeList['commit'] = '提交注释包含关键字';
|
||||
$lang->job->triggerTypeList['schedule'] = '定时计划';
|
||||
|
||||
$lang->job->frameList[''] = '';
|
||||
$lang->job->frameList['junit'] = 'JUnit';
|
||||
$lang->job->frameList['testng'] = 'TestNG';
|
||||
$lang->job->frameList['phpunit'] = 'PHPUnit';
|
||||
$lang->job->frameList['pytest'] = 'Pytest';
|
||||
$lang->job->frameList['jtest'] = 'JTest';
|
||||
$lang->job->frameList['cppunit'] = 'CppUnit';
|
||||
$lang->job->frameList['gtest'] = 'GTest';
|
||||
$lang->job->frameList['qtest'] = 'QTest';
|
||||
$lang->job->frameList[''] = '';
|
||||
$lang->job->frameList['junit'] = 'JUnit';
|
||||
$lang->job->frameList['testng'] = 'TestNG';
|
||||
$lang->job->frameList['phpunit'] = 'PHPUnit';
|
||||
$lang->job->frameList['pytest'] = 'Pytest';
|
||||
$lang->job->frameList['jtest'] = 'JTest';
|
||||
$lang->job->frameList['cppunit'] = 'CppUnit';
|
||||
$lang->job->frameList['gtest'] = 'GTest';
|
||||
$lang->job->frameList['qtest'] = 'QTest';
|
||||
$lang->job->frameList['sonarqube'] = 'SonarQube';
|
||||
|
||||
$lang->job->paramValueList[''] = '';
|
||||
$lang->job->paramValueList['$zentao_version'] = '当前版本号';
|
||||
|
||||
+57
-3
@@ -156,7 +156,8 @@ class jobModel extends model
|
||||
public function create()
|
||||
{
|
||||
$job = fixer::input('post')
|
||||
->setDefault('atDay', '')
|
||||
->setDefault('atDay,projectKey', '')
|
||||
->setDefault('sonarqubeServer', 0)
|
||||
->add('createdBy', $this->app->user->account)
|
||||
->add('createdDate', helper::now())
|
||||
->remove('repoType,reference')
|
||||
@@ -181,6 +182,24 @@ class jobModel extends model
|
||||
unset($job->jkTask);
|
||||
unset($job->gitlabRepo);
|
||||
|
||||
/* SonarQube tool is only used if the engine is JenKins. */
|
||||
if($job->engine != 'jenkins' and $job->frame == 'sonarqube')
|
||||
{
|
||||
dao::$errors[]['frame'] = $this->lang->job->mustUseJenkins;
|
||||
return false;
|
||||
}
|
||||
|
||||
if($job->repo > 0 and $job->frame == 'sonarqube')
|
||||
{
|
||||
$sonarqubeJob = $this->getSonarqubeByRepo(array($job->repo));
|
||||
if(!empty($sonarqubeJob))
|
||||
{
|
||||
$message = sprintf($this->lang->job->repoExists, $repo[$repoID]->id . '-' . $repo[$repoID]->name);
|
||||
dao::$errors[]['repo'] = $message;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if($job->triggerType == 'schedule') $job->atDay = empty($_POST['atDay']) ? '' : join(',', $this->post->atDay);
|
||||
|
||||
$job->svnDir = '';
|
||||
@@ -219,6 +238,7 @@ class jobModel extends model
|
||||
->batchCheckIF($job->triggerType === 'schedule', "atDay,atTime", 'notempty')
|
||||
->batchCheckIF($job->triggerType === 'commit', "comment", 'notempty')
|
||||
->batchCheckIF(($this->post->repoType == 'Subversion' and $job->triggerType == 'tag'), "svnDir", 'notempty')
|
||||
->batchCheckIF($job->frame === 'sonarqube', "sonarqubeServer,projectKey", 'notempty')
|
||||
->autoCheck()
|
||||
->exec();
|
||||
if(dao::isError()) return false;
|
||||
@@ -268,6 +288,24 @@ class jobModel extends model
|
||||
unset($job->jkTask);
|
||||
unset($job->gitlabRepo);
|
||||
|
||||
/* SonarQube tool is only used if the engine is JenKins. */
|
||||
if($job->engine != 'jenkins' and $job->frame == 'sonarqube')
|
||||
{
|
||||
dao::$errors[] = $this->lang->job->mustUseJenkins;
|
||||
return false;
|
||||
}
|
||||
|
||||
if($job->repo > 0 and $job->frame == 'sonarqube')
|
||||
{
|
||||
$sonarqubeJob = $this->getSonarqubeByRepo(array($job->repo), $id);
|
||||
if(!empty($sonarqubeJob))
|
||||
{
|
||||
$message = sprintf($this->lang->job->repoExists, $repo[$repoID]->id . '-' . $repo[$repoID]->name);
|
||||
dao::$errors[]['repo'] = $message;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if($job->triggerType == 'schedule') $job->atDay = empty($_POST['atDay']) ? '' : join(',', $this->post->atDay);
|
||||
|
||||
$job->svnDir = '';
|
||||
@@ -304,11 +342,10 @@ class jobModel extends model
|
||||
|
||||
$this->dao->update(TABLE_JOB)->data($job)
|
||||
->batchCheck($this->config->job->edit->requiredFields, 'notempty')
|
||||
|
||||
->batchCheckIF($job->triggerType === 'schedule', "atDay,atTime", 'notempty')
|
||||
->batchCheckIF($job->triggerType === 'commit', "comment", 'notempty')
|
||||
->batchCheckIF(($this->post->repoType == 'Subversion' and $job->triggerType == 'tag'), "svnDir", 'notempty')
|
||||
|
||||
->batchCheckIF($job->frame === 'sonarqube', "sonarqubeServer,projectKey", 'notempty')
|
||||
->autoCheck()
|
||||
->where('id')->eq($id)
|
||||
->exec();
|
||||
@@ -539,4 +576,21 @@ class jobModel extends model
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sonarqube by RepoID.
|
||||
*
|
||||
* @param array $repoIDList
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getSonarqubeByRepo($repoIDList, $jobID = 0)
|
||||
{
|
||||
return $this->dao->select('id,name,repo')->from(TABLE_JOB)
|
||||
->where('deleted')->eq('0')
|
||||
->andWhere('frame')->eq('sonarqube')
|
||||
->andWhere('repo')->in($repoIDList)
|
||||
->beginIF($jobID > 0)->andWhere('id')->ne($jobID)->fi()
|
||||
->fetchAll('repo');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<?php js::set('triggerType', 'tag');?>
|
||||
<?php js::set('dirChange', $lang->job->dirChange);?>
|
||||
<?php js::set('buildTag', $lang->job->buildTag);?>
|
||||
<?php js::set('frameList', $lang->job->frameList);?>
|
||||
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='main-content'>
|
||||
@@ -26,7 +27,7 @@
|
||||
<form id='jobForm' method='post' class='form-ajax'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='w-120px'><?php echo $lang->job->name; ?></th>
|
||||
<th class='w-140px'><?php echo $lang->job->name; ?></th>
|
||||
<td class='required'><?php echo html::input('name', '', "class='form-control'"); ?></td>
|
||||
<td colspan="2" ></td>
|
||||
</tr>
|
||||
@@ -51,9 +52,13 @@
|
||||
<th><?php echo $lang->job->product; ?></th>
|
||||
<td><?php echo html::select('product', '', '', "class='form-control chosen'"); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr id="frameBox">
|
||||
<th><?php echo $lang->job->frame; ?></th>
|
||||
<td><?php echo html::select('frame', $lang->job->frameList, '', "class='form-control chosen'"); ?></td>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select('frame', array('' => ''), '', "class='form-control chosen'"); ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->job->triggerType; ?></th>
|
||||
@@ -68,6 +73,20 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='sonarqube hide'>
|
||||
<th><?php echo $lang->job->sonarqubeServer;?></th>
|
||||
<td><?php echo html::select('sonarqubeServer', $sonarqubeServerList, '', "class='form-control chosen' required");?></td>
|
||||
<td colspan="2"></td>
|
||||
</tr>
|
||||
<tr id='sonarProject' class='sonarqube hide'>
|
||||
<th><?php echo $lang->job->projectKey;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select('projectKey', array('' => ''), '', "class='form-control chosen' required");?>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="2"></td>
|
||||
</tr>
|
||||
<tr class="comment-fields">
|
||||
<th><?php echo $lang->job->comment;?></th>
|
||||
<td class='required'><?php echo html::input('comment', '', "class='form-control'");?></td>
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
<?php js::set('dirChange', $lang->job->dirChange);?>
|
||||
<?php js::set('buildTag', $lang->job->buildTag);?>
|
||||
<?php js::set('jkTask', $job->pipeline);?>
|
||||
<?php js::set('job', $job);?>
|
||||
<?php js::set('frameList', $lang->job->frameList);?>
|
||||
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='main-content'>
|
||||
@@ -28,7 +30,7 @@
|
||||
<form id='jobForm' method='post' class='form-ajax'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='w-120px'><?php echo $lang->job->name;?></th>
|
||||
<th class='w-140px'><?php echo $lang->job->name;?></th>
|
||||
<td class='required'><?php echo html::input('name', $job->name, "class='form-control'");?></td>
|
||||
<td colspan="2" ></td>
|
||||
</tr>
|
||||
@@ -50,9 +52,13 @@
|
||||
<th><?php echo $lang->job->product;?></th>
|
||||
<td><?php echo html::select('product', $products, $job->product, "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr id="frameBox">
|
||||
<th><?php echo $lang->job->frame;?></th>
|
||||
<td><?php echo html::select('frame', $lang->job->frameList, $job->frame, "class='form-control chosen'");?></td>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select('frame', array('' => ''), '', "class='form-control chosen'"); ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->job->triggerType;?></th>
|
||||
@@ -88,6 +94,20 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='sonarqube hide'>
|
||||
<th><?php echo $lang->job->sonarqubeServer;?></th>
|
||||
<td><?php echo html::select('sonarqubeServer', $sonarqubeServerList, $job->sonarqubeServer, "class='form-control chosen' required");?></td>
|
||||
<td colspan="2"></td>
|
||||
</tr>
|
||||
<tr id='sonarProject' class='sonarqube hide'>
|
||||
<th><?php echo $lang->job->projectKey;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select('projectKey', array('' => ''), '', "class='form-control chosen' required");?>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="2"></td>
|
||||
</tr>
|
||||
<tr class="comment-fields">
|
||||
<th><?php echo $lang->job->comment;?></th>
|
||||
<td class='required'><?php echo html::input('comment', $job->comment, "class='form-control'");?></td>
|
||||
|
||||
@@ -83,7 +83,8 @@ class repo extends control
|
||||
$repoID = $this->repo->saveState(0, $objectID);
|
||||
if($this->viewType !== 'json') $this->commonAction($repoID, $objectID);
|
||||
|
||||
$repoList = $this->repo->getList(0, '', $orderBy);
|
||||
$repoList = $this->repo->getList(0, '', $orderBy);
|
||||
$sonarRepoList = $this->loadModel('sonarqube')->getSonarqubeByRepo(array_keys($repoList));
|
||||
|
||||
/* Pager. */
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
@@ -95,11 +96,12 @@ class repo extends control
|
||||
$this->view->position[] = $this->lang->repo->common;
|
||||
$this->view->position[] = $this->lang->repo->browse;
|
||||
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->objectID = $objectID;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->repoList = empty($repoList) ? $repoList: $repoList[$pageID - 1];;
|
||||
$this->view->products = $this->loadModel('product')->getPairs();
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->objectID = $objectID;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->repoList = empty($repoList) ? $repoList: $repoList[$pageID - 1];;
|
||||
$this->view->products = $this->loadModel('product')->getPairs();
|
||||
$this->view->sonarRepoList = $sonarRepoList;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<th class='c-name text-left'><?php common::printOrderLink('name', $orderBy, $vars, $lang->repo->name); ?></th>
|
||||
<th class='c-product text-left'><?php common::printOrderLink('product', $orderBy, $vars, $lang->repo->product); ?></th>
|
||||
<th class='text-left'><?php echo $lang->repo->path; ?></th>
|
||||
<th class='c-actions-3 w-150px'><?php echo $lang->actions; ?></th>
|
||||
<th class='c-actions-6'><?php echo $lang->actions; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -59,6 +59,11 @@
|
||||
common::printIcon('gitlab', 'createWebhook', "repoID=$repo->id", '', 'list', 'change', 'hiddenwin');
|
||||
common::printIcon('gitlab', 'importIssue', "repo={$repo->id}", '', 'list', 'link');
|
||||
}
|
||||
if(isset($sonarRepoList[$repo->id]))
|
||||
{
|
||||
$jobID = $sonarRepoList[$repo->id]->id;
|
||||
common::printIcon('sonarqube', 'execJob', "jobID=$jobID", '', 'list', 'sonarqube', 'hiddenwin');
|
||||
}
|
||||
common::printIcon('repo', 'delete', "repoID=$repo->id&objectID=$objectID", '', 'list', 'trash', 'hiddenwin');
|
||||
?>
|
||||
</td>
|
||||
|
||||
@@ -11,19 +11,6 @@
|
||||
*/
|
||||
class sonarqube extends control
|
||||
{
|
||||
/**
|
||||
* The sonarqube constructor.
|
||||
* @param string $moduleName
|
||||
* @param string $methodName
|
||||
*/
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
{
|
||||
parent::__construct($moduleName, $methodName);
|
||||
|
||||
/* Optional: common::setMenuVars('devops', $this->session->repoID); */
|
||||
$this->loadModel('ci')->setMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse sonarqube.
|
||||
*
|
||||
@@ -49,6 +36,24 @@ class sonarqube extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get project list.
|
||||
*
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetProjectList($sonarqubeID)
|
||||
{
|
||||
$projectList = $this->loadModel('sonarqube')->getList($sonarqubeID);
|
||||
$projectPairs = array(0 => '');
|
||||
foreach($projectList as $project)
|
||||
{
|
||||
$projectPairs[$project->id] = $project->name;
|
||||
}
|
||||
echo html::select('projectKey', $projectPairs, '', "class='form-control chosen' required");
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sonarqube.
|
||||
*
|
||||
@@ -63,8 +68,7 @@ class sonarqube extends control
|
||||
$sonarqubeID = $this->loadModel('pipeline')->create('sonarqube');
|
||||
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
$this->loadModel('action');
|
||||
$actionID = $this->action->create('sonarqube', $sonarqubeID, 'created');
|
||||
$actionID = $this->loadModel('action')->create('sonarqube', $sonarqubeID, 'created');
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
}
|
||||
|
||||
@@ -96,4 +100,16 @@ class sonarqube extends control
|
||||
if(!isset($result->valid) or !$result->valid) return $this->send(array('result' => 'fail', 'message' => array('token' => array($this->lang->sonarqube->validError))));
|
||||
$this->post->set('token', $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exec job.
|
||||
*
|
||||
* @param int $jobID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function execJob($jobID)
|
||||
{
|
||||
echo $this->fetch('job', 'exec', "jobID=$jobID");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ $lang->sonarqube->delete = 'Delete SonarQube';
|
||||
$lang->sonarqube->confirmDelete = 'Do you want to delete this SonarQube server?';
|
||||
$lang->sonarqube->serverFail = 'Connect to SonarQube server failed, please check the SonarQube server.';
|
||||
$lang->sonarqube->browseProject = "SonarQube Project List";
|
||||
$lang->sonarqube->execJob = "Exec SonarQube Job";
|
||||
|
||||
$lang->sonarqube->id = 'ID';
|
||||
$lang->sonarqube->name = "{$lang->sonarqube->common} Name";
|
||||
|
||||
@@ -9,6 +9,7 @@ $lang->sonarqube->delete = '删除SonarQube';
|
||||
$lang->sonarqube->confirmDelete = '确认删除该SonarQube吗?';
|
||||
$lang->sonarqube->serverFail = '连接SonarQube服务器异常,请检查SonarQube服务器。';
|
||||
$lang->sonarqube->browseProject = "SonarQube项目列表";
|
||||
$lang->sonarqube->execJob = "执行SonarQube任务";
|
||||
|
||||
$lang->sonarqube->id = 'ID';
|
||||
$lang->sonarqube->name = "{$lang->sonarqube->common}名称";
|
||||
|
||||
@@ -28,6 +28,17 @@ class sonarqubeModel extends model
|
||||
return $sonarqubeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sonarqube pairs.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getPairs()
|
||||
{
|
||||
return $this->loadModel('pipeline')->getPairs('sonarqube');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sonarqube api base url and header by id.
|
||||
*
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<th class='c-id'><?php common::printOrderLink('id', $orderBy, $vars, $lang->sonarqube->id);?></th>
|
||||
<th class='c-name text-left'><?php common::printOrderLink('name', $orderBy, $vars, $lang->sonarqube->name);?></th>
|
||||
<th class='text-left'><?php common::printOrderLink('url', $orderBy, $vars, $lang->sonarqube->url);?></th>
|
||||
<th class='c-actions-6'><?php echo $lang->actions;?></th>
|
||||
<th class='c-actions-3'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
Reference in New Issue
Block a user