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/db/update16.0.beta1.sql b/db/update16.0.beta1.sql
index 102e159f6b..4146dd9522 100644
--- a/db/update16.0.beta1.sql
+++ b/db/update16.0.beta1.sql
@@ -8,4 +8,10 @@ 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_job` ADD `buildDir` text COLLATE 'utf8_general_ci' NULL AFTER `lastTag`;
+ALTER TABLE `zt_mr` ADD `synced` enum('0','1') COLLATE 'utf8_general_ci' NOT NULL DEFAULT '1';
+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`;
diff --git a/db/zentao.sql b/db/zentao.sql
index 41ec30e1e5..70620b2195 100644
--- a/db/zentao.sql
+++ b/db/zentao.sql
@@ -747,6 +747,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/module/gitlab/control.php b/module/gitlab/control.php
index ed6176c46e..d603e3c9ed 100644
--- a/module/gitlab/control.php
+++ b/module/gitlab/control.php
@@ -945,8 +945,12 @@ class gitlab extends control
$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);
+ $result = $this->gitlab->apiGetTags($gitlabID, $projectID, $orderBy, $keyword, $pager);
foreach($result as $gitlabTag)
{
$tag = new stdClass();
@@ -957,12 +961,6 @@ class gitlab extends control
$tagList[] = $tag;
}
- /* Pager. */
- $this->app->loadClass('pager', $static = true);
- $recTotal = count($tagList);
- $pager = new pager($recTotal, $recPerPage, $pageID);
- $tagList = array_chunk($tagList, $pager->recPerPage);
-
$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;
@@ -970,7 +968,7 @@ class gitlab extends control
$this->view->projectID = $projectID;
$this->view->keyword = $keyword;
$this->view->project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
- $this->view->gitlabTagList = empty($tagList) ? $tagList: $tagList[$pageID - 1];
+ $this->view->gitlabTagList = $tagList;
$this->view->orderBy = $orderBy;
$this->display();
}
diff --git a/module/gitlab/model.php b/module/gitlab/model.php
index 1a63acf70b..0743d6277c 100644
--- a/module/gitlab/model.php
+++ b/module/gitlab/model.php
@@ -1466,10 +1466,11 @@ class gitlabModel extends model
* @param int $projectID
* @param string $orderBy
* @param string $keyword
+ * @param object $pager
* @access public
* @return object
*/
- public function apiGetTags($gitlabID, $projectID, $orderBy = '', $keyword = '')
+ public function apiGetTags($gitlabID, $projectID, $orderBy = '', $keyword = '', $pager = null)
{
$apiRoot = $this->getApiRoot($gitlabID);
@@ -1482,8 +1483,24 @@ class gitlabModel extends model
if($keyword) $apiRoot .= "&search={$keyword}";
- $url = sprintf($apiRoot, "/projects/{$projectID}/repository/tags");
- return json_decode(commonModel::http($url));
+ 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']);
+ }
}
/**
diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php
index fafd69beb0..9fb49c0a5e 100644
--- a/module/group/lang/resource.php
+++ b/module/group/lang/resource.php
@@ -1043,20 +1043,21 @@ $lang->resource->automation->browse = 'browse';
$lang->automation->methodOrder[0] = 'browse';
-$lang->resource->repo = new stdclass();
-$lang->resource->repo->browse = 'browseAction';
-$lang->resource->repo->view = 'view';
-$lang->resource->repo->log = 'log';
-$lang->resource->repo->revision = 'revisionAction';
-$lang->resource->repo->blame = 'blameAction';
-$lang->resource->repo->create = 'createAction';
-$lang->resource->repo->edit = 'editAction';
-$lang->resource->repo->delete = 'delete';
-$lang->resource->repo->showSyncCommit = 'showSyncCommit';
-$lang->resource->repo->diff = 'diffAction';
-$lang->resource->repo->download = 'downloadAction';
-$lang->resource->repo->maintain = 'maintain';
-$lang->resource->repo->setRules = 'setRules';
+$lang->resource->repo = new stdclass();
+$lang->resource->repo->browse = 'browseAction';
+$lang->resource->repo->view = 'view';
+$lang->resource->repo->log = 'log';
+$lang->resource->repo->revision = 'revisionAction';
+$lang->resource->repo->blame = 'blameAction';
+$lang->resource->repo->create = 'createAction';
+$lang->resource->repo->edit = 'editAction';
+$lang->resource->repo->delete = 'delete';
+$lang->resource->repo->showSyncCommit = 'showSyncCommit';
+$lang->resource->repo->diff = 'diffAction';
+$lang->resource->repo->download = 'downloadAction';
+$lang->resource->repo->maintain = 'maintain';
+$lang->resource->repo->setRules = 'setRules';
+$lang->resource->repo->apiGetRepoByUrl = 'apiGetRepoByUrl';
$lang->repo->methodOrder[5] = 'create';
$lang->repo->methodOrder[10] = 'edit';
@@ -1071,6 +1072,7 @@ $lang->repo->methodOrder[50] = 'revision';
$lang->repo->methodOrder[55] = 'blame';
$lang->repo->methodOrder[60] = 'download';
$lang->repo->methodOrder[65] = 'setRules';
+$lang->repo->methodOrder[70] = 'apiGetRepoByUrl';
$lang->resource->ci = new stdclass();
$lang->resource->ci->commitResult = 'commitResult';
diff --git a/module/mr/config.php b/module/mr/config.php
index 15d15a4851..e3c53e3e05 100644
--- a/module/mr/config.php
+++ b/module/mr/config.php
@@ -12,6 +12,9 @@ $config->mr->edit->requiredFields = 'gitlabID,sourceProject,sourceBranch,targetP
$config->mr->editor = new stdclass();
$config->mr->editor->diff = array('id' => 'commentText', 'tools' => 'simpleTools');
+$config->mr->apicreate = new stdclass();
+$config->mr->apicreate->requiredFields = 'repoID,sourceBranch,targetBranch,diffs,mergeStatus,hasNoConflict';
+
$config->mr->maps = new stdclass;
$config->mr->maps->sync = array();
$config->mr->maps->sync['title'] = 'title|field|';
diff --git a/module/mr/control.php b/module/mr/control.php
index e8c2423a20..b62d4e450a 100644
--- a/module/mr/control.php
+++ b/module/mr/control.php
@@ -84,6 +84,21 @@ class mr extends control
$this->display();
}
+ /**
+ * Create MR function by api.
+ *
+ * @access public
+ * @return void
+ */
+ public function apiCreate()
+ {
+ if($_POST)
+ {
+ $result = $this->mr->apiCreate();
+ return $this->send($result);
+ }
+ }
+
/**
* Edit MR function.
*
diff --git a/module/mr/model.php b/module/mr/model.php
index d934f051b7..c27f908279 100644
--- a/module/mr/model.php
+++ b/module/mr/model.php
@@ -178,6 +178,71 @@ class mrModel extends model
return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => helper::createLink('mr', 'browse'));
}
+ /**
+ * Create MR function by api.
+ *
+ * @access public
+ * @return int|bool|object
+ */
+ public function apiCreate()
+ {
+ $postData = fixer::input('post')
+ ->setDefault('url,sourceBranch,targetBranch,diff,mergeStatus,hasNoConflict', '')
+ ->get();
+
+ $repo = $this->loadModel('repo')->getRepoByUrl($postData->url);
+ if(!$repo || $repo->result != 'fail') return false;
+ $repo = (object)$repo->data;
+
+ /* Process and insert mr data. */
+ $MR = new stdClass();
+ $MR->gitlabID = $repo->client;
+ $MR->sourceProject = $repo->path;
+ $MR->sourceBranch = $postData->sourceBranch;
+ $MR->targetProject = $repo->path;
+ $MR->targetBranch = $postData->taretBranch;
+ $MR->diffs = $postData->diff;
+ $MR->title = 'Merge request';
+ $MR->repoID = $repo->id;
+ $MR->jobID = $postData->jobID;
+ $MR->synced = '0';
+ $MR->needCI = '1';
+ $MR->approvalStatus = 'approved';
+ $MR->hasNoConflict = $postData->hasNoConflict ? '1' : '0';
+ $MR->mergeStatus = $postData->mergeStatus ? 'can_be_merged' : 'cannot_be_merged';
+ $MR->createdBy = $this->app->user->account;
+ $MR->createdDate = date('Y-m-d H:i:s');
+
+ $this->dao->insert(TABLE_MR)->data($MR, $this->config->mr->create->skippedFields)
+ ->batchCheck($this->config->mr->apicreate->requiredFields, 'notempty')
+ ->checkIF($MR->needCI, 'jobID', 'notempty')
+ ->autoCheck()
+ ->exec();
+ if(dao::isError()) return false;
+
+ /* Exec Job */
+ if($MR->hasNoConflict == '1' && $MR->mergeStatus == 'can_be_merged' && $MR->jobID)
+ {
+ $MRID = $this->dao->lastInsertId();
+ $pipeline = $this->loadModel('job')->exec($MR->jobID);
+ if(!empty($pipeline->queue))
+ {
+ $newMR = new stdClass();
+ $compile = $this->loadModel('compile')->getByQueue($pipeline->queue);
+ $newMR->compileID = $compile->id;
+ $newMR->compileStatus = $compile->status;
+
+ /* Update MR in Zentao database. */
+ $this->dao->update(TABLE_MR)->data($newMR)
+ ->where('id')->eq($MRID)
+ ->autoCheck()
+ ->exec();
+ if(dao::isError()) return false;
+ }
+ }
+ return true;
+ }
+
/**
* Edit MR function.
*
diff --git a/module/mr/view/view.html.php b/module/mr/view/view.html.php
index 55f984cbaa..55bf2c2f1c 100644
--- a/module/mr/view/view.html.php
+++ b/module/mr/view/view.html.php
@@ -74,7 +74,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;?> |
@@ -96,10 +97,10 @@
- approvalStatus != 'approved' or ($MR->compileID !=0 and $MR->compileStatus != 'success')) ? ' disabled' : ''; ?>
+ approvalStatus != 'approved' or ($MR->compileID != 0 and $MR->compileStatus != 'success')) ? ' disabled' : ''; ?>
state == 'opened' and !$rawMR->has_conflicts) common::printIcon('mr', 'accept', "mr=$MR->id", $MR, 'button', 'flow', 'hiddenwin', 'mergeButton btn', false, $acceptDisabled, $lang->mr->acceptMR);?>
state == 'opened'): ?>
- has_conflicts or ($MR->compileID !=0 and $MR->compileStatus != 'success') or $MR->approvalStatus == 'approved'):?>
+ has_conflicts or ($MR->compileID != 0 and $MR->compileStatus != 'success') or $MR->approvalStatus == 'approved'):?>
id&action=approve", $MR, 'button', 'ok', 'hiddenwin', 'mergeButton', true, 'disabled', $lang->mr->approve);?>
id&action=approve", $MR, 'button', 'ok', 'hiddenwin', 'mergeButton btn iframe showinonlybody', true, '', $lang->mr->approve);?>
diff --git a/module/repo/control.php b/module/repo/control.php
index f021d47d62..7875d8b64a 100644
--- a/module/repo/control.php
+++ b/module/repo/control.php
@@ -1177,4 +1177,24 @@ class repo extends control
echo html::select('product', array('') + $productPairs, key($productPairs), "class='form-control chosen'");
}
+ /**
+ * API: get repo by url.
+ *
+ * @param string $type gitlab
+ * @access public
+ * @return void
+ */
+ public function apiGetRepoByUrl()
+ {
+ $url = urldecode($this->post->repoUrl);
+ $result = $this->repo->getRepoByUrl($url);
+ if($result['result'] == 'fail') return $this->send($result);
+
+ $repo = $result['data'];
+ $fileServer = new stdclass();
+ $fileServer->fileServerUrl = $repo->fileServerUrl;
+ $fileServer->fileServerAccount = $repo->fileServerAccount;
+ $fileServer->fileServerPassword = $repo->fileServerPassword;
+ return $this->send($fileServer);
+ }
}
diff --git a/module/repo/lang/en.php b/module/repo/lang/en.php
index e5fa02bbc2..75d213ae5e 100644
--- a/module/repo/lang/en.php
+++ b/module/repo/lang/en.php
@@ -24,6 +24,7 @@ $lang->repo->repo = 'Repository';
$lang->repo->parent = 'Parent File';
$lang->repo->branch = 'Branch';
$lang->repo->addWebHook = 'Add Webhook';
+$lang->repo->apiGetRepoByUrl = 'API: Get repo by URL';
$lang->repo->browseAction = 'Browse Repo';
$lang->repo->createAction = 'Create Repo';
diff --git a/module/repo/lang/zh-cn.php b/module/repo/lang/zh-cn.php
index 5283beb6f4..301470e473 100644
--- a/module/repo/lang/zh-cn.php
+++ b/module/repo/lang/zh-cn.php
@@ -24,6 +24,7 @@ $lang->repo->repo = '代码库';
$lang->repo->parent = '父文件夹';
$lang->repo->branch = '分支';
$lang->repo->addWebHook = '添加Webhook';
+$lang->repo->apiGetRepoByUrl = '接口:通过URL获取版本库';
$lang->repo->browseAction = '浏览版本库';
$lang->repo->createAction = '创建版本库';
diff --git a/module/repo/model.php b/module/repo/model.php
index a69ce07eab..df9beb7264 100644
--- a/module/repo/model.php
+++ b/module/repo/model.php
@@ -396,6 +396,76 @@ class repoModel extends model
return $repo;
}
+ /**
+ * Get repo by url.
+ *
+ * @param string $url
+ * @access public
+ * @return array
+ */
+ public function getRepoByUrl($url)
+ {
+ if(empty($url)) return array('result' => 'fail', 'message' => 'Url is empty.');
+
+ $parsedUrl = parse_url($url);
+
+ $isSSH = $parsedUrl['scheme'] == 'ssh';
+ $baseURL = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . (isset($parsedUrl['port']) ? ":{$parsedUrl['port']}" : '');
+
+ /* Get gitlabs by URL. */
+ $gitlabs = $this->dao->select('*')->from(TABLE_PIPELINE)->where('type')->eq('gitlab')
+ ->beginIF($isSSH)->andWhere('url')->like("%{$parsedUrl['host']}%")->fi()
+ ->beginIF(!$isSSH)->andWhere('url')->eq($baseURL)->fi()
+ ->orderBy('id_desc')
+ ->fetchAll('id');
+
+ /* Convert to id by url. */
+ $this->loadModel('gitlab');
+ $matched = new stdclass();
+ $matched->gitlab = 0;
+ $matched->project = 0;
+ foreach($gitlabs as $gitlabID => $gitlab)
+ {
+ $projects = $this->gitlab->apiGetProjects($gitlabID);
+ foreach($projects as $project)
+ {
+ if((!$isSSH and $project->http_url_to_repo == $url) or ($isSSH and $project->ssh_url_to_repo == $url))
+ {
+ $matched->gitlab = $gitlabID;
+ $matched->project = $project->id;
+ break;
+ }
+ }
+ }
+ if(empty($matched->gitlab) or empty($matched->project)) return array('result' => 'fail', 'message' => 'No matched gitlab.');
+
+ $matchedRepos = $this->dao->select('*')->from(TABLE_REPO)->where('SCM')->eq('Gitlab')
+ ->andWhere('client')->eq($matched->gitlab)
+ ->andWhere('path')->eq($matched->project)
+ ->andWhere('deleted')->eq('0')
+ ->orderBy('id_desc')
+ ->fetchAll();
+ if(empty($matchedRepos)) return array('result' => 'fail', 'message' => 'No matched gitlab.');
+
+ $matchedRepo = '';
+ foreach($matchedRepos as $repo)
+ {
+ if(!empty($repo->preMerge))
+ {
+ $matchedRepo = $repo;
+ break;
+ }
+ }
+ if(empty($matchedRepo)) return array('result' => 'fail', 'message' => 'Matched gitlab is not open pre merge.');
+ if(empty($matchedRepo->job)) return array('result' => 'fail', 'message' => 'No linked job.');
+
+ $job = $this->dao->select('*')->from(TABLE_JOB)->where('id')->eq($matchedRepo->job)->andWhere('deleted')->eq(0)->fetch();
+ if(empty($job)) return array('result' => 'fail', 'message' => 'Linked job is not exists.');
+
+ $matchedRepo->job = $job;
+ return array('result' => 'success', 'data' => $matchedRepo);
+ }
+
/**
* Get by id list.
*