diff --git a/modules/migrations/gitea_downloader.go b/modules/migrations/gitea_downloader.go
index 665466ffef..2ed6c9113d 100644
--- a/modules/migrations/gitea_downloader.go
+++ b/modules/migrations/gitea_downloader.go
@@ -181,7 +181,7 @@ func (g *GiteaDownloader) GetMilestones() ([]*base.Milestone, error) {
 
 		for i := range ms {
 			// old gitea instances dont have this information
-			createdAT := time.Now()
+			createdAT := time.Time{}
 			var updatedAT *time.Time
 			if ms[i].Closed != nil {
 				createdAT = *ms[i].Closed
@@ -548,11 +548,11 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques
 			assignees = append(assignees, pr.Assignees[i].UserName)
 		}
 
-		createdAt := time.Now()
+		createdAt := time.Time{}
 		if pr.Created != nil {
 			createdAt = *pr.Created
 		}
-		updatedAt := time.Now()
+		updatedAt := time.Time{}
 		if pr.Created != nil {
 			updatedAt = *pr.Updated
 		}
diff --git a/modules/migrations/gitea_downloader_test.go b/modules/migrations/gitea_downloader_test.go
index f62b19897c..7ce8aa0e0b 100644
--- a/modules/migrations/gitea_downloader_test.go
+++ b/modules/migrations/gitea_downloader_test.go
@@ -6,7 +6,6 @@ package migrations
 
 import (
 	"context"
-	"fmt"
 	"net/http"
 	"os"
 	"sort"
@@ -18,29 +17,6 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-func assertEqualIssue(t *testing.T, issueExp, issueGet *base.Issue) {
-	assert.EqualValues(t, issueExp.Number, issueGet.Number)
-	assert.EqualValues(t, issueExp.Title, issueGet.Title)
-	assert.EqualValues(t, issueExp.Content, issueGet.Content)
-	assert.EqualValues(t, issueExp.Milestone, issueGet.Milestone)
-	assert.EqualValues(t, issueExp.PosterID, issueGet.PosterID)
-	assert.EqualValues(t, issueExp.PosterName, issueGet.PosterName)
-	assert.EqualValues(t, issueExp.PosterEmail, issueGet.PosterEmail)
-	assert.EqualValues(t, issueExp.IsLocked, issueGet.IsLocked)
-	assert.EqualValues(t, issueExp.Created.Unix(), issueGet.Created.Unix())
-	assert.EqualValues(t, issueExp.Updated.Unix(), issueGet.Updated.Unix())
-	if issueExp.Closed != nil {
-		assert.EqualValues(t, issueExp.Closed.Unix(), issueGet.Closed.Unix())
-	} else {
-		assert.True(t, issueGet.Closed == nil)
-	}
-	sort.Strings(issueExp.Assignees)
-	sort.Strings(issueGet.Assignees)
-	assert.EqualValues(t, issueExp.Assignees, issueGet.Assignees)
-	assert.EqualValues(t, issueExp.Labels, issueGet.Labels)
-	assert.EqualValues(t, issueExp.Reactions, issueGet.Reactions)
-}
-
 func TestGiteaDownloadRepo(t *testing.T) {
 	// Skip tests if Gitea token is not found
 	giteaToken := os.Getenv("GITEA_TOKEN")
@@ -63,7 +39,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
 
 	repo, err := downloader.GetRepoInfo()
 	assert.NoError(t, err)
-	assert.EqualValues(t, &base.Repository{
+	assertRepositoryEqual(t, &base.Repository{
 		Name:          "test_repo",
 		Owner:         "gitea",
 		IsPrivate:     false,
@@ -80,54 +56,57 @@ func TestGiteaDownloadRepo(t *testing.T) {
 
 	labels, err := downloader.GetLabels()
 	assert.NoError(t, err)
-	assert.Len(t, labels, 6)
-	for _, l := range labels {
-		switch l.Name {
-		case "Bug":
-			assertLabelEqual(t, "Bug", "e11d21", "", l)
-		case "documentation":
-			assertLabelEqual(t, "Enhancement", "207de5", "", l)
-		case "confirmed":
-			assertLabelEqual(t, "Feature", "0052cc", "a feature request", l)
-		case "enhancement":
-			assertLabelEqual(t, "Invalid", "d4c5f9", "", l)
-		case "critical":
-			assertLabelEqual(t, "Question", "fbca04", "", l)
-		case "discussion":
-			assertLabelEqual(t, "Valid", "53e917", "", l)
-		default:
-			assert.Error(t, fmt.Errorf("unexpected label: %s", l.Name))
-		}
-	}
+	assertLabelsEqual(t, []*base.Label{
+		{
+			Name:  "Bug",
+			Color: "e11d21",
+		},
+		{
+			Name:  "Enhancement",
+			Color: "207de5",
+		},
+		{
+			Name:        "Feature",
+			Color:       "0052cc",
+			Description: "a feature request",
+		},
+		{
+			Name:  "Invalid",
+			Color: "d4c5f9",
+		},
+		{
+			Name:  "Question",
+			Color: "fbca04",
+		},
+		{
+			Name:  "Valid",
+			Color: "53e917",
+		},
+	}, labels)
 
 	milestones, err := downloader.GetMilestones()
 	assert.NoError(t, err)
-	assert.Len(t, milestones, 2)
-
-	for _, milestone := range milestones {
-		switch milestone.Title {
-		case "V1":
-			assert.EqualValues(t, "Generate Content", milestone.Description)
-			// assert.EqualValues(t, "ToDo", milestone.Created)
-			// assert.EqualValues(t, "ToDo", milestone.Updated)
-			assert.EqualValues(t, 1598985406, milestone.Closed.Unix())
-			assert.True(t, milestone.Deadline == nil)
-			assert.EqualValues(t, "closed", milestone.State)
-		case "V2 Finalize":
-			assert.EqualValues(t, "", milestone.Description)
-			// assert.EqualValues(t, "ToDo", milestone.Created)
-			// assert.EqualValues(t, "ToDo", milestone.Updated)
-			assert.True(t, milestone.Closed == nil)
-			assert.EqualValues(t, 1599263999, milestone.Deadline.Unix())
-			assert.EqualValues(t, "open", milestone.State)
-		default:
-			assert.Error(t, fmt.Errorf("unexpected milestone: %s", milestone.Title))
-		}
-	}
+	assertMilestonesEqual(t, []*base.Milestone{
+		{
+			Title:    "V2 Finalize",
+			Created:  time.Unix(0, 0),
+			Deadline: timePtr(time.Unix(1599263999, 0)),
+			Updated:  timePtr(time.Unix(0, 0)),
+			State:    "open",
+		},
+		{
+			Title:       "V1",
+			Description: "Generate Content",
+			Created:     time.Unix(0, 0),
+			Updated:     timePtr(time.Unix(0, 0)),
+			Closed:      timePtr(time.Unix(1598985406, 0)),
+			State:       "closed",
+		},
+	}, milestones)
 
 	releases, err := downloader.GetReleases()
 	assert.NoError(t, err)
-	assert.EqualValues(t, []*base.Release{
+	assertReleasesEqual(t, []*base.Release{
 		{
 			Name:            "Second Release",
 			TagName:         "v2-rc1",
@@ -139,7 +118,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
 			Published:       time.Date(2020, 9, 1, 18, 2, 43, 0, time.UTC),
 			PublisherID:     689,
 			PublisherName:   "6543",
-			PublisherEmail:  "6543@noreply.gitea.io",
+			PublisherEmail:  "6543@obermui.de",
 		},
 		{
 			Name:            "First Release",
@@ -152,95 +131,85 @@ func TestGiteaDownloadRepo(t *testing.T) {
 			Published:       time.Date(2020, 9, 1, 17, 30, 32, 0, time.UTC),
 			PublisherID:     689,
 			PublisherName:   "6543",
-			PublisherEmail:  "6543@noreply.gitea.io",
+			PublisherEmail:  "6543@obermui.de",
 		},
 	}, releases)
 
 	issues, isEnd, err := downloader.GetIssues(1, 50)
 	assert.NoError(t, err)
-	assert.Len(t, issues, 7)
 	assert.True(t, isEnd)
+	assert.Len(t, issues, 7)
 	assert.EqualValues(t, "open", issues[0].State)
 
 	issues, isEnd, err = downloader.GetIssues(3, 2)
 	assert.NoError(t, err)
-	assert.Len(t, issues, 2)
 	assert.False(t, isEnd)
 
-	var (
-		closed4 = time.Date(2020, 9, 1, 15, 49, 34, 0, time.UTC)
-		closed2 = time.Unix(1598969497, 0)
-	)
-
-	assertEqualIssue(t, &base.Issue{
-		Number:      4,
-		Title:       "what is this repo about?",
-		Content:     "",
-		Milestone:   "V1",
-		PosterID:    -1,
-		PosterName:  "Ghost",
-		PosterEmail: "",
-		State:       "closed",
-		IsLocked:    true,
-		Created:     time.Unix(1598975321, 0),
-		Updated:     time.Unix(1598975400, 0),
-		Labels: []*base.Label{{
-			Name:        "Question",
-			Color:       "fbca04",
-			Description: "",
-		}},
-		Reactions: []*base.Reaction{
-			{
-				UserID:   689,
-				UserName: "6543",
-				Content:  "gitea",
-			},
-			{
-				UserID:   689,
-				UserName: "6543",
-				Content:  "laugh",
+	assertIssuesEqual(t, []*base.Issue{
+		{
+			Number:      4,
+			Title:       "what is this repo about?",
+			Content:     "",
+			Milestone:   "V1",
+			PosterID:    -1,
+			PosterName:  "Ghost",
+			PosterEmail: "",
+			State:       "closed",
+			IsLocked:    true,
+			Created:     time.Unix(1598975321, 0),
+			Updated:     time.Unix(1598975400, 0),
+			Labels: []*base.Label{{
+				Name:        "Question",
+				Color:       "fbca04",
+				Description: "",
+			}},
+			Reactions: []*base.Reaction{
+				{
+					UserID:   689,
+					UserName: "6543",
+					Content:  "gitea",
+				},
+				{
+					UserID:   689,
+					UserName: "6543",
+					Content:  "laugh",
+				},
 			},
+			Closed: timePtr(time.Date(2020, 9, 1, 15, 49, 34, 0, time.UTC)),
 		},
-		Closed: &closed4,
-	}, issues[0])
-	assertEqualIssue(t, &base.Issue{
-		Number:      2,
-		Title:       "Spam",
-		Content:     ":(",
-		Milestone:   "",
-		PosterID:    689,
-		PosterName:  "6543",
-		PosterEmail: "6543@noreply.gitea.io",
-		State:       "closed",
-		IsLocked:    false,
-		Created:     time.Unix(1598919780, 0),
-		Updated:     closed2,
-		Labels: []*base.Label{{
-			Name:        "Invalid",
-			Color:       "d4c5f9",
-			Description: "",
-		}},
-		Reactions: nil,
-		Closed:    &closed2,
-	}, issues[1])
+		{
+			Number:      2,
+			Title:       "Spam",
+			Content:     ":(",
+			Milestone:   "",
+			PosterID:    689,
+			PosterName:  "6543",
+			PosterEmail: "6543@obermui.de",
+			State:       "closed",
+			IsLocked:    false,
+			Created:     time.Unix(1598919780, 0),
+			Updated:     time.Unix(1598969497, 0),
+			Labels: []*base.Label{{
+				Name:        "Invalid",
+				Color:       "d4c5f9",
+				Description: "",
+			}},
+			Closed: timePtr(time.Unix(1598969497, 0)),
+		},
+	}, issues)
 
 	comments, _, err := downloader.GetComments(base.GetCommentOptions{
 		IssueNumber: 4,
 	})
 	assert.NoError(t, err)
-	assert.Len(t, comments, 2)
-	assert.EqualValues(t, 1598975370, comments[0].Created.Unix())
-	assert.EqualValues(t, 1599070865, comments[0].Updated.Unix())
-	assert.EqualValues(t, 1598975393, comments[1].Created.Unix())
-	assert.EqualValues(t, 1598975393, comments[1].Updated.Unix())
-	assert.EqualValues(t, []*base.Comment{
+	assertCommentsEqual(t, []*base.Comment{
 		{
 			IssueIndex:  4,
 			PosterID:    689,
 			PosterName:  "6543",
-			PosterEmail: "6543@noreply.gitea.io",
-			Created:     comments[0].Created,
-			Updated:     comments[0].Updated,
+			PosterEmail: "6543@obermui.de",
+			Created:     time.Unix(1598975370, 0),
+			Updated:     time.Unix(1599070865, 0),
 			Content:     "a really good question!\n\nIt is the used as TESTSET for gitea2gitea repo migration function",
 		},
 		{
@@ -248,8 +217,8 @@ func TestGiteaDownloadRepo(t *testing.T) {
 			PosterID:    -1,
 			PosterName:  "Ghost",
 			PosterEmail: "",
-			Created:     comments[1].Created,
-			Updated:     comments[1].Updated,
+			Created:     time.Unix(1598975393, 0),
+			Updated:     time.Unix(1598975393, 0),
 			Content:     "Oh!",
 		},
 	}, comments)
@@ -262,12 +231,11 @@ func TestGiteaDownloadRepo(t *testing.T) {
 	assert.NoError(t, err)
 	assert.False(t, isEnd)
 	assert.Len(t, prs, 3)
-	merged12 := time.Unix(1598982934, 0)
-	assertEqualPulls(t, &base.PullRequest{
+	assertPullRequestEqual(t, &base.PullRequest{
 		Number:      12,
 		PosterID:    689,
 		PosterName:  "6543",
-		PosterEmail: "6543@noreply.gitea.io",
+		PosterEmail: "6543@obermui.de",
 		Title:       "Dont Touch",
 		Content:     "\r\nadd dont touch note",
 		Milestone:   "V2 Finalize",
@@ -275,10 +243,8 @@ func TestGiteaDownloadRepo(t *testing.T) {
 		IsLocked:    false,
 		Created:     time.Unix(1598982759, 0),
 		Updated:     time.Unix(1599023425, 0),
-		Closed:      &merged12,
+		Closed:      timePtr(time.Unix(1598982934, 0)),
 		Assignees:   []string{"techknowlogick"},
-		Labels:      []*base.Label{},
-
 		Base: base.PullRequestBranch{
 			CloneURL:  "",
 			Ref:       "master",
@@ -294,74 +260,59 @@ func TestGiteaDownloadRepo(t *testing.T) {
 			OwnerName: "6543-forks",
 		},
 		Merged:         true,
-		MergedTime:     &merged12,
+		MergedTime:     timePtr(time.Unix(1598982934, 0)),
 		MergeCommitSHA: "827aa28a907853e5ddfa40c8f9bc52471a2685fd",
 		PatchURL:       "https://gitea.com/gitea/test_repo/pulls/12.patch",
 	}, prs[1])
 
 	reviews, err := downloader.GetReviews(7)
 	assert.NoError(t, err)
-	if assert.Len(t, reviews, 3) {
-		assert.EqualValues(t, 689, reviews[0].ReviewerID)
-		assert.EqualValues(t, "6543", reviews[0].ReviewerName)
-		assert.EqualValues(t, "techknowlogick", reviews[1].ReviewerName)
-		assert.EqualValues(t, "techknowlogick", reviews[2].ReviewerName)
-		assert.False(t, reviews[1].Official)
-		assert.EqualValues(t, "I think this needs some changes", reviews[1].Content)
-		assert.EqualValues(t, "REQUEST_CHANGES", reviews[1].State)
-		assert.True(t, reviews[2].Official)
-		assert.EqualValues(t, "looks good", reviews[2].Content)
-		assert.EqualValues(t, "APPROVED", reviews[2].State)
-
-		// TODO: https://github.com/go-gitea/gitea/issues/12846
-		// assert.EqualValues(t, 9, reviews[1].ReviewerID)
-		// assert.EqualValues(t, 9, reviews[2].ReviewerID)
-
-		assert.Len(t, reviews[0].Comments, 1)
-		assert.EqualValues(t, &base.ReviewComment{
-			ID:        116561,
-			InReplyTo: 0,
-			Content:   "is one `\\newline` to less?",
-			TreePath:  "README.md",
-			DiffHunk:  "@@ -2,3 +2,3 @@\n \n-Test repository for testing migration from gitea 2 gitea\n\\ No newline at end of file\n+Test repository for testing migration from gitea 2 gitea",
-			Position:  0,
-			Line:      4,
-			CommitID:  "187ece0cb6631e2858a6872e5733433bb3ca3b03",
-			PosterID:  689,
-			Reactions: nil,
-			CreatedAt: time.Date(2020, 9, 1, 16, 12, 58, 0, time.UTC),
-			UpdatedAt: time.Date(2020, 9, 1, 16, 12, 58, 0, time.UTC),
-		}, reviews[0].Comments[0])
-	}
-}
-
-func assertEqualPulls(t *testing.T, pullExp, pullGet *base.PullRequest) {
-	assertEqualIssue(t, pull2issue(pullExp), pull2issue(pullGet))
-	assert.EqualValues(t, 0, pullGet.OriginalNumber)
-	assert.EqualValues(t, pullExp.PatchURL, pullGet.PatchURL)
-	assert.EqualValues(t, pullExp.Merged, pullGet.Merged)
-	assert.EqualValues(t, pullExp.MergedTime.Unix(), pullGet.MergedTime.Unix())
-	assert.EqualValues(t, pullExp.MergeCommitSHA, pullGet.MergeCommitSHA)
-	assert.EqualValues(t, pullExp.Base, pullGet.Base)
-	assert.EqualValues(t, pullExp.Head, pullGet.Head)
-}
-
-func pull2issue(pull *base.PullRequest) *base.Issue {
-	return &base.Issue{
-		Number:      pull.Number,
-		PosterID:    pull.PosterID,
-		PosterName:  pull.PosterName,
-		PosterEmail: pull.PosterEmail,
-		Title:       pull.Title,
-		Content:     pull.Content,
-		Milestone:   pull.Milestone,
-		State:       pull.State,
-		IsLocked:    pull.IsLocked,
-		Created:     pull.Created,
-		Updated:     pull.Updated,
-		Closed:      pull.Closed,
-		Labels:      pull.Labels,
-		Reactions:   pull.Reactions,
-		Assignees:   pull.Assignees,
-	}
+	assertReviewsEqual(t, []*base.Review{
+		{
+			ID:           1770,
+			IssueIndex:   7,
+			ReviewerID:   689,
+			ReviewerName: "6543",
+			CommitID:     "187ece0cb6631e2858a6872e5733433bb3ca3b03",
+			CreatedAt:    time.Date(2020, 9, 1, 16, 12, 58, 0, time.UTC),
+			State:        "COMMENT", // TODO
+			Comments: []*base.ReviewComment{
+				{
+					ID:        116561,
+					InReplyTo: 0,
+					Content:   "is one `\\newline` to less?",
+					TreePath:  "README.md",
+					DiffHunk:  "@@ -2,3 +2,3 @@\n \n-Test repository for testing migration from gitea 2 gitea\n\\ No newline at end of file\n+Test repository for testing migration from gitea 2 gitea",
+					Position:  0,
+					Line:      4,
+					CommitID:  "187ece0cb6631e2858a6872e5733433bb3ca3b03",
+					PosterID:  689,
+					Reactions: nil,
+					CreatedAt: time.Date(2020, 9, 1, 16, 12, 58, 0, time.UTC),
+					UpdatedAt: time.Date(2020, 9, 1, 16, 12, 58, 0, time.UTC),
+				},
+			},
+		},
+		{
+			ID:           1771,
+			IssueIndex:   7,
+			ReviewerID:   9,
+			ReviewerName: "techknowlogick",
+			CommitID:     "187ece0cb6631e2858a6872e5733433bb3ca3b03",
+			CreatedAt:    time.Date(2020, 9, 1, 17, 6, 47, 0, time.UTC),
+			State:        "REQUEST_CHANGES", // TODO
+			Content:      "I think this needs some changes",
+		},
+		{
+			ID:           1772,
+			IssueIndex:   7,
+			ReviewerID:   9,
+			ReviewerName: "techknowlogick",
+			CommitID:     "187ece0cb6631e2858a6872e5733433bb3ca3b03",
+			CreatedAt:    time.Date(2020, 9, 1, 17, 19, 51, 0, time.UTC),
+			State:        base.ReviewStateApproved,
+			Official:     true,
+			Content:      "looks good",
+		},
+	}, reviews)
 }
diff --git a/modules/migrations/gitea_uploader.go b/modules/migrations/gitea_uploader.go
index e852d0f885..01fb9bda8a 100644
--- a/modules/migrations/gitea_uploader.go
+++ b/modules/migrations/gitea_uploader.go
@@ -165,11 +165,27 @@ func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) err
 		if deadline == 0 {
 			deadline = timeutil.TimeStamp(time.Date(9999, 1, 1, 0, 0, 0, 0, setting.DefaultUILocation).Unix())
 		}
+
+		if milestone.Created.IsZero() {
+			if milestone.Updated != nil {
+				milestone.Created = *milestone.Updated
+			} else if milestone.Deadline != nil {
+				milestone.Created = *milestone.Deadline
+			} else {
+				milestone.Created = time.Now()
+			}
+		}
+		if milestone.Updated == nil || milestone.Updated.IsZero() {
+			milestone.Updated = &milestone.Created
+		}
+
 		var ms = models.Milestone{
 			RepoID:       g.repo.ID,
 			Name:         milestone.Title,
 			Content:      milestone.Description,
 			IsClosed:     milestone.State == "closed",
+			CreatedUnix:  timeutil.TimeStamp(milestone.Created.Unix()),
+			UpdatedUnix:  timeutil.TimeStamp(milestone.Updated.Unix()),
 			DeadlineUnix: deadline,
 		}
 		if ms.IsClosed && milestone.Closed != nil {
@@ -215,6 +231,14 @@ func (g *GiteaLocalUploader) CreateLabels(labels ...*base.Label) error {
 func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error {
 	var rels = make([]*models.Release, 0, len(releases))
 	for _, release := range releases {
+		if release.Created.IsZero() {
+			if !release.Published.IsZero() {
+				release.Created = release.Published
+			} else {
+				release.Created = time.Now()
+			}
+		}
+
 		var rel = models.Release{
 			RepoID:       g.repo.ID,
 			TagName:      release.TagName,
@@ -263,6 +287,13 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error {
 		}
 
 		for _, asset := range release.Assets {
+			if asset.Created.IsZero() {
+				if !asset.Updated.IsZero() {
+					asset.Created = asset.Updated
+				} else {
+					asset.Created = release.Created
+				}
+			}
 			var attach = models.Attachment{
 				UUID:          gouuid.New().String(),
 				Name:          asset.Name,
@@ -332,6 +363,21 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {
 			}
 		}
 
+		if issue.Created.IsZero() {
+			if issue.Closed != nil {
+				issue.Created = *issue.Closed
+			} else {
+				issue.Created = time.Now()
+			}
+		}
+		if issue.Updated.IsZero() {
+			if issue.Closed != nil {
+				issue.Updated = *issue.Closed
+			} else {
+				issue.Updated = time.Now()
+			}
+		}
+
 		var is = models.Issue{
 			RepoID:      g.repo.ID,
 			Repo:        g.repo,
@@ -406,7 +452,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {
 		}
 
 		for _, is := range iss {
-			g.issues.Store(is.Index, is.ID)
+			g.issues.Store(is.Index, is)
 		}
 	}
 
@@ -417,16 +463,17 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {
 func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error {
 	var cms = make([]*models.Comment, 0, len(comments))
 	for _, comment := range comments {
-		var issueID int64
-		if issueIDStr, ok := g.issues.Load(comment.IssueIndex); !ok {
-			issue, err := models.GetIssueByIndex(g.repo.ID, comment.IssueIndex)
+		var issue *models.Issue
+		issueInter, ok := g.issues.Load(comment.IssueIndex)
+		if !ok {
+			var err error
+			issue, err = models.GetIssueByIndex(g.repo.ID, comment.IssueIndex)
 			if err != nil {
 				return err
 			}
-			issueID = issue.ID
-			g.issues.Store(comment.IssueIndex, issueID)
+			g.issues.Store(comment.IssueIndex, issue)
 		} else {
-			issueID = issueIDStr.(int64)
+			issue = issueInter.(*models.Issue)
 		}
 
 		userid, ok := g.userMap[comment.PosterID]
@@ -442,8 +489,15 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error {
 			}
 		}
 
+		if comment.Created.IsZero() {
+			comment.Created = time.Unix(int64(issue.CreatedUnix), 0)
+		}
+		if comment.Updated.IsZero() {
+			comment.Updated = comment.Created
+		}
+
 		cm := models.Comment{
-			IssueID:     issueID,
+			IssueID:     issue.ID,
 			Type:        models.CommentTypeComment,
 			Content:     comment.Content,
 			CreatedUnix: timeutil.TimeStamp(comment.Created.Unix()),
@@ -530,7 +584,7 @@ func (g *GiteaLocalUploader) CreatePullRequests(prs ...*base.PullRequest) error
 		return err
 	}
 	for _, pr := range gprs {
-		g.issues.Store(pr.Issue.Index, pr.Issue.ID)
+		g.issues.Store(pr.Issue.Index, pr.Issue)
 		pull.AddToTaskQueue(pr)
 	}
 	return nil
@@ -634,6 +688,19 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR
 		head = pr.Head.Ref
 	}
 
+	if pr.Created.IsZero() {
+		if pr.Closed != nil {
+			pr.Created = *pr.Closed
+		} else if pr.MergedTime != nil {
+			pr.Created = *pr.MergedTime
+		} else {
+			pr.Created = time.Now()
+		}
+	}
+	if pr.Updated.IsZero() {
+		pr.Updated = pr.Created
+	}
+
 	var issue = models.Issue{
 		RepoID:      g.repo.ID,
 		Repo:        g.repo,
@@ -743,16 +810,17 @@ func convertReviewState(state string) models.ReviewType {
 func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error {
 	var cms = make([]*models.Review, 0, len(reviews))
 	for _, review := range reviews {
-		var issueID int64
-		if issueIDStr, ok := g.issues.Load(review.IssueIndex); !ok {
-			issue, err := models.GetIssueByIndex(g.repo.ID, review.IssueIndex)
+		var issue *models.Issue
+		issueInter, ok := g.issues.Load(review.IssueIndex)
+		if !ok {
+			var err error
+			issue, err = models.GetIssueByIndex(g.repo.ID, review.IssueIndex)
 			if err != nil {
 				return err
 			}
-			issueID = issue.ID
-			g.issues.Store(review.IssueIndex, issueID)
+			g.issues.Store(review.IssueIndex, issue)
 		} else {
-			issueID = issueIDStr.(int64)
+			issue = issueInter.(*models.Issue)
 		}
 
 		userid, ok := g.userMap[review.ReviewerID]
@@ -768,9 +836,13 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error {
 			}
 		}
 
+		if review.CreatedAt.IsZero() {
+			review.CreatedAt = time.Unix(int64(issue.CreatedUnix), 0)
+		}
+
 		var cm = models.Review{
 			Type:        convertReviewState(review.State),
-			IssueID:     issueID,
+			IssueID:     issue.ID,
 			Content:     review.Content,
 			Official:    review.Official,
 			CreatedUnix: timeutil.TimeStamp(review.CreatedAt.Unix()),
@@ -786,14 +858,14 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error {
 		}
 
 		// get pr
-		pr, ok := g.prCache[issueID]
+		pr, ok := g.prCache[issue.ID]
 		if !ok {
 			var err error
-			pr, err = models.GetPullRequestByIssueIDWithNoAttributes(issueID)
+			pr, err = models.GetPullRequestByIssueIDWithNoAttributes(issue.ID)
 			if err != nil {
 				return err
 			}
-			g.prCache[issueID] = pr
+			g.prCache[issue.ID] = pr
 		}
 
 		for _, comment := range review.Comments {
@@ -824,10 +896,17 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error {
 
 			patch, _ = git.CutDiffAroundLine(reader, int64((&models.Comment{Line: int64(line + comment.Position - 1)}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines)
 
+			if comment.CreatedAt.IsZero() {
+				comment.CreatedAt = review.CreatedAt
+			}
+			if comment.UpdatedAt.IsZero() {
+				comment.UpdatedAt = comment.CreatedAt
+			}
+
 			var c = models.Comment{
 				Type:        models.CommentTypeCode,
 				PosterID:    comment.PosterID,
-				IssueID:     issueID,
+				IssueID:     issue.ID,
 				Content:     comment.Content,
 				Line:        int64(line + comment.Position - 1),
 				TreePath:    comment.TreePath,
diff --git a/modules/migrations/gitea_uploader_test.go b/modules/migrations/gitea_uploader_test.go
index 2f854ba368..032393032b 100644
--- a/modules/migrations/gitea_uploader_test.go
+++ b/modules/migrations/gitea_uploader_test.go
@@ -70,7 +70,7 @@ func TestGiteaUploadRepo(t *testing.T) {
 
 	labels, err := models.GetLabelsByRepoID(repo.ID, "", models.ListOptions{})
 	assert.NoError(t, err)
-	assert.Len(t, labels, 11)
+	assert.Len(t, labels, 12)
 
 	releases, err := models.GetReleasesByRepoID(repo.ID, models.FindReleasesOptions{
 		ListOptions: models.ListOptions{
@@ -98,7 +98,7 @@ func TestGiteaUploadRepo(t *testing.T) {
 		SortType: "oldest",
 	})
 	assert.NoError(t, err)
-	assert.Len(t, issues, 14)
+	assert.Len(t, issues, 15)
 	assert.NoError(t, issues[0].LoadDiscussComments())
 	assert.Empty(t, issues[0].Comments)
 
@@ -106,7 +106,7 @@ func TestGiteaUploadRepo(t *testing.T) {
 		SortType: "oldest",
 	})
 	assert.NoError(t, err)
-	assert.Len(t, pulls, 34)
+	assert.Len(t, pulls, 30)
 	assert.NoError(t, pulls[0].LoadIssue())
 	assert.NoError(t, pulls[0].Issue.LoadDiscussComments())
 	assert.Len(t, pulls[0].Issue.Comments, 2)
diff --git a/modules/migrations/github_test.go b/modules/migrations/github_test.go
index e0ee2fea84..16d79d200c 100644
--- a/modules/migrations/github_test.go
+++ b/modules/migrations/github_test.go
@@ -16,53 +16,6 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-func assertMilestoneEqual(t *testing.T, description, title, dueOn, created, updated, closed, state string, ms *base.Milestone) {
-	var tmPtr *time.Time
-	if dueOn != "" {
-		tm, err := time.Parse("2006-01-02 15:04:05 -0700 MST", dueOn)
-		assert.NoError(t, err)
-		tmPtr = &tm
-	}
-	var (
-		createdTM time.Time
-		updatedTM *time.Time
-		closedTM  *time.Time
-	)
-	if created != "" {
-		var err error
-		createdTM, err = time.Parse("2006-01-02 15:04:05 -0700 MST", created)
-		assert.NoError(t, err)
-	}
-	if updated != "" {
-		updatedTemp, err := time.Parse("2006-01-02 15:04:05 -0700 MST", updated)
-		assert.NoError(t, err)
-		updatedTM = &updatedTemp
-	}
-	if closed != "" {
-		closedTemp, err := time.Parse("2006-01-02 15:04:05 -0700 MST", closed)
-		assert.NoError(t, err)
-		closedTM = &closedTemp
-	}
-
-	assert.EqualValues(t, &base.Milestone{
-		Description: description,
-		Title:       title,
-		Deadline:    tmPtr,
-		State:       state,
-		Created:     createdTM,
-		Updated:     updatedTM,
-		Closed:      closedTM,
-	}, ms)
-}
-
-func assertLabelEqual(t *testing.T, name, color, description string, label *base.Label) {
-	assert.EqualValues(t, &base.Label{
-		Name:        name,
-		Color:       color,
-		Description: description,
-	}, label)
-}
-
 func TestGitHubDownloadRepo(t *testing.T) {
 	GithubLimitRateRemaining = 3 //Wait at 3 remaining since we could have 3 CI in //
 	downloader := NewGithubDownloaderV3(context.Background(), "https://github.com", "", "", os.Getenv("GITHUB_READ_TOKEN"), "go-gitea", "test_repo")
@@ -71,7 +24,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
 
 	repo, err := downloader.GetRepoInfo()
 	assert.NoError(t, err)
-	assert.EqualValues(t, &base.Repository{
+	assertRepositoryEqual(t, &base.Repository{
 		Name:          "test_repo",
 		Owner:         "go-gitea",
 		Description:   "Test repository for testing migration from github to gitea",
@@ -86,52 +39,80 @@ func TestGitHubDownloadRepo(t *testing.T) {
 
 	milestones, err := downloader.GetMilestones()
 	assert.NoError(t, err)
-	assert.True(t, len(milestones) >= 2)
-
-	for _, milestone := range milestones {
-		switch milestone.Title {
-		case "1.0.0":
-			assertMilestoneEqual(t, "Milestone 1.0.0", "1.0.0", "2019-11-11 08:00:00 +0000 UTC",
-				"2019-11-12 19:37:08 +0000 UTC",
-				"2019-11-12 21:56:17 +0000 UTC",
-				"2019-11-12 19:45:49 +0000 UTC",
-				"closed", milestone)
-		case "1.1.0":
-			assertMilestoneEqual(t, "Milestone 1.1.0", "1.1.0", "2019-11-12 08:00:00 +0000 UTC",
-				"2019-11-12 19:37:25 +0000 UTC",
-				"2019-11-12 21:39:27 +0000 UTC",
-				"2019-11-12 19:45:46 +0000 UTC",
-				"closed", milestone)
-		}
-	}
+	assertMilestonesEqual(t, []*base.Milestone{
+		{
+			Title:       "1.0.0",
+			Description: "Milestone 1.0.0",
+			Deadline:    timePtr(time.Date(2019, 11, 11, 8, 0, 0, 0, time.UTC)),
+			Created:     time.Date(2019, 11, 12, 19, 37, 8, 0, time.UTC),
+			Updated:     timePtr(time.Date(2019, 11, 12, 21, 56, 17, 0, time.UTC)),
+			Closed:      timePtr(time.Date(2019, 11, 12, 19, 45, 49, 0, time.UTC)),
+			State:       "closed",
+		},
+		{
+			Title:       "1.1.0",
+			Description: "Milestone 1.1.0",
+			Deadline:    timePtr(time.Date(2019, 11, 12, 8, 0, 0, 0, time.UTC)),
+			Created:     time.Date(2019, 11, 12, 19, 37, 25, 0, time.UTC),
+			Updated:     timePtr(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
+			Closed:      timePtr(time.Date(2019, 11, 12, 19, 45, 46, 0, time.UTC)),
+			State:       "closed",
+		},
+	}, milestones)
 
 	labels, err := downloader.GetLabels()
 	assert.NoError(t, err)
-	assert.True(t, len(labels) >= 8)
-	for _, l := range labels {
-		switch l.Name {
-		case "bug":
-			assertLabelEqual(t, "bug", "d73a4a", "Something isn't working", l)
-		case "documentation":
-			assertLabelEqual(t, "documentation", "0075ca", "Improvements or additions to documentation", l)
-		case "duplicate":
-			assertLabelEqual(t, "duplicate", "cfd3d7", "This issue or pull request already exists", l)
-		case "enhancement":
-			assertLabelEqual(t, "enhancement", "a2eeef", "New feature or request", l)
-		case "good first issue":
-			assertLabelEqual(t, "good first issue", "7057ff", "Good for newcomers", l)
-		case "help wanted":
-			assertLabelEqual(t, "help wanted", "008672", "Extra attention is needed", l)
-		case "invalid":
-			assertLabelEqual(t, "invalid", "e4e669", "This doesn't seem right", l)
-		case "question":
-			assertLabelEqual(t, "question", "d876e3", "Further information is requested", l)
-		}
-	}
+	assertLabelsEqual(t, []*base.Label{
+		{
+			Name:        "bug",
+			Color:       "d73a4a",
+			Description: "Something isn't working",
+		},
+		{
+			Name:        "documentation",
+			Color:       "0075ca",
+			Description: "Improvements or additions to documentation",
+		},
+		{
+			Name:        "duplicate",
+			Color:       "cfd3d7",
+			Description: "This issue or pull request already exists",
+		},
+		{
+			Name:        "enhancement",
+			Color:       "a2eeef",
+			Description: "New feature or request",
+		},
+		{
+			Name:        "good first issue",
+			Color:       "7057ff",
+			Description: "Good for newcomers",
+		},
+		{
+			Name:        "help wanted",
+			Color:       "008672",
+			Description: "Extra attention is needed",
+		},
+		{
+			Name:        "invalid",
+			Color:       "e4e669",
+			Description: "This doesn't seem right",
+		},
+		{
+			Name:        "question",
+			Color:       "d876e3",
+			Description: "Further information is requested",
+		},
+		{
+			Name:        "wontfix",
+			Color:       "ffffff",
+			Description: "This will not be worked on",
+		},
+	}, labels)
 
 	releases, err := downloader.GetReleases()
 	assert.NoError(t, err)
-	assert.EqualValues(t, []*base.Release{
+	assertReleasesEqual(t, []*base.Release{
 		{
 			TagName:         "v0.9.99",
 			TargetCommitish: "master",
@@ -142,19 +123,13 @@ func TestGitHubDownloadRepo(t *testing.T) {
 			PublisherID:     1669571,
 			PublisherName:   "mrsdizzie",
 		},
-	}, releases[len(releases)-1:])
+	}, releases)
 
 	// downloader.GetIssues()
 	issues, isEnd, err := downloader.GetIssues(1, 2)
 	assert.NoError(t, err)
-	assert.Len(t, issues, 2)
 	assert.False(t, isEnd)
-
-	var (
-		closed1 = time.Date(2019, 11, 12, 20, 22, 22, 0, time.UTC)
-		closed2 = time.Date(2019, 11, 12, 21, 1, 31, 0, time.UTC)
-	)
-	assert.EqualValues(t, []*base.Issue{
+	assertIssuesEqual(t, []*base.Issue{
 		{
 			Number:     1,
 			Title:      "Please add an animated gif icon to the merge button",
@@ -184,7 +159,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
 					Content:  "+1",
 				},
 			},
-			Closed: &closed1,
+			Closed: timePtr(time.Date(2019, 11, 12, 20, 22, 22, 0, time.UTC)),
 		},
 		{
 			Number:     2,
@@ -235,7 +210,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
 					Content:  "+1",
 				},
 			},
-			Closed: &closed2,
+			Closed: timePtr(time.Date(2019, 11, 12, 21, 1, 31, 0, time.UTC)),
 		},
 	}, issues)
 
@@ -244,8 +219,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
 		IssueNumber: 2,
 	})
 	assert.NoError(t, err)
-	assert.Len(t, comments, 2)
-	assert.EqualValues(t, []*base.Comment{
+	assertCommentsEqual(t, []*base.Comment{
 		{
 			IssueIndex: 2,
 			PosterID:   1669571,
@@ -270,17 +244,12 @@ func TestGitHubDownloadRepo(t *testing.T) {
 			Content:    "A second comment",
 			Reactions:  nil,
 		},
-	}, comments[:2])
+	}, comments)
 
 	// downloader.GetPullRequests()
 	prs, _, err := downloader.GetPullRequests(1, 2)
 	assert.NoError(t, err)
-	assert.Len(t, prs, 2)
-
-	closed1 = time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)
-	var merged1 = time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)
-
-	assert.EqualValues(t, []*base.PullRequest{
+	assertPullRequestsEqual(t, []*base.PullRequest{
 		{
 			Number:     3,
 			Title:      "Update README.md",
@@ -313,9 +282,9 @@ func TestGitHubDownloadRepo(t *testing.T) {
 				OwnerName: "go-gitea",
 				RepoName:  "test_repo",
 			},
-			Closed:         &closed1,
+			Closed:         timePtr(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
 			Merged:         true,
-			MergedTime:     &merged1,
+			MergedTime:     timePtr(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
 			MergeCommitSHA: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
 		},
 		{
@@ -368,7 +337,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
 
 	reviews, err := downloader.GetReviews(3)
 	assert.NoError(t, err)
-	assert.EqualValues(t, []*base.Review{
+	assertReviewsEqual(t, []*base.Review{
 		{
 			ID:           315859956,
 			IssueIndex:   3,
@@ -400,7 +369,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
 
 	reviews, err = downloader.GetReviews(4)
 	assert.NoError(t, err)
-	assert.EqualValues(t, []*base.Review{
+	assertReviewsEqual(t, []*base.Review{
 		{
 			ID:           338338740,
 			IssueIndex:   4,
diff --git a/modules/migrations/gitlab.go b/modules/migrations/gitlab.go
index fe763f9900..1050ffd0c9 100644
--- a/modules/migrations/gitlab.go
+++ b/modules/migrations/gitlab.go
@@ -609,7 +609,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
 
 // GetReviews returns pull requests review
 func (g *GitlabDownloader) GetReviews(pullRequestNumber int64) ([]*base.Review, error) {
-	state, resp, err := g.client.MergeRequestApprovals.GetApprovalState(g.repoID, int(pullRequestNumber), gitlab.WithContext(g.ctx))
+	approvals, resp, err := g.client.MergeRequestApprovals.GetConfiguration(g.repoID, int(pullRequestNumber), gitlab.WithContext(g.ctx))
 	if err != nil {
 		if resp != nil && resp.StatusCode == 404 {
 			log.Error(fmt.Sprintf("GitlabDownloader: while migrating a error occurred: '%s'", err.Error()))
@@ -618,21 +618,12 @@ func (g *GitlabDownloader) GetReviews(pullRequestNumber int64) ([]*base.Review,
 		return nil, err
 	}
 
-	// GitLab's Approvals are equivalent to Gitea's approve reviews
-	approvers := make(map[int]string)
-	for i := range state.Rules {
-		for u := range state.Rules[i].ApprovedBy {
-			approvers[state.Rules[i].ApprovedBy[u].ID] = state.Rules[i].ApprovedBy[u].Username
-		}
-	}
-
-	var reviews = make([]*base.Review, 0, len(approvers))
-	for id, name := range approvers {
+	var reviews = make([]*base.Review, 0, len(approvals.ApprovedBy))
+	for _, user := range approvals.ApprovedBy {
 		reviews = append(reviews, &base.Review{
-			ReviewerID:   int64(id),
-			ReviewerName: name,
-			// GitLab API doesn't return a creation date
-			CreatedAt: time.Now(),
+			ReviewerID:   int64(user.User.ID),
+			ReviewerName: user.User.Username,
+			CreatedAt:    *approvals.UpdatedAt,
 			// All we get are approvals
 			State: base.ReviewStateApproved,
 		})
diff --git a/modules/migrations/gitlab_test.go b/modules/migrations/gitlab_test.go
index 6a77ff3c23..8fd915e0f5 100644
--- a/modules/migrations/gitlab_test.go
+++ b/modules/migrations/gitlab_test.go
@@ -36,7 +36,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
 	repo, err := downloader.GetRepoInfo()
 	assert.NoError(t, err)
 	// Repo Owner is blank in Gitlab Group repos
-	assert.EqualValues(t, &base.Repository{
+	assertRepositoryEqual(t, &base.Repository{
 		Name:          "test_repo",
 		Owner:         "",
 		Description:   "Test repository for testing migration from gitlab to gitea",
@@ -52,56 +52,66 @@ func TestGitlabDownloadRepo(t *testing.T) {
 
 	milestones, err := downloader.GetMilestones()
 	assert.NoError(t, err)
-	assert.True(t, len(milestones) >= 2)
-
-	for _, milestone := range milestones {
-		switch milestone.Title {
-		case "1.0":
-			assertMilestoneEqual(t, "", "1.0",
-				"",
-				"2019-11-28 08:42:30.301 +0000 UTC",
-				"2019-11-28 15:57:52.401 +0000 UTC",
-				"",
-				"closed", milestone)
-		case "1.1.0":
-			assertMilestoneEqual(t, "", "1.1.0",
-				"",
-				"2019-11-28 08:42:44.575 +0000 UTC",
-				"2019-11-28 08:42:44.575 +0000 UTC",
-				"",
-				"active", milestone)
-		}
-	}
+	assertMilestonesEqual(t, []*base.Milestone{
+		{
+			Title:   "1.1.0",
+			Created: time.Date(2019, 11, 28, 8, 42, 44, 575000000, time.UTC),
+			Updated: timePtr(time.Date(2019, 11, 28, 8, 42, 44, 575000000, time.UTC)),
+			State:   "active",
+		},
+		{
+			Title:   "1.0.0",
+			Created: time.Date(2019, 11, 28, 8, 42, 30, 301000000, time.UTC),
+			Updated: timePtr(time.Date(2019, 11, 28, 15, 57, 52, 401000000, time.UTC)),
+			Closed:  timePtr(time.Date(2019, 11, 28, 15, 57, 52, 401000000, time.UTC)),
+			State:   "closed",
+		},
+	}, milestones)
 
 	labels, err := downloader.GetLabels()
 	assert.NoError(t, err)
-	assert.True(t, len(labels) >= 9)
-	for _, l := range labels {
-		switch l.Name {
-		case "bug":
-			assertLabelEqual(t, "bug", "d9534f", "", l)
-		case "documentation":
-			assertLabelEqual(t, "documentation", "f0ad4e", "", l)
-		case "confirmed":
-			assertLabelEqual(t, "confirmed", "d9534f", "", l)
-		case "enhancement":
-			assertLabelEqual(t, "enhancement", "5cb85c", "", l)
-		case "critical":
-			assertLabelEqual(t, "critical", "d9534f", "", l)
-		case "discussion":
-			assertLabelEqual(t, "discussion", "428bca", "", l)
-		case "suggestion":
-			assertLabelEqual(t, "suggestion", "428bca", "", l)
-		case "support":
-			assertLabelEqual(t, "support", "f0ad4e", "", l)
-		case "duplicate":
-			assertLabelEqual(t, "duplicate", "7F8C8D", "", l)
-		}
-	}
+	assertLabelsEqual(t, []*base.Label{
+		{
+			Name:  "bug",
+			Color: "d9534f",
+		},
+		{
+			Name:  "confirmed",
+			Color: "d9534f",
+		},
+		{
+			Name:  "critical",
+			Color: "d9534f",
+		},
+		{
+			Name:  "discussion",
+			Color: "428bca",
+		},
+		{
+			Name:  "documentation",
+			Color: "f0ad4e",
+		},
+		{
+			Name:  "duplicate",
+			Color: "7f8c8d",
+		},
+		{
+			Name:  "enhancement",
+			Color: "5cb85c",
+		},
+		{
+			Name:  "suggestion",
+			Color: "428bca",
+		},
+		{
+			Name:  "support",
+			Color: "f0ad4e",
+		},
+	}, labels)
 
 	releases, err := downloader.GetReleases()
 	assert.NoError(t, err)
-	assert.EqualValues(t, []*base.Release{
+	assertReleasesEqual(t, []*base.Release{
 		{
 			TagName:         "v0.9.99",
 			TargetCommitish: "0720a3ec57c1f843568298117b874319e7deee75",
@@ -111,18 +121,13 @@ func TestGitlabDownloadRepo(t *testing.T) {
 			PublisherID:     1241334,
 			PublisherName:   "lafriks",
 		},
-	}, releases[len(releases)-1:])
+	}, releases)
 
 	issues, isEnd, err := downloader.GetIssues(1, 2)
 	assert.NoError(t, err)
-	assert.Len(t, issues, 2)
 	assert.False(t, isEnd)
 
-	var (
-		closed1 = time.Date(2019, 11, 28, 8, 46, 23, 275000000, time.UTC)
-		closed2 = time.Date(2019, 11, 28, 8, 45, 44, 959000000, time.UTC)
-	)
-	assert.EqualValues(t, []*base.Issue{
+	assertIssuesEqual(t, []*base.Issue{
 		{
 			Number:     1,
 			Title:      "Please add an animated gif icon to the merge button",
@@ -152,7 +157,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
 					UserName: "lafriks",
 					Content:  "open_mouth",
 				}},
-			Closed: &closed1,
+			Closed: timePtr(time.Date(2019, 11, 28, 8, 46, 23, 275000000, time.UTC)),
 		},
 		{
 			Number:     2,
@@ -200,7 +205,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
 					UserName: "lafriks",
 					Content:  "hearts",
 				}},
-			Closed: &closed2,
+			Closed: timePtr(time.Date(2019, 11, 28, 8, 45, 44, 959000000, time.UTC)),
 		},
 	}, issues)
 
@@ -208,8 +213,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
 		IssueNumber: 2,
 	})
 	assert.NoError(t, err)
-	assert.Len(t, comments, 4)
-	assert.EqualValues(t, []*base.Comment{
+	assertCommentsEqual(t, []*base.Comment{
 		{
 			IssueIndex: 2,
 			PosterID:   1241334,
@@ -242,13 +246,11 @@ func TestGitlabDownloadRepo(t *testing.T) {
 			Content:    "A second comment",
 			Reactions:  nil,
 		},
-	}, comments[:4])
+	}, comments)
 
 	prs, _, err := downloader.GetPullRequests(1, 1)
 	assert.NoError(t, err)
-	assert.Len(t, prs, 1)
-
-	assert.EqualValues(t, []*base.PullRequest{
+	assertPullRequestsEqual(t, []*base.PullRequest{
 		{
 			Number:         4,
 			OriginalNumber: 2,
@@ -296,27 +298,29 @@ func TestGitlabDownloadRepo(t *testing.T) {
 
 	rvs, err := downloader.GetReviews(1)
 	assert.NoError(t, err)
-	if assert.Len(t, rvs, 2) {
-		for i := range rvs {
-			switch rvs[i].ReviewerID {
-			case 4102996:
-				assert.EqualValues(t, "zeripath", rvs[i].ReviewerName)
-				assert.EqualValues(t, "APPROVED", rvs[i].State)
-			case 527793:
-				assert.EqualValues(t, "axifive", rvs[i].ReviewerName)
-				assert.EqualValues(t, "APPROVED", rvs[i].State)
-			default:
-				t.Errorf("Unexpected Reviewer ID: %d", rvs[i].ReviewerID)
+	assertReviewsEqual(t, []*base.Review{
+		{
+			ReviewerID:   4102996,
+			ReviewerName: "zeripath",
+			CreatedAt:    time.Date(2019, 11, 28, 16, 02, 8, 377000000, time.UTC),
+			State:        "APPROVED",
+		},
+		{
+			ReviewerID:   527793,
+			ReviewerName: "axifive",
+			CreatedAt:    time.Date(2019, 11, 28, 16, 02, 8, 377000000, time.UTC),
+			State:        "APPROVED",
+		},
+	}, rvs)
 
-			}
-		}
-	}
 	rvs, err = downloader.GetReviews(2)
 	assert.NoError(t, err)
-	if assert.Len(t, prs, 1) {
-		assert.EqualValues(t, 4575606, rvs[0].ReviewerID)
-		assert.EqualValues(t, "real6543", rvs[0].ReviewerName)
-		assert.EqualValues(t, "APPROVED", rvs[0].State)
-	}
-
+	assertReviewsEqual(t, []*base.Review{
+		{
+			ReviewerID:   4575606,
+			ReviewerName: "real6543",
+			CreatedAt:    time.Date(2020, 04, 19, 19, 24, 21, 108000000, time.UTC),
+			State:        "APPROVED",
+		},
+	}, rvs)
 }
diff --git a/modules/migrations/gogs.go b/modules/migrations/gogs.go
index 9e663fd1fe..388020c88a 100644
--- a/modules/migrations/gogs.go
+++ b/modules/migrations/gogs.go
@@ -146,16 +146,12 @@ func (g *GogsDownloader) GetMilestones() ([]*base.Milestone, error) {
 		return nil, err
 	}
 
-	t := time.Now()
-
 	for _, m := range ms {
 		milestones = append(milestones, &base.Milestone{
 			Title:       m.Title,
 			Description: m.Description,
 			Deadline:    m.Deadline,
 			State:       string(m.State),
-			Created:     t,
-			Updated:     &t,
 			Closed:      m.Closed,
 		})
 	}
@@ -294,12 +290,14 @@ func convertGogsIssue(issue *gogs.Issue) *base.Issue {
 	return &base.Issue{
 		Title:       issue.Title,
 		Number:      issue.Index,
+		PosterID:    issue.Poster.ID,
 		PosterName:  issue.Poster.Login,
 		PosterEmail: issue.Poster.Email,
 		Content:     issue.Body,
 		Milestone:   milestone,
 		State:       string(issue.State),
 		Created:     issue.Created,
+		Updated:     issue.Updated,
 		Labels:      labels,
 		Closed:      closed,
 	}
diff --git a/modules/migrations/gogs_test.go b/modules/migrations/gogs_test.go
index 4e384036d7..e5bd634c55 100644
--- a/modules/migrations/gogs_test.go
+++ b/modules/migrations/gogs_test.go
@@ -34,65 +34,73 @@ func TestGogsDownloadRepo(t *testing.T) {
 	repo, err := downloader.GetRepoInfo()
 	assert.NoError(t, err)
 
-	assert.EqualValues(t, &base.Repository{
-		Name:        "TESTREPO",
-		Owner:       "lunnytest",
-		Description: "",
-		CloneURL:    "https://try.gogs.io/lunnytest/TESTREPO.git",
+	assertRepositoryEqual(t, &base.Repository{
+		Name:          "TESTREPO",
+		Owner:         "lunnytest",
+		Description:   "",
+		CloneURL:      "https://try.gogs.io/lunnytest/TESTREPO.git",
+		OriginalURL:   "https://try.gogs.io/lunnytest/TESTREPO",
+		DefaultBranch: "master",
 	}, repo)
 
 	milestones, err := downloader.GetMilestones()
 	assert.NoError(t, err)
-	assert.True(t, len(milestones) == 1)
-
-	for _, milestone := range milestones {
-		switch milestone.Title {
-		case "1.0":
-			assert.EqualValues(t, "open", milestone.State)
-		}
-	}
+	assertMilestonesEqual(t, []*base.Milestone{
+		{
+			Title: "1.0",
+			State: "open",
+		},
+	}, milestones)
 
 	labels, err := downloader.GetLabels()
 	assert.NoError(t, err)
-	assert.Len(t, labels, 7)
-	for _, l := range labels {
-		switch l.Name {
-		case "bug":
-			assertLabelEqual(t, "bug", "ee0701", "", l)
-		case "duplicated":
-			assertLabelEqual(t, "duplicated", "cccccc", "", l)
-		case "enhancement":
-			assertLabelEqual(t, "enhancement", "84b6eb", "", l)
-		case "help wanted":
-			assertLabelEqual(t, "help wanted", "128a0c", "", l)
-		case "invalid":
-			assertLabelEqual(t, "invalid", "e6e6e6", "", l)
-		case "question":
-			assertLabelEqual(t, "question", "cc317c", "", l)
-		case "wontfix":
-			assertLabelEqual(t, "wontfix", "ffffff", "", l)
-		}
-	}
-
-	_, err = downloader.GetReleases()
-	assert.Error(t, err)
+	assertLabelsEqual(t, []*base.Label{
+		{
+			Name:  "bug",
+			Color: "ee0701",
+		},
+		{
+			Name:  "duplicate",
+			Color: "cccccc",
+		},
+		{
+			Name:  "enhancement",
+			Color: "84b6eb",
+		},
+		{
+			Name:  "help wanted",
+			Color: "128a0c",
+		},
+		{
+			Name:  "invalid",
+			Color: "e6e6e6",
+		},
+		{
+			Name:  "question",
+			Color: "cc317c",
+		},
+		{
+			Name:  "wontfix",
+			Color: "ffffff",
+		},
+	}, labels)
 
 	// downloader.GetIssues()
 	issues, isEnd, err := downloader.GetIssues(1, 8)
 	assert.NoError(t, err)
-	assert.Len(t, issues, 1)
 	assert.False(t, isEnd)
-
-	assert.EqualValues(t, []*base.Issue{
+	assertIssuesEqual(t, []*base.Issue{
 		{
 			Number:      1,
+			PosterID:    5331,
+			PosterName:  "lunny",
+			PosterEmail: "xiaolunwen@gmail.com",
 			Title:       "test",
 			Content:     "test",
 			Milestone:   "",
-			PosterName:  "lunny",
-			PosterEmail: "xiaolunwen@gmail.com",
 			State:       "open",
 			Created:     time.Date(2019, 06, 11, 8, 16, 44, 0, time.UTC),
+			Updated:     time.Date(2019, 10, 26, 11, 07, 2, 0, time.UTC),
 			Labels: []*base.Label{
 				{
 					Name:  "bug",
@@ -107,14 +115,24 @@ func TestGogsDownloadRepo(t *testing.T) {
 		IssueNumber: 1,
 	})
 	assert.NoError(t, err)
-	assert.Len(t, comments, 1)
-	assert.EqualValues(t, []*base.Comment{
+	assertCommentsEqual(t, []*base.Comment{
 		{
+			IssueIndex:  1,
+			PosterID:    5331,
 			PosterName:  "lunny",
 			PosterEmail: "xiaolunwen@gmail.com",
 			Created:     time.Date(2019, 06, 11, 8, 19, 50, 0, time.UTC),
 			Updated:     time.Date(2019, 06, 11, 8, 19, 50, 0, time.UTC),
-			Content:     `1111`,
+			Content:     "1111",
+		},
+		{
+			IssueIndex:  1,
+			PosterID:    15822,
+			PosterName:  "clacplouf",
+			PosterEmail: "test1234@dbn.re",
+			Created:     time.Date(2019, 10, 26, 11, 7, 2, 0, time.UTC),
+			Updated:     time.Date(2019, 10, 26, 11, 7, 2, 0, time.UTC),
+			Content:     "88888888",
 		},
 	}, comments)
 
diff --git a/modules/migrations/main_test.go b/modules/migrations/main_test.go
index a982ab3e6f..86aee4e86b 100644
--- a/modules/migrations/main_test.go
+++ b/modules/migrations/main_test.go
@@ -8,10 +8,259 @@ package migrations
 import (
 	"path/filepath"
 	"testing"
+	"time"
 
 	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/modules/migrations/base"
+
+	"github.com/stretchr/testify/assert"
 )
 
 func TestMain(m *testing.M) {
 	models.MainTest(m, filepath.Join("..", ".."))
 }
+
+func timePtr(t time.Time) *time.Time {
+	return &t
+}
+
+func assertTimeEqual(t *testing.T, expected, actual time.Time) {
+	assert.Equal(t, expected.UTC(), actual.UTC())
+}
+
+func assertTimePtrEqual(t *testing.T, expected, actual *time.Time) {
+	if expected == nil {
+		assert.Nil(t, actual)
+	} else {
+		assertTimeEqual(t, *expected, *actual)
+	}
+}
+
+func assertCommentEqual(t *testing.T, expected, actual *base.Comment) {
+	assert.Equal(t, expected.IssueIndex, actual.IssueIndex)
+	assert.Equal(t, expected.PosterID, actual.PosterID)
+	assert.Equal(t, expected.PosterName, actual.PosterName)
+	assert.Equal(t, expected.PosterEmail, actual.PosterEmail)
+	assertTimeEqual(t, expected.Created, actual.Created)
+	assertTimeEqual(t, expected.Updated, actual.Updated)
+	assert.Equal(t, expected.Content, actual.Content)
+	assertReactionsEqual(t, expected.Reactions, actual.Reactions)
+}
+
+func assertCommentsEqual(t *testing.T, expected, actual []*base.Comment) {
+	if assert.Len(t, actual, len(expected)) {
+		for i := range expected {
+			assertCommentEqual(t, expected[i], actual[i])
+		}
+	}
+}
+
+func assertLabelEqual(t *testing.T, expected, actual *base.Label) {
+	assert.Equal(t, expected.Name, actual.Name)
+	assert.Equal(t, expected.Color, actual.Color)
+	assert.Equal(t, expected.Description, actual.Description)
+}
+
+func assertLabelsEqual(t *testing.T, expected, actual []*base.Label) {
+	if assert.Len(t, actual, len(expected)) {
+		for i := range expected {
+			assertLabelEqual(t, expected[i], actual[i])
+		}
+	}
+}
+
+func assertMilestoneEqual(t *testing.T, expected, actual *base.Milestone) {
+	assert.Equal(t, expected.Title, actual.Title)
+	assert.Equal(t, expected.Description, actual.Description)
+	assertTimePtrEqual(t, expected.Deadline, actual.Deadline)
+	assertTimeEqual(t, expected.Created, actual.Created)
+	assertTimePtrEqual(t, expected.Updated, actual.Updated)
+	assertTimePtrEqual(t, expected.Closed, actual.Closed)
+	assert.Equal(t, expected.State, actual.State)
+}
+
+func assertMilestonesEqual(t *testing.T, expected, actual []*base.Milestone) {
+	if assert.Len(t, actual, len(expected)) {
+		for i := range expected {
+			assertMilestoneEqual(t, expected[i], actual[i])
+		}
+	}
+}
+
+func assertIssueEqual(t *testing.T, expected, actual *base.Issue) {
+	assert.Equal(t, expected.Number, actual.Number)
+	assert.Equal(t, expected.PosterID, actual.PosterID)
+	assert.Equal(t, expected.PosterName, actual.PosterName)
+	assert.Equal(t, expected.PosterEmail, actual.PosterEmail)
+	assert.Equal(t, expected.Title, actual.Title)
+	assert.Equal(t, expected.Content, actual.Content)
+	assert.Equal(t, expected.Ref, actual.Ref)
+	assert.Equal(t, expected.Milestone, actual.Milestone)
+	assert.Equal(t, expected.State, actual.State)
+	assert.Equal(t, expected.IsLocked, actual.IsLocked)
+	assertTimeEqual(t, expected.Created, actual.Created)
+	assertTimeEqual(t, expected.Updated, actual.Updated)
+	assertTimePtrEqual(t, expected.Closed, actual.Closed)
+	assertLabelsEqual(t, expected.Labels, actual.Labels)
+	assertReactionsEqual(t, expected.Reactions, actual.Reactions)
+	assert.ElementsMatch(t, expected.Assignees, actual.Assignees)
+}
+
+func assertIssuesEqual(t *testing.T, expected, actual []*base.Issue) {
+	if assert.Len(t, actual, len(expected)) {
+		for i := range expected {
+			assertIssueEqual(t, expected[i], actual[i])
+		}
+	}
+}
+
+func assertPullRequestEqual(t *testing.T, expected, actual *base.PullRequest) {
+	assert.Equal(t, expected.Number, actual.Number)
+	assert.Equal(t, expected.Title, actual.Title)
+	assert.Equal(t, expected.PosterID, actual.PosterID)
+	assert.Equal(t, expected.PosterName, actual.PosterName)
+	assert.Equal(t, expected.PosterEmail, actual.PosterEmail)
+	assert.Equal(t, expected.Content, actual.Content)
+	assert.Equal(t, expected.Milestone, actual.Milestone)
+	assert.Equal(t, expected.State, actual.State)
+	assertTimeEqual(t, expected.Created, actual.Created)
+	assertTimeEqual(t, expected.Updated, actual.Updated)
+	assertTimePtrEqual(t, expected.Closed, actual.Closed)
+	assertLabelsEqual(t, expected.Labels, actual.Labels)
+	assert.Equal(t, expected.PatchURL, actual.PatchURL)
+	assert.Equal(t, expected.Merged, actual.Merged)
+	assertTimePtrEqual(t, expected.MergedTime, actual.MergedTime)
+	assert.Equal(t, expected.MergeCommitSHA, actual.MergeCommitSHA)
+	assertPullRequestBranchEqual(t, expected.Head, actual.Head)
+	assertPullRequestBranchEqual(t, expected.Base, actual.Base)
+	assert.ElementsMatch(t, expected.Assignees, actual.Assignees)
+	assert.Equal(t, expected.IsLocked, actual.IsLocked)
+	assertReactionsEqual(t, expected.Reactions, actual.Reactions)
+}
+
+func assertPullRequestsEqual(t *testing.T, expected, actual []*base.PullRequest) {
+	if assert.Len(t, actual, len(expected)) {
+		for i := range expected {
+			assertPullRequestEqual(t, expected[i], actual[i])
+		}
+	}
+}
+
+func assertPullRequestBranchEqual(t *testing.T, expected, actual base.PullRequestBranch) {
+	assert.Equal(t, expected.CloneURL, actual.CloneURL)
+	assert.Equal(t, expected.Ref, actual.Ref)
+	assert.Equal(t, expected.SHA, actual.SHA)
+	assert.Equal(t, expected.RepoName, actual.RepoName)
+	assert.Equal(t, expected.OwnerName, actual.OwnerName)
+}
+
+func assertReactionEqual(t *testing.T, expected, actual *base.Reaction) {
+	assert.Equal(t, expected.UserID, actual.UserID)
+	assert.Equal(t, expected.UserName, actual.UserName)
+	assert.Equal(t, expected.Content, actual.Content)
+}
+
+func assertReactionsEqual(t *testing.T, expected, actual []*base.Reaction) {
+	if assert.Len(t, actual, len(expected)) {
+		for i := range expected {
+			assertReactionEqual(t, expected[i], actual[i])
+		}
+	}
+}
+
+func assertReleaseAssetEqual(t *testing.T, expected, actual *base.ReleaseAsset) {
+	assert.Equal(t, expected.ID, actual.ID)
+	assert.Equal(t, expected.Name, actual.Name)
+	assert.Equal(t, expected.ContentType, actual.ContentType)
+	assert.Equal(t, expected.Size, actual.Size)
+	assert.Equal(t, expected.DownloadCount, actual.DownloadCount)
+	assertTimeEqual(t, expected.Created, actual.Created)
+	assertTimeEqual(t, expected.Updated, actual.Updated)
+	assert.Equal(t, expected.DownloadURL, actual.DownloadURL)
+}
+
+func assertReleaseAssetsEqual(t *testing.T, expected, actual []*base.ReleaseAsset) {
+	if assert.Len(t, actual, len(expected)) {
+		for i := range expected {
+			assertReleaseAssetEqual(t, expected[i], actual[i])
+		}
+	}
+}
+
+func assertReleaseEqual(t *testing.T, expected, actual *base.Release) {
+	assert.Equal(t, expected.TagName, actual.TagName)
+	assert.Equal(t, expected.TargetCommitish, actual.TargetCommitish)
+	assert.Equal(t, expected.Name, actual.Name)
+	assert.Equal(t, expected.Body, actual.Body)
+	assert.Equal(t, expected.Draft, actual.Draft)
+	assert.Equal(t, expected.Prerelease, actual.Prerelease)
+	assert.Equal(t, expected.PublisherID, actual.PublisherID)
+	assert.Equal(t, expected.PublisherName, actual.PublisherName)
+	assert.Equal(t, expected.PublisherEmail, actual.PublisherEmail)
+	assertReleaseAssetsEqual(t, expected.Assets, actual.Assets)
+	assertTimeEqual(t, expected.Created, actual.Created)
+	assertTimeEqual(t, expected.Published, actual.Published)
+}
+
+func assertReleasesEqual(t *testing.T, expected, actual []*base.Release) {
+	if assert.Len(t, actual, len(expected)) {
+		for i := range expected {
+			assertReleaseEqual(t, expected[i], actual[i])
+		}
+	}
+}
+
+func assertRepositoryEqual(t *testing.T, expected, actual *base.Repository) {
+	assert.Equal(t, expected.Name, actual.Name)
+	assert.Equal(t, expected.Owner, actual.Owner)
+	assert.Equal(t, expected.IsPrivate, actual.IsPrivate)
+	assert.Equal(t, expected.IsMirror, actual.IsMirror)
+	assert.Equal(t, expected.Description, actual.Description)
+	assert.Equal(t, expected.CloneURL, actual.CloneURL)
+	assert.Equal(t, expected.OriginalURL, actual.OriginalURL)
+	assert.Equal(t, expected.DefaultBranch, actual.DefaultBranch)
+}
+
+func assertReviewEqual(t *testing.T, expected, actual *base.Review) {
+	assert.Equal(t, expected.ID, actual.ID)
+	assert.Equal(t, expected.IssueIndex, actual.IssueIndex)
+	assert.Equal(t, expected.ReviewerID, actual.ReviewerID)
+	assert.Equal(t, expected.ReviewerName, actual.ReviewerName)
+	assert.Equal(t, expected.Official, actual.Official)
+	assert.Equal(t, expected.CommitID, actual.CommitID)
+	assert.Equal(t, expected.Content, actual.Content)
+	assertTimeEqual(t, expected.CreatedAt, actual.CreatedAt)
+	assert.Equal(t, expected.State, actual.State)
+	assertReviewCommentsEqual(t, expected.Comments, actual.Comments)
+}
+
+func assertReviewsEqual(t *testing.T, expected, actual []*base.Review) {
+	if assert.Len(t, actual, len(expected)) {
+		for i := range expected {
+			assertReviewEqual(t, expected[i], actual[i])
+		}
+	}
+}
+
+func assertReviewCommentEqual(t *testing.T, expected, actual *base.ReviewComment) {
+	assert.Equal(t, expected.ID, actual.ID)
+	assert.Equal(t, expected.InReplyTo, actual.InReplyTo)
+	assert.Equal(t, expected.Content, actual.Content)
+	assert.Equal(t, expected.TreePath, actual.TreePath)
+	assert.Equal(t, expected.DiffHunk, actual.DiffHunk)
+	assert.Equal(t, expected.Position, actual.Position)
+	assert.Equal(t, expected.Line, actual.Line)
+	assert.Equal(t, expected.CommitID, actual.CommitID)
+	assert.Equal(t, expected.PosterID, actual.PosterID)
+	assertReactionsEqual(t, expected.Reactions, actual.Reactions)
+	assertTimeEqual(t, expected.CreatedAt, actual.CreatedAt)
+	assertTimeEqual(t, expected.UpdatedAt, actual.UpdatedAt)
+}
+
+func assertReviewCommentsEqual(t *testing.T, expected, actual []*base.ReviewComment) {
+	if assert.Len(t, actual, len(expected)) {
+		for i := range expected {
+			assertReviewCommentEqual(t, expected[i], actual[i])
+		}
+	}
+}