[GITEA] Avoid conflicts of issue and PR numbers in GitLab migration (#1790)

Closes #1789.

The bug was due to the fact that GitLab does not guarantee that issue numbers are created sequentially: some identifiers can be skipped. Therefore, the new pull requests numbers should not be offset by the number of issues, but by the maximum issue number.

See for instance https://gitlab.com/troyengel/archbuild/-/issues/?sort=created_date&state=all&first_page_size=20, where there is only a singe issue with number "2".

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/1790
Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>
Co-committed-by: Antonin Delpeuch <antonin@delpeuch.eu>
(cherry picked from commit 2c185c39fe)
(cherry picked from commit 8f68dc4c9c)
(cherry picked from commit 7e932b7fca)
(cherry picked from commit 6bbe75ecf8)
(cherry picked from commit b18c2e8d65)

Conflicts:
	services/migrations/gitlab.go
	https://codeberg.org/forgejo/forgejo/pulls/2075
(cherry picked from commit abc129c762)
(cherry picked from commit 28884fac10)
(cherry picked from commit 5f528dd85f)

(cherry picked from commit cb9b8a31b2)
(cherry picked from commit 97f02df163)
This commit is contained in:
Antonin Delpeuch 2023-11-30 13:56:47 +00:00 committed by Earl Warren
parent 65060c6961
commit 4611e10e6a
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
9 changed files with 251 additions and 0 deletions

View file

@ -334,6 +334,49 @@ func TestGitlabDownloadRepo(t *testing.T) {
}, rvs)
}
func TestGitlabSkippedIssueNumber(t *testing.T) {
// If a GitLab access token is provided, this test will make HTTP requests to the live gitlab.com instance.
// When doing so, the responses from gitlab.com will be saved as test data files.
// If no access token is available, those cached responses will be used instead.
gitlabPersonalAccessToken := os.Getenv("GITLAB_READ_TOKEN")
fixturePath := "./testdata/gitlab/skipped_issue_number"
server := unittest.NewMockWebServer(t, "https://gitlab.com", fixturePath, gitlabPersonalAccessToken != "")
defer server.Close()
downloader, err := NewGitlabDownloader(context.Background(), server.URL, "troyengel/archbuild", "", "", gitlabPersonalAccessToken)
if err != nil {
t.Fatalf("NewGitlabDownloader is nil: %v", err)
}
repo, err := downloader.GetRepoInfo()
assert.NoError(t, err)
assertRepositoryEqual(t, &base.Repository{
Name: "archbuild",
Owner: "troyengel",
Description: "Arch packaging and build files",
CloneURL: server.URL + "/troyengel/archbuild.git",
OriginalURL: server.URL + "/troyengel/archbuild",
DefaultBranch: "master",
}, repo)
issues, isEnd, err := downloader.GetIssues(1, 10)
assert.NoError(t, err)
assert.True(t, isEnd)
// the only issue in this repository has number 2
assert.EqualValues(t, 1, len(issues))
assert.EqualValues(t, 2, issues[0].Number)
assert.EqualValues(t, "vpn unlimited errors", issues[0].Title)
prs, _, err := downloader.GetPullRequests(1, 10)
assert.NoError(t, err)
// the only merge request in this repository has number 1,
// but we offset it by the maximum issue number so it becomes
// pull request 3 in Forgejo
assert.EqualValues(t, 1, len(prs))
assert.EqualValues(t, 3, prs[0].Number)
assert.EqualValues(t, "Review", prs[0].Title)
}
func gitlabClientMockSetup(t *testing.T) (*http.ServeMux, *httptest.Server, *gitlab.Client) {
// mux is the HTTP request multiplexer used with the test server.
mux := http.NewServeMux()