diff --git a/module/gitea/control.php b/module/gitea/control.php index 56f80776f0..be079cb338 100644 --- a/module/gitea/control.php +++ b/module/gitea/control.php @@ -197,4 +197,25 @@ class gitea extends control $this->view->matchedResult = $this->gitea->getMatchedUsers($giteaID, $this->view->giteaUsers, $zentaoUsers); $this->display(); } + + /** + * Ajax getProjectBranches + * + * @param int $giteaID + * @param string $project + * @access public + * @return void + */ + public function ajaxGetProjectBranches($giteaID, $project) + { + if(!$giteaID or !$project) return $this->send(array('message' => array())); + + $branches = $this->gitea->apiGetBranches($giteaID, $project); + $options = ""; + foreach($branches as $branch) + { + $options .= ""; + } + $this->send($options); + } } diff --git a/module/gitea/model.php b/module/gitea/model.php index 86cba73100..1dcc9d97c5 100644 --- a/module/gitea/model.php +++ b/module/gitea/model.php @@ -454,4 +454,56 @@ class giteaModel extends model return $users; } + + /** + * Get project repository branches by api. + * + * @param int $giteaID + * @param string $project + * @access public + * @return object + */ + public function apiGetBranches($giteaID, $project, $pager = null) + { + $url = sprintf($this->getApiRoot($giteaID), "/repos/{$project}/branches"); + $allResults = array(); + for($page = 1; true; $page++) + { + $results = json_decode(commonModel::http($url . "&page={$page}&limit=50")); + if(!is_array($results)) break; + if(!empty($results)) $allResults = array_merge($allResults, $results); + if(count($results) < 100) break; + } + + return $allResults; + } + + /** + * Get Forks of a project by API. + * + * @param int $giteaID + * @param string $projectID + * @access public + * @return object + */ + public function apiGetForks($giteaID, $projectID) + { + $url = sprintf($this->getApiRoot($giteaID), "/repos/$projectID/forks"); + return json_decode(commonModel::http($url)); + } + + /** + * Get upstream project by API. + * + * @param int $giteaID + * @param string $projectID + * @access public + * @return void + */ + public function apiGetUpstream($giteaID, $projectID) + { + $currentProject = $this->apiGetSingleProject($giteaID, $projectID); + if(isset($currentProject->parent->full_name)) return $currentProject->parent->full_name; + return array(); + } } diff --git a/module/gitlab/control.php b/module/gitlab/control.php index cc5ac6877a..6cd8195de4 100644 --- a/module/gitlab/control.php +++ b/module/gitlab/control.php @@ -720,7 +720,7 @@ class gitlab extends control } $gitlab = $this->gitlab->getByID($gitlabID); - $repos = $this->loadModel('repo')->getGitLabRepoList($gitlabID); + $repos = $this->loadModel('repo')->getRepoListByClient($gitlabID); $repoPairs = array(); foreach($repos as $repo) $repoPairs[$repo->path] = $repo->id; diff --git a/module/mr/control.php b/module/mr/control.php index c5b097ba52..757db431c9 100644 --- a/module/mr/control.php +++ b/module/mr/control.php @@ -34,7 +34,7 @@ class mr extends control $this->app->loadClass('pager', $static = true); $pager = new pager($recTotal, $recPerPage, $pageID); - $repos = $this->loadModel('repo')->getListBySCM('Gitlab'); + $repos = $this->loadModel('repo')->getListBySCM(array('Gitlab', 'Gitea')); if(empty($repos)) $this->locate($this->repo->createLink('create')); $repoID = $this->repo->saveState($repoID, $objectID); @@ -42,7 +42,7 @@ class mr extends control if(!in_array(strtolower($repo->SCM), $this->config->mr->gitServiceList)) $repo = $repos[0]; $this->loadModel('ci')->setMenu($repo->id); - $projects = $this->mr->getAllGitlabProjects($repoID); + $projects = $this->mr->getAllProjects($repoID, $repo->SCM); $MRList = $this->mr->getList($mode, $param, $orderBy, $pager, empty($projects) ? false : $projects, $repoID); /* Save current URI to session. */ @@ -52,7 +52,6 @@ class mr extends control $MRList = $this->mr->batchSyncMR($MRList); /* Check whether Mr is linked with the product. */ - $this->loadModel('gitlab'); foreach($MRList as $MR) { $product = $this->mr->getMRProduct($MR); @@ -95,19 +94,30 @@ class mr extends control return $this->send($result); } - $gitlabHosts = $this->loadModel('gitlab')->getPairs(); - $gitlabUsers = $this->gitlab->getGitLabListByAccount(); - foreach($gitlabHosts as $gitlabID=> $gitlabHost) + $hosts = $this->loadModel('pipeline')->getList(array('gitea', 'gitlab')); + if(!$this->app->user->admin) { - if(!$this->app->user->admin and !isset($gitlabUsers[$gitlabID])) unset($gitlabHosts[$gitlabID]); + $gitlabUsers = $this->loadModel('gitlab')->getGitLabListByAccount(); + $giteaUsers = $this->loadModel('gitea')->getGiteaListByAccount(); + foreach($hosts as $hostID => $host) + { + if($host->type == 'gitLab' and isset($gitlabUsers[$hostID])) continue; + if($host->type == 'gitea' and isset($giteaUsers[$hostID])) continue; + + unset($hosts[$hostID]); + } } + $hostPairs = array(); + foreach($hosts as $host) $hostPairs[$host->id] = '[' . ucfirst($host->type) . "] {$host->name}"; + $this->app->loadLang('repo'); /* Import lang in repo module. */ $this->app->loadLang('compile'); - $this->view->title = $this->lang->mr->create; - $this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed'); - $this->view->jobList = $this->loadModel('job')->getList(); - $this->view->gitlabHosts = $gitlabHosts; + $this->view->title = $this->lang->mr->create; + $this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed'); + $this->view->jobList = $this->loadModel('job')->getList(); + $this->view->hostPairs = $hostPairs; + $this->view->hosts = $hosts; $this->display(); } @@ -166,7 +176,7 @@ class mr extends control $this->loadModel('compile'); $repoList = array(); - $rawRepoList = $this->repo->getGitLabRepoList($MR->hostID, $MR->sourceProject); + $rawRepoList = $this->repo->getRepoListByClient($MR->hostID, $MR->sourceProject); foreach($rawRepoList as $rawRepo) $repoList[$rawRepo->id] = "[$rawRepo->id] $rawRepo->name"; $jobList = array(); @@ -207,9 +217,9 @@ class mr extends control $res = $this->mr->apiDeleteMR($MR->hostID, $MR->targetProject, $MR->mriid); if(isset($res->message)) return print(js::alert($this->mr->convertApiError($res->message))); } - $this->dao->delete()->from(TABLE_MR)->where('id')->eq($id)->exec(); + //$this->dao->delete()->from(TABLE_MR)->where('id')->eq($id)->exec(); - echo js::locate(inlink('browse'), 'parent'); + echo js::reload('parent'); } /** @@ -889,41 +899,50 @@ class mr extends control * @access public * @return void */ - public function ajaxGetMRTargetProjects($hostID, $projectID) + public function ajaxGetMRTargetProjects($hostID, $projectID, $scm = 'gitlab') { - $this->loadModel('gitlab'); + $this->loadModel($scm); /* First step: get forks. Only get first level forks(not recursively). */ - $projects = $this->gitlab->apiGetForks($hostID, $projectID); + $projects = $this->$scm->apiGetForks($hostID, $projectID); /* Second step: get project itself. */ - $projects[] = $this->gitlab->apiGetSingleProject($hostID, $projectID); + $projects[] = $this->$scm->apiGetSingleProject($hostID, $projectID); /* Last step: find its upstream recursively. */ - $project = $this->gitlab->apiGetUpstream($hostID, $projectID); + $project = $this->$scm->apiGetUpstream($hostID, $projectID); if(!empty($project)) $projects[] = $project; - while(!empty($project) and isset($project->id)) + if(!empty($project) and isset($project->id)) { - $project = $this->gitlab->apiGetUpstream($hostID, $project->id); - if(empty($project)) break; - $projects[] = $project; + $project = $this->$scm->apiGetUpstream($hostID, $project->id); + if(!empty($project)) $projects[] = $project; } - $groupIDList = array(0 => 0); - $groups = $this->gitlab->apiGetGroups($hostID, 'name_asc', 'developer'); - foreach($groups as $group) $groupIDList[] = $group->id; - foreach($projects as $key => $project) + if($scm == 'gitlab') { - if($this->gitlab->checkUserAccess($hostID, 0, $project, $groupIDList, 'developer') == false) unset($projects[$key]); - } + $groupIDList = array(0 => 0); + $groups = $this->$scm->apiGetGroups($hostID, 'name_asc', 'developer'); + foreach($groups as $group) $groupIDList[] = $group->id; + foreach($projects as $key => $project) + { + if($this->$scm->checkUserAccess($hostID, 0, $project, $groupIDList, 'developer') == false) unset($projects[$key]); + } - if(!$projects) return $this->send(array('message' => array())); + if(!$projects) return $this->send(array('message' => array())); + } $options = ""; foreach($projects as $project) { - $options .= ""; + if($scm == 'gitlab') + { + $options .= ""; + } + else + { + $options .= ""; + } } $this->send($options); @@ -939,7 +958,7 @@ class mr extends control public function ajaxGetRepoList($hostID, $projectID) { $this->loadModel('repo'); - $repoList = $this->repo->getGitLabRepoList($hostID, $projectID); + $repoList = $this->repo->getRepoListByClient($hostID, $projectID); if(!$repoList) return $this->send(array('message' => array())); $options = ""; diff --git a/module/mr/js/create.js b/module/mr/js/create.js index 85adcbe3ce..584caad186 100644 --- a/module/mr/js/create.js +++ b/module/mr/js/create.js @@ -5,7 +5,14 @@ $(function() var hostID = $('#hostID').val(); if(hostID == '') return false; - var url = createLink('repo', 'ajaxgetgitlabprojects', "hostID=" + hostID + "&projectIdList=&filter=IS_DEVELOPER"); + if(hosts[hostID].type == 'gitlab') + { + var url = createLink('repo', 'ajaxGetGitlabProjects', "gitlabID=" + hostID + "&projectIdList=&filter=IS_DEVELOPER"); + } + else + { + var url = createLink('repo', 'ajaxGetGiteaProjects', "giteaID=" + hostID); + } $.get(url, function(response) { $('#sourceProject').html('').append(response); @@ -18,7 +25,7 @@ $(function() var hostID = $('#hostID').val(); var sourceProject = $(this).val(); var branchSelect = $(this).parents('td').find('select[name*=Branch]'); - var branchUrl = createLink('gitlab', 'ajaxgetprojectbranches', "hostID=" + hostID + "&projectID=" + sourceProject); + var branchUrl = createLink(hosts[hostID].type, 'ajaxGetProjectBranches', "hostID=" + hostID + "&projectID=" + sourceProject); $.get(branchUrl, function(response) { branchSelect.html('').append(response); @@ -31,7 +38,7 @@ $(function() { var hostID = $('#hostID').val(); var sourceProject = $(this).val(); - var projectUrl = createLink('mr', 'ajaxGetMRTargetProjects', "hostID=" + hostID + "&projectID=" + sourceProject); + var projectUrl = createLink('mr', 'ajaxGetMRTargetProjects', "hostID=" + hostID + "&projectID=" + sourceProject + "&scm=" + hosts[hostID].type); $.get(projectUrl, function(response) { $('#targetProject').html('').append(response); diff --git a/module/mr/lang/de.php b/module/mr/lang/de.php index 46ed175893..737cebfa40 100644 --- a/module/mr/lang/de.php +++ b/module/mr/lang/de.php @@ -1,6 +1,7 @@ mr = new stdclass; $lang->mr->common = "Merge Request"; +$lang->mr->server = "Server"; $lang->mr->view = "Survey"; $lang->mr->create = "Create"; $lang->mr->apiCreate = "Interface: Create"; diff --git a/module/mr/lang/en.php b/module/mr/lang/en.php index 2b9f8e9ebc..19e369019c 100644 --- a/module/mr/lang/en.php +++ b/module/mr/lang/en.php @@ -1,6 +1,7 @@ mr = new stdclass; $lang->mr->common = "Merge Request"; +$lang->mr->server = "Server"; $lang->mr->view = "Survey"; $lang->mr->create = "Create"; $lang->mr->apiCreate = "Interface: Create"; @@ -116,11 +117,15 @@ $lang->mr->apiErrorMap[1] = "You can't use same project/branch for source and ta $lang->mr->apiErrorMap[2] = "/Another open merge request already exists for this source branch: !([0-9]+)/"; $lang->mr->apiErrorMap[3] = "401 Unauthorized"; $lang->mr->apiErrorMap[4] = "403 Forbidden"; +$lang->mr->apiErrorMap[5] = "/(pull request already exists for these targets).*/"; +$lang->mr->apiErrorMap[6] = "Invalid PullRequest: There are no changes between the head and the base"; $lang->mr->errorLang[1] = 'The source project branch cannot be the same as the target project branch'; $lang->mr->errorLang[2] = 'Another open merge request already exists for this source branch: ID%u'; $lang->mr->errorLang[3] = "Unauthorized"; $lang->mr->errorLang[4] = 'Permission denied'; +$lang->mr->errorLang[5] = 'Another open merge request already exists for this source branch'; +$lang->mr->errorLang[6] = 'The source project branch cannot be the same as the target project branch'; $lang->mr->from = "from"; $lang->mr->to = "to"; diff --git a/module/mr/lang/fr.php b/module/mr/lang/fr.php index 46ed175893..737cebfa40 100644 --- a/module/mr/lang/fr.php +++ b/module/mr/lang/fr.php @@ -1,6 +1,7 @@ mr = new stdclass; $lang->mr->common = "Merge Request"; +$lang->mr->server = "Server"; $lang->mr->view = "Survey"; $lang->mr->create = "Create"; $lang->mr->apiCreate = "Interface: Create"; diff --git a/module/mr/lang/vi.php b/module/mr/lang/vi.php new file mode 100644 index 0000000000..2229b85679 --- /dev/null +++ b/module/mr/lang/vi.php @@ -0,0 +1,194 @@ +mr = new stdclass; +$lang->mr->common = "Merge Request"; +$lang->mr->server = "Server"; +$lang->mr->view = "Survey"; +$lang->mr->create = "Create"; +$lang->mr->apiCreate = "Interface: Create"; +$lang->mr->browse = "Browse"; +$lang->mr->list = "List"; +$lang->mr->edit = "Edit"; +$lang->mr->delete = "Delete"; +$lang->mr->accept = "Accept"; +$lang->mr->source = 'source'; +$lang->mr->target = 'target'; +$lang->mr->viewDiff = 'View diff'; +$lang->mr->diff = 'View diff'; +$lang->mr->viewInGitlab = 'View in GitLab'; +$lang->mr->link = 'Link of stories,Bugs,tasks'; +$lang->mr->createAction = '%s, %s submitted a Merge Request.'; + +$lang->mr->linkList = 'Link List of stories,Bugs,tasks'; +$lang->mr->linkStory = 'Link Stories'; +$lang->mr->linkBug = 'Link Bugs'; +$lang->mr->linkTask = 'Link Tasks'; +$lang->mr->unlink = 'UnLink of stories,Bugs,tasks'; +$lang->mr->addReview = 'Add Review'; + +$lang->mr->id = 'ID'; +$lang->mr->mriid = "raw MR ID"; +$lang->mr->title = 'Name'; +$lang->mr->status = 'Status'; +$lang->mr->author = 'Author'; +$lang->mr->assignee = 'Assignee'; +$lang->mr->reviewer = 'Reviewer'; +$lang->mr->mergeStatus = 'Merge status'; +$lang->mr->commits = 'commits'; +$lang->mr->changes = 'changes'; +$lang->mr->gitlabID = 'GitLab'; +$lang->mr->repoID = 'Repo'; +$lang->mr->jobID = 'Compile job'; + +$lang->mr->canMerge = "Can merge"; +$lang->mr->cantMerge = "不可合并"; + +$lang->mr->approval = 'Approval'; +$lang->mr->approve = 'Approve'; +$lang->mr->reject = 'Reject'; +$lang->mr->close = 'Close'; +$lang->mr->reopen = 'Reopen'; + +$lang->mr->reviewType = 'Review Type'; +$lang->mr->reviewTypeList = array(); +$lang->mr->reviewTypeList['bug'] = 'Bug'; +$lang->mr->reviewTypeList['task'] = 'Task'; + +$lang->mr->approvalResult = 'Approval result'; +$lang->mr->approvalResultList = array(); +$lang->mr->approvalResultList['approve'] = 'Approve'; +$lang->mr->approvalResultList['reject'] = 'Reject'; + +$lang->mr->needApproved = 'This MR should be approved before merge'; +$lang->mr->needCI = 'Merge only after passing CI'; +$lang->mr->removeSourceBranch = 'Delete source branch after merge'; +$lang->mr->squash = 'Squash commits'; + +$lang->mr->repeatedOperation = 'Do not repeat operations'; + +$lang->mr->approvalStatus = 'Approve status'; +$lang->mr->approvalStatusList = array(); +$lang->mr->approvalStatusList['notReviewed'] = 'notReviewed'; +$lang->mr->approvalStatusList['approved'] = 'Approved'; +$lang->mr->approvalStatusList['rejected'] = 'Rejected'; + +$lang->mr->notApproved = 'Rejected'; +$lang->mr->assignedToMe = 'AssignedToMe'; +$lang->mr->createdByMe = 'CreatedByMe'; + +$lang->mr->statusList = array(); +$lang->mr->statusList['all'] = 'all'; +$lang->mr->statusList['opened'] = 'opened'; +$lang->mr->statusList['merged'] = 'merged'; +$lang->mr->statusList['closed'] = 'closed'; + +$lang->mr->mergeStatusList = array(); +$lang->mr->mergeStatusList['unchecked'] = 'unchecked'; +$lang->mr->mergeStatusList['checking'] = 'checking'; +$lang->mr->mergeStatusList['can_be_merged'] = 'can be merged'; +$lang->mr->mergeStatusList['cannot_be_merged'] = 'cannot be merged'; +$lang->mr->mergeStatusList['cannot_merge_by_fail'] = 'Cannot be merged, check failed'; + +$lang->mr->description = 'Description'; +$lang->mr->confirmDelete = 'Are you sure to delete this merge request?'; +$lang->mr->sourceProject = 'Source project'; +$lang->mr->sourceBranch = 'Source branch'; +$lang->mr->targetProject = 'Target project'; +$lang->mr->targetBranch = 'Target branch'; +$lang->mr->noCompileJob = 'No Compile Job'; +$lang->mr->compileUnexecuted = 'Compile Unexecuted'; + +$lang->mr->notFound = "Merge Request does not exist!"; +$lang->mr->toCreatedMessage = "The merge request you submitted:%s, the build task succeeded."; +$lang->mr->toReviewerMessage = "You have one merge request %s waiting."; +$lang->mr->failMessage = "Your merge request %s failed. Please check its execution result. "; +$lang->mr->storySummary = "Total %s {$lang->SRCommon} on this page."; + +$lang->mr->apiError = new stdclass; +$lang->mr->apiError->createMR = "Failed to create a merge request through API. Reason: %s"; +$lang->mr->apiError->sudo = "Unable to operate with the GitLab account bound to the current user. Reason: %s"; + +$lang->mr->createFailedFromAPI = "Failed to create Merge Request."; +$lang->mr->hasSameOpenedMR = "There are duplicate and unclosed merge requests: ID%u"; +$lang->mr->accessGitlabFailed = "Unable to connect to the GitLab server."; +$lang->mr->reopenSuccess = "The merge request was reopened."; +$lang->mr->closeSuccess = "Merge request closed."; + +$lang->mr->apiErrorMap[1] = "You can't use same project/branch for source and target"; +$lang->mr->apiErrorMap[2] = "/Another open merge request already exists for this source branch: !([0-9]+)/"; +$lang->mr->apiErrorMap[3] = "401 Unauthorized"; +$lang->mr->apiErrorMap[4] = "403 Forbidden"; + +$lang->mr->errorLang[1] = 'The source project branch cannot be the same as the target project branch'; +$lang->mr->errorLang[2] = 'Another open merge request already exists for this source branch: ID%u'; +$lang->mr->errorLang[3] = "Unauthorized"; +$lang->mr->errorLang[4] = 'Permission denied'; + +$lang->mr->from = "from"; +$lang->mr->to = "to"; +$lang->mr->at = "at"; + +$lang->mr->pipeline = "Pipeline"; +$lang->mr->pipelineSuccess = "Success"; +$lang->mr->pipelineFailed = "Failed"; +$lang->mr->pipelineCanceled = "Canceled"; +$lang->mr->pipelineUnknown = "Unknown"; + +$lang->mr->pipelineStatus = array(); +$lang->mr->pipelineStatus['success'] = "success"; +$lang->mr->pipelineStatus['failed'] = "failed"; +$lang->mr->pipelineStatus['canceled'] = "canceled"; + +$lang->mr->MRHasConflicts = "Merge Request has a conflict"; +$lang->mr->hasConflicts = "There are merge conflicts or wait for push"; +$lang->mr->hasNoConflict = "Can merge"; +$lang->mr->acceptMR = "Accept Merge request "; +$lang->mr->mergeFailed = "Unable to merge request, please check the merge request status"; +$lang->mr->mergeSuccess = "Merge Request Successfully"; + +$lang->mr->todomessage = "project was assigned to you"; + +/** + * Merge Command Document. + * + * %s source_project::http_url_to_repo + * %s mr::source_branch + * %s source_project::path_with_namespace . '-' . mr::source_branch + * %s mr::target_branch + * %s source_project::path_with_namespace . '-' . mr::source_branch + * %s mr::target_branch + */ +$lang->mr->commandDocument = <<< EOD +
Note: This merge request status will be changed automatically after you merged locally.+
+ step 1. Change directory to target project. Fetch and check out the branch for this merge request +
+ git fetch "%s" %s + git checkout -b "%s" FETCH_HEAD+ +
+ step 2. Review the changes locally. You can use git log to view the changes
+
+ step 3. Merge the branch and fix any conflicts that come up +
+ git fetch origin + git checkout "%s" + git merge --no-ff "%s"+ +
+ step 4. Push the result of the merge to GitLab +
git push origin "%s"+ +