Use known issue IID to generate new PR index number when migrating from GitLab (#28616) (#28618)

Backport #28616 by wxiaoguang

Fix #13884

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Giteabot 2023-12-27 09:59:29 +08:00 committed by GitHub
parent 7a2786ca6c
commit bf983735fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 11 deletions

View file

@ -55,19 +55,36 @@ func (f *GitlabDownloaderFactory) GitServiceType() structs.GitServiceType {
return structs.GitlabService return structs.GitlabService
} }
type gitlabIIDResolver struct {
maxIssueIID int64
frozen bool
}
func (r *gitlabIIDResolver) recordIssueIID(issueIID int) {
if r.frozen {
panic("cannot record issue IID after pull request IID generation has started")
}
r.maxIssueIID = max(r.maxIssueIID, int64(issueIID))
}
func (r *gitlabIIDResolver) generatePullRequestNumber(mrIID int) int64 {
r.frozen = true
return r.maxIssueIID + int64(mrIID)
}
// GitlabDownloader implements a Downloader interface to get repository information // GitlabDownloader implements a Downloader interface to get repository information
// from gitlab via go-gitlab // from gitlab via go-gitlab
// - issueCount is incremented in GetIssues() to ensure PR and Issue numbers do not overlap, // - issueCount is incremented in GetIssues() to ensure PR and Issue numbers do not overlap,
// because Gitlab has individual Issue and Pull Request numbers. // because Gitlab has individual Issue and Pull Request numbers.
type GitlabDownloader struct { type GitlabDownloader struct {
base.NullDownloader base.NullDownloader
ctx context.Context ctx context.Context
client *gitlab.Client client *gitlab.Client
baseURL string baseURL string
repoID int repoID int
repoName string repoName string
issueCount int64 iidResolver gitlabIIDResolver
maxPerPage int maxPerPage int
} }
// NewGitlabDownloader creates a gitlab Downloader via gitlab API // NewGitlabDownloader creates a gitlab Downloader via gitlab API
@ -450,8 +467,8 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
Context: gitlabIssueContext{IsMergeRequest: false}, Context: gitlabIssueContext{IsMergeRequest: false},
}) })
// increment issueCount, to be used in GetPullRequests() // record the issue IID, to be used in GetPullRequests()
g.issueCount++ g.iidResolver.recordIssueIID(issue.IID)
} }
return allIssues, len(issues) < perPage, nil return allIssues, len(issues) < perPage, nil
@ -594,8 +611,8 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
awardPage++ awardPage++
} }
// Add the PR ID to the Issue Count because PR and Issues share ID space in Gitea // Generate new PR Numbers by the known Issue Numbers, because they share the same number space in Gitea, but they are independent in Gitlab
newPRNumber := g.issueCount + int64(pr.IID) newPRNumber := g.iidResolver.generatePullRequestNumber(pr.IID)
allPRs = append(allPRs, &base.PullRequest{ allPRs = append(allPRs, &base.PullRequest{
Title: pr.Title, Title: pr.Title,

View file

@ -516,3 +516,20 @@ func TestAwardsToReactions(t *testing.T) {
}, },
}, reactions) }, reactions)
} }
func TestGitlabIIDResolver(t *testing.T) {
r := gitlabIIDResolver{}
r.recordIssueIID(1)
r.recordIssueIID(2)
r.recordIssueIID(3)
r.recordIssueIID(2)
assert.EqualValues(t, 4, r.generatePullRequestNumber(1))
assert.EqualValues(t, 13, r.generatePullRequestNumber(10))
assert.Panics(t, func() {
r := gitlabIIDResolver{}
r.recordIssueIID(1)
assert.EqualValues(t, 2, r.generatePullRequestNumber(1))
r.recordIssueIID(3) // the generation procedure has been started, it shouldn't accept any new issue IID, so it panics
})
}