diff --git a/module/gitlab/config.php b/module/gitlab/config.php index bc042904bb..8a97ecd2bd 100644 --- a/module/gitlab/config.php +++ b/module/gitlab/config.php @@ -5,7 +5,10 @@ $config->gitlab->create->requiredFields = 'name,url,token'; $config->gitlab->edit = new stdclass(); $config->gitlab->edit->requiredFields = 'name,url,token'; -$config->gitlab->zentaoLabel = 'Zentao'; +$config->gitlab->labelPattern = new stdclass; +$config->gitlab->labelPattern->task = '/^zentao_task\/\d+$/'; +$config->gitlab->labelPattern->bug = '/^zentao_bug\/\d+$/'; +$config->gitlab->labelPattern->story = '/^zentao_story\/\d+$/'; $config->gitlab->actions = array(); $config->gitlab->actions['issue'] = array(); @@ -43,7 +46,7 @@ $config->gitlab->maps->task['openedDate'] = 'created_at|field|'; $config->gitlab->maps->task['assignedTo'] = 'assignee_id|userPairs|'; $config->gitlab->maps->task['lastEditedDate'] = 'updated_at|field|'; $config->gitlab->maps->task['deadline'] = 'due_date|field|'; -$config->gitlab->maps->task['status'] = 'state_event|configItems|taskStateMap'; +$config->gitlab->maps->task['status'] = 'state|configItems|taskStateMap'; $config->gitlab->maps->task['pri'] = 'weight|configItems|taskWeightMap'; $config->gitlab->taskWeightMap = array(); diff --git a/module/gitlab/control.php b/module/gitlab/control.php index e61210e52a..b559ae27fa 100644 --- a/module/gitlab/control.php +++ b/module/gitlab/control.php @@ -211,22 +211,10 @@ class gitlab extends control $gitlab = $this->get->gitlab; $project = $this->get->project; - $json = '{"object_kind":"note","event_type":"note","user":{"id":1,"name":"Administrator","username":"root","avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon","email":"admin@example.com"},"project_id":36,"project":{"id":36,"name":"zenops202106dgd","description":"repo for dingguodong dev env","web_url":"http://192.168.1.161:51080/root/zenops202106dgd","avatar_url":null,"git_ssh_url":"ssh://git@192.168.1.161:51022/root/zenops202106dgd.git","git_http_url":"http://192.168.1.161:51080/root/zenops202106dgd.git","namespace":"Administrator","visibility_level":0,"path_with_namespace":"root/zenops202106dgd","default_branch":"master","ci_config_path":null,"homepage":"http://192.168.1.161:51080/root/zenops202106dgd","url":"ssh://git@192.168.1.161:51022/root/zenops202106dgd.git","ssh_url":"ssh://git@192.168.1.161:51022/root/zenops202106dgd.git","http_url":"http://192.168.1.161:51080/root/zenops202106dgd.git"},"object_attributes":{"attachment":null,"author_id":1,"change_position":null,"commit_id":null,"created_at":"2021-06-22 03:04:00 UTC","discussion_id":"1e66ea56b811ac13502252c62e1d22a6ddcf4340","id":705,"line_code":null,"note":"124ds q ew 1234 142dsf ssdfgsdg","noteable_id":32,"noteable_type":"Issue","original_position":null,"position":null,"project_id":36,"resolved_at":null,"resolved_by_id":null,"resolved_by_push":null,"st_diff":null,"system":false,"type":null,"updated_at":"2021-06-22 03:04:00 UTC","updated_by_id":null,"description":"124ds q ew 1234 142dsf ssdfgsdg","url":"http://192.168.1.161:51080/root/zenops202106dgd/-/issues/2#note_705"},"repository":{"name":"zenops202106dgd","url":"ssh://git@192.168.1.161:51022/root/zenops202106dgd.git","description":"repo for dingguodong dev env","homepage":"http://192.168.1.161:51080/root/zenops202106dgd"},"issue":{"author_id":1,"closed_at":null,"confidential":false,"created_at":"2021-06-16 10:52:00 UTC","description":"the issue description","discussion_locked":null,"due_date":null,"id":32,"iid":2,"last_edited_at":null,"last_edited_by_id":null,"milestone_id":null,"moved_to_id":null,"duplicated_to_id":null,"project_id":36,"relative_position":1026,"state_id":1,"time_estimate":0,"title":"test issue","updated_at":"2021-06-22 03:04:00 UTC","updated_by_id":1,"url":"http://192.168.1.161:51080/root/zenops202106dgd/-/issues/2","total_time_spent":0,"human_total_time_spent":null,"human_time_estimate":null,"assignee_ids":[],"assignee_id":null,"labels":[{"id":38,"title":"zentao task","color":"#0033CC","project_id":36,"created_at":"2021-06-16 12:04:23 UTC","updated_at":"2021-06-16 12:04:23 UTC","template":false,"description":"task label from zentao","type":"ProjectLabel","group_id":null},{"id":40,"title":"zentao task : 121","color":"#428BCA","project_id":36,"created_at":"2021-06-21 08:58:17 UTC","updated_at":"2021-06-21 08:58:17 UTC","template":false,"description":"121","type":"ProjectLabel","group_id":null}],"state":"opened"}}'; - //$json = file_get_contents('php://input'); - $requestBody = json_decode($json); - $request = $this->gitlab->webhookParseBody($requestBody); - - exit; - - switch($request->type) - { - case 'issue_create': - $this->createTaskFromIssue($request); - break; - case 'issue_update': - $this->updateTaskFromIssue($request); - break; - } + $input = '{"object_kind":"issue","event_type":"issue","user":{"id":1,"name":"Administrator","username":"root","avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon","email":"admin@example.com"},"project":{"id":36,"name":"zenops202106dgd","description":"repo for dingguodong dev env","web_url":"http://192.168.1.161:51080/root/zenops202106dgd","avatar_url":null,"git_ssh_url":"ssh://git@192.168.1.161:51022/root/zenops202106dgd.git","git_http_url":"http://192.168.1.161:51080/root/zenops202106dgd.git","namespace":"Administrator","visibility_level":0,"path_with_namespace":"root/zenops202106dgd","default_branch":"master","ci_config_path":null,"homepage":"http://192.168.1.161:51080/root/zenops202106dgd","url":"ssh://git@192.168.1.161:51022/root/zenops202106dgd.git","ssh_url":"ssh://git@192.168.1.161:51022/root/zenops202106dgd.git","http_url":"http://192.168.1.161:51080/root/zenops202106dgd.git"},"object_attributes":{"author_id":1,"closed_at":null,"confidential":false,"created_at":"2021-06-22 02:38:01 UTC","description":"扩展动作的公式保存之后再点设置按钮报js错误\nnew issue 0622 desc ee\n![elephant](http://192.168.1.161:51080/root/zenops202106dgd/uploads/9b85fd397a602b628a271ce02264f502/elephant.jpg)","discussion_locked":null,"due_date":"2021-06-25","id":33,"iid":3,"last_edited_at":"2021-06-24 02:53:52 UTC","last_edited_by_id":1,"milestone_id":null,"moved_to_id":null,"duplicated_to_id":null,"project_id":36,"relative_position":1539,"state_id":1,"time_estimate":0,"title":"new issue 0622","updated_at":"2021-06-24 02:53:52 UTC","updated_by_id":1,"url":"http://192.168.1.161:51080/root/zenops202106dgd/-/issues/3","total_time_spent":0,"human_total_time_spent":null,"human_time_estimate":null,"assignee_ids":[8],"assignee_id":8,"labels":[{"id":38,"title":"zentao_objectType","color":"#0033CC","project_id":36,"created_at":"2021-06-16 12:04:23 UTC","updated_at":"2021-06-22 05:17:29 UTC","template":false,"description":"task","type":"ProjectLabel","group_id":null},{"id":40,"title":"zentao_task/12738","color":"#428BCA","project_id":36,"created_at":"2021-06-21 08:58:17 UTC","updated_at":"2021-06-24 02:46:14 UTC","template":false,"description":"type:bug,id:1234,url:https://back.zcorp.cc/pms/project-browse-1291-all.html","type":"ProjectLabel","group_id":null}],"state":"opened","action":"update"},"labels":[{"id":38,"title":"zentao_objectType","color":"#0033CC","project_id":36,"created_at":"2021-06-16 12:04:23 UTC","updated_at":"2021-06-22 05:17:29 UTC","template":false,"description":"task","type":"ProjectLabel","group_id":null},{"id":40,"title":"zentao_task/12738","color":"#428BCA","project_id":36,"created_at":"2021-06-21 08:58:17 UTC","updated_at":"2021-06-24 02:46:14 UTC","template":false,"description":"type:bug,id:1234,url:https://back.zcorp.cc/pms/project-browse-1291-all.html","type":"ProjectLabel","group_id":null}],"changes":{},"repository":{"name":"zenops202106dgd","url":"ssh://git@192.168.1.161:51022/root/zenops202106dgd.git","description":"repo for dingguodong dev env","homepage":"http://192.168.1.161:51080/root/zenops202106dgd"},"assignees":[{"id":8,"name":"dingguodong","username":"dingguodong","avatar_url":"https://www.gravatar.com/avatar/11302c6dd9e26e9f8e4517538f51e4a2?s=80\u0026d=identicon","email":"dingguodong@easycorp.ltd"}]}'; + //$input = file_get_contents('php://input'); + $requestBody = json_decode($input); + $result = $this->gitlab->webhookParseBody($requestBody, $gitlab); $logFile = $this->app->getLogRoot() . 'webhook.'. date('Ymd') . '.log.php'; if(!file_exists($logFile)) file_put_contents($logFile, ''); @@ -235,12 +223,18 @@ class gitlab extends control if($fh) { fwrite($fh, date('Ymd H:i:s') . ": " . $this->app->getURI() . "\n"); - fwrite($fh, "JSON: " . $json . "\n"); - fwrite($fh, "GET: " . print_r($_GET, true) . "\n"); - fwrite($fh, "Body: " . var_export($requestBody, true) . "\n"); + fwrite($fh, "JSON: \n " . $input . "\n"); + fwrite($fh, "Parsed object: {$result->objectType} :\n " . print_r($result->object, true) . "\n"); fclose($fh); } + switch($result->objectType) + { + case 'task': + $this->updateTaskFromIssue($request); + break; + } + $this->view->result = 'success'; $this->view->status = 'ok'; $this->view->data = 'ougiugjvh'; @@ -253,13 +247,8 @@ class gitlab extends control $task = $this->loadModel('task')->getByID($id); $issue = $this->gitlab->taskToIssue($gitlabID, $projectID, $task); $issue = $this->gitlab->apiCreateIssue($gitlabID, $projectID, $issue); - a($issue); $this->gitlab->saveSyncedIssue('task', $task, $gitlabID, $issue); exit; } - - - - } diff --git a/module/gitlab/model.php b/module/gitlab/model.php index 27efcb26d1..0a3a2e900b 100644 --- a/module/gitlab/model.php +++ b/module/gitlab/model.php @@ -47,6 +47,21 @@ class gitlabModel extends model return $this->loadModel('pipeline')->getPairs('gitlab'); } + /** + * Get gitlab api base url with access_token + * + * @param int $id + * @access public + * @return string gitlab api base url with access_token + */ + public function getApiRoot($id) + { + $gitlab = $this->getByID($id); + if(!$gitlab) return ""; + $gitlab_url = rtrim($gitlab->url, '/').'/api/v4%s'."?private_token={$gitlab->token}"; + return $gitlab_url; + } + /** * Get gitlab user id zentao account pairs of one gitlab. * @@ -122,7 +137,6 @@ class gitlabModel extends model * @access public * @return array */ - public function apiGetUsers($gitlab) { $api = rtrim($gitlab->url, '/') . '/api/v4/users?private_token=' . $gitlab->token; @@ -145,59 +159,6 @@ class gitlabModel extends model return $users; } - /** - * Get matched gitlab users. - * - * @param array $gitlabUsers - * @param array $zentaoUsers - * @access public - * @return array - */ - public function getMatchedUsers($gitlabID, $gitlabUsers, $zentaoUsers) - { - $matches = new stdclass; - foreach($gitlabUsers as $gitlabUser) - { - foreach($zentaoUsers as $zentaoUser) - { - if($gitlabUser->account == $zentaoUser->account) $matches->accounts[$gitlabUser->account][] = $zentaoUser->account; - if($gitlabUser->realname == $zentaoUser->realname) $matches->names[$gitlabUser->realname][] = $zentaoUser->account; - if($gitlabUser->email == $zentaoUser->email) $matches->emails[$gitlabUser->email][] = $zentaoUser->account; - } - } - - $bindedUsers = $this->dao->select('openID,account') - ->from(TABLE_OAUTH) - ->where('providerType')->eq('gitlab') - ->andWhere('providerID')->eq($gitlabID) - ->fetchPairs(); - - $matchedUsers = array(); - foreach($gitlabUsers as $gitlabUser) - { - if(isset($bindedUsers[$gitlabUser->id])) - { - $gitlabUser->zentaoAccount = $bindedUsers[$gitlabUser->id]; - $matchedUsers[] = $gitlabUser; - continue; - } - - $matchedZentaoUsers = array(); - if(isset($matches->accounts[$gitlabUser->account])) $matchedZentaoUsers = array_merge($matchedZentaoUsers, $matches->accounts[$gitlabUser->account]); - if(isset($matches->emails[$gitlabUser->email])) $matchedZentaoUsers = array_merge($matchedZentaoUsers, $matches->emails[$gitlabUser->email]); - if(isset($matches->names[$gitlabUser->realname])) $matchedZentaoUsers = array_merge($matchedZentaoUsers, $matches->names[$gitlabUser->realname]); - - $matchedZentaoUsers = array_unique($matchedZentaoUsers); - if(count($matchedZentaoUsers) == 1) - { - $gitlabUser->zentaoAccount = current($matchedZentaoUsers); - $matchedUsers[] = $gitlabUser; - } - } - - return $matchedUsers; - } - /** * Get projects of one gitlab. * @@ -206,7 +167,7 @@ class gitlabModel extends model * @return void */ public function apiGetProjects($gitlabID) - { + { $gitlab = $this->getByID($gitlabID); if(!$gitlab) return array(); $host = rtrim($gitlab->url, '/'); @@ -222,115 +183,6 @@ class gitlabModel extends model return $allResults; } - public function getProjectPairs($gitlabID) - { - $projects = $this->apiGetProjects($gitlabID); - $projectPairs = array(); - foreach($projects as $project) - { - $projectPairs[$project->id] = $project->name_with_namespace; - } - - return $projectPairs; - } - - public function getProjectDisplayName($gitlabID, $projectID) - { - return array_key_exists($gitlabID, $projectID) ? $this->gitlab->getProjectPairs($gitlabID)[$projectID]: ""; - } - - /** - * Get gitlab api base url with access_token - * - * @param int $id - * @access public - * @return string gitlab api base url with access_token - */ - public function getApiRoot($id) - { - $gitlab = $this->getByID($id); - if(!$gitlab) return ""; - $gitlab_url = rtrim($gitlab->url, '/').'/api/v4%s'."?private_token={$gitlab->token}"; - return $gitlab_url; - } - - /** - * Bind gitlab project. - * - * @param int $gitlabID - * @param int $projectID - * @access public - * @return array - */ - public function getProjectsByExecution($executionID) - { - $products = $this->loadModel('execution')->getProducts($executionID, false); - $productIdList = array_keys($products); - - return $this->dao->select('AID,BID as gitlabProject') - ->from(TABLE_RELATION) - ->where('relation')->eq('interrated') - ->andWhere('AType')->eq('gitlab') - ->andWhere('BType')->eq('gitlabProject') - ->andWhere('product')->in($productIdList) - ->fetchGroup('AID'); - } - - /** - * Create relationship between zentao product and gitlab project. - * - * @param int $gitlabID - * @param int $projectID - * @access public - * @return void - */ - public function saveRelation($products, $gitlabID, $gitlabProjectID) - { - $programs = $this->dao->select('id,program')->from(TABLE_PRODUCT)->where('id')->in($products)->fetchPairs(); - - $relation = new stdclass; - $relation->execution = 0; - $relation->AType = 'gitlab'; - $relation->AID = $gitlabID; - $relation->AVersion = ''; - $relation->relation = 'interrated'; - $relation->BType = 'gitlabProject'; - $relation->BID = $gitlabProjectID; - $relation->BVersion = ''; - $relation->extra = ''; - - foreach($products as $product) - { - $relation->project = zget($programs, $product, 0); - $relation->product = $product; - $this->dao->replace(TABLE_RELATION)->data($relation)->exec(); - } - return true; - } - - /** - * Create webhook for zentao. - * - * @param int $gitlabID - * @param int $projectID - * @access public - * @return void - */ - public function createWebhook($products, $gitlabID, $projectID) - { - $urls = $this->getWebhookUrls($gitlabID, $projectID); - - foreach($products as $index => $product) - { - $url = sprintf($this->config->gitlab->zentaoApiWebhookUrl, commonModel::getSysURL(), $product, $gitlabID, $projectID); - if(! array_key_exists($url, array_flip($urls))) - { - $response = $this->apiCreateHook($gitlabID, $projectID, $url, $this->config->gitlab->zentaoApiWebhookToken); - } - } - return true; - } - /** * Get hooks. * @@ -366,25 +218,6 @@ class gitlabModel extends model return $response; } - /** - * Get webhook urls - * - * @param int $gitlabID - * @param int $projectID - * @access public - * @return array $urls; - */ - public function getWebhookUrls($gitlabID, $projectID) - { - $urls = array(); - $webhooks = $this->apiGetHooks($gitlabID, $projectID); - foreach($webhooks as $index => $webhook) - { - $urls[] = $webhook->url; - } - return $urls; - } - /** * Create hook. * @@ -500,6 +333,172 @@ class gitlabModel extends model return $labels; } + /** + * Get project pairs of one gitlab. + * + * @param int $gitlabID + * @access public + * @return array + */ + public function getProjectPairs($gitlabID) + { + $projects = $this->apiGetProjects($gitlabID); + + $projectPairs = array(); + foreach($projects as $project) $projectPairs[$project->id] = $project->name_with_namespace; + + return $projectPairs; + } + + /** + * Get matched gitlab users. + * + * @param array $gitlabUsers + * @param array $zentaoUsers + * @access public + * @return array + */ + public function getMatchedUsers($gitlabID, $gitlabUsers, $zentaoUsers) + { + $matches = new stdclass; + foreach($gitlabUsers as $gitlabUser) + { + foreach($zentaoUsers as $zentaoUser) + { + if($gitlabUser->account == $zentaoUser->account) $matches->accounts[$gitlabUser->account][] = $zentaoUser->account; + if($gitlabUser->realname == $zentaoUser->realname) $matches->names[$gitlabUser->realname][] = $zentaoUser->account; + if($gitlabUser->email == $zentaoUser->email) $matches->emails[$gitlabUser->email][] = $zentaoUser->account; + } + } + + $bindedUsers = $this->dao->select('openID,account') + ->from(TABLE_OAUTH) + ->where('providerType')->eq('gitlab') + ->andWhere('providerID')->eq($gitlabID) + ->fetchPairs(); + + $matchedUsers = array(); + foreach($gitlabUsers as $gitlabUser) + { + if(isset($bindedUsers[$gitlabUser->id])) + { + $gitlabUser->zentaoAccount = $bindedUsers[$gitlabUser->id]; + $matchedUsers[] = $gitlabUser; + continue; + } + + $matchedZentaoUsers = array(); + if(isset($matches->accounts[$gitlabUser->account])) $matchedZentaoUsers = array_merge($matchedZentaoUsers, $matches->accounts[$gitlabUser->account]); + if(isset($matches->emails[$gitlabUser->email])) $matchedZentaoUsers = array_merge($matchedZentaoUsers, $matches->emails[$gitlabUser->email]); + if(isset($matches->names[$gitlabUser->realname])) $matchedZentaoUsers = array_merge($matchedZentaoUsers, $matches->names[$gitlabUser->realname]); + + $matchedZentaoUsers = array_unique($matchedZentaoUsers); + if(count($matchedZentaoUsers) == 1) + { + $gitlabUser->zentaoAccount = current($matchedZentaoUsers); + $matchedUsers[] = $gitlabUser; + } + } + + return $matchedUsers; + } + + /** + * Bind gitlab project. + * + * @param int $gitlabID + * @param int $projectID + * @access public + * @return array + */ + public function getProjectsByExecution($executionID) + { + $products = $this->loadModel('execution')->getProducts($executionID, false); + $productIdList = array_keys($products); + + return $this->dao->select('AID,BID as gitlabProject') + ->from(TABLE_RELATION) + ->where('relation')->eq('interrated') + ->andWhere('AType')->eq('gitlab') + ->andWhere('BType')->eq('gitlabProject') + ->andWhere('product')->in($productIdList) + ->fetchGroup('AID'); + } + + /** + * Create relationship between zentao product and gitlab project. + * + * @param int $gitlabID + * @param int $projectID + * @access public + * @return void + */ + public function saveRelation($products, $gitlabID, $gitlabProjectID) + { + $programs = $this->dao->select('id,program')->from(TABLE_PRODUCT)->where('id')->in($products)->fetchPairs(); + + $relation = new stdclass; + $relation->execution = 0; + $relation->AType = 'gitlab'; + $relation->AID = $gitlabID; + $relation->AVersion = ''; + $relation->relation = 'interrated'; + $relation->BType = 'gitlabProject'; + $relation->BID = $gitlabProjectID; + $relation->BVersion = ''; + $relation->extra = ''; + + foreach($products as $product) + { + $relation->project = zget($programs, $product, 0); + $relation->product = $product; + $this->dao->replace(TABLE_RELATION)->data($relation)->exec(); + } + return true; + } + + /** + * Create webhook for zentao. + * + * @param int $gitlabID + * @param int $projectID + * @access public + * @return void + */ + public function createWebhook($products, $gitlabID, $projectID) + { + $urls = $this->getWebhookUrls($gitlabID, $projectID); + + foreach($products as $index => $product) + { + $url = sprintf($this->config->gitlab->zentaoApiWebhookUrl, commonModel::getSysURL(), $product, $gitlabID, $projectID); + if(! array_key_exists($url, array_flip($urls))) + { + $response = $this->apiCreateHook($gitlabID, $projectID, $url, $this->config->gitlab->zentaoApiWebhookToken); + } + } + return true; + } + + /** + * Get webhook urls + * + * @param int $gitlabID + * @param int $projectID + * @access public + * @return array $urls; + */ + public function getWebhookUrls($gitlabID, $projectID) + { + $urls = array(); + $webhooks = $this->apiGetHooks($gitlabID, $projectID); + foreach($webhooks as $index => $webhook) + { + $urls[] = $webhook->url; + } + return $urls; + } + /** * Check if predefined label exist in project. * @@ -857,6 +856,14 @@ class gitlabModel extends model return $object; } + /** + * Parse issue to task. + * + * @param object $issue + * @param int $gitlabID + * @access public + * @return object + */ public function issueToTask($issue, $gitlabID) { $task = new stdclass; @@ -875,32 +882,39 @@ class gitlabModel extends model return $task; } - public function issueToStory($issue) + /** + * Parse issue to story. + * + * @param object $issue + * @param int $gitlabID + * @access public + * @return object + */ + public function issueToStory($issue, $gitlabID) { } - public function issueToBug($issue) + /** + * Parse issue to task. + * + * @param object $issue + * @param int $gitlabID + * @access public + * @return object + */ + public function issueToBug($issue, $gitlabID) { } /** - * Get account in zentaopms. + * Get gitlab userID by account. * - * @param int $gitlabID - * @param int $userID + * @param int $gitlabID + * @param string $account * @access public - * @return string|false + * @return void */ - public function getAccount($gitlabID, $userID) - { - return $this->dao->select('account')->from(TABLE_OAUTH) - ->where('providerType')->eq('gitlab') - ->andWhere('providerID')->eq($gitlabID) - ->andWhere('openID')->eq($userID) - ->fetch('account'); - } - public function getGitlabUserID($gitlabID, $account) { return $this->dao->select('openID')->from(TABLE_OAUTH)