Skip to content

Commit

Permalink
Use known issue IID to generate new PR index number when migrating fr…
Browse files Browse the repository at this point in the history
…om GitLab (#28616) (#28618)

Backport #28616 by wxiaoguang

Fix #13884

Co-authored-by: wxiaoguang <[email protected]>
  • Loading branch information
GiteaBot and wxiaoguang authored Dec 27, 2023
1 parent 7a2786c commit bf98373
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 11 deletions.
39 changes: 28 additions & 11 deletions services/migrations/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,36 @@ func (f *GitlabDownloaderFactory) GitServiceType() structs.GitServiceType {
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
// 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.
type GitlabDownloader struct {
base.NullDownloader
ctx context.Context
client *gitlab.Client
baseURL string
repoID int
repoName string
issueCount int64
maxPerPage int
ctx context.Context
client *gitlab.Client
baseURL string
repoID int
repoName string
iidResolver gitlabIIDResolver
maxPerPage int
}

// NewGitlabDownloader creates a gitlab Downloader via gitlab API
Expand Down Expand Up @@ -450,8 +467,8 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
Context: gitlabIssueContext{IsMergeRequest: false},
})

// increment issueCount, to be used in GetPullRequests()
g.issueCount++
// record the issue IID, to be used in GetPullRequests()
g.iidResolver.recordIssueIID(issue.IID)
}

return allIssues, len(issues) < perPage, nil
Expand Down Expand Up @@ -594,8 +611,8 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
awardPage++
}

// Add the PR ID to the Issue Count because PR and Issues share ID space in Gitea
newPRNumber := g.issueCount + int64(pr.IID)
// 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.iidResolver.generatePullRequestNumber(pr.IID)

allPRs = append(allPRs, &base.PullRequest{
Title: pr.Title,
Expand Down
17 changes: 17 additions & 0 deletions services/migrations/gitlab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,3 +516,20 @@ func TestAwardsToReactions(t *testing.T) {
},
}, 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
})
}

0 comments on commit bf98373

Please sign in to comment.