diff --git a/api/v1/entries/reporules.php b/api/v1/entries/reporules.php new file mode 100644 index 0000000000..693d9ce90c --- /dev/null +++ b/api/v1/entries/reporules.php @@ -0,0 +1,32 @@ + + * @package entries + * @version 1 + * @link http://www.zentao.net + */ +class repoRulesEntry extends entry +{ + /** + * GET method. + * + * @access public + * @return void + */ + public function get() + { + $control = $this->loadController('repo', 'ajaxGetRules'); + $control->ajaxGetRules(); + + $data = $this->getData(); + + if(!$data or !isset($data->status)) return $this->send400('error'); + if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message); + + $this->send(200, $data->rules); + } +} diff --git a/config/filter.php b/config/filter.php index 1b2e6f2ec5..b0215c07eb 100644 --- a/config/filter.php +++ b/config/filter.php @@ -147,6 +147,7 @@ $filter->user->edit = new stdclass(); $filter->webhook->bind = new stdclass(); $filter->user->ajaxgetmore = new stdclass(); $filter->repo->ajaxsynccommit = new stdclass(); +$filter->repo->apigetrepobyurl = new stdclass(); $filter->search->index = new stdclass(); $filter->gitlab->webhook = new stdclass(); $filter->gitlab->importissue = new stdclass(); @@ -365,6 +366,8 @@ $filter->repo->default->get['repoPath'] = 'reg::base64'; $filter->repo->default->get['path'] = 'reg::base64'; $filter->repo->default->get['entry'] = 'reg::base64'; +$filter->repo->apigetrepobyurl->get['url'] = 'reg::any'; + $filter->repo->default->cookie['repoBranch'] = 'reg::any'; $filter->repo->diff->cookie['arrange'] = 'reg::word'; $filter->repo->diff->cookie['repoPairs'] = 'array'; diff --git a/config/routes.php b/config/routes.php index 5e6fac9e6f..c47cd483aa 100644 --- a/config/routes.php +++ b/config/routes.php @@ -118,7 +118,8 @@ $routes['/doclibs/:id'] = 'docs'; $routes['/docs'] = 'docs'; $routes['/docs/:id'] = 'doc'; -$routes['/repos'] = 'repos'; +$routes['/repos'] = 'repos'; +$routes['/repos/rules'] = 'reporules'; $routes['/reports'] = 'reports'; diff --git a/db/update16.0.beta1.sql b/db/update16.0.beta1.sql index f47a61a0d9..4a3b176200 100644 --- a/db/update16.0.beta1.sql +++ b/db/update16.0.beta1.sql @@ -114,3 +114,14 @@ ALTER TABLE `zt_task` ADD `mr` mediumint(8) unsigned NOT NULL AFTER `repo`; ALTER TABLE `zt_bug` ADD `mr` mediumint(8) unsigned NOT NULL AFTER `repo`; UPDATE `zt_grouppriv` SET `method`='addReview' where `module`='mr' and `method`='addBug'; + +ALTER TABLE `zt_repo` ADD `preMerge` enum('0','1') COLLATE 'utf8_general_ci' NOT NULL DEFAULT '0' AFTER `extra`; +ALTER TABLE `zt_repo` ADD `job` mediumint unsigned NOT NULL AFTER `preMerge`; +ALTER TABLE `zt_mr` ADD `synced` enum('0','1') COLLATE 'utf8_general_ci' NOT NULL DEFAULT '1'; +ALTER TABLE `zt_mr` ADD `hasNoConflict` enum('0','1') COLLATE 'utf8_general_ci' NOT NULL DEFAULT '0'; +ALTER TABLE `zt_mr` ADD `diffs` longtext COLLATE 'utf8_general_ci' NULL AFTER `synced`; +ALTER TABLE `zt_mr` ADD `removeSourceBranch` ENUM('0','1') NOT NULL DEFAULT '0' AFTER `compileStatus`; + +ALTER TABLE zt_repo ADD fileServerUrl text COLLATE 'utf8_general_ci' NULL AFTER `job`; +ALTER TABLE zt_repo ADD fileServerAccount varchar(40) NOT NULL default '' AFTER `fileServerUrl`; +ALTER TABLE zt_repo ADD fileServerPassword varchar(100) NOT NULL default '' AFTER `fileServerAccount`; diff --git a/db/zentao.sql b/db/zentao.sql index 733fbca6d5..7eda9dbaac 100644 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -847,6 +847,7 @@ CREATE TABLE IF NOT EXISTS `zt_mr` ( `jobID` mediumint(8) unsigned NOT NULL, `compileID` mediumint(8) unsigned NOT NULL, `compileStatus` char(30) NOT NULL, + `removeSourceBranch` enum('0','1') NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_mrapproval`; diff --git a/lib/scm/gitlab.class.php b/lib/scm/gitlab.class.php index 8966dd7fc6..044b12e610 100644 --- a/lib/scm/gitlab.class.php +++ b/lib/scm/gitlab.class.php @@ -593,6 +593,7 @@ class gitlab public function getCommittedDate($sha) { if(!scm::checkRevision($sha)) return null; + if(!$sha or $sha == 'HEAD') return date('c'); global $dao; $time = $dao->select('time')->from(TABLE_REPOHISTORY)->where('revision')->eq($sha)->fetch('time'); diff --git a/module/action/lang/en.php b/module/action/lang/en.php index c6c7e56262..445d378656 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -125,6 +125,7 @@ $lang->action->objectTypes['gitlabuser'] = 'GitLab User'; $lang->action->objectTypes['gitlabgroup'] = 'GitLab Group'; $lang->action->objectTypes['gitlabbranch'] = 'GitLab Branch'; $lang->action->objectTypes['gitlabbranchpriv'] = 'GitLab Protected Branches'; +$lang->action->objectTypes['gitlabtag'] = 'GitLab Tag'; $lang->action->objectTypes['kanbanspace'] = 'Kanban Space'; $lang->action->objectTypes['kanban'] = 'Kanban'; $lang->action->objectTypes['kanbanregion'] = 'Kanban Region'; diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 5f043c6650..9285bf0bb9 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -125,6 +125,7 @@ $lang->action->objectTypes['gitlabuser'] = 'GitLab用户'; $lang->action->objectTypes['gitlabgroup'] = 'GitLab群组'; $lang->action->objectTypes['gitlabbranch'] = 'GitLab分支'; $lang->action->objectTypes['gitlabbranchpriv'] = 'GitLab保护分支'; +$lang->action->objectTypes['gitlabtag'] = 'GitLab标签'; $lang->action->objectTypes['kanbanspace'] = '看板空间'; $lang->action->objectTypes['kanban'] = '看板'; $lang->action->objectTypes['kanbanregion'] = '看板区域'; diff --git a/module/ci/model.php b/module/ci/model.php index 0bf3b7ca57..2a5fcf2fae 100644 --- a/module/ci/model.php +++ b/module/ci/model.php @@ -199,6 +199,50 @@ class ciModel extends model { $this->dao->update(TABLE_COMPILE)->set('status')->eq($status)->where('id')->eq($build->id)->exec(); $this->dao->update(TABLE_JOB)->set('lastExec')->eq(helper::now())->set('lastStatus')->eq($status)->where('id')->eq($build->job)->exec(); + + if($status == 'building') return; + $relateMR = $this->dao->select('*')->from(TABLE_MR)->where('compileID')->eq($build->id)->fetch(); + if(isset($relateMR->synced) and $relateMR->synced == '0' and $status == 'success') + { + $newMR = new stdclass(); + $newMR->mergeStatus = 'can_be_merged'; + + /* Create a gitlab mr. */ + $MRObject = new stdclass(); + $MRObject->target_project_id = $relateMR->targetProject; + $MRObject->source_branch = $relateMR->sourceBranch; + $MRObject->target_branch = $relateMR->targetBranch; + $MRObject->title = $relateMR->title; + $MRObject->description = $relateMR->description; + $MRObject->remove_source_branch = $relateMR->removeSourceBranch == '1' ? true : false; + if($relateMR->assignee) + { + $gitlabAssignee = $this->gitlab->getUserIDByZentaoAccount($relateMR->gitlabID, $relateMR->assignee); + if($gitlabAssignee) $MRObject->assignee_ids = $gitlabAssignee; + } + + $rawMR = $this->loadModel('mr')->apiCreateMR($relateMR->gitlabID, $relateMR->sourceProject, $MRObject); + + if(!empty($rawMR->iid)) + { + $newMR->mriid = $rawMR->iid; + $newMR->status = $rawMR->state; + $newMR->synced = '1'; + } + + $this->dao->update(TABLE_MR)->data($newMR) + ->where('id')->eq($relateMR->id) + ->exec(); + } + else + { + $newMR = new stdclass(); + $newMR->mergeStatus = 'cannot_merge_by_fail'; + + $this->dao->update(TABLE_MR)->data($newMR) + ->where('id')->eq($relateMR->id) + ->exec(); + } } /** diff --git a/module/dept/model.php b/module/dept/model.php index 3a6a9eb89f..fc13b9926f 100644 --- a/module/dept/model.php +++ b/module/dept/model.php @@ -132,7 +132,7 @@ class deptModel extends model * @access public * @return string */ - public function getTreeMenu($rootDeptID = 0, $userFunc, $param = 0) + public function getTreeMenu($rootDeptID = 0, $userFunc = '', $param = 0) { $deptMenu = array(); $stmt = $this->dbh->query($this->buildMenuQuery($rootDeptID)); @@ -376,7 +376,7 @@ class deptModel extends model * @access public * @return array */ - public function getUsers($browseType = 'inside', $deptID, $pager = null, $orderBy = 'id') + public function getUsers($browseType = 'inside', $deptID = 0, $pager = null, $orderBy = 'id') { return $this->dao->select('*')->from(TABLE_USER) ->where('deleted')->eq(0) diff --git a/module/extension/control.php b/module/extension/control.php index 36d63875d6..07a87c4a28 100644 --- a/module/extension/control.php +++ b/module/extension/control.php @@ -430,8 +430,13 @@ class extension extends control $tmpName = $_FILES['file']['tmp_name']; $fileName = $_FILES['file']['name']; - $dest = $this->app->getTmpRoot() . "/extension/$fileName"; - move_uploaded_file($tmpName, $dest); + $dest = $this->app->getTmpRoot() . "extension/$fileName"; + if(!move_uploaded_file($tmpName, $dest)) + { + $downloadPath = $this->app->getTmpRoot() . 'extension/'; + $errorMessage = strip_tags(sprintf($this->lang->extension->errorDownloadPathNotWritable, $downloadPath, $downloadPath)); + die(js::alert($errorMessage)); + } $extension = basename($fileName, '.zip'); $return = $this->extension->extractPackage($extension); diff --git a/module/gitlab/config.php b/module/gitlab/config.php index d02cf70f27..c431543e6b 100644 --- a/module/gitlab/config.php +++ b/module/gitlab/config.php @@ -11,6 +11,9 @@ $config->gitlab->createbranch->requiredFields = 'branch,ref'; $config->gitlab->createbranchpriv = new stdclass; $config->gitlab->createbranchpriv->requiredFields = 'name'; +$config->gitlab->createtag = new stdclass; +$config->gitlab->createtag->requiredFields = 'tag_name,ref'; + $config->gitlab->labelPattern = new stdclass; $config->gitlab->labelPattern->task = '/^zentao_task\/\d+$/'; $config->gitlab->labelPattern->bug = '/^zentao_bug\/\d+$/'; diff --git a/module/gitlab/control.php b/module/gitlab/control.php index d6e34fc2c2..a56097db8f 100644 --- a/module/gitlab/control.php +++ b/module/gitlab/control.php @@ -858,7 +858,6 @@ class gitlab extends control $branchPriv->mergeAccessLevel = 40; // Initialize data, and the operation authority is the maintainers by default. $branchPriv->pushAccessLevel = 40; // Initialize data, and the operation authority is the maintainers by default. - $gitlab = $this->gitlab->getByID($gitlabID); $title = $this->lang->gitlab->createBranchPriv; if($branch) @@ -881,7 +880,6 @@ class gitlab extends control $this->view->title = $this->lang->gitlab->common . $this->lang->colon . $title; $this->view->pageTitle = $title; - $this->view->gitlab = $gitlab; $this->view->gitlabID = $gitlabID; $this->view->branch = $branch; $this->view->projectID = $projectID; @@ -930,6 +928,52 @@ class gitlab extends control die(js::alert($reponse->message)); } + /** + * Browse gitlab tag. + * + * @param int $gitlabID + * @param int $projectID + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function browseTag($gitlabID, $projectID, $orderBy = 'updated_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + { + $this->session->set('gitlabTagList', $this->app->getURI(true)); + $keyword = fixer::input('post')->setDefault('keyword', '')->get('keyword'); + + /* Pager. */ + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + $tagList = array(); + $result = $this->gitlab->apiGetTags($gitlabID, $projectID, $orderBy, $keyword, $pager); + foreach($result as $gitlabTag) + { + $tag = new stdClass(); + $tag->name = $gitlabTag->name; + $tag->lastCommitter = $gitlabTag->commit->committer_name; + $tag->updated = date('Y-m-d H:i:s', strtotime($gitlabTag->commit->committed_date)); + $tag->protected = $gitlabTag->protected; + + $tagList[] = $tag; + } + + $this->view->gitlab = $this->gitlab->getByID($gitlabID); + $this->view->pager = $pager; + $this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->browseTag; + $this->view->gitlabID = $gitlabID; + $this->view->projectID = $projectID; + $this->view->keyword = $keyword; + $this->view->project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID); + $this->view->gitlabTagList = $tagList; + $this->view->orderBy = $orderBy; + $this->display(); + } + /** * Import gitlab issue to zentaopms. * @@ -1281,4 +1325,62 @@ class gitlab extends control } $this->send($options); } + + /** + * Create a gitlab tag. + * + * @param int $gitlabID + * @param int $projectID + * @access public + * @return void + */ + public function createTag($gitlabID, $projectID) + { + if($_POST) + { + $this->gitlab->createTag($gitlabID, $projectID); + + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browseTag', "gitlabID=$gitlabID&projectID=$projectID"))); + } + + $gitlabBranches = $this->gitlab->apiGetBranches($gitlabID, $projectID); + $branches = array(); + foreach($gitlabBranches as $branch) + { + $branches[$branch->name] = $branch->name; + } + + $this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->createTag; + $this->view->gitlabID = $gitlabID; + $this->view->projectID = $projectID; + $this->view->branches = $branches; + $this->display(); + } + + /** + * Delete a gitlab tag. + * + * @param int $gitlabID + * @param int $projectID + * @param string $tagName + * @param string $confirm yes|no + * @access public + * @return void + */ + public function deleteTag($gitlabID, $projectID, $tagName = '', $confirm = 'no') + { + if($confirm != 'yes') die(js::confirm($this->lang->gitlab->tag->confirmDelete , inlink('deleteTag', "gitlabID=$gitlabID&projectID=$projectID&tagName=$tagName&confirm=yes"))); + + $reponse = $this->gitlab->apiDeleteTag($gitlabID, $projectID, $tagName); + + /* If the status code beginning with 20 is returned or empty is returned, it is successful. */ + if(!$reponse or substr($reponse->message, 0, 2) == '20') + { + $this->loadModel('action')->create('gitlabtag', $projectID, 'deleted', '', $project->name); + die(js::reload('parent')); + } + + die(js::alert($reponse->message)); + } } diff --git a/module/gitlab/css/browsetag.css b/module/gitlab/css/browsetag.css new file mode 100644 index 0000000000..237fdb885d --- /dev/null +++ b/module/gitlab/css/browsetag.css @@ -0,0 +1,3 @@ +.text-c-counts > span {margin-left: 5px;} +#mainMenu .pull-left {margin-right: 15px;} +.c-actions-1 {width: 60px;} diff --git a/module/gitlab/css/createtag.css b/module/gitlab/css/createtag.css new file mode 100644 index 0000000000..025aeb5e7f --- /dev/null +++ b/module/gitlab/css/createtag.css @@ -0,0 +1,2 @@ +.table-form>tbody>tr>th {width: 110px;} +.table-form {width: 50%;} diff --git a/module/gitlab/js/browsetag.js b/module/gitlab/js/browsetag.js new file mode 100644 index 0000000000..68a15f6a9f --- /dev/null +++ b/module/gitlab/js/browsetag.js @@ -0,0 +1,17 @@ +$(document).ready(function() +{ + $('#tagSearch').click(function() + { + triggerSearch(); + }); + $('#keyword').keypress(function(event) + { + if(event.which == 13) triggerSearch(); + }) + +}); + +function triggerSearch() +{ + $("#tagForm").submit(); +} diff --git a/module/gitlab/lang/en.php b/module/gitlab/lang/en.php index b03cf87c94..c23b2a631e 100644 --- a/module/gitlab/lang/en.php +++ b/module/gitlab/lang/en.php @@ -31,6 +31,7 @@ $lang->gitlab->browseProject = "GitLab Project List"; $lang->gitlab->browseUser = "User List"; $lang->gitlab->browseGroup = "Group List"; $lang->gitlab->browseBranch = "GitLab Branch List"; +$lang->gitlab->browseTag = "GitLab Tag List"; $lang->gitlab->gitlabIssue = "GitLab Issue"; $lang->gitlab->zentaoProduct = 'Zentao Product'; $lang->gitlab->objectType = 'Type'; // task, bug, story @@ -51,6 +52,8 @@ $lang->gitlab->browseBranchPriv = 'Protect branch'; $lang->gitlab->createBranchPriv = 'Cerate branch protected'; $lang->gitlab->editBranchPriv = 'Edit branch protected'; $lang->gitlab->deleteBranchPriv = 'Delete branch protected'; +$lang->gitlab->createTag = 'Create Tag'; +$lang->gitlab->deleteTag = 'Delete tag'; $lang->gitlab->id = 'ID'; $lang->gitlab->name = "GitLab Name"; @@ -202,3 +205,15 @@ $lang->gitlab->branch->branchCreationLevelList[30] = "Developers + Maintainers"; $lang->gitlab->branch->branchCreationLevelList[0] = "No one"; $lang->gitlab->branch->emptyPrivNameError = "Branch cannot be empty."; $lang->gitlab->branch->issetPrivNameError = "The protection branch already exists"; + +$lang->gitlab->tag = new stdclass(); +$lang->gitlab->tag->name = 'Tag name'; +$lang->gitlab->tag->ref = 'Create from'; +$lang->gitlab->tag->message = 'Message'; +$lang->gitlab->tag->lastCommitter = 'Last Committer'; +$lang->gitlab->tag->lastCommittedDate = 'Last Committed Date'; +$lang->gitlab->tag->placeholderSearch = "Enter branch tag"; +$lang->gitlab->tag->emptyNameError = "Name cannot be empty."; +$lang->gitlab->tag->emptyRefError = "Create from cannot be empty."; +$lang->gitlab->tag->issetNameError = "The tag already exists"; +$lang->gitlab->tag->confirmDelete = 'Do you want to delete this GitLab tag?'; diff --git a/module/gitlab/lang/zh-cn.php b/module/gitlab/lang/zh-cn.php index 658367e491..932a2a947c 100644 --- a/module/gitlab/lang/zh-cn.php +++ b/module/gitlab/lang/zh-cn.php @@ -31,6 +31,7 @@ $lang->gitlab->browseProject = "{$lang->gitlab->common}项目列表"; $lang->gitlab->browseUser = "用户列表"; $lang->gitlab->browseGroup = "群组列表"; $lang->gitlab->browseBranch = "GitLab分支列表"; +$lang->gitlab->browseTag = "GitLab标签列表"; $lang->gitlab->gitlabIssue = "{$lang->gitlab->common} issue"; $lang->gitlab->zentaoProduct = '禅道产品'; $lang->gitlab->objectType = '类型'; // task, bug, story @@ -51,6 +52,8 @@ $lang->gitlab->browseBranchPriv = '分支保护管理'; $lang->gitlab->createBranchPriv = '创建分支保护'; $lang->gitlab->editBranchPriv = '编辑分支保护'; $lang->gitlab->deleteBranchPriv = '删除分支保护'; +$lang->gitlab->createTag = '创建标签'; +$lang->gitlab->deleteTag = '删除标签'; $lang->gitlab->id = 'ID'; $lang->gitlab->name = "{$lang->gitlab->common}名称"; @@ -202,3 +205,15 @@ $lang->gitlab->branch->branchCreationLevelList[30] = "开发者 + 维护者"; $lang->gitlab->branch->branchCreationLevelList[0] = "禁止"; $lang->gitlab->branch->emptyPrivNameError = "分支不能为空"; $lang->gitlab->branch->issetPrivNameError = "已存在该保护分支"; + +$lang->gitlab->tag = new stdclass(); +$lang->gitlab->tag->name = '标签名'; +$lang->gitlab->tag->ref = '创建自'; +$lang->gitlab->tag->lastCommitter = '最后提交'; +$lang->gitlab->tag->lastCommittedDate = '最后修改时间'; +$lang->gitlab->tag->placeholderSearch = "请输入标签名称"; +$lang->gitlab->tag->message = '信息'; +$lang->gitlab->tag->emptyNameError = "标签名不能为空"; +$lang->gitlab->tag->emptyRefError = "创建自不能为空"; +$lang->gitlab->tag->issetNameError = "已存在该标签"; +$lang->gitlab->tag->confirmDelete = '确认删除该GitLab标签吗?'; diff --git a/module/gitlab/model.php b/module/gitlab/model.php index 47cbbd899b..94669970c6 100644 --- a/module/gitlab/model.php +++ b/module/gitlab/model.php @@ -635,7 +635,7 @@ class gitlabModel extends model * * @param int $gitlabID * @access public - * @return array + * @return array */ public function apiGetProjects($gitlabID) { @@ -1462,15 +1462,63 @@ class gitlabModel extends model /** * Get project repository tags by api. * - * @param int $gitlabID - * @param int $projectID + * @param int $gitlabID + * @param int $projectID + * @param string $orderBy + * @param string $keyword + * @param object $pager * @access public * @return object */ - public function apiGetTags($gitlabID, $projectID) + public function apiGetTags($gitlabID, $projectID, $orderBy = '', $keyword = '', $pager = null) { - $url = sprintf($this->getApiRoot($gitlabID), "/projects/{$projectID}/repository/tags"); - return json_decode(commonModel::http($url)); + $apiRoot = $this->getApiRoot($gitlabID); + + /* Parse order string. */ + if($orderBy) + { + list($order, $sort) = explode('_', $orderBy); + $apiRoot .= "&order_by={$order}&sort={$sort}"; + } + + if($keyword) $apiRoot .= "&search={$keyword}"; + + if(!$pager) + { + $url = sprintf($apiRoot, "/projects/{$projectID}/repository/tags"); + return json_decode(commonModel::http($url)); + } + else + { + $apiRoot .= "&per_page={$pager->recPerPage}&page={$pager->pageID}"; + $url = sprintf($apiRoot, "/projects/{$projectID}/repository/tags"); + $result = commonModel::httpWithHeader($url); + + $header = $result['header']; + $pager->setRecTotal($header['X-Total']); + $pager->setPageTotal(); + if($pager->pageID > $pager->pageTotal) $pager->setPageID($pager->pageTotal); + + return json_decode($result['body']); + } + } + + /** + * Delete a gitab tag by api. + * + * @param int $gitlabID + * @param int $projectID + * @param string $tagName + * @access public + * @return object + */ + public function apiDeleteTag($gitlabID, $projectID, $tagName = '') + { + if(!(int)$gitlabID or !(int)$projectID or empty($tagName)) return false; + + $apiRoot = $this->getApiRoot($gitlabID); + $url = sprintf($apiRoot, "/projects/{$projectID}/repository/tags/{$tagName}"); + return json_decode(commonModel::http($url, array(), $options = array(CURLOPT_CUSTOMREQUEST => 'DELETE'))); } /** @@ -2460,7 +2508,7 @@ class gitlabModel extends model if(is_array($accessLevels)) { $levels = array(); - foreach($accessLevels as $level) + foreach($accessLevels as $level) { if(is_array($level)) $level = (object)$level; $levels[] = isset($level->access_level) ? (int)$level->access_level : $maintainerAccess; @@ -2470,4 +2518,52 @@ class gitlabModel extends model } return $maintainerAccess; } + + /** + * Get single branch by API. + * + * @param int $gitlabID + * @param int $projectID + * @param string $tag + * @access public + * @return object + */ + public function apiGetSingleTag($gitlabID, $projectID, $tag) + { + if(empty($gitlabID)) return false; + $url = sprintf($this->getApiRoot($gitlabID), "/projects/$projectID/repository/tags/$tag"); + return json_decode(commonModel::http($url)); + } + + /** + * Create gitlab tag. + * + * @param int $gitlabID + * @param int $projectID + * @access public + * @return bool + */ + public function createTag($gitlabID, $projectID) + { + if(empty($gitlabID)) return false; + + $tag = fixer::input('post')->get(); + if(empty($tag->tag_name)) dao::$errors['tag_name'][] = $this->lang->gitlab->tag->emptyNameError; + if(empty($tag->ref)) dao::$errors['ref'][] = $this->lang->gitlab->tag->emptyRefError; + + $singleBranch = $this->apiGetSingleTag($gitlabID, $projectID, $tag->tag_name); + if(!empty($singleBranch->name)) dao::$errors['tag_name'][] = $this->lang->gitlab->tag->issetNameError; + if(dao::isError()) return false; + + $url = sprintf($this->getApiRoot($gitlabID), "/projects/" . $projectID . '/repository/tags'); + $response = json_decode(commonModel::http($url, $tag)); + + if(!empty($response->name)) + { + $this->loadModel('action')->create('gitlabtag', 0, 'created', '', $response->name); + return true; + } + + return $this->apiErrorHandling($response); + } } diff --git a/module/gitlab/view/browseproject.html.php b/module/gitlab/view/browseproject.html.php index ab0bcfadad..6a2e47bdda 100644 --- a/module/gitlab/view/browseproject.html.php +++ b/module/gitlab/view/browseproject.html.php @@ -52,7 +52,7 @@
+ noData;?> + + createLink('gitlab', 'createTag', "gitlabID=$gitlabID&projectID=$projectID"), " " . $lang->gitlab->createTag, '', "class='btn btn-info'");?> + +
+| gitlab->branch->name;?> | -gitlab->branch->name}'");?> | +||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| gitlab->branch->name;?> | -name, "class='form-control chosen' data-placeholder='{$lang->gitlab->branch->placeholderSelect}' " . ($branch ? 'disabled' : ''));?> | +name, "class='form-control chosen' " . ($branch ? 'disabled' : ''));?> | |
|---|---|---|---|
| gitlab->branch->mergeAllowed;?> | diff --git a/module/gitlab/view/createtag.html.php b/module/gitlab/view/createtag.html.php new file mode 100644 index 0000000000..a578bd52cb --- /dev/null +++ b/module/gitlab/view/createtag.html.php @@ -0,0 +1,46 @@ + + * @package gitlab + * @version $Id$ + * @link http://www.zentao.net + */ +?> + +devops->repo;?> | ||
| mr->removeSourceBranch;?> | +
+
+
+
+
+ |
+ ||
| mr->needCI;?> |
diff --git a/module/mr/view/diff.html.php b/module/mr/view/diff.html.php
index a2d835be88..9a5d29464a 100644
--- a/module/mr/view/diff.html.php
+++ b/module/mr/view/diff.html.php
@@ -34,7 +34,7 @@
- id)): ?>
+ synced and (empty($rawMR) or !isset($rawMR->id))): ?>
diff --git a/module/mr/view/edit.html.php b/module/mr/view/edit.html.php index 4489aeb320..deeafe821f 100644 --- a/module/mr/view/edit.html.php +++ b/module/mr/view/edit.html.php @@ -69,6 +69,16 @@ devops->repo;?> |
repoID, "class='form-control chosen'");?> |
|
| mr->removeSourceBranch;?> | +
+
+ removeSourceBranch== '1' ? 'checked' : '' ?>
+ name="removeSourceBranch" value="1" id="removeSourceBranch">
+
+
+ |
+ ||
| mr->needCI;?> |
diff --git a/module/mr/view/view.html.php b/module/mr/view/view.html.php
index 55f984cbaa..4f865583ec 100644
--- a/module/mr/view/view.html.php
+++ b/module/mr/view/view.html.php
@@ -11,7 +11,7 @@
-id)): ?>
+synced and (empty($rawMR) or !isset($rawMR->id))): ?>
@@ -28,7 +28,9 @@
id ?>
title; ?>
+ synced):?>
web_url, $lang->mr->viewInGitlab, "_blank", "class='btn btn-link btn-active-text' style='color: blue'"); ?>
+
- mr->from . html::a($sourceProjectURL, $sourceProjectName . ":" . $MR->sourceBranch, "_blank", "class='btn btn-link btn-active-text' style='color: blue'") . $lang->mr->to . html::a($targetProjectURL, $targetProjectName . ":" . $MR->targetBranch, "_blank", "class='btn btn-link btn-active-text' style='color: blue'"); ?>
+ status == 'merged' and $MR->removeSourceBranch == '1') ? 'disabled' : '';?>
+ mr->from . html::a($sourceProjectURL, $sourceProjectName . ":" . $MR->sourceBranch, "_blank", "class='btn btn-link btn-active-text' style='color: blue' $sourceDisabled") . $lang->mr->to . html::a($targetProjectURL, $targetProjectName . ":" . $MR->targetBranch, "_blank", "class='btn btn-link btn-active-text' style='color: blue'"); ?>
|
| |
| mr->mergeStatus; ?> | - changes_count)):?> + synced and empty($rawMR->changes_count)):?>
mr->cantMerge; ?>
mr->noChanges;?>
@@ -74,7 +77,8 @@
| ||
| mr->MRHasConflicts; ?> | -has_conflicts ? $lang->mr->hasConflicts : $lang->mr->hasNoConflict);?> | + synced === '1' ? $rawMR->has_conflicts : (bool)$MR->hasNoConflict; ?> +mr->hasConflicts : $lang->mr->hasNoConflict);?> | |
| mr->description;?> | @@ -89,17 +93,17 @@ - state == 'opened'): ?> + synced and $rawMR->state == 'opened'): ?>|||