diff --git a/db/update16.1.sql b/db/update16.1.sql new file mode 100644 index 0000000000..6644596c3b --- /dev/null +++ b/db/update16.1.sql @@ -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`; diff --git a/module/action/lang/en.php b/module/action/lang/en.php index 93f9ddca4d..b739065286 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -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; diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 13e034b34c..851e8f58f4 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -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(); diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php index 7949388c3c..4918fb2d72 100644 --- a/module/group/lang/resource.php +++ b/module/group/lang/resource.php @@ -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'; diff --git a/module/job/control.php b/module/job/control.php index 961f71c525..d3ed975c64 100644 --- a/module/job/control.php +++ b/module/job/control.php @@ -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' => '')); + } } diff --git a/module/job/js/create.js b/module/job/js/create.js index 635ce8abc2..225b2d83b6 100644 --- a/module/job/js/create.js +++ b/module/job/js/create.js @@ -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("
"); + var html = "'; + + $('#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("
"); + $.getJSON(createLink('sonarqube', 'ajaxGetProjectList', 'sonarqubeID=' + sonarqubeID), function(html) + { + $('#sonarProject .loading').remove(); + $('#sonarProject .input-group').append(html); + $('#sonarProject #projectKey').chosen({drop_direction: 'auto'}); + }) }) var scheduleOption = ""; @@ -161,6 +241,7 @@ $(document).ready(function() $('tr.gitlabRepo').hide(); $('tr.commonRepo').show(); } + getFrameSelect(engine); }); $('#engine').change(); diff --git a/module/job/js/edit.js b/module/job/js/edit.js index f91c2aef1b..0f799e31a2 100644 --- a/module/job/js/edit.js +++ b/module/job/js/edit.js @@ -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("
"); + var html = "'; + + $('#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("
"); + $.getJSON(createLink('sonarqube', 'ajaxGetProjectList', 'sonarqubeID=' + sonarqubeID), function(html) + { + $('#sonarProject .loading').remove(); + $('#sonarProject .input-group').append(html); + $('#sonarProject #projectKey').chosen({drop_direction: 'auto'}); + }) }) var scheduleOption = ""; @@ -169,6 +252,7 @@ $(document).ready(function() $('#engine').change(); $('#jkServer').change(); + $('#frame').change(); $('#triggerType').change(); }); diff --git a/module/job/lang/en.php b/module/job/lang/en.php index f2353087d6..5aa7bb3833 100644 --- a/module/job/lang/en.php +++ b/module/job/lang/en.php @@ -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'; diff --git a/module/job/lang/zh-cn.php b/module/job/lang/zh-cn.php index 780ec84159..1994eab804 100644 --- a/module/job/lang/zh-cn.php +++ b/module/job/lang/zh-cn.php @@ -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'] = '当前版本号'; diff --git a/module/job/model.php b/module/job/model.php index 97673d40cc..8806a75d67 100644 --- a/module/job/model.php +++ b/module/job/model.php @@ -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'); + } } diff --git a/module/job/view/create.html.php b/module/job/view/create.html.php index ac885915c0..9877deea00 100644 --- a/module/job/view/create.html.php +++ b/module/job/view/create.html.php @@ -16,6 +16,7 @@ job->dirChange);?> job->buildTag);?> +job->frameList);?>
@@ -26,7 +27,7 @@
- + @@ -51,9 +52,13 @@ - + - + @@ -68,6 +73,20 @@ + + + + + + + + + + diff --git a/module/job/view/edit.html.php b/module/job/view/edit.html.php index 863e03f716..7703d31190 100644 --- a/module/job/view/edit.html.php +++ b/module/job/view/edit.html.php @@ -18,6 +18,8 @@ job->dirChange);?> job->buildTag);?> pipeline);?> + +job->frameList);?>
@@ -28,7 +30,7 @@
job->name; ?>job->name; ?>
job->product; ?>
job->frame; ?>job->frameList, '', "class='form-control chosen'"); ?> +
+ ''), '', "class='form-control chosen'"); ?> +
+
job->triggerType; ?>
job->sonarqubeServer;?>
job->projectKey;?> +
+ ''), '', "class='form-control chosen' required");?> +
+
job->comment;?>
- + @@ -50,9 +52,13 @@ - + - + @@ -88,6 +94,20 @@ + + + + + + + + + + diff --git a/module/repo/control.php b/module/repo/control.php index e1d3e0c407..5d7cdff573 100644 --- a/module/repo/control.php +++ b/module/repo/control.php @@ -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(); } diff --git a/module/repo/view/maintain.html.php b/module/repo/view/maintain.html.php index f4f083953d..33ea5cdc56 100644 --- a/module/repo/view/maintain.html.php +++ b/module/repo/view/maintain.html.php @@ -27,7 +27,7 @@ - + @@ -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'); ?> diff --git a/module/sonarqube/control.php b/module/sonarqube/control.php index f6dd4434cc..dec4397ee5 100644 --- a/module/sonarqube/control.php +++ b/module/sonarqube/control.php @@ -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"); + } } diff --git a/module/sonarqube/lang/en.php b/module/sonarqube/lang/en.php index f1dd3b27a2..c562bdbdb1 100644 --- a/module/sonarqube/lang/en.php +++ b/module/sonarqube/lang/en.php @@ -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"; diff --git a/module/sonarqube/lang/zh-cn.php b/module/sonarqube/lang/zh-cn.php index dea6c84c2d..306938acfc 100644 --- a/module/sonarqube/lang/zh-cn.php +++ b/module/sonarqube/lang/zh-cn.php @@ -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}名称"; diff --git a/module/sonarqube/model.php b/module/sonarqube/model.php index 91b529ba19..13a6ecccc5 100644 --- a/module/sonarqube/model.php +++ b/module/sonarqube/model.php @@ -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. * diff --git a/module/sonarqube/view/browse.html.php b/module/sonarqube/view/browse.html.php index 505b2ce183..3048164339 100644 --- a/module/sonarqube/view/browse.html.php +++ b/module/sonarqube/view/browse.html.php @@ -35,7 +35,7 @@ - +
job->name;?>job->name;?> name, "class='form-control'");?>
job->product;?> product, "class='form-control chosen'");?>
job->frame;?>job->frameList, $job->frame, "class='form-control chosen'");?> +
+ ''), '', "class='form-control chosen'"); ?> +
+
job->triggerType;?>
job->sonarqubeServer;?>sonarqubeServer, "class='form-control chosen' required");?>
job->projectKey;?> +
+ ''), '', "class='form-control chosen' required");?> +
+
job->comment;?> comment, "class='form-control'");?>repo->name); ?> repo->product); ?> repo->path; ?>actions; ?>actions; ?>
sonarqube->id);?> sonarqube->name);?> sonarqube->url);?>actions;?>actions;?>