forked from forgejo/forgejo
Migrate reviews when migrating repository from github (#9463)
* fix typo * Migrate reviews when migrating repository from github * fix lint * Added test and migration when external user login * fix test * fix commented state * Some improvements * fix bug when get pull request and ref original author on code comments * Fix migrated line; Added comment for review * Don't load all pull requests attributes * Fix typo * wrong change copy head * fix tests * fix reactions * Fix test * fix fmt * fix review comment reactions
This commit is contained in:
parent
bfdfa9a8b3
commit
f6067a8465
18 changed files with 567 additions and 32 deletions
|
@ -6,6 +6,7 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -27,6 +28,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/services/gitdiff"
|
||||
|
||||
gouuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
@ -48,6 +50,7 @@ type GiteaLocalUploader struct {
|
|||
gitRepo *git.Repository
|
||||
prHeadCache map[string]struct{}
|
||||
userMap map[int64]int64 // external user id mapping to user id
|
||||
prCache map[int64]*models.PullRequest
|
||||
gitServiceType structs.GitServiceType
|
||||
}
|
||||
|
||||
|
@ -60,6 +63,7 @@ func NewGiteaLocalUploader(ctx context.Context, doer *models.User, repoOwner, re
|
|||
repoName: repoName,
|
||||
prHeadCache: make(map[string]struct{}),
|
||||
userMap: make(map[int64]int64),
|
||||
prCache: make(map[int64]*models.PullRequest),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -706,6 +710,122 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR
|
|||
return &pullRequest, nil
|
||||
}
|
||||
|
||||
func convertReviewState(state string) models.ReviewType {
|
||||
switch state {
|
||||
case base.ReviewStatePending:
|
||||
return models.ReviewTypePending
|
||||
case base.ReviewStateApproved:
|
||||
return models.ReviewTypeApprove
|
||||
case base.ReviewStateChangesRequested:
|
||||
return models.ReviewTypeReject
|
||||
case base.ReviewStateCommented:
|
||||
return models.ReviewTypeComment
|
||||
default:
|
||||
return models.ReviewTypePending
|
||||
}
|
||||
}
|
||||
|
||||
// CreateReviews create pull request reviews
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
issueID = issue.ID
|
||||
g.issues.Store(review.IssueIndex, issueID)
|
||||
} else {
|
||||
issueID = issueIDStr.(int64)
|
||||
}
|
||||
|
||||
userid, ok := g.userMap[review.ReviewerID]
|
||||
tp := g.gitServiceType.Name()
|
||||
if !ok && tp != "" {
|
||||
var err error
|
||||
userid, err = models.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", review.ReviewerID))
|
||||
if err != nil {
|
||||
log.Error("GetUserIDByExternalUserID: %v", err)
|
||||
}
|
||||
if userid > 0 {
|
||||
g.userMap[review.ReviewerID] = userid
|
||||
}
|
||||
}
|
||||
|
||||
var cm = models.Review{
|
||||
Type: convertReviewState(review.State),
|
||||
IssueID: issueID,
|
||||
Content: review.Content,
|
||||
Official: review.Official,
|
||||
CreatedUnix: timeutil.TimeStamp(review.CreatedAt.Unix()),
|
||||
UpdatedUnix: timeutil.TimeStamp(review.CreatedAt.Unix()),
|
||||
}
|
||||
|
||||
if userid > 0 {
|
||||
cm.ReviewerID = userid
|
||||
} else {
|
||||
cm.ReviewerID = g.doer.ID
|
||||
cm.OriginalAuthor = review.ReviewerName
|
||||
cm.OriginalAuthorID = review.ReviewerID
|
||||
}
|
||||
|
||||
// get pr
|
||||
pr, ok := g.prCache[issueID]
|
||||
if !ok {
|
||||
var err error
|
||||
pr, err = models.GetPullRequestByIssueIDWithNoAttributes(issueID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
g.prCache[issueID] = pr
|
||||
}
|
||||
|
||||
for _, comment := range review.Comments {
|
||||
headCommitID, err := g.gitRepo.GetRefCommitID(pr.GetGitRefName())
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err)
|
||||
}
|
||||
patchBuf := new(bytes.Buffer)
|
||||
if err := gitdiff.GetRawDiffForFile(g.gitRepo.Path, pr.MergeBase, headCommitID, gitdiff.RawDiffNormal, comment.TreePath, patchBuf); err != nil {
|
||||
return fmt.Errorf("GetRawDiffForLine[%s, %s, %s, %s]: %v", g.gitRepo.Path, pr.MergeBase, headCommitID, comment.TreePath, err)
|
||||
}
|
||||
|
||||
_, _, line, _ := gitdiff.ParseDiffHunkString(comment.DiffHunk)
|
||||
|
||||
patch := gitdiff.CutDiffAroundLine(patchBuf, int64((&models.Comment{Line: int64(line + comment.Position - 1)}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines)
|
||||
|
||||
var c = models.Comment{
|
||||
Type: models.CommentTypeCode,
|
||||
PosterID: comment.PosterID,
|
||||
IssueID: issueID,
|
||||
Content: comment.Content,
|
||||
Line: int64(line + comment.Position - 1),
|
||||
TreePath: comment.TreePath,
|
||||
CommitSHA: comment.CommitID,
|
||||
Patch: patch,
|
||||
CreatedUnix: timeutil.TimeStamp(comment.CreatedAt.Unix()),
|
||||
UpdatedUnix: timeutil.TimeStamp(comment.UpdatedAt.Unix()),
|
||||
}
|
||||
|
||||
if userid > 0 {
|
||||
c.PosterID = userid
|
||||
} else {
|
||||
c.PosterID = g.doer.ID
|
||||
c.OriginalAuthor = review.ReviewerName
|
||||
c.OriginalAuthorID = review.ReviewerID
|
||||
}
|
||||
|
||||
cm.Comments = append(cm.Comments, &c)
|
||||
}
|
||||
|
||||
cms = append(cms, &cm)
|
||||
}
|
||||
|
||||
return models.InsertReviews(cms)
|
||||
}
|
||||
|
||||
// Rollback when migrating failed, this will rollback all the changes.
|
||||
func (g *GiteaLocalUploader) Rollback() error {
|
||||
if g.repo != nil && g.repo.ID > 0 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue