diff options
Diffstat (limited to 'services/migrations')
-rw-r--r-- | services/migrations/codebase.go | 2 | ||||
-rw-r--r-- | services/migrations/codecommit.go | 21 | ||||
-rw-r--r-- | services/migrations/dump.go | 6 | ||||
-rw-r--r-- | services/migrations/error.go | 2 | ||||
-rw-r--r-- | services/migrations/gitea_downloader.go | 2 | ||||
-rw-r--r-- | services/migrations/gitea_downloader_test.go | 4 | ||||
-rw-r--r-- | services/migrations/gitea_uploader.go | 22 | ||||
-rw-r--r-- | services/migrations/gitea_uploader_test.go | 20 | ||||
-rw-r--r-- | services/migrations/github.go | 70 | ||||
-rw-r--r-- | services/migrations/github_test.go | 34 | ||||
-rw-r--r-- | services/migrations/gitlab.go | 11 | ||||
-rw-r--r-- | services/migrations/gitlab_test.go | 6 | ||||
-rw-r--r-- | services/migrations/migrate.go | 11 | ||||
-rw-r--r-- | services/migrations/onedev.go | 2 |
14 files changed, 142 insertions, 71 deletions
diff --git a/services/migrations/codebase.go b/services/migrations/codebase.go index 880dd21497..240c7bcdc9 100644 --- a/services/migrations/codebase.go +++ b/services/migrations/codebase.go @@ -134,7 +134,7 @@ func (d *CodebaseDownloader) callAPI(ctx context.Context, endpoint string, param u.RawQuery = query.Encode() } - req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) if err != nil { return err } diff --git a/services/migrations/codecommit.go b/services/migrations/codecommit.go index c45f9e5943..d08b2e6d4a 100644 --- a/services/migrations/codecommit.go +++ b/services/migrations/codecommit.go @@ -5,7 +5,7 @@ package migrations import ( "context" - "fmt" + "errors" "net/url" "strconv" "strings" @@ -42,13 +42,13 @@ func (c *CodeCommitDownloaderFactory) New(ctx context.Context, opts base.Migrate hostElems := strings.Split(u.Host, ".") if len(hostElems) != 4 { - return nil, fmt.Errorf("cannot get the region from clone URL") + return nil, errors.New("cannot get the region from clone URL") } region := hostElems[1] pathElems := strings.Split(u.Path, "/") if len(pathElems) == 0 { - return nil, fmt.Errorf("cannot get the repo name from clone URL") + return nil, errors.New("cannot get the repo name from clone URL") } repoName := pathElems[len(pathElems)-1] @@ -155,10 +155,7 @@ func (c *CodeCommitDownloader) GetPullRequests(ctx context.Context, page, perPag } startIndex := (page - 1) * perPage - endIndex := page * perPage - if endIndex > len(allPullRequestIDs) { - endIndex = len(allPullRequestIDs) - } + endIndex := min(page*perPage, len(allPullRequestIDs)) batch := allPullRequestIDs[startIndex:endIndex] prs := make([]*base.PullRequest, 0, len(batch)) @@ -180,11 +177,15 @@ func (c *CodeCommitDownloader) GetPullRequests(ctx context.Context, page, perPag continue } target := orig.PullRequestTargets[0] + description := "" + if orig.Description != nil { + description = *orig.Description + } pr := &base.PullRequest{ Number: number, Title: *orig.Title, PosterName: c.getUsernameFromARN(*orig.AuthorArn), - Content: *orig.Description, + Content: description, State: "open", Created: *orig.CreationDate, Updated: *orig.LastActivityDate, @@ -206,6 +207,10 @@ func (c *CodeCommitDownloader) GetPullRequests(ctx context.Context, page, perPag pr.State = "closed" pr.Closed = orig.LastActivityDate } + if pr.Merged { + pr.MergeCommitSHA = *target.MergeMetadata.MergeCommitId + pr.MergedTime = orig.LastActivityDate + } _ = CheckAndEnsureSafePR(pr, c.baseURL, c) prs = append(prs, pr) diff --git a/services/migrations/dump.go b/services/migrations/dump.go index b4ca1e41e0..8edd567b08 100644 --- a/services/migrations/dump.go +++ b/services/migrations/dump.go @@ -488,7 +488,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR if pr.Head.CloneURL == "" || pr.Head.Ref == "" { // Set head information if pr.Head.SHA is available if pr.Head.SHA != "" { - _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()}) + _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()}) if err != nil { log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err) } @@ -518,7 +518,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR if !ok { // Set head information if pr.Head.SHA is available if pr.Head.SHA != "" { - _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()}) + _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()}) if err != nil { log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err) } @@ -577,7 +577,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR pr.Head.SHA = headSha } if pr.Head.SHA != "" { - _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()}) + _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()}) if err != nil { log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) } diff --git a/services/migrations/error.go b/services/migrations/error.go index c7d912f50b..9b470149bf 100644 --- a/services/migrations/error.go +++ b/services/migrations/error.go @@ -7,7 +7,7 @@ package migrations import ( "errors" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v71/github" ) // ErrRepoNotCreated returns the error that repository not created diff --git a/services/migrations/gitea_downloader.go b/services/migrations/gitea_downloader.go index f92f318293..5d48d2f003 100644 --- a/services/migrations/gitea_downloader.go +++ b/services/migrations/gitea_downloader.go @@ -298,7 +298,7 @@ func (g *GiteaDownloader) convertGiteaRelease(rel *gitea_sdk.Release) *base.Rele } // FIXME: for a private download? - req, err := http.NewRequest("GET", assetDownloadURL, nil) + req, err := http.NewRequest(http.MethodGet, assetDownloadURL, nil) if err != nil { return nil, err } diff --git a/services/migrations/gitea_downloader_test.go b/services/migrations/gitea_downloader_test.go index da56120065..bb1760e889 100644 --- a/services/migrations/gitea_downloader_test.go +++ b/services/migrations/gitea_downloader_test.go @@ -47,7 +47,7 @@ func TestGiteaDownloadRepo(t *testing.T) { topics, err := downloader.GetTopics(ctx) assert.NoError(t, err) sort.Strings(topics) - assert.EqualValues(t, []string{"ci", "gitea", "migration", "test"}, topics) + assert.Equal(t, []string{"ci", "gitea", "migration", "test"}, topics) labels, err := downloader.GetLabels(ctx) assert.NoError(t, err) @@ -134,7 +134,7 @@ func TestGiteaDownloadRepo(t *testing.T) { assert.NoError(t, err) assert.True(t, isEnd) assert.Len(t, issues, 7) - assert.EqualValues(t, "open", issues[0].State) + assert.Equal(t, "open", issues[0].State) issues, isEnd, err = downloader.GetIssues(ctx, 3, 2) assert.NoError(t, err) diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index b17cc3ce41..75eb06d01f 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -107,7 +107,7 @@ func (g *GiteaLocalUploader) CreateRepo(ctx context.Context, repo *base.Reposito IsPrivate: opts.Private || setting.Repository.ForcePrivate, IsMirror: opts.Mirror, Status: repo_model.RepositoryBeingMigrated, - }) + }, false) } else { r, err = repo_model.GetRepositoryByID(ctx, opts.MigrateToRepoID) } @@ -148,7 +148,7 @@ func (g *GiteaLocalUploader) CreateRepo(ctx context.Context, repo *base.Reposito return err } g.repo.ObjectFormatName = objectFormat.Name() - return repo_model.UpdateRepositoryCols(ctx, g.repo, "object_format_name") + return repo_model.UpdateRepositoryColsNoAutoTime(ctx, g.repo, "object_format_name") } // Close closes this uploader @@ -556,7 +556,7 @@ func (g *GiteaLocalUploader) CreatePullRequests(ctx context.Context, prs ...*bas } for _, pr := range gprs { g.issues[pr.Issue.Index] = pr.Issue - pull.AddToTaskQueue(ctx, pr) + pull.StartPullRequestCheckImmediately(ctx, pr) } return nil } @@ -681,7 +681,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba pr.Head.SHA = headSha } - _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()}) + _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()}) if err != nil { return "", err } @@ -701,10 +701,10 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba _, _, err = git.NewCommand("rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()}) if err != nil { // Git update-ref remove bad references with a relative path - log.Warn("Deprecated local head %s for PR #%d in %s/%s, removing %s", pr.Head.SHA, pr.Number, g.repoOwner, g.repoName, pr.GetGitRefName()) + log.Warn("Deprecated local head %s for PR #%d in %s/%s, removing %s", pr.Head.SHA, pr.Number, g.repoOwner, g.repoName, pr.GetGitHeadRefName()) } else { // set head information - _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()}) + _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()}) if err != nil { log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) } @@ -765,7 +765,7 @@ func (g *GiteaLocalUploader) newPullRequest(ctx context.Context, pr *base.PullRe issue := issues_model.Issue{ RepoID: g.repo.ID, Repo: g.repo, - Title: prTitle, + Title: util.TruncateRunes(prTitle, 255), Index: pr.Number, Content: pr.Content, MilestoneID: milestoneID, @@ -880,9 +880,9 @@ func (g *GiteaLocalUploader) CreateReviews(ctx context.Context, reviews ...*base continue } - headCommitID, err := g.gitRepo.GetRefCommitID(pr.GetGitRefName()) + headCommitID, err := g.gitRepo.GetRefCommitID(pr.GetGitHeadRefName()) if err != nil { - log.Warn("PR #%d GetRefCommitID[%s] in %s/%s: %v, all review comments will be ignored", pr.Index, pr.GetGitRefName(), g.repoOwner, g.repoName, err) + log.Warn("PR #%d GetRefCommitID[%s] in %s/%s: %v, all review comments will be ignored", pr.Index, pr.GetGitHeadRefName(), g.repoOwner, g.repoName, err) continue } @@ -975,7 +975,7 @@ func (g *GiteaLocalUploader) Finish(ctx context.Context) error { } g.repo.Status = repo_model.RepositoryReady - return repo_model.UpdateRepositoryCols(ctx, g.repo, "status") + return repo_model.UpdateRepositoryColsWithAutoTime(ctx, g.repo, "status") } func (g *GiteaLocalUploader) remapUser(ctx context.Context, source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) error { @@ -1017,7 +1017,7 @@ func (g *GiteaLocalUploader) remapLocalUser(ctx context.Context, source user_mod func (g *GiteaLocalUploader) remapExternalUser(ctx context.Context, source user_model.ExternalUserMigrated) (userid int64, err error) { userid, ok := g.userMap[source.GetExternalID()] if !ok { - userid, err = user_model.GetUserIDByExternalUserID(ctx, g.gitServiceType.Name(), fmt.Sprintf("%d", source.GetExternalID())) + userid, err = user_model.GetUserIDByExternalUserID(ctx, g.gitServiceType.Name(), strconv.FormatInt(source.GetExternalID(), 10)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) return 0, err diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index f52d4157c8..1970c0550c 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -64,7 +64,7 @@ func TestGiteaUploadRepo(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: repoName}) assert.True(t, repo.HasWiki()) - assert.EqualValues(t, repo_model.RepositoryReady, repo.Status) + assert.Equal(t, repo_model.RepositoryReady, repo.Status) milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ RepoID: repo.ID, @@ -152,7 +152,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { uploader.userMap = make(map[int64]int64) err := uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) - assert.EqualValues(t, doer.ID, target.GetUserID()) + assert.Equal(t, doer.ID, target.GetUserID()) // // The externalID matches a known user but the name does not match, @@ -163,7 +163,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { uploader.userMap = make(map[int64]int64) err = uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) - assert.EqualValues(t, doer.ID, target.GetUserID()) + assert.Equal(t, doer.ID, target.GetUserID()) // // The externalID and externalName match an existing user, everything @@ -174,7 +174,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { uploader.userMap = make(map[int64]int64) err = uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) - assert.EqualValues(t, user.ID, target.GetUserID()) + assert.Equal(t, user.ID, target.GetUserID()) } func TestGiteaUploadRemapExternalUser(t *testing.T) { @@ -202,7 +202,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) { target := repo_model.Release{} err := uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) - assert.EqualValues(t, doer.ID, target.GetUserID()) + assert.Equal(t, doer.ID, target.GetUserID()) // // Link the external ID to an existing user @@ -225,7 +225,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) { target = repo_model.Release{} err = uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) - assert.EqualValues(t, linkedUser.ID, target.GetUserID()) + assert.Equal(t, linkedUser.ID, target.GetUserID()) } func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { @@ -239,7 +239,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false, fromRepo.ObjectFormatName)) err := git.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(git.DefaultContext, &git.RunOpts{Dir: fromRepo.RepoPath()}) assert.NoError(t, err) - assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", fromRepo.RepoPath())), 0o644)) + assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("# Testing Repository\n\nOriginally created in: "+fromRepo.RepoPath()), 0o644)) assert.NoError(t, git.AddChanges(fromRepo.RepoPath(), true)) signature := git.Signature{ Email: "test@example.com", @@ -287,7 +287,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { })) _, _, err = git.NewCommand("checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(git.DefaultContext, &git.RunOpts{Dir: forkRepo.RepoPath()}) assert.NoError(t, err) - assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# branch2 %s", forkRepo.RepoPath())), 0o644)) + assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte("# branch2 "+forkRepo.RepoPath()), 0o644)) assert.NoError(t, git.AddChanges(forkRepo.RepoPath(), true)) assert.NoError(t, git.CommitChanges(forkRepo.RepoPath(), git.CommitChangesOptions{ Committer: &signature, @@ -508,14 +508,14 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { head, err := uploader.updateGitForPullRequest(ctx, &testCase.pr) assert.NoError(t, err) - assert.EqualValues(t, testCase.head, head) + assert.Equal(t, testCase.head, head) log.Info(stopMark) logFiltered, logStopped := logChecker.Check(5 * time.Second) assert.True(t, logStopped) if len(testCase.logFilter) > 0 { - assert.EqualValues(t, testCase.logFiltered, logFiltered, "for log message filters: %v", testCase.logFilter) + assert.Equal(t, testCase.logFiltered, logFiltered, "for log message filters: %v", testCase.logFilter) } }) } diff --git a/services/migrations/github.go b/services/migrations/github.go index b00d6ed27f..c6cd6ea173 100644 --- a/services/migrations/github.go +++ b/services/migrations/github.go @@ -20,7 +20,7 @@ import ( "code.gitea.io/gitea/modules/proxy" "code.gitea.io/gitea/modules/structs" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v71/github" "golang.org/x/oauth2" ) @@ -89,8 +89,8 @@ func NewGithubDownloaderV3(_ context.Context, baseURL, userName, password, token } if token != "" { - tokens := strings.Split(token, ",") - for _, token := range tokens { + tokens := strings.SplitSeq(token, ",") + for token := range tokens { token = strings.TrimSpace(token) ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: token}, @@ -133,7 +133,7 @@ func (g *GithubDownloaderV3) LogString() string { func (g *GithubDownloaderV3) addClient(client *http.Client, baseURL string) { githubClient := github.NewClient(client) if baseURL != "https://github.com" { - githubClient, _ = github.NewClient(client).WithEnterpriseURLs(baseURL, baseURL) + githubClient, _ = githubClient.WithEnterpriseURLs(baseURL, baseURL) } g.clients = append(g.clients, githubClient) g.rates = append(g.rates, nil) @@ -322,7 +322,10 @@ func (g *GithubDownloaderV3) convertGithubRelease(ctx context.Context, rel *gith httpClient := NewMigrationHTTPClient() for _, asset := range rel.Assets { - assetID := *asset.ID // Don't optimize this, for closure we need a local variable + assetID := asset.GetID() // Don't optimize this, for closure we need a local variable TODO: no need to do so in new Golang + if assetID == 0 { + continue + } r.Assets = append(r.Assets, &base.ReleaseAsset{ ID: asset.GetID(), Name: asset.GetName(), @@ -358,7 +361,7 @@ func (g *GithubDownloaderV3) convertGithubRelease(ctx context.Context, rel *gith } g.waitAndPickClient(ctx) - req, err := http.NewRequestWithContext(ctx, "GET", redirectURL, nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, redirectURL, nil) if err != nil { return nil, err } @@ -441,9 +444,11 @@ func (g *GithubDownloaderV3) GetIssues(ctx context.Context, page, perPage int) ( if !g.SkipReactions { for i := 1; ; i++ { g.waitAndPickClient(ctx) - res, resp, err := g.getClient().Reactions.ListIssueReactions(ctx, g.repoOwner, g.repoName, issue.GetNumber(), &github.ListOptions{ - Page: i, - PerPage: perPage, + res, resp, err := g.getClient().Reactions.ListIssueReactions(ctx, g.repoOwner, g.repoName, issue.GetNumber(), &github.ListReactionOptions{ + ListOptions: github.ListOptions{ + Page: i, + PerPage: perPage, + }, }) if err != nil { return nil, false, err @@ -527,9 +532,11 @@ func (g *GithubDownloaderV3) getComments(ctx context.Context, commentable base.C if !g.SkipReactions { for i := 1; ; i++ { g.waitAndPickClient(ctx) - res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{ - Page: i, - PerPage: g.maxPerPage, + res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListReactionOptions{ + ListOptions: github.ListOptions{ + Page: i, + PerPage: g.maxPerPage, + }, }) if err != nil { return nil, err @@ -602,9 +609,11 @@ func (g *GithubDownloaderV3) GetAllComments(ctx context.Context, page, perPage i if !g.SkipReactions { for i := 1; ; i++ { g.waitAndPickClient(ctx) - res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{ - Page: i, - PerPage: g.maxPerPage, + res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListReactionOptions{ + ListOptions: github.ListOptions{ + Page: i, + PerPage: g.maxPerPage, + }, }) if err != nil { return nil, false, err @@ -673,9 +682,11 @@ func (g *GithubDownloaderV3) GetPullRequests(ctx context.Context, page, perPage if !g.SkipReactions { for i := 1; ; i++ { g.waitAndPickClient(ctx) - res, resp, err := g.getClient().Reactions.ListIssueReactions(ctx, g.repoOwner, g.repoName, pr.GetNumber(), &github.ListOptions{ - Page: i, - PerPage: perPage, + res, resp, err := g.getClient().Reactions.ListIssueReactions(ctx, g.repoOwner, g.repoName, pr.GetNumber(), &github.ListReactionOptions{ + ListOptions: github.ListOptions{ + Page: i, + PerPage: perPage, + }, }) if err != nil { return nil, false, err @@ -760,9 +771,11 @@ func (g *GithubDownloaderV3) convertGithubReviewComments(ctx context.Context, cs if !g.SkipReactions { for i := 1; ; i++ { g.waitAndPickClient(ctx) - res, resp, err := g.getClient().Reactions.ListPullRequestCommentReactions(ctx, g.repoOwner, g.repoName, c.GetID(), &github.ListOptions{ - Page: i, - PerPage: g.maxPerPage, + res, resp, err := g.getClient().Reactions.ListPullRequestCommentReactions(ctx, g.repoOwner, g.repoName, c.GetID(), &github.ListReactionOptions{ + ListOptions: github.ListOptions{ + Page: i, + PerPage: g.maxPerPage, + }, }) if err != nil { return nil, err @@ -872,3 +885,18 @@ func (g *GithubDownloaderV3) GetReviews(ctx context.Context, reviewable base.Rev } return allReviews, nil } + +// FormatCloneURL add authentication into remote URLs +func (g *GithubDownloaderV3) FormatCloneURL(opts MigrateOptions, remoteAddr string) (string, error) { + u, err := url.Parse(remoteAddr) + if err != nil { + return "", err + } + if len(opts.AuthToken) > 0 { + // "multiple tokens" are used to benefit more "API rate limit quota" + // git clone doesn't count for rate limits, so only use the first token. + // source: https://github.com/orgs/community/discussions/44515 + u.User = url.UserPassword("oauth2", strings.Split(opts.AuthToken, ",")[0]) + } + return u.String(), nil +} diff --git a/services/migrations/github_test.go b/services/migrations/github_test.go index 2625fb62ec..6d1a5378b9 100644 --- a/services/migrations/github_test.go +++ b/services/migrations/github_test.go @@ -12,6 +12,7 @@ import ( base "code.gitea.io/gitea/modules/migration" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestGitHubDownloadRepo(t *testing.T) { @@ -429,3 +430,36 @@ func TestGitHubDownloadRepo(t *testing.T) { }, }, reviews) } + +func TestGithubMultiToken(t *testing.T) { + testCases := []struct { + desc string + token string + expectedCloneURL string + }{ + { + desc: "Single Token", + token: "single_token", + expectedCloneURL: "https://oauth2:single_token@github.com", + }, + { + desc: "Multi Token", + token: "token1,token2", + expectedCloneURL: "https://oauth2:token1@github.com", + }, + } + factory := GithubDownloaderV3Factory{} + + for _, tC := range testCases { + t.Run(tC.desc, func(t *testing.T) { + opts := base.MigrateOptions{CloneAddr: "https://github.com/go-gitea/gitea", AuthToken: tC.token} + client, err := factory.New(t.Context(), opts) + require.NoError(t, err) + + cloneURL, err := client.FormatCloneURL(opts, "https://github.com") + require.NoError(t, err) + + assert.Equal(t, tC.expectedCloneURL, cloneURL) + }) + } +} diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go index efc5b960cf..a19a04bc44 100644 --- a/services/migrations/gitlab.go +++ b/services/migrations/gitlab.go @@ -16,6 +16,7 @@ import ( "time" issues_model "code.gitea.io/gitea/models/issues" + "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" base "code.gitea.io/gitea/modules/migration" @@ -340,7 +341,7 @@ func (g *GitlabDownloader) convertGitlabRelease(ctx context.Context, rel *gitlab return io.NopCloser(strings.NewReader(link.URL)), nil } - req, err := http.NewRequest("GET", link.URL, nil) + req, err := http.NewRequest(http.MethodGet, link.URL, nil) if err != nil { return nil, err } @@ -535,11 +536,15 @@ func (g *GitlabDownloader) GetComments(ctx context.Context, commentable base.Com } for _, stateEvent := range stateEvents { + posterUserID, posterUsername := user.GhostUserID, user.GhostUserName + if stateEvent.User != nil { + posterUserID, posterUsername = int64(stateEvent.User.ID), stateEvent.User.Username + } comment := &base.Comment{ IssueIndex: commentable.GetLocalIndex(), Index: int64(stateEvent.ID), - PosterID: int64(stateEvent.User.ID), - PosterName: stateEvent.User.Username, + PosterID: posterUserID, + PosterName: posterUsername, Content: "", Created: *stateEvent.CreatedAt, } diff --git a/services/migrations/gitlab_test.go b/services/migrations/gitlab_test.go index 52f5827dfe..73a1b6a276 100644 --- a/services/migrations/gitlab_test.go +++ b/services/migrations/gitlab_test.go @@ -50,7 +50,7 @@ func TestGitlabDownloadRepo(t *testing.T) { topics, err := downloader.GetTopics(ctx) assert.NoError(t, err) assert.Len(t, topics, 2) - assert.EqualValues(t, []string{"migration", "test"}, topics) + assert.Equal(t, []string{"migration", "test"}, topics) milestones, err := downloader.GetMilestones(ctx) assert.NoError(t, err) @@ -501,7 +501,7 @@ func TestAwardsToReactions(t *testing.T) { assert.NoError(t, json.Unmarshal([]byte(testResponse), &awards)) reactions := downloader.awardsToReactions(awards) - assert.EqualValues(t, []*base.Reaction{ + assert.Equal(t, []*base.Reaction{ { UserName: "lafriks", UserID: 1241334, @@ -593,7 +593,7 @@ func TestNoteToComment(t *testing.T) { for i, note := range notes { actualComment := *downloader.convertNoteToComment(17, ¬e) - assert.EqualValues(t, actualComment, comments[i]) + assert.Equal(t, actualComment, comments[i]) } } diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go index 5dda12286f..eba9c79df5 100644 --- a/services/migrations/migrate.go +++ b/services/migrations/migrate.go @@ -6,6 +6,7 @@ package migrations import ( "context" + "errors" "fmt" "net" "net/url" @@ -74,11 +75,9 @@ func IsMigrateURLAllowed(remoteURL string, doer *user_model.User) error { return &git.ErrInvalidCloneAddr{Host: u.Host, IsProtocolInvalid: true, IsPermissionDenied: true, IsURLError: true} } - hostName, _, err := net.SplitHostPort(u.Host) - if err != nil { - // u.Host can be "host" or "host:port" - err = nil //nolint - hostName = u.Host + hostName, _, errIgnored := net.SplitHostPort(u.Host) + if errIgnored != nil { + hostName = u.Host // u.Host can be "host" or "host:port" } // some users only use proxy, there is no DNS resolver. it's safe to ignore the LookupIP error @@ -211,7 +210,7 @@ func migrateRepository(ctx context.Context, doer *user_model.User, downloader ba if cloneURL.Scheme == "file" || cloneURL.Scheme == "" { if cloneAddrURL.Scheme != "file" && cloneAddrURL.Scheme != "" { - return fmt.Errorf("repo info has changed from external to local filesystem") + return errors.New("repo info has changed from external to local filesystem") } } diff --git a/services/migrations/onedev.go b/services/migrations/onedev.go index 4ce35dd12e..e052cba0cc 100644 --- a/services/migrations/onedev.go +++ b/services/migrations/onedev.go @@ -128,7 +128,7 @@ func (d *OneDevDownloader) callAPI(ctx context.Context, endpoint string, paramet u.RawQuery = query.Encode() } - req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) if err != nil { return err } |