1
0
Fork 0
forked from forgejo/forgejo

Add migrate from OneDev (#16356)

* Use context to simplify logic.

* Added migration from OneDev.
This PR adds [OneDev](https://code.onedev.io/) as migration source.

Supported:
- [x] Milestones
- [x] Issues
- [x] Pull Requests
- [x] Comments
- [x] Reviews
- [x] Labels
This commit is contained in:
KN4CK3R 2021-08-22 00:47:45 +02:00 committed by GitHub
parent 2d1935acc7
commit cee5f7c5e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 1093 additions and 92 deletions

View file

@ -63,17 +63,14 @@ func (f *GitlabDownloaderFactory) GitServiceType() structs.GitServiceType {
// from gitlab via go-gitlab
// - issueCount is incremented in GetIssues() to ensure PR and Issue numbers do not overlap,
// because Gitlab has individual Issue and Pull Request numbers.
// - issueSeen, working alongside issueCount, is checked in GetComments() to see whether we
// need to fetch the Issue or PR comments, as Gitlab stores them separately.
type GitlabDownloader struct {
base.NullDownloader
ctx context.Context
client *gitlab.Client
repoID int
repoName string
issueCount int64
fetchPRcomments bool
maxPerPage int
ctx context.Context
client *gitlab.Client
repoID int
repoName string
issueCount int64
maxPerPage int
}
// NewGitlabDownloader creates a gitlab Downloader via gitlab API
@ -364,6 +361,20 @@ func (g *GitlabDownloader) GetReleases() ([]*base.Release, error) {
return releases, nil
}
type gitlabIssueContext struct {
foreignID int64
localID int64
IsMergeRequest bool
}
func (c gitlabIssueContext) LocalID() int64 {
return c.localID
}
func (c gitlabIssueContext) ForeignID() int64 {
return c.foreignID
}
// GetIssues returns issues according start and limit
// Note: issue label description and colors are not supported by the go-gitlab library at this time
func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, error) {
@ -433,6 +444,11 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
Closed: issue.ClosedAt,
IsLocked: issue.DiscussionLocked,
Updated: *issue.UpdatedAt,
Context: gitlabIssueContext{
foreignID: int64(issue.IID),
localID: int64(issue.IID),
IsMergeRequest: false,
},
})
// increment issueCount, to be used in GetPullRequests()
@ -445,27 +461,26 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
// GetComments returns comments according issueNumber
// TODO: figure out how to transfer comment reactions
func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Comment, bool, error) {
var issueNumber = opts.IssueNumber
context, ok := opts.Context.(gitlabIssueContext)
if !ok {
return nil, false, fmt.Errorf("unexpected context: %+v", opts.Context)
}
var allComments = make([]*base.Comment, 0, g.maxPerPage)
var page = 1
var realIssueNumber int64
for {
var comments []*gitlab.Discussion
var resp *gitlab.Response
var err error
// fetchPRcomments decides whether to fetch Issue or PR comments
if !g.fetchPRcomments {
realIssueNumber = issueNumber
comments, resp, err = g.client.Discussions.ListIssueDiscussions(g.repoID, int(realIssueNumber), &gitlab.ListIssueDiscussionsOptions{
if !context.IsMergeRequest {
comments, resp, err = g.client.Discussions.ListIssueDiscussions(g.repoID, int(context.ForeignID()), &gitlab.ListIssueDiscussionsOptions{
Page: page,
PerPage: g.maxPerPage,
}, nil, gitlab.WithContext(g.ctx))
} else {
// If this is a PR, we need to figure out the Gitlab/original PR ID to be passed below
realIssueNumber = issueNumber - g.issueCount
comments, resp, err = g.client.Discussions.ListMergeRequestDiscussions(g.repoID, int(realIssueNumber), &gitlab.ListMergeRequestDiscussionsOptions{
comments, resp, err = g.client.Discussions.ListMergeRequestDiscussions(g.repoID, int(context.ForeignID()), &gitlab.ListMergeRequestDiscussionsOptions{
Page: page,
PerPage: g.maxPerPage,
}, nil, gitlab.WithContext(g.ctx))
@ -479,7 +494,7 @@ func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
if !comment.IndividualNote {
for _, note := range comment.Notes {
allComments = append(allComments, &base.Comment{
IssueIndex: realIssueNumber,
IssueIndex: context.LocalID(),
PosterID: int64(note.Author.ID),
PosterName: note.Author.Username,
PosterEmail: note.Author.Email,
@ -490,7 +505,7 @@ func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
} else {
c := comment.Notes[0]
allComments = append(allComments, &base.Comment{
IssueIndex: realIssueNumber,
IssueIndex: context.LocalID(),
PosterID: int64(c.Author.ID),
PosterName: c.Author.Username,
PosterEmail: c.Author.Email,
@ -521,9 +536,6 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
},
}
// Set fetchPRcomments to true here, so PR comments are fetched instead of Issue comments
g.fetchPRcomments = true
var allPRs = make([]*base.PullRequest, 0, perPage)
prs, _, err := g.client.MergeRequests.ListProjectMergeRequests(g.repoID, opt, nil, gitlab.WithContext(g.ctx))
@ -587,7 +599,6 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
allPRs = append(allPRs, &base.PullRequest{
Title: pr.Title,
Number: newPRNumber,
OriginalNumber: int64(pr.IID),
PosterName: pr.Author.Username,
PosterID: int64(pr.Author.ID),
Content: pr.Description,
@ -615,6 +626,11 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
OwnerName: pr.Author.Username,
},
PatchURL: pr.WebURL + ".patch",
Context: gitlabIssueContext{
foreignID: int64(pr.IID),
localID: newPRNumber,
IsMergeRequest: true,
},
})
}
@ -622,8 +638,8 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
}
// GetReviews returns pull requests review
func (g *GitlabDownloader) GetReviews(pullRequestNumber int64) ([]*base.Review, error) {
approvals, resp, err := g.client.MergeRequestApprovals.GetConfiguration(g.repoID, int(pullRequestNumber), gitlab.WithContext(g.ctx))
func (g *GitlabDownloader) GetReviews(context base.IssueContext) ([]*base.Review, error) {
approvals, resp, err := g.client.MergeRequestApprovals.GetConfiguration(g.repoID, int(context.ForeignID()), 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()))
@ -635,6 +651,7 @@ func (g *GitlabDownloader) GetReviews(pullRequestNumber int64) ([]*base.Review,
var reviews = make([]*base.Review, 0, len(approvals.ApprovedBy))
for _, user := range approvals.ApprovedBy {
reviews = append(reviews, &base.Review{
IssueIndex: context.LocalID(),
ReviewerID: int64(user.User.ID),
ReviewerName: user.User.Username,
CreatedAt: *approvals.UpdatedAt,