You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by ly...@apache.org on 2024/06/03 03:24:05 UTC

(incubator-devlake) branch main updated: feat: add assignees and reviewers to pull_request_x table (#7556)

This is an automated email from the ASF dual-hosted git repository.

lynwee pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 2816c188f feat: add assignees and reviewers to pull_request_x table (#7556)
2816c188f is described below

commit 2816c188f2f3c8ff4eb78c23399dc3823f4af692
Author: abeizn <zi...@merico.dev>
AuthorDate: Mon Jun 3 11:24:01 2024 +0800

    feat: add assignees and reviewers to pull_request_x table (#7556)
    
    * feat: add assignees and reviewers to pull_request_x table
    
    * fix: unit test and e2e test
    
    * fix: unit test
    
    * fix: some tips
    
    * fix: rename assignee reviewer id name
---
 .../domainlayer/code/pull_request_assignees.go}    | 21 ++---
 .../domainlayer/code/pull_request_reviewers.go}    | 21 ++---
 .../models/domainlayer/domaininfo/domaininfo.go    |  2 +
 .../20240531_add_pr_assignees_and_reviewers.go}    | 33 ++++----
 .../archived/pull_request_assignees.go}            | 25 ++----
 .../archived/pull_request_reviewers.go}            | 25 ++----
 backend/core/models/migrationscripts/register.go   |  1 +
 backend/plugins/gitlab/e2e/mr_commits_test.go      |  2 +
 backend/plugins/gitlab/impl/impl.go                |  1 +
 .../gitlab/models/{reviewer.go => assignee.go}     | 11 ++-
 .../migrationscripts/20240531_add_mr_assignees.go  | 53 +++++++++++++
 .../archived/{reviewer.go => assignee.go}          | 11 ++-
 .../models/migrationscripts/archived/reviewer.go   |  5 +-
 .../gitlab/models/migrationscripts/register.go     |  1 +
 backend/plugins/gitlab/models/reviewer.go          |  5 +-
 .../plugins/gitlab/tasks/mr_assignee_convertor.go  | 90 ++++++++++++++++++++++
 .../plugins/gitlab/tasks/mr_detail_extractor.go    | 17 +++-
 backend/plugins/gitlab/tasks/mr_extractor.go       | 29 ++++++-
 .../plugins/gitlab/tasks/mr_reviewer_convertor.go  | 90 ++++++++++++++++++++++
 19 files changed, 347 insertions(+), 96 deletions(-)

diff --git a/backend/plugins/gitlab/models/reviewer.go b/backend/core/models/domainlayer/code/pull_request_assignees.go
similarity index 61%
copy from backend/plugins/gitlab/models/reviewer.go
copy to backend/core/models/domainlayer/code/pull_request_assignees.go
index 5c3735591..22a3ffd1d 100644
--- a/backend/plugins/gitlab/models/reviewer.go
+++ b/backend/core/models/domainlayer/code/pull_request_assignees.go
@@ -15,26 +15,21 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package models
+package code
 
 import (
 	"github.com/apache/incubator-devlake/core/models/common"
 )
 
-type GitlabReviewer struct {
-	ConnectionId uint64 `gorm:"primaryKey"`
+type PullRequestAssignee struct {
+	PullRequestId string `json:"id" gorm:"primaryKey;type:varchar(255);comment:This key is generated based on details from the original plugin"` // format: <Plugin>:<Entity>:<PK0>:<PK1>
+	AssigneeId    int    `gorm:"primaryKey"`
+	Name          string `gorm:"type:varchar(255)"`
+	UserName      string `gorm:"type:varchar(255)"`
 
-	GitlabId       int    `gorm:"primaryKey"`
-	MergeRequestId int    `gorm:"index"`
-	ProjectId      int    `gorm:"index"`
-	Name           string `gorm:"type:varchar(255)"`
-	Username       string `gorm:"type:varchar(255)"`
-	State          string `gorm:"type:varchar(255)"`
-	AvatarUrl      string `gorm:"type:varchar(255)"`
-	WebUrl         string `gorm:"type:varchar(255)"`
 	common.NoPKModel
 }
 
-func (GitlabReviewer) TableName() string {
-	return "_tool_gitlab_reviewers"
+func (PullRequestAssignee) TableName() string {
+	return "pull_request_assignees"
 }
diff --git a/backend/plugins/gitlab/models/reviewer.go b/backend/core/models/domainlayer/code/pull_request_reviewers.go
similarity index 61%
copy from backend/plugins/gitlab/models/reviewer.go
copy to backend/core/models/domainlayer/code/pull_request_reviewers.go
index 5c3735591..2fdc20d1e 100644
--- a/backend/plugins/gitlab/models/reviewer.go
+++ b/backend/core/models/domainlayer/code/pull_request_reviewers.go
@@ -15,26 +15,21 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package models
+package code
 
 import (
 	"github.com/apache/incubator-devlake/core/models/common"
 )
 
-type GitlabReviewer struct {
-	ConnectionId uint64 `gorm:"primaryKey"`
+type PullRequestReviewer struct {
+	PullRequestId string `json:"id" gorm:"primaryKey;type:varchar(255);comment:This key is generated based on details from the original plugin"` // format: <Plugin>:<Entity>:<PK0>:<PK1>
+	ReviewerId    int    `gorm:"primaryKey"`
+	Name          string `gorm:"type:varchar(255)"`
+	UserName      string `gorm:"type:varchar(255)"`
 
-	GitlabId       int    `gorm:"primaryKey"`
-	MergeRequestId int    `gorm:"index"`
-	ProjectId      int    `gorm:"index"`
-	Name           string `gorm:"type:varchar(255)"`
-	Username       string `gorm:"type:varchar(255)"`
-	State          string `gorm:"type:varchar(255)"`
-	AvatarUrl      string `gorm:"type:varchar(255)"`
-	WebUrl         string `gorm:"type:varchar(255)"`
 	common.NoPKModel
 }
 
-func (GitlabReviewer) TableName() string {
-	return "_tool_gitlab_reviewers"
+func (PullRequestReviewer) TableName() string {
+	return "pull_request_reviewers"
 }
diff --git a/backend/core/models/domainlayer/domaininfo/domaininfo.go b/backend/core/models/domainlayer/domaininfo/domaininfo.go
index 92fa770e9..422f537ab 100644
--- a/backend/core/models/domainlayer/domaininfo/domaininfo.go
+++ b/backend/core/models/domainlayer/domaininfo/domaininfo.go
@@ -39,6 +39,8 @@ func GetDomainTablesInfo() []dal.Tabler {
 		&code.PullRequestComment{},
 		&code.PullRequestCommit{},
 		&code.PullRequestLabel{},
+		&code.PullRequestReviewer{},
+		&code.PullRequestAssignee{},
 		&code.Ref{},
 		&code.CommitsDiff{},
 		&code.RefCommit{},
diff --git a/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go b/backend/core/models/migrationscripts/20240531_add_pr_assignees_and_reviewers.go
similarity index 57%
copy from backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
copy to backend/core/models/migrationscripts/20240531_add_pr_assignees_and_reviewers.go
index f59101e05..fa852c960 100644
--- a/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
+++ b/backend/core/models/migrationscripts/20240531_add_pr_assignees_and_reviewers.go
@@ -15,26 +15,29 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package archived
+package migrationscripts
 
 import (
+	"github.com/apache/incubator-devlake/core/context"
+	"github.com/apache/incubator-devlake/core/errors"
 	"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+	"github.com/apache/incubator-devlake/helpers/migrationhelper"
 )
 
-type GitlabReviewer struct {
-	ConnectionId uint64 `gorm:"primaryKey"`
-
-	GitlabId       int    `gorm:"primaryKey"`
-	MergeRequestId int    `gorm:"index"`
-	ProjectId      int    `gorm:"index"`
-	Name           string `gorm:"type:varchar(255)"`
-	Username       string `gorm:"type:varchar(255)"`
-	State          string `gorm:"type:varchar(255)"`
-	AvatarUrl      string `gorm:"type:varchar(255)"`
-	WebUrl         string `gorm:"type:varchar(255)"`
-	archived.NoPKModel
+type addPrAssigneeAndReviewer struct{}
+
+func (u *addPrAssigneeAndReviewer) Up(basicRes context.BasicRes) errors.Error {
+	return migrationhelper.AutoMigrateTables(
+		basicRes,
+		&archived.PullRequestAssignee{},
+		&archived.PullRequestReviewer{},
+	)
+}
+
+func (*addPrAssigneeAndReviewer) Version() uint64 {
+	return 20250531000041
 }
 
-func (GitlabReviewer) TableName() string {
-	return "_tool_gitlab_reviewers"
+func (*addPrAssigneeAndReviewer) Name() string {
+	return "add pull_request_reviewers and pull_request_assignees tables"
 }
diff --git a/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go b/backend/core/models/migrationscripts/archived/pull_request_assignees.go
similarity index 55%
copy from backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
copy to backend/core/models/migrationscripts/archived/pull_request_assignees.go
index f59101e05..d1881b979 100644
--- a/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
+++ b/backend/core/models/migrationscripts/archived/pull_request_assignees.go
@@ -17,24 +17,15 @@ limitations under the License.
 
 package archived
 
-import (
-	"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
-)
+type PullRequestAssignee struct {
+	PullRequestId string `json:"id" gorm:"primaryKey;type:varchar(255);comment:This key is generated based on details from the original plugin"` // format: <Plugin>:<Entity>:<PK0>:<PK1>
+	AssigneeId    int    `gorm:"primaryKey"`
+	Name          string `gorm:"type:varchar(255)"`
+	UserName      string `gorm:"type:varchar(255)"`
 
-type GitlabReviewer struct {
-	ConnectionId uint64 `gorm:"primaryKey"`
-
-	GitlabId       int    `gorm:"primaryKey"`
-	MergeRequestId int    `gorm:"index"`
-	ProjectId      int    `gorm:"index"`
-	Name           string `gorm:"type:varchar(255)"`
-	Username       string `gorm:"type:varchar(255)"`
-	State          string `gorm:"type:varchar(255)"`
-	AvatarUrl      string `gorm:"type:varchar(255)"`
-	WebUrl         string `gorm:"type:varchar(255)"`
-	archived.NoPKModel
+	NoPKModel
 }
 
-func (GitlabReviewer) TableName() string {
-	return "_tool_gitlab_reviewers"
+func (PullRequestAssignee) TableName() string {
+	return "pull_request_assignees"
 }
diff --git a/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go b/backend/core/models/migrationscripts/archived/pull_request_reviewers.go
similarity index 55%
copy from backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
copy to backend/core/models/migrationscripts/archived/pull_request_reviewers.go
index f59101e05..8d47cf052 100644
--- a/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
+++ b/backend/core/models/migrationscripts/archived/pull_request_reviewers.go
@@ -17,24 +17,15 @@ limitations under the License.
 
 package archived
 
-import (
-	"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
-)
+type PullRequestReviewer struct {
+	PullRequestId string `json:"id" gorm:"primaryKey;type:varchar(255);comment:This key is generated based on details from the original plugin"` // format: <Plugin>:<Entity>:<PK0>:<PK1>
+	ReviewerId    int    `gorm:"primaryKey"`
+	Name          string `gorm:"type:varchar(255)"`
+	UserName      string `gorm:"type:varchar(255)"`
 
-type GitlabReviewer struct {
-	ConnectionId uint64 `gorm:"primaryKey"`
-
-	GitlabId       int    `gorm:"primaryKey"`
-	MergeRequestId int    `gorm:"index"`
-	ProjectId      int    `gorm:"index"`
-	Name           string `gorm:"type:varchar(255)"`
-	Username       string `gorm:"type:varchar(255)"`
-	State          string `gorm:"type:varchar(255)"`
-	AvatarUrl      string `gorm:"type:varchar(255)"`
-	WebUrl         string `gorm:"type:varchar(255)"`
-	archived.NoPKModel
+	NoPKModel
 }
 
-func (GitlabReviewer) TableName() string {
-	return "_tool_gitlab_reviewers"
+func (PullRequestReviewer) TableName() string {
+	return "pull_request_reviewers"
 }
diff --git a/backend/core/models/migrationscripts/register.go b/backend/core/models/migrationscripts/register.go
index c434700bc..422c2a818 100644
--- a/backend/core/models/migrationscripts/register.go
+++ b/backend/core/models/migrationscripts/register.go
@@ -119,5 +119,6 @@ func All() []plugin.MigrationScript {
 		new(updatePluginOptionInProjectMetricSetting),
 		new(modifyCicdDeploymentCommitsRepoUrlLength),
 		new(modifyCicdPipelineCommitsRepoUrlLength),
+		new(addPrAssigneeAndReviewer),
 	}
 }
diff --git a/backend/plugins/gitlab/e2e/mr_commits_test.go b/backend/plugins/gitlab/e2e/mr_commits_test.go
index 897cf9c0d..d5ef9d2a4 100644
--- a/backend/plugins/gitlab/e2e/mr_commits_test.go
+++ b/backend/plugins/gitlab/e2e/mr_commits_test.go
@@ -48,6 +48,8 @@ func TestGitlabMrCommitDataFlow(t *testing.T) {
 	// verify extraction
 	dataflowTester.FlushTabler(&models.GitlabMergeRequest{})
 	dataflowTester.FlushTabler(&models.GitlabMrLabel{})
+	dataflowTester.FlushTabler(&models.GitlabAssignee{})
+	dataflowTester.FlushTabler(&models.GitlabReviewer{})
 	dataflowTester.Subtask(tasks.ExtractApiMergeRequestsMeta, taskData)
 	dataflowTester.VerifyTable(
 		models.GitlabMergeRequest{},
diff --git a/backend/plugins/gitlab/impl/impl.go b/backend/plugins/gitlab/impl/impl.go
index 166624536..1d72bf052 100644
--- a/backend/plugins/gitlab/impl/impl.go
+++ b/backend/plugins/gitlab/impl/impl.go
@@ -98,6 +98,7 @@ func (p Gitlab) GetTablesInfo() []dal.Tabler {
 		&models.GitlabProject{},
 		&models.GitlabProjectCommit{},
 		&models.GitlabReviewer{},
+		&models.GitlabAssignee{},
 		&models.GitlabTag{},
 		&models.GitlabIssueAssignee{},
 		&models.GitlabScopeConfig{},
diff --git a/backend/plugins/gitlab/models/reviewer.go b/backend/plugins/gitlab/models/assignee.go
similarity index 86%
copy from backend/plugins/gitlab/models/reviewer.go
copy to backend/plugins/gitlab/models/assignee.go
index 5c3735591..85f3b377b 100644
--- a/backend/plugins/gitlab/models/reviewer.go
+++ b/backend/plugins/gitlab/models/assignee.go
@@ -21,10 +21,9 @@ import (
 	"github.com/apache/incubator-devlake/core/models/common"
 )
 
-type GitlabReviewer struct {
-	ConnectionId uint64 `gorm:"primaryKey"`
-
-	GitlabId       int    `gorm:"primaryKey"`
+type GitlabAssignee struct {
+	ConnectionId   uint64 `gorm:"primaryKey"`
+	AssigneeId     int    `gorm:"primaryKey"`
 	MergeRequestId int    `gorm:"index"`
 	ProjectId      int    `gorm:"index"`
 	Name           string `gorm:"type:varchar(255)"`
@@ -35,6 +34,6 @@ type GitlabReviewer struct {
 	common.NoPKModel
 }
 
-func (GitlabReviewer) TableName() string {
-	return "_tool_gitlab_reviewers"
+func (GitlabAssignee) TableName() string {
+	return "_tool_gitlab_assignees"
 }
diff --git a/backend/plugins/gitlab/models/migrationscripts/20240531_add_mr_assignees.go b/backend/plugins/gitlab/models/migrationscripts/20240531_add_mr_assignees.go
new file mode 100644
index 000000000..908577448
--- /dev/null
+++ b/backend/plugins/gitlab/models/migrationscripts/20240531_add_mr_assignees.go
@@ -0,0 +1,53 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package migrationscripts
+
+import (
+	"github.com/apache/incubator-devlake/core/context"
+	"github.com/apache/incubator-devlake/core/errors"
+	"github.com/apache/incubator-devlake/helpers/migrationhelper"
+	"github.com/apache/incubator-devlake/plugins/gitlab/models/migrationscripts/archived"
+)
+
+type addGitlabAssignee struct{}
+
+func (*addGitlabAssignee) Up(baseRes context.BasicRes) errors.Error {
+	err := baseRes.GetDal().DropTables(archived.GitlabAssignee{})
+	if err != nil {
+		return err
+	}
+
+	err = migrationhelper.AutoMigrateTables(
+		baseRes,
+		&archived.GitlabAssignee{},
+		&archived.GitlabReviewer{},
+	)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (*addGitlabAssignee) Version() uint64 {
+	return 20240531110339
+}
+
+func (*addGitlabAssignee) Name() string {
+	return "add _tool_gitlab_assignees table"
+}
diff --git a/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go b/backend/plugins/gitlab/models/migrationscripts/archived/assignee.go
similarity index 86%
copy from backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
copy to backend/plugins/gitlab/models/migrationscripts/archived/assignee.go
index f59101e05..bc283ead0 100644
--- a/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
+++ b/backend/plugins/gitlab/models/migrationscripts/archived/assignee.go
@@ -21,10 +21,9 @@ import (
 	"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
 )
 
-type GitlabReviewer struct {
-	ConnectionId uint64 `gorm:"primaryKey"`
-
-	GitlabId       int    `gorm:"primaryKey"`
+type GitlabAssignee struct {
+	ConnectionId   uint64 `gorm:"primaryKey"`
+	AssigneeId     int    `gorm:"primaryKey"`
 	MergeRequestId int    `gorm:"index"`
 	ProjectId      int    `gorm:"index"`
 	Name           string `gorm:"type:varchar(255)"`
@@ -35,6 +34,6 @@ type GitlabReviewer struct {
 	archived.NoPKModel
 }
 
-func (GitlabReviewer) TableName() string {
-	return "_tool_gitlab_reviewers"
+func (GitlabAssignee) TableName() string {
+	return "_tool_gitlab_assignees"
 }
diff --git a/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go b/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
index f59101e05..2fa1e27fb 100644
--- a/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
+++ b/backend/plugins/gitlab/models/migrationscripts/archived/reviewer.go
@@ -22,9 +22,8 @@ import (
 )
 
 type GitlabReviewer struct {
-	ConnectionId uint64 `gorm:"primaryKey"`
-
-	GitlabId       int    `gorm:"primaryKey"`
+	ConnectionId   uint64 `gorm:"primaryKey"`
+	ReviewerId     int    `gorm:"primaryKey"`
 	MergeRequestId int    `gorm:"index"`
 	ProjectId      int    `gorm:"index"`
 	Name           string `gorm:"type:varchar(255)"`
diff --git a/backend/plugins/gitlab/models/migrationscripts/register.go b/backend/plugins/gitlab/models/migrationscripts/register.go
index 270bb296f..b60a41e4e 100644
--- a/backend/plugins/gitlab/models/migrationscripts/register.go
+++ b/backend/plugins/gitlab/models/migrationscripts/register.go
@@ -48,5 +48,6 @@ func All() []plugin.MigrationScript {
 		new(addTimeToGitlabPipelineProject),
 		new(modifyDeploymentCommitTitle),
 		new(addWebUrlToGitlabPipelineProject),
+		new(addGitlabAssignee),
 	}
 }
diff --git a/backend/plugins/gitlab/models/reviewer.go b/backend/plugins/gitlab/models/reviewer.go
index 5c3735591..8bffc2f54 100644
--- a/backend/plugins/gitlab/models/reviewer.go
+++ b/backend/plugins/gitlab/models/reviewer.go
@@ -22,9 +22,8 @@ import (
 )
 
 type GitlabReviewer struct {
-	ConnectionId uint64 `gorm:"primaryKey"`
-
-	GitlabId       int    `gorm:"primaryKey"`
+	ConnectionId   uint64 `gorm:"primaryKey"`
+	ReviewerId     int    `gorm:"primaryKey"`
 	MergeRequestId int    `gorm:"index"`
 	ProjectId      int    `gorm:"index"`
 	Name           string `gorm:"type:varchar(255)"`
diff --git a/backend/plugins/gitlab/tasks/mr_assignee_convertor.go b/backend/plugins/gitlab/tasks/mr_assignee_convertor.go
new file mode 100644
index 000000000..3ae9523ee
--- /dev/null
+++ b/backend/plugins/gitlab/tasks/mr_assignee_convertor.go
@@ -0,0 +1,90 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package tasks
+
+import (
+	"reflect"
+
+	"github.com/apache/incubator-devlake/core/dal"
+	"github.com/apache/incubator-devlake/core/errors"
+	"github.com/apache/incubator-devlake/core/models/domainlayer/code"
+	"github.com/apache/incubator-devlake/core/models/domainlayer/didgen"
+	"github.com/apache/incubator-devlake/core/plugin"
+	helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+	"github.com/apache/incubator-devlake/plugins/gitlab/models"
+)
+
+func init() {
+	RegisterSubtaskMeta(&ConvertMrAssigneesMeta)
+}
+
+var ConvertMrAssigneesMeta = plugin.SubTaskMeta{
+	Name:             "Convert MR Assignees",
+	EntryPoint:       ConvertMrAssignees,
+	EnabledByDefault: true,
+	Description:      "Convert tool layer table gitlab_assignees into  domain layer table pull_request_assignees",
+	DomainTypes:      []string{plugin.DOMAIN_TYPE_CODE_REVIEW},
+	Dependencies:     []*plugin.SubTaskMeta{&ExtractApiMergeRequestDetailsMeta},
+}
+
+func ConvertMrAssignees(taskCtx plugin.SubTaskContext) errors.Error {
+	db := taskCtx.GetDal()
+	rawDataSubTaskArgs, data := CreateRawDataSubTaskArgs(taskCtx, RAW_MERGE_REQUEST_TABLE)
+	projectId := data.Options.ProjectId
+	clauses := []dal.Clause{
+		dal.Select("_tool_gitlab_assignees.*"),
+		dal.From(&models.GitlabAssignee{}),
+		dal.Join(`left join _tool_gitlab_merge_requests mr on
+			mr.gitlab_id = _tool_gitlab_assignees.merge_request_id`),
+		dal.Where(`mr.project_id = ?
+			and mr.connection_id = ?`,
+			projectId, data.Options.ConnectionId),
+		dal.Orderby("_tool_gitlab_assignees.merge_request_id ASC"),
+	}
+
+	cursor, err := db.Cursor(clauses...)
+	if err != nil {
+		return err
+	}
+	defer cursor.Close()
+
+	mrIdGen := didgen.NewDomainIdGenerator(&models.GitlabMergeRequest{})
+
+	converter, err := helper.NewDataConverter(helper.DataConverterArgs{
+		RawDataSubTaskArgs: *rawDataSubTaskArgs,
+		InputRowType:       reflect.TypeOf(models.GitlabAssignee{}),
+		Input:              cursor,
+		Convert: func(inputRow interface{}) ([]interface{}, errors.Error) {
+			mrAssignee := inputRow.(*models.GitlabAssignee)
+			domainPrAssigne := &code.PullRequestAssignee{
+				PullRequestId: mrIdGen.Generate(data.Options.ConnectionId, mrAssignee.MergeRequestId),
+				AssigneeId:    mrAssignee.AssigneeId,
+				Name:          mrAssignee.Name,
+				UserName:      mrAssignee.Username,
+			}
+			return []interface{}{
+				domainPrAssigne,
+			}, nil
+		},
+	})
+	if err != nil {
+		return err
+	}
+
+	return converter.Execute()
+}
diff --git a/backend/plugins/gitlab/tasks/mr_detail_extractor.go b/backend/plugins/gitlab/tasks/mr_detail_extractor.go
index 38ce2901c..3dbc72e8a 100644
--- a/backend/plugins/gitlab/tasks/mr_detail_extractor.go
+++ b/backend/plugins/gitlab/tasks/mr_detail_extractor.go
@@ -95,7 +95,7 @@ func ExtractApiMergeRequestDetails(taskCtx plugin.SubTaskContext) errors.Error {
 			for _, reviewer := range mr.Reviewers {
 				gitlabReviewer := &models.GitlabReviewer{
 					ConnectionId:   data.Options.ConnectionId,
-					GitlabId:       reviewer.GitlabId,
+					ReviewerId:     reviewer.ReviewerIdId,
 					MergeRequestId: mr.GitlabId,
 					ProjectId:      data.Options.ProjectId,
 					Username:       reviewer.Username,
@@ -107,6 +107,21 @@ func ExtractApiMergeRequestDetails(taskCtx plugin.SubTaskContext) errors.Error {
 				results = append(results, gitlabReviewer)
 			}
 
+			for _, assignee := range mr.Assignees {
+				gitlabAssignee := &models.GitlabAssignee{
+					ConnectionId:   data.Options.ConnectionId,
+					AssigneeId:     assignee.AssigneeId,
+					MergeRequestId: mr.GitlabId,
+					ProjectId:      data.Options.ProjectId,
+					Username:       assignee.Username,
+					Name:           assignee.Name,
+					State:          assignee.State,
+					AvatarUrl:      assignee.AvatarUrl,
+					WebUrl:         assignee.WebUrl,
+				}
+				results = append(results, gitlabAssignee)
+			}
+
 			return results, nil
 		},
 	})
diff --git a/backend/plugins/gitlab/tasks/mr_extractor.go b/backend/plugins/gitlab/tasks/mr_extractor.go
index a45bc924e..76253833b 100644
--- a/backend/plugins/gitlab/tasks/mr_extractor.go
+++ b/backend/plugins/gitlab/tasks/mr_extractor.go
@@ -62,12 +62,23 @@ type MergeRequestRes struct {
 		Username string `json:"username"`
 	}
 	Reviewers        []Reviewer
+	Assignees        []Assignee
 	FirstCommentTime common.Iso8601Time
 	Labels           []string `json:"labels"`
 }
 
 type Reviewer struct {
-	GitlabId       int `json:"id"`
+	ReviewerIdId   int `json:"id"`
+	MergeRequestId int
+	Name           string
+	Username       string
+	State          string
+	AvatarUrl      string `json:"avatar_url"`
+	WebUrl         string `json:"web_url"`
+}
+
+type Assignee struct {
+	AssigneeId     int `json:"id"`
 	MergeRequestId int
 	Name           string
 	Username       string
@@ -152,7 +163,7 @@ func ExtractApiMergeRequests(taskCtx plugin.SubTaskContext) errors.Error {
 			for _, reviewer := range mr.Reviewers {
 				gitlabReviewer := &models.GitlabReviewer{
 					ConnectionId:   data.Options.ConnectionId,
-					GitlabId:       reviewer.GitlabId,
+					ReviewerId:     reviewer.ReviewerIdId,
 					MergeRequestId: mr.GitlabId,
 					ProjectId:      data.Options.ProjectId,
 					Username:       reviewer.Username,
@@ -163,6 +174,20 @@ func ExtractApiMergeRequests(taskCtx plugin.SubTaskContext) errors.Error {
 				}
 				results = append(results, gitlabReviewer)
 			}
+			for _, assignee := range mr.Assignees {
+				gitlabAssignee := &models.GitlabAssignee{
+					ConnectionId:   data.Options.ConnectionId,
+					AssigneeId:     assignee.AssigneeId,
+					MergeRequestId: mr.GitlabId,
+					ProjectId:      data.Options.ProjectId,
+					Username:       assignee.Username,
+					Name:           assignee.Name,
+					State:          assignee.State,
+					AvatarUrl:      assignee.AvatarUrl,
+					WebUrl:         assignee.WebUrl,
+				}
+				results = append(results, gitlabAssignee)
+			}
 
 			return results, nil
 		},
diff --git a/backend/plugins/gitlab/tasks/mr_reviewer_convertor.go b/backend/plugins/gitlab/tasks/mr_reviewer_convertor.go
new file mode 100644
index 000000000..dbbf10a14
--- /dev/null
+++ b/backend/plugins/gitlab/tasks/mr_reviewer_convertor.go
@@ -0,0 +1,90 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package tasks
+
+import (
+	"reflect"
+
+	"github.com/apache/incubator-devlake/core/dal"
+	"github.com/apache/incubator-devlake/core/errors"
+	"github.com/apache/incubator-devlake/core/models/domainlayer/code"
+	"github.com/apache/incubator-devlake/core/models/domainlayer/didgen"
+	"github.com/apache/incubator-devlake/core/plugin"
+	helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+	"github.com/apache/incubator-devlake/plugins/gitlab/models"
+)
+
+func init() {
+	RegisterSubtaskMeta(&ConvertMrReviewersMeta)
+}
+
+var ConvertMrReviewersMeta = plugin.SubTaskMeta{
+	Name:             "Convert MR Reviewers",
+	EntryPoint:       ConvertMrReviewers,
+	EnabledByDefault: true,
+	Description:      "Convert tool layer table gitlab_reviewers into domain layer table pull_request_reviewers",
+	DomainTypes:      []string{plugin.DOMAIN_TYPE_CODE_REVIEW},
+	Dependencies:     []*plugin.SubTaskMeta{&ExtractApiMergeRequestDetailsMeta},
+}
+
+func ConvertMrReviewers(taskCtx plugin.SubTaskContext) errors.Error {
+	db := taskCtx.GetDal()
+	rawDataSubTaskArgs, data := CreateRawDataSubTaskArgs(taskCtx, RAW_MERGE_REQUEST_TABLE)
+	projectId := data.Options.ProjectId
+	clauses := []dal.Clause{
+		dal.Select("_tool_gitlab_reviewers.*"),
+		dal.From(&models.GitlabReviewer{}),
+		dal.Join(`left join _tool_gitlab_merge_requests mr on
+			mr.gitlab_id = _tool_gitlab_reviewers.merge_request_id`),
+		dal.Where(`mr.project_id = ?
+			and mr.connection_id = ?`,
+			projectId, data.Options.ConnectionId),
+		dal.Orderby("_tool_gitlab_reviewers.merge_request_id ASC"),
+	}
+
+	cursor, err := db.Cursor(clauses...)
+	if err != nil {
+		return err
+	}
+	defer cursor.Close()
+
+	mrIdGen := didgen.NewDomainIdGenerator(&models.GitlabMergeRequest{})
+
+	converter, err := helper.NewDataConverter(helper.DataConverterArgs{
+		RawDataSubTaskArgs: *rawDataSubTaskArgs,
+		InputRowType:       reflect.TypeOf(models.GitlabReviewer{}),
+		Input:              cursor,
+		Convert: func(inputRow interface{}) ([]interface{}, errors.Error) {
+			mrReviewer := inputRow.(*models.GitlabReviewer)
+			domainPrReviewer := &code.PullRequestReviewer{
+				PullRequestId: mrIdGen.Generate(data.Options.ConnectionId, mrReviewer.MergeRequestId),
+				ReviewerId:    mrReviewer.ReviewerId,
+				Name:          mrReviewer.Name,
+				UserName:      mrReviewer.Username,
+			}
+			return []interface{}{
+				domainPrReviewer,
+			}, nil
+		},
+	})
+	if err != nil {
+		return err
+	}
+
+	return converter.Execute()
+}