feat: vendor gitea 1.16.2
This commit is contained in:
@@ -54,12 +54,12 @@ func TestCodebaseDownloadRepo(t *testing.T) {
|
||||
assertMilestonesEqual(t, []*base.Milestone{
|
||||
{
|
||||
Title: "Milestone1",
|
||||
Deadline: timePtr(time.Date(2021, time.September, 16, 0, 0, 0, 0, time.UTC)),
|
||||
Deadline: new(time.Date(2021, time.September, 16, 0, 0, 0, 0, time.UTC)),
|
||||
},
|
||||
{
|
||||
Title: "Milestone2",
|
||||
Deadline: timePtr(time.Date(2021, time.September, 17, 0, 0, 0, 0, time.UTC)),
|
||||
Closed: timePtr(time.Date(2021, time.September, 17, 0, 0, 0, 0, time.UTC)),
|
||||
Deadline: new(time.Date(2021, time.September, 17, 0, 0, 0, 0, time.UTC)),
|
||||
Closed: new(time.Date(2021, time.September, 17, 0, 0, 0, 0, time.UTC)),
|
||||
State: "closed",
|
||||
},
|
||||
}, milestones)
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
base "code.gitea.io/gitea/modules/migration"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/credentials"
|
||||
"github.com/aws/aws-sdk-go-v2/service/codecommit"
|
||||
@@ -87,7 +86,7 @@ type CodeCommitDownloader struct {
|
||||
// GetRepoInfo returns a repository information
|
||||
func (c *CodeCommitDownloader) GetRepoInfo(ctx context.Context) (*base.Repository, error) {
|
||||
output, err := c.codeCommitClient.GetRepository(ctx, &codecommit.GetRepositoryInput{
|
||||
RepositoryName: util.ToPointer(c.repoName),
|
||||
RepositoryName: new(c.repoName),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -119,7 +118,7 @@ func (c *CodeCommitDownloader) GetComments(ctx context.Context, commentable base
|
||||
for {
|
||||
resp, err := c.codeCommitClient.GetCommentsForPullRequest(ctx, &codecommit.GetCommentsForPullRequestInput{
|
||||
NextToken: nextToken,
|
||||
PullRequestId: util.ToPointer(strconv.FormatInt(commentable.GetForeignIndex(), 10)),
|
||||
PullRequestId: new(strconv.FormatInt(commentable.GetForeignIndex(), 10)),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
@@ -161,7 +160,7 @@ func (c *CodeCommitDownloader) GetPullRequests(ctx context.Context, page, perPag
|
||||
prs := make([]*base.PullRequest, 0, len(batch))
|
||||
for _, id := range batch {
|
||||
output, err := c.codeCommitClient.GetPullRequest(ctx, &codecommit.GetPullRequestInput{
|
||||
PullRequestId: util.ToPointer(id),
|
||||
PullRequestId: new(id),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
@@ -241,7 +240,7 @@ func (c *CodeCommitDownloader) getAllPullRequestIDs(ctx context.Context) ([]stri
|
||||
|
||||
for {
|
||||
output, err := c.codeCommitClient.ListPullRequests(ctx, &codecommit.ListPullRequestsInput{
|
||||
RepositoryName: util.ToPointer(c.repoName),
|
||||
RepositoryName: new(c.repoName),
|
||||
NextToken: nextToken,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -288,12 +288,13 @@ func (g *RepositoryDumper) CreateLabels(_ context.Context, labels ...*base.Label
|
||||
func (g *RepositoryDumper) CreateReleases(_ context.Context, releases ...*base.Release) error {
|
||||
if g.opts.ReleaseAssets {
|
||||
for _, release := range releases {
|
||||
attachDir := filepath.Join("release_assets", release.TagName)
|
||||
attachDir := filepath.Join("release_assets", uuid.New().String())
|
||||
if err := os.MkdirAll(filepath.Join(g.baseDir, attachDir), os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, asset := range release.Assets {
|
||||
attachLocalPath := filepath.Join(attachDir, asset.Name)
|
||||
// we cannot use asset.Name because it might contains special characters.
|
||||
attachLocalPath := filepath.Join(attachDir, uuid.New().String())
|
||||
|
||||
// SECURITY: We cannot check the DownloadURL and DownloadFunc are safe here
|
||||
// ... we must assume that they are safe and simply download the attachment
|
||||
@@ -306,14 +307,15 @@ func (g *RepositoryDumper) CreateReleases(_ context.Context, releases ...*base.R
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rc.Close()
|
||||
} else {
|
||||
resp, err := http.Get(*asset.DownloadURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
rc = resp.Body
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
fw, err := os.Create(attachPath)
|
||||
if err != nil {
|
||||
@@ -357,6 +359,11 @@ func (g *RepositoryDumper) SyncTags(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SyncBranches syncs branches in the database
|
||||
func (g *RepositoryDumper) SyncBranches(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateIssues creates issues
|
||||
func (g *RepositoryDumper) CreateIssues(_ context.Context, issues ...*base.Issue) error {
|
||||
var err error
|
||||
@@ -489,7 +496,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 = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
|
||||
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).WithDir(g.gitPath()).RunStdString(ctx)
|
||||
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)
|
||||
}
|
||||
@@ -519,7 +526,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 = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
|
||||
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).WithDir(g.gitPath()).RunStdString(ctx)
|
||||
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)
|
||||
}
|
||||
@@ -554,7 +561,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
|
||||
fetchArg = git.BranchPrefix + fetchArg
|
||||
}
|
||||
|
||||
_, _, err = gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
|
||||
_, _, err = gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).WithDir(g.gitPath()).RunStdString(ctx)
|
||||
if err != nil {
|
||||
log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err)
|
||||
// We need to continue here so that the Head.Ref is reset and we attempt to set the gitref for the PR
|
||||
@@ -578,7 +585,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
|
||||
pr.Head.SHA = headSha
|
||||
}
|
||||
if pr.Head.SHA != "" {
|
||||
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
|
||||
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).WithDir(g.gitPath()).RunStdString(ctx)
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ package migrations
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/google/go-github/v74/github"
|
||||
"github.com/google/go-github/v84/github"
|
||||
)
|
||||
|
||||
// ErrRepoNotCreated returns the error that repository not created
|
||||
|
||||
@@ -186,7 +186,7 @@ func (g *GiteaDownloader) GetMilestones(ctx context.Context) ([]*base.Milestone,
|
||||
}
|
||||
|
||||
for i := range ms {
|
||||
// old gitea instances dont have this information
|
||||
// old gitea instances don't have this information
|
||||
createdAT := time.Time{}
|
||||
var updatedAT *time.Time
|
||||
if ms[i].Closed != nil {
|
||||
@@ -345,25 +345,43 @@ func (g *GiteaDownloader) GetReleases(ctx context.Context) ([]*base.Release, err
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
func (g *GiteaDownloader) getIssueReactions(index int64) ([]*base.Reaction, error) {
|
||||
var reactions []*base.Reaction
|
||||
func (g *GiteaDownloader) getIssueReactions(ctx context.Context, index int64) ([]*base.Reaction, error) {
|
||||
if err := g.client.CheckServerVersionConstraint(">=1.11"); err != nil {
|
||||
log.Info("GiteaDownloader: instance to old, skip getIssueReactions")
|
||||
return reactions, nil
|
||||
}
|
||||
rl, _, err := g.client.GetIssueReactions(g.repoOwner, g.repoName, index)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, reaction := range rl {
|
||||
reactions = append(reactions, &base.Reaction{
|
||||
UserID: reaction.User.ID,
|
||||
UserName: reaction.User.UserName,
|
||||
Content: reaction.Reaction,
|
||||
})
|
||||
allReactions := make([]*base.Reaction, 0, g.maxPerPage)
|
||||
|
||||
for i := 1; ; i++ {
|
||||
// make sure gitea can shutdown gracefully
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, nil
|
||||
default:
|
||||
}
|
||||
|
||||
reactions, _, err := g.client.ListIssueReactions(g.repoOwner, g.repoName, index, gitea_sdk.ListIssueReactionsOptions{ListOptions: gitea_sdk.ListOptions{
|
||||
PageSize: g.maxPerPage,
|
||||
Page: i,
|
||||
}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, reaction := range reactions {
|
||||
allReactions = append(allReactions, &base.Reaction{
|
||||
UserID: reaction.User.ID,
|
||||
UserName: reaction.User.UserName,
|
||||
Content: reaction.Reaction,
|
||||
})
|
||||
}
|
||||
|
||||
if !g.pagination || len(reactions) < g.maxPerPage {
|
||||
break
|
||||
}
|
||||
}
|
||||
return reactions, nil
|
||||
return allReactions, nil
|
||||
}
|
||||
|
||||
func (g *GiteaDownloader) getCommentReactions(commentID int64) ([]*base.Reaction, error) {
|
||||
@@ -388,7 +406,7 @@ func (g *GiteaDownloader) getCommentReactions(commentID int64) ([]*base.Reaction
|
||||
}
|
||||
|
||||
// GetIssues returns issues according start and limit
|
||||
func (g *GiteaDownloader) GetIssues(_ context.Context, page, perPage int) ([]*base.Issue, bool, error) {
|
||||
func (g *GiteaDownloader) GetIssues(ctx context.Context, page, perPage int) ([]*base.Issue, bool, error) {
|
||||
if perPage > g.maxPerPage {
|
||||
perPage = g.maxPerPage
|
||||
}
|
||||
@@ -413,7 +431,7 @@ func (g *GiteaDownloader) GetIssues(_ context.Context, page, perPage int) ([]*ba
|
||||
milestone = issue.Milestone.Title
|
||||
}
|
||||
|
||||
reactions, err := g.getIssueReactions(issue.Index)
|
||||
reactions, err := g.getIssueReactions(ctx, issue.Index)
|
||||
if err != nil {
|
||||
WarnAndNotice("Unable to load reactions during migrating issue #%d in %s. Error: %v", issue.Index, g, err)
|
||||
}
|
||||
@@ -497,7 +515,7 @@ func (g *GiteaDownloader) GetComments(ctx context.Context, commentable base.Comm
|
||||
}
|
||||
|
||||
// GetPullRequests returns pull requests according page and perPage
|
||||
func (g *GiteaDownloader) GetPullRequests(_ context.Context, page, perPage int) ([]*base.PullRequest, bool, error) {
|
||||
func (g *GiteaDownloader) GetPullRequests(ctx context.Context, page, perPage int) ([]*base.PullRequest, bool, error) {
|
||||
if perPage > g.maxPerPage {
|
||||
perPage = g.maxPerPage
|
||||
}
|
||||
@@ -546,7 +564,7 @@ func (g *GiteaDownloader) GetPullRequests(_ context.Context, page, perPage int)
|
||||
mergeCommitSHA = *pr.MergedCommitID
|
||||
}
|
||||
|
||||
reactions, err := g.getIssueReactions(pr.Index)
|
||||
reactions, err := g.getIssueReactions(ctx, pr.Index)
|
||||
if err != nil {
|
||||
WarnAndNotice("Unable to load reactions during migrating pull #%d in %s. Error: %v", pr.Index, g, err)
|
||||
}
|
||||
|
||||
@@ -17,16 +17,17 @@ import (
|
||||
)
|
||||
|
||||
func TestGiteaDownloadRepo(t *testing.T) {
|
||||
// Skip tests if Gitea token is not found
|
||||
giteaToken := os.Getenv("GITEA_TOKEN")
|
||||
// Skip tests if Gitea token is not found (TODO: this test seems stopped for long time because there is no token in CI secrets)
|
||||
giteaToken := os.Getenv("GITEA_TEST_OFFICIAL_SITE_TOKEN")
|
||||
if giteaToken == "" {
|
||||
t.Skip("skipped test because GITEA_TOKEN was not in the environment")
|
||||
t.Skip("skipped test because GITEA_TEST_OFFICIAL_SITE_TOKEN was not in the environment")
|
||||
}
|
||||
|
||||
resp, err := http.Get("https://gitea.com/gitea")
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
t.Skipf("Can't reach https://gitea.com, skipping %s", t.Name())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ctx := t.Context()
|
||||
downloader, err := NewGiteaDownloader(ctx, "https://gitea.com", "gitea/test_repo", "", "", giteaToken)
|
||||
require.NoError(t, err, "NewGiteaDownloader error occur")
|
||||
@@ -85,16 +86,16 @@ func TestGiteaDownloadRepo(t *testing.T) {
|
||||
{
|
||||
Title: "V2 Finalize",
|
||||
Created: time.Unix(0, 0),
|
||||
Deadline: timePtr(time.Unix(1599263999, 0)),
|
||||
Updated: timePtr(time.Unix(0, 0)),
|
||||
Deadline: new(time.Unix(1599263999, 0)),
|
||||
Updated: new(time.Unix(0, 0)),
|
||||
State: "open",
|
||||
},
|
||||
{
|
||||
Title: "V1",
|
||||
Description: "Generate Content",
|
||||
Created: time.Unix(0, 0),
|
||||
Updated: timePtr(time.Unix(0, 0)),
|
||||
Closed: timePtr(time.Unix(1598985406, 0)),
|
||||
Updated: new(time.Unix(0, 0)),
|
||||
Closed: new(time.Unix(1598985406, 0)),
|
||||
State: "closed",
|
||||
},
|
||||
}, milestones)
|
||||
@@ -170,7 +171,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
|
||||
Content: "laugh",
|
||||
},
|
||||
},
|
||||
Closed: timePtr(time.Date(2020, 9, 1, 15, 49, 34, 0, time.UTC)),
|
||||
Closed: new(time.Date(2020, 9, 1, 15, 49, 34, 0, time.UTC)),
|
||||
},
|
||||
{
|
||||
Number: 2,
|
||||
@@ -189,7 +190,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
|
||||
Color: "d4c5f9",
|
||||
Description: "",
|
||||
}},
|
||||
Closed: timePtr(time.Unix(1598969497, 0)),
|
||||
Closed: new(time.Unix(1598969497, 0)),
|
||||
},
|
||||
}, issues)
|
||||
|
||||
@@ -236,7 +237,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
|
||||
IsLocked: false,
|
||||
Created: time.Unix(1598982759, 0),
|
||||
Updated: time.Unix(1599023425, 0),
|
||||
Closed: timePtr(time.Unix(1598982934, 0)),
|
||||
Closed: new(time.Unix(1598982934, 0)),
|
||||
Assignees: []string{"techknowlogick"},
|
||||
Base: base.PullRequestBranch{
|
||||
CloneURL: "",
|
||||
@@ -253,7 +254,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
|
||||
OwnerName: "6543-forks",
|
||||
},
|
||||
Merged: true,
|
||||
MergedTime: timePtr(time.Unix(1598982934, 0)),
|
||||
MergedTime: new(time.Unix(1598982934, 0)),
|
||||
MergeCommitSHA: "827aa28a907853e5ddfa40c8f9bc52471a2685fd",
|
||||
PatchURL: "https://gitea.com/gitea/test_repo/pulls/12.patch",
|
||||
}, prs[1])
|
||||
|
||||
@@ -6,10 +6,9 @@ package migrations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -303,7 +302,7 @@ func (g *GiteaLocalUploader) CreateReleases(ctx context.Context, releases ...*ba
|
||||
return fmt.Errorf("GetTagCommit[%v]: %w", rel.TagName, err)
|
||||
}
|
||||
rel.Sha1 = commit.ID.String()
|
||||
rel.NumCommits, err = commit.CommitsCount()
|
||||
rel.NumCommits, err = gitrepo.CommitsCountOfCommit(ctx, g.repo, commit.ID.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("CommitsCount: %w", err)
|
||||
}
|
||||
@@ -366,7 +365,13 @@ func (g *GiteaLocalUploader) CreateReleases(ctx context.Context, releases ...*ba
|
||||
|
||||
// SyncTags syncs releases with tags in the database
|
||||
func (g *GiteaLocalUploader) SyncTags(ctx context.Context) error {
|
||||
return repo_module.SyncReleasesWithTags(ctx, g.repo, g.gitRepo)
|
||||
_, err := repo_module.SyncReleasesWithTags(ctx, g.repo, g.gitRepo)
|
||||
return err
|
||||
}
|
||||
|
||||
func (g *GiteaLocalUploader) SyncBranches(ctx context.Context) error {
|
||||
_, _, err := repo_module.SyncRepoBranchesWithRepo(ctx, g.repo, g.gitRepo, g.doer.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateIssues creates issues
|
||||
@@ -585,12 +590,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba
|
||||
}
|
||||
defer ret.Close()
|
||||
|
||||
pullDir := filepath.Join(g.repo.RepoPath(), "pulls")
|
||||
if err = os.MkdirAll(pullDir, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(pullDir, fmt.Sprintf("%d.patch", pr.Number)))
|
||||
f, err := gitrepo.CreateRepoFile(ctx, g.repo, fmt.Sprintf("pulls/%d.patch", pr.Number))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -664,7 +664,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba
|
||||
fetchArg = git.BranchPrefix + fetchArg
|
||||
}
|
||||
|
||||
_, _, err = gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.repo.RepoPath()})
|
||||
_, _, err = gitrepo.RunCmdString(ctx, g.repo, gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg))
|
||||
if err != nil {
|
||||
log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err)
|
||||
return head, nil
|
||||
@@ -699,7 +699,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba
|
||||
// The SHA is empty
|
||||
log.Warn("Empty reference, no pull head for PR #%d in %s/%s", pr.Number, g.repoOwner, g.repoName)
|
||||
} else {
|
||||
_, _, err = gitcmd.NewCommand("rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.repo.RepoPath()})
|
||||
_, _, err = gitrepo.RunCmdString(ctx, g.repo, gitcmd.NewCommand("rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA))
|
||||
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.GetGitHeadRefName())
|
||||
@@ -735,7 +735,7 @@ func (g *GiteaLocalUploader) newPullRequest(ctx context.Context, pr *base.PullRe
|
||||
if pr.Base.Ref != "" && pr.Head.SHA != "" {
|
||||
// A PR against a tag base does not make sense - therefore pr.Base.Ref must be a branch
|
||||
// TODO: should we be checking for the refs/heads/ prefix on the pr.Base.Ref? (i.e. are these actually branches or refs)
|
||||
pr.Base.SHA, _, err = g.gitRepo.GetMergeBase("", git.BranchPrefix+pr.Base.Ref, pr.Head.SHA)
|
||||
pr.Base.SHA, err = gitrepo.MergeBase(ctx, g.repo, git.BranchPrefix+pr.Base.Ref, pr.Head.SHA)
|
||||
if err != nil {
|
||||
log.Error("Cannot determine the merge base for PR #%d in %s/%s. Error: %v", pr.Number, g.repoOwner, g.repoName, err)
|
||||
}
|
||||
@@ -897,21 +897,10 @@ func (g *GiteaLocalUploader) CreateReviews(ctx context.Context, reviews ...*base
|
||||
// SECURITY: The TreePath must be cleaned! use relative path
|
||||
comment.TreePath = util.PathJoinRel(comment.TreePath)
|
||||
|
||||
var patch string
|
||||
reader, writer := io.Pipe()
|
||||
defer func() {
|
||||
_ = reader.Close()
|
||||
_ = writer.Close()
|
||||
}()
|
||||
go func(comment *base.ReviewComment) {
|
||||
if err := git.GetRepoRawDiffForFile(g.gitRepo, pr.MergeBase, headCommitID, git.RawDiffNormal, comment.TreePath, writer); err != nil {
|
||||
// We should ignore the error since the commit maybe removed when force push to the pull request
|
||||
log.Warn("GetRepoRawDiffForFile failed when migrating [%s, %s, %s, %s]: %v", g.gitRepo.Path, pr.MergeBase, headCommitID, comment.TreePath, err)
|
||||
}
|
||||
_ = writer.Close()
|
||||
}(comment)
|
||||
|
||||
patch, _ = git.CutDiffAroundLine(reader, int64((&issues_model.Comment{Line: int64(line + comment.Position - 1)}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines)
|
||||
patch, _ := git.GetFileDiffCutAroundLine(
|
||||
g.gitRepo, pr.MergeBase, headCommitID, comment.TreePath,
|
||||
int64((&issues_model.Comment{Line: int64(line + comment.Position - 1)}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines,
|
||||
)
|
||||
|
||||
if comment.CreatedAt.IsZero() {
|
||||
comment.CreatedAt = review.CreatedAt
|
||||
@@ -999,12 +988,15 @@ func (g *GiteaLocalUploader) remapUser(ctx context.Context, source user_model.Ex
|
||||
func (g *GiteaLocalUploader) remapLocalUser(ctx context.Context, source user_model.ExternalUserMigrated) (int64, error) {
|
||||
userid, ok := g.userMap[source.GetExternalID()]
|
||||
if !ok {
|
||||
name, err := user_model.GetUserNameByID(ctx, source.GetExternalID())
|
||||
if err != nil {
|
||||
user, err := user_model.GetUserByID(ctx, source.GetExternalID())
|
||||
if errors.Is(err, util.ErrNotExist) {
|
||||
g.userMap[source.GetExternalID()] = userid
|
||||
return 0, nil
|
||||
} else if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// let's not reuse an ID when the user was deleted or has a different user name
|
||||
if name != source.GetExternalName() {
|
||||
// let's not reuse an ID when the user was deleted or has a different username
|
||||
if !util.AsciiEqualFold(user.Name, source.GetExternalName()) {
|
||||
userid = 0
|
||||
} else {
|
||||
userid = source.GetExternalID()
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -17,15 +14,10 @@ import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
base "code.gitea.io/gitea/modules/migration"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -228,297 +220,3 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, linkedUser.ID, target.GetUserID())
|
||||
}
|
||||
|
||||
func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
//
|
||||
// fromRepo master
|
||||
//
|
||||
fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
baseRef := "master"
|
||||
// this is very different from the real situation. It should be a bare repository for all the Gitea managed repositories
|
||||
assert.NoError(t, git.InitRepository(t.Context(), fromRepo.RepoPath(), false, fromRepo.ObjectFormatName))
|
||||
err := gitcmd.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(t.Context(), &gitcmd.RunOpts{Dir: fromRepo.RepoPath()})
|
||||
assert.NoError(t, err)
|
||||
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(t.Context(), fromRepo.RepoPath(), true))
|
||||
signature := git.Signature{
|
||||
Email: "test@example.com",
|
||||
Name: "test",
|
||||
When: time.Now(),
|
||||
}
|
||||
assert.NoError(t, git.CommitChanges(t.Context(), fromRepo.RepoPath(), git.CommitChangesOptions{
|
||||
Committer: &signature,
|
||||
Author: &signature,
|
||||
Message: "Initial Commit",
|
||||
}))
|
||||
fromGitRepo, err := gitrepo.OpenRepository(t.Context(), fromRepo)
|
||||
assert.NoError(t, err)
|
||||
defer fromGitRepo.Close()
|
||||
baseSHA, err := fromGitRepo.GetBranchCommitID(baseRef)
|
||||
assert.NoError(t, err)
|
||||
|
||||
//
|
||||
// fromRepo branch1
|
||||
//
|
||||
headRef := "branch1"
|
||||
_, _, err = gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(headRef).RunStdString(t.Context(), &gitcmd.RunOpts{Dir: fromRepo.RepoPath()})
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("SOMETHING"), 0o644))
|
||||
assert.NoError(t, git.AddChanges(t.Context(), fromRepo.RepoPath(), true))
|
||||
signature.When = time.Now()
|
||||
assert.NoError(t, git.CommitChanges(t.Context(), fromRepo.RepoPath(), git.CommitChangesOptions{
|
||||
Committer: &signature,
|
||||
Author: &signature,
|
||||
Message: "Pull request",
|
||||
}))
|
||||
assert.NoError(t, err)
|
||||
headSHA, err := fromGitRepo.GetBranchCommitID(headRef)
|
||||
assert.NoError(t, err)
|
||||
|
||||
fromRepoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: fromRepo.OwnerID})
|
||||
|
||||
//
|
||||
// forkRepo branch2
|
||||
//
|
||||
forkHeadRef := "branch2"
|
||||
forkRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8})
|
||||
assert.NoError(t, git.Clone(t.Context(), fromRepo.RepoPath(), forkRepo.RepoPath(), git.CloneRepoOptions{
|
||||
Branch: headRef,
|
||||
}))
|
||||
_, _, err = gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(t.Context(), &gitcmd.RunOpts{Dir: forkRepo.RepoPath()})
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte("# branch2 "+forkRepo.RepoPath()), 0o644))
|
||||
assert.NoError(t, git.AddChanges(t.Context(), forkRepo.RepoPath(), true))
|
||||
assert.NoError(t, git.CommitChanges(t.Context(), forkRepo.RepoPath(), git.CommitChangesOptions{
|
||||
Committer: &signature,
|
||||
Author: &signature,
|
||||
Message: "branch2 commit",
|
||||
}))
|
||||
forkGitRepo, err := gitrepo.OpenRepository(t.Context(), forkRepo)
|
||||
assert.NoError(t, err)
|
||||
defer forkGitRepo.Close()
|
||||
forkHeadSHA, err := forkGitRepo.GetBranchCommitID(forkHeadRef)
|
||||
assert.NoError(t, err)
|
||||
|
||||
toRepoName := "migrated"
|
||||
ctx := t.Context()
|
||||
uploader := NewGiteaLocalUploader(ctx, fromRepoOwner, fromRepoOwner.Name, toRepoName)
|
||||
uploader.gitServiceType = structs.GiteaService
|
||||
|
||||
assert.NoError(t, repo_service.Init(t.Context()))
|
||||
assert.NoError(t, uploader.CreateRepo(ctx, &base.Repository{
|
||||
Description: "description",
|
||||
OriginalURL: fromRepo.RepoPath(),
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
IsPrivate: false,
|
||||
IsMirror: true,
|
||||
}, base.MigrateOptions{
|
||||
GitServiceType: structs.GiteaService,
|
||||
Private: false,
|
||||
Mirror: true,
|
||||
}))
|
||||
|
||||
for _, testCase := range []struct {
|
||||
name string
|
||||
head string
|
||||
logFilter []string
|
||||
logFiltered []bool
|
||||
pr base.PullRequest
|
||||
}{
|
||||
{
|
||||
name: "fork, good Head.SHA",
|
||||
head: fmt.Sprintf("%s/%s", forkRepo.OwnerName, forkHeadRef),
|
||||
pr: base.PullRequest{
|
||||
PatchURL: "",
|
||||
Number: 1,
|
||||
State: "open",
|
||||
Base: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: baseRef,
|
||||
SHA: baseSHA,
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
Head: base.PullRequestBranch{
|
||||
CloneURL: forkRepo.RepoPath(),
|
||||
Ref: forkHeadRef,
|
||||
SHA: forkHeadSHA,
|
||||
RepoName: forkRepo.Name,
|
||||
OwnerName: forkRepo.OwnerName,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "fork, invalid Head.Ref",
|
||||
head: "unknown repository",
|
||||
pr: base.PullRequest{
|
||||
PatchURL: "",
|
||||
Number: 1,
|
||||
State: "open",
|
||||
Base: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: baseRef,
|
||||
SHA: baseSHA,
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
Head: base.PullRequestBranch{
|
||||
CloneURL: forkRepo.RepoPath(),
|
||||
Ref: "INVALID",
|
||||
SHA: forkHeadSHA,
|
||||
RepoName: forkRepo.Name,
|
||||
OwnerName: forkRepo.OwnerName,
|
||||
},
|
||||
},
|
||||
logFilter: []string{"Fetch branch from"},
|
||||
logFiltered: []bool{true},
|
||||
},
|
||||
{
|
||||
name: "invalid fork CloneURL",
|
||||
head: "unknown repository",
|
||||
pr: base.PullRequest{
|
||||
PatchURL: "",
|
||||
Number: 1,
|
||||
State: "open",
|
||||
Base: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: baseRef,
|
||||
SHA: baseSHA,
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
Head: base.PullRequestBranch{
|
||||
CloneURL: "UNLIKELY",
|
||||
Ref: forkHeadRef,
|
||||
SHA: forkHeadSHA,
|
||||
RepoName: forkRepo.Name,
|
||||
OwnerName: "WRONG",
|
||||
},
|
||||
},
|
||||
logFilter: []string{"AddRemote"},
|
||||
logFiltered: []bool{true},
|
||||
},
|
||||
{
|
||||
name: "no fork, good Head.SHA",
|
||||
head: headRef,
|
||||
pr: base.PullRequest{
|
||||
PatchURL: "",
|
||||
Number: 1,
|
||||
State: "open",
|
||||
Base: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: baseRef,
|
||||
SHA: baseSHA,
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
Head: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: headRef,
|
||||
SHA: headSHA,
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no fork, empty Head.SHA",
|
||||
head: headRef,
|
||||
pr: base.PullRequest{
|
||||
PatchURL: "",
|
||||
Number: 1,
|
||||
State: "open",
|
||||
Base: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: baseRef,
|
||||
SHA: baseSHA,
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
Head: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: headRef,
|
||||
SHA: "",
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
},
|
||||
logFilter: []string{"Empty reference", "Cannot remove local head"},
|
||||
logFiltered: []bool{true, false},
|
||||
},
|
||||
{
|
||||
name: "no fork, invalid Head.SHA",
|
||||
head: headRef,
|
||||
pr: base.PullRequest{
|
||||
PatchURL: "",
|
||||
Number: 1,
|
||||
State: "open",
|
||||
Base: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: baseRef,
|
||||
SHA: baseSHA,
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
Head: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: headRef,
|
||||
SHA: "brokenSHA",
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
},
|
||||
logFilter: []string{"Deprecated local head"},
|
||||
logFiltered: []bool{true},
|
||||
},
|
||||
{
|
||||
name: "no fork, not found Head.SHA",
|
||||
head: headRef,
|
||||
pr: base.PullRequest{
|
||||
PatchURL: "",
|
||||
Number: 1,
|
||||
State: "open",
|
||||
Base: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: baseRef,
|
||||
SHA: baseSHA,
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
Head: base.PullRequestBranch{
|
||||
CloneURL: fromRepo.RepoPath(),
|
||||
Ref: headRef,
|
||||
SHA: "2697b352310fcd01cbd1f3dbd43b894080027f68",
|
||||
RepoName: fromRepo.Name,
|
||||
OwnerName: fromRepo.OwnerName,
|
||||
},
|
||||
},
|
||||
logFilter: []string{"Deprecated local head", "Cannot remove local head"},
|
||||
logFiltered: []bool{true, false},
|
||||
},
|
||||
} {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
stopMark := fmt.Sprintf(">>>>>>>>>>>>>STOP: %s<<<<<<<<<<<<<<<", testCase.name)
|
||||
|
||||
logChecker, cleanup := test.NewLogChecker(log.DEFAULT)
|
||||
logChecker.Filter(testCase.logFilter...).StopMark(stopMark)
|
||||
defer cleanup()
|
||||
|
||||
testCase.pr.EnsuredSafe = true
|
||||
|
||||
head, err := uploader.updateGitForPullRequest(ctx, &testCase.pr)
|
||||
assert.NoError(t, err)
|
||||
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.Equal(t, testCase.logFiltered, logFiltered, "for log message filters: %v", testCase.logFilter)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/proxy"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
|
||||
"github.com/google/go-github/v74/github"
|
||||
"github.com/google/go-github/v84/github"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
@@ -861,28 +861,22 @@ func (g *GithubDownloaderV3) GetReviews(ctx context.Context, reviewable base.Rev
|
||||
opt.Page = resp.NextPage
|
||||
}
|
||||
// Get requested reviews
|
||||
for {
|
||||
g.waitAndPickClient(ctx)
|
||||
reviewers, resp, err := g.getClient().PullRequests.ListReviewers(ctx, g.repoOwner, g.repoName, int(reviewable.GetForeignIndex()), opt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while listing repos: %w", err)
|
||||
}
|
||||
g.setRate(&resp.Rate)
|
||||
for _, user := range reviewers.Users {
|
||||
r := &base.Review{
|
||||
ReviewerID: user.GetID(),
|
||||
ReviewerName: user.GetLogin(),
|
||||
State: base.ReviewStateRequestReview,
|
||||
IssueIndex: reviewable.GetLocalIndex(),
|
||||
}
|
||||
allReviews = append(allReviews, r)
|
||||
}
|
||||
// TODO: Handle Team requests
|
||||
if resp.NextPage == 0 {
|
||||
break
|
||||
}
|
||||
opt.Page = resp.NextPage
|
||||
g.waitAndPickClient(ctx)
|
||||
reviewers, resp, err := g.getClient().PullRequests.ListReviewers(ctx, g.repoOwner, g.repoName, int(reviewable.GetForeignIndex()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while listing repos: %w", err)
|
||||
}
|
||||
g.setRate(&resp.Rate)
|
||||
for _, user := range reviewers.Users {
|
||||
r := &base.Review{
|
||||
ReviewerID: user.GetID(),
|
||||
ReviewerName: user.GetLogin(),
|
||||
State: base.ReviewStateRequestReview,
|
||||
IssueIndex: reviewable.GetLocalIndex(),
|
||||
}
|
||||
allReviews = append(allReviews, r)
|
||||
}
|
||||
// TODO: Handle Team requests
|
||||
return allReviews, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -47,19 +47,19 @@ func TestGitHubDownloadRepo(t *testing.T) {
|
||||
{
|
||||
Title: "1.0.0",
|
||||
Description: "Milestone 1.0.0",
|
||||
Deadline: timePtr(time.Date(2019, 11, 11, 8, 0, 0, 0, time.UTC)),
|
||||
Deadline: new(time.Date(2019, 11, 11, 8, 0, 0, 0, time.UTC)),
|
||||
Created: time.Date(2019, 11, 12, 19, 37, 8, 0, time.UTC),
|
||||
Updated: timePtr(time.Date(2019, 11, 12, 21, 56, 17, 0, time.UTC)),
|
||||
Closed: timePtr(time.Date(2019, 11, 12, 19, 45, 49, 0, time.UTC)),
|
||||
Updated: new(time.Date(2019, 11, 12, 21, 56, 17, 0, time.UTC)),
|
||||
Closed: new(time.Date(2019, 11, 12, 19, 45, 49, 0, time.UTC)),
|
||||
State: "closed",
|
||||
},
|
||||
{
|
||||
Title: "1.1.0",
|
||||
Description: "Milestone 1.1.0",
|
||||
Deadline: timePtr(time.Date(2019, 11, 12, 8, 0, 0, 0, time.UTC)),
|
||||
Deadline: new(time.Date(2019, 11, 12, 8, 0, 0, 0, time.UTC)),
|
||||
Created: time.Date(2019, 11, 12, 19, 37, 25, 0, time.UTC),
|
||||
Updated: timePtr(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
|
||||
Closed: timePtr(time.Date(2019, 11, 12, 19, 45, 46, 0, time.UTC)),
|
||||
Updated: new(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
|
||||
Closed: new(time.Date(2019, 11, 12, 19, 45, 46, 0, time.UTC)),
|
||||
State: "closed",
|
||||
},
|
||||
}, milestones)
|
||||
@@ -163,7 +163,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
|
||||
Content: "+1",
|
||||
},
|
||||
},
|
||||
Closed: timePtr(time.Date(2019, 11, 12, 20, 22, 22, 0, time.UTC)),
|
||||
Closed: new(time.Date(2019, 11, 12, 20, 22, 22, 0, time.UTC)),
|
||||
},
|
||||
{
|
||||
Number: 2,
|
||||
@@ -214,7 +214,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
|
||||
Content: "+1",
|
||||
},
|
||||
},
|
||||
Closed: timePtr(time.Date(2019, 11, 12, 21, 1, 31, 0, time.UTC)),
|
||||
Closed: new(time.Date(2019, 11, 12, 21, 1, 31, 0, time.UTC)),
|
||||
},
|
||||
}, issues)
|
||||
|
||||
@@ -284,9 +284,9 @@ func TestGitHubDownloadRepo(t *testing.T) {
|
||||
OwnerName: "go-gitea",
|
||||
RepoName: "test_repo",
|
||||
},
|
||||
Closed: timePtr(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
|
||||
Closed: new(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
|
||||
Merged: true,
|
||||
MergedTime: timePtr(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
|
||||
MergedTime: new(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
|
||||
MergeCommitSHA: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
|
||||
ForeignIndex: 3,
|
||||
},
|
||||
|
||||
@@ -63,16 +63,16 @@ type gitlabIIDResolver struct {
|
||||
frozen bool
|
||||
}
|
||||
|
||||
func (r *gitlabIIDResolver) recordIssueIID(issueIID int) {
|
||||
func (r *gitlabIIDResolver) recordIssueIID(issueIID int64) {
|
||||
if r.frozen {
|
||||
panic("cannot record issue IID after pull request IID generation has started")
|
||||
}
|
||||
r.maxIssueIID = max(r.maxIssueIID, int64(issueIID))
|
||||
r.maxIssueIID = max(r.maxIssueIID, issueIID)
|
||||
}
|
||||
|
||||
func (r *gitlabIIDResolver) generatePullRequestNumber(mrIID int) int64 {
|
||||
func (r *gitlabIIDResolver) generatePullRequestNumber(mrIID int64) int64 {
|
||||
r.frozen = true
|
||||
return r.maxIssueIID + int64(mrIID)
|
||||
return r.maxIssueIID + mrIID
|
||||
}
|
||||
|
||||
// GitlabDownloader implements a Downloader interface to get repository information
|
||||
@@ -83,7 +83,7 @@ type GitlabDownloader struct {
|
||||
base.NullDownloader
|
||||
client *gitlab.Client
|
||||
baseURL string
|
||||
repoID int
|
||||
repoID int64
|
||||
repoName string
|
||||
iidResolver gitlabIIDResolver
|
||||
maxPerPage int
|
||||
@@ -212,8 +212,8 @@ func (g *GitlabDownloader) GetMilestones(ctx context.Context) ([]*base.Milestone
|
||||
ms, _, err := g.client.Milestones.ListMilestones(g.repoID, &gitlab.ListMilestonesOptions{
|
||||
State: &state,
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: i,
|
||||
PerPage: perPage,
|
||||
Page: int64(i),
|
||||
PerPage: int64(perPage),
|
||||
},
|
||||
}, nil, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
@@ -281,8 +281,8 @@ func (g *GitlabDownloader) GetLabels(ctx context.Context) ([]*base.Label, error)
|
||||
labels := make([]*base.Label, 0, perPage)
|
||||
for i := 1; ; i++ {
|
||||
ls, _, err := g.client.Labels.ListLabels(g.repoID, &gitlab.ListLabelsOptions{ListOptions: gitlab.ListOptions{
|
||||
Page: i,
|
||||
PerPage: perPage,
|
||||
Page: int64(i),
|
||||
PerPage: int64(perPage),
|
||||
}}, nil, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -310,7 +310,7 @@ func (g *GitlabDownloader) convertGitlabRelease(ctx context.Context, rel *gitlab
|
||||
Name: rel.Name,
|
||||
Body: rel.Description,
|
||||
Created: *rel.CreatedAt,
|
||||
PublisherID: int64(rel.Author.ID),
|
||||
PublisherID: rel.Author.ID,
|
||||
PublisherName: rel.Author.Username,
|
||||
}
|
||||
|
||||
@@ -319,7 +319,7 @@ func (g *GitlabDownloader) convertGitlabRelease(ctx context.Context, rel *gitlab
|
||||
for _, asset := range rel.Assets.Links {
|
||||
assetID := asset.ID // Don't optimize this, for closure we need a local variable
|
||||
r.Assets = append(r.Assets, &base.ReleaseAsset{
|
||||
ID: int64(asset.ID),
|
||||
ID: asset.ID,
|
||||
Name: asset.Name,
|
||||
Size: &zero,
|
||||
DownloadCount: &zero,
|
||||
@@ -359,8 +359,8 @@ func (g *GitlabDownloader) GetReleases(ctx context.Context) ([]*base.Release, er
|
||||
for i := 1; ; i++ {
|
||||
ls, _, err := g.client.Releases.ListReleases(g.repoID, &gitlab.ListReleasesOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: i,
|
||||
PerPage: perPage,
|
||||
Page: int64(i),
|
||||
PerPage: int64(perPage),
|
||||
},
|
||||
}, nil, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
@@ -396,8 +396,8 @@ func (g *GitlabDownloader) GetIssues(ctx context.Context, page, perPage int) ([]
|
||||
State: &state,
|
||||
Sort: &sort,
|
||||
ListOptions: gitlab.ListOptions{
|
||||
PerPage: perPage,
|
||||
Page: page,
|
||||
PerPage: int64(perPage),
|
||||
Page: int64(page),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -423,7 +423,7 @@ func (g *GitlabDownloader) GetIssues(ctx context.Context, page, perPage int) ([]
|
||||
var reactions []*gitlab.AwardEmoji
|
||||
awardPage := 1
|
||||
for {
|
||||
awards, _, err := g.client.AwardEmoji.ListIssueAwardEmoji(g.repoID, issue.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(ctx))
|
||||
awards, _, err := g.client.AwardEmoji.ListIssueAwardEmoji(g.repoID, issue.IID, &gitlab.ListAwardEmojiOptions{ListOptions: gitlab.ListOptions{Page: int64(awardPage), PerPage: int64(perPage)}}, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error while listing issue awards: %w", err)
|
||||
}
|
||||
@@ -439,8 +439,8 @@ func (g *GitlabDownloader) GetIssues(ctx context.Context, page, perPage int) ([]
|
||||
|
||||
allIssues = append(allIssues, &base.Issue{
|
||||
Title: issue.Title,
|
||||
Number: int64(issue.IID),
|
||||
PosterID: int64(issue.Author.ID),
|
||||
Number: issue.IID,
|
||||
PosterID: issue.Author.ID,
|
||||
PosterName: issue.Author.Username,
|
||||
Content: issue.Description,
|
||||
Milestone: milestone,
|
||||
@@ -451,7 +451,7 @@ func (g *GitlabDownloader) GetIssues(ctx context.Context, page, perPage int) ([]
|
||||
Closed: issue.ClosedAt,
|
||||
IsLocked: issue.DiscussionLocked,
|
||||
Updated: *issue.UpdatedAt,
|
||||
ForeignIndex: int64(issue.IID),
|
||||
ForeignIndex: issue.IID,
|
||||
Context: gitlabIssueContext{IsMergeRequest: false},
|
||||
})
|
||||
|
||||
@@ -472,21 +472,25 @@ func (g *GitlabDownloader) GetComments(ctx context.Context, commentable base.Com
|
||||
|
||||
allComments := make([]*base.Comment, 0, g.maxPerPage)
|
||||
|
||||
page := 1
|
||||
var page int64 = 1
|
||||
|
||||
for {
|
||||
var comments []*gitlab.Discussion
|
||||
var resp *gitlab.Response
|
||||
var err error
|
||||
if !context.IsMergeRequest {
|
||||
comments, resp, err = g.client.Discussions.ListIssueDiscussions(g.repoID, int(commentable.GetForeignIndex()), &gitlab.ListIssueDiscussionsOptions{
|
||||
Page: page,
|
||||
PerPage: g.maxPerPage,
|
||||
comments, resp, err = g.client.Discussions.ListIssueDiscussions(g.repoID, commentable.GetForeignIndex(), &gitlab.ListIssueDiscussionsOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: page,
|
||||
PerPage: int64(g.maxPerPage),
|
||||
},
|
||||
}, nil, gitlab.WithContext(ctx))
|
||||
} else {
|
||||
comments, resp, err = g.client.Discussions.ListMergeRequestDiscussions(g.repoID, int(commentable.GetForeignIndex()), &gitlab.ListMergeRequestDiscussionsOptions{
|
||||
Page: page,
|
||||
PerPage: g.maxPerPage,
|
||||
comments, resp, err = g.client.Discussions.ListMergeRequestDiscussions(g.repoID, commentable.GetForeignIndex(), &gitlab.ListMergeRequestDiscussionsOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: page,
|
||||
PerPage: int64(g.maxPerPage),
|
||||
},
|
||||
}, nil, gitlab.WithContext(ctx))
|
||||
}
|
||||
|
||||
@@ -510,17 +514,17 @@ func (g *GitlabDownloader) GetComments(ctx context.Context, commentable base.Com
|
||||
var resp *gitlab.Response
|
||||
var err error
|
||||
if context.IsMergeRequest {
|
||||
stateEvents, resp, err = g.client.ResourceStateEvents.ListMergeStateEvents(g.repoID, int(commentable.GetForeignIndex()), &gitlab.ListStateEventsOptions{
|
||||
stateEvents, resp, err = g.client.ResourceStateEvents.ListMergeStateEvents(g.repoID, commentable.GetForeignIndex(), &gitlab.ListStateEventsOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: page,
|
||||
PerPage: g.maxPerPage,
|
||||
PerPage: int64(g.maxPerPage),
|
||||
},
|
||||
}, nil, gitlab.WithContext(ctx))
|
||||
} else {
|
||||
stateEvents, resp, err = g.client.ResourceStateEvents.ListIssueStateEvents(g.repoID, int(commentable.GetForeignIndex()), &gitlab.ListStateEventsOptions{
|
||||
stateEvents, resp, err = g.client.ResourceStateEvents.ListIssueStateEvents(g.repoID, commentable.GetForeignIndex(), &gitlab.ListStateEventsOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: page,
|
||||
PerPage: g.maxPerPage,
|
||||
PerPage: int64(g.maxPerPage),
|
||||
},
|
||||
}, nil, gitlab.WithContext(ctx))
|
||||
}
|
||||
@@ -531,11 +535,11 @@ 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
|
||||
posterUserID, posterUsername = stateEvent.User.ID, stateEvent.User.Username
|
||||
}
|
||||
comment := &base.Comment{
|
||||
IssueIndex: commentable.GetLocalIndex(),
|
||||
Index: int64(stateEvent.ID),
|
||||
Index: stateEvent.ID,
|
||||
PosterID: posterUserID,
|
||||
PosterName: posterUsername,
|
||||
Content: "",
|
||||
@@ -569,8 +573,8 @@ var targetBranchChangeRegexp = regexp.MustCompile("^changed target branch from `
|
||||
func (g *GitlabDownloader) convertNoteToComment(localIndex int64, note *gitlab.Note) *base.Comment {
|
||||
comment := &base.Comment{
|
||||
IssueIndex: localIndex,
|
||||
Index: int64(note.ID),
|
||||
PosterID: int64(note.Author.ID),
|
||||
Index: note.ID,
|
||||
PosterID: note.Author.ID,
|
||||
PosterName: note.Author.Username,
|
||||
PosterEmail: note.Author.Email,
|
||||
Content: note.Body,
|
||||
@@ -603,8 +607,8 @@ func (g *GitlabDownloader) GetPullRequests(ctx context.Context, page, perPage in
|
||||
view := "simple"
|
||||
opt := &gitlab.ListProjectMergeRequestsOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
PerPage: perPage,
|
||||
Page: page,
|
||||
PerPage: int64(perPage),
|
||||
Page: int64(page),
|
||||
},
|
||||
View: &view,
|
||||
}
|
||||
@@ -664,7 +668,7 @@ func (g *GitlabDownloader) GetPullRequests(ctx context.Context, page, perPage in
|
||||
var reactions []*gitlab.AwardEmoji
|
||||
awardPage := 1
|
||||
for {
|
||||
awards, _, err := g.client.AwardEmoji.ListMergeRequestAwardEmoji(g.repoID, pr.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(ctx))
|
||||
awards, _, err := g.client.AwardEmoji.ListMergeRequestAwardEmoji(g.repoID, pr.IID, &gitlab.ListAwardEmojiOptions{ListOptions: gitlab.ListOptions{Page: int64(awardPage), PerPage: int64(perPage)}}, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error while listing merge requests awards: %w", err)
|
||||
}
|
||||
@@ -685,7 +689,7 @@ func (g *GitlabDownloader) GetPullRequests(ctx context.Context, page, perPage in
|
||||
Title: pr.Title,
|
||||
Number: newPRNumber,
|
||||
PosterName: pr.Author.Username,
|
||||
PosterID: int64(pr.Author.ID),
|
||||
PosterID: pr.Author.ID,
|
||||
Content: pr.Description,
|
||||
Milestone: milestone,
|
||||
State: pr.State,
|
||||
@@ -711,7 +715,7 @@ func (g *GitlabDownloader) GetPullRequests(ctx context.Context, page, perPage in
|
||||
OwnerName: pr.Author.Username,
|
||||
},
|
||||
PatchURL: pr.WebURL + ".patch",
|
||||
ForeignIndex: int64(pr.IID),
|
||||
ForeignIndex: pr.IID,
|
||||
Context: gitlabIssueContext{IsMergeRequest: true},
|
||||
IsDraft: pr.Draft,
|
||||
})
|
||||
@@ -725,7 +729,7 @@ func (g *GitlabDownloader) GetPullRequests(ctx context.Context, page, perPage in
|
||||
|
||||
// GetReviews returns pull requests review
|
||||
func (g *GitlabDownloader) GetReviews(ctx context.Context, reviewable base.Reviewable) ([]*base.Review, error) {
|
||||
approvals, resp, err := g.client.MergeRequestApprovals.GetConfiguration(g.repoID, int(reviewable.GetForeignIndex()), gitlab.WithContext(ctx))
|
||||
approvals, resp, err := g.client.MergeRequestApprovals.GetConfiguration(g.repoID, reviewable.GetForeignIndex(), gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
||||
log.Error(fmt.Sprintf("GitlabDownloader: while migrating a error occurred: '%s'", err.Error()))
|
||||
@@ -747,7 +751,7 @@ func (g *GitlabDownloader) GetReviews(ctx context.Context, reviewable base.Revie
|
||||
for _, user := range approvals.ApprovedBy {
|
||||
reviews = append(reviews, &base.Review{
|
||||
IssueIndex: reviewable.GetLocalIndex(),
|
||||
ReviewerID: int64(user.User.ID),
|
||||
ReviewerID: user.User.ID,
|
||||
ReviewerName: user.User.Username,
|
||||
CreatedAt: createdAt,
|
||||
// All we get are approvals
|
||||
@@ -765,7 +769,7 @@ func (g *GitlabDownloader) awardsToReactions(awards []*gitlab.AwardEmoji) []*bas
|
||||
uid := fmt.Sprintf("%s%d", award.Name, award.User.ID)
|
||||
if uniqCheck.Add(uid) {
|
||||
result = append(result, &base.Reaction{
|
||||
UserID: int64(award.User.ID),
|
||||
UserID: award.User.ID,
|
||||
UserName: award.User.Username,
|
||||
Content: award.Name,
|
||||
})
|
||||
|
||||
@@ -30,6 +30,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
t.Skipf("Can't access test repo, skipping %s", t.Name())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ctx := t.Context()
|
||||
downloader, err := NewGitlabDownloader(ctx, "https://gitlab.com", "gitea/test_repo", gitlabPersonalAccessToken)
|
||||
if err != nil {
|
||||
@@ -58,14 +59,14 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
||||
{
|
||||
Title: "1.1.0",
|
||||
Created: time.Date(2019, 11, 28, 8, 42, 44, 575000000, time.UTC),
|
||||
Updated: timePtr(time.Date(2019, 11, 28, 8, 42, 44, 575000000, time.UTC)),
|
||||
Updated: new(time.Date(2019, 11, 28, 8, 42, 44, 575000000, time.UTC)),
|
||||
State: "active",
|
||||
},
|
||||
{
|
||||
Title: "1.0.0",
|
||||
Created: time.Date(2019, 11, 28, 8, 42, 30, 301000000, time.UTC),
|
||||
Updated: timePtr(time.Date(2019, 11, 28, 15, 57, 52, 401000000, time.UTC)),
|
||||
Closed: timePtr(time.Date(2019, 11, 28, 15, 57, 52, 401000000, time.UTC)),
|
||||
Updated: new(time.Date(2019, 11, 28, 15, 57, 52, 401000000, time.UTC)),
|
||||
Closed: new(time.Date(2019, 11, 28, 15, 57, 52, 401000000, time.UTC)),
|
||||
State: "closed",
|
||||
},
|
||||
}, milestones)
|
||||
@@ -160,7 +161,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
||||
Content: "open_mouth",
|
||||
},
|
||||
},
|
||||
Closed: timePtr(time.Date(2019, 11, 28, 8, 46, 23, 275000000, time.UTC)),
|
||||
Closed: new(time.Date(2019, 11, 28, 8, 46, 23, 275000000, time.UTC)),
|
||||
},
|
||||
{
|
||||
Number: 2,
|
||||
@@ -209,7 +210,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
|
||||
Content: "hearts",
|
||||
},
|
||||
},
|
||||
Closed: timePtr(time.Date(2019, 11, 28, 8, 45, 44, 959000000, time.UTC)),
|
||||
Closed: new(time.Date(2019, 11, 28, 8, 45, 44, 959000000, time.UTC)),
|
||||
},
|
||||
}, issues)
|
||||
|
||||
@@ -357,7 +358,7 @@ func gitlabClientMockTeardown(server *httptest.Server) {
|
||||
}
|
||||
|
||||
type reviewTestCase struct {
|
||||
repoID, prID, reviewerID int
|
||||
repoID, prID, reviewerID int64
|
||||
reviewerName string
|
||||
createdAt, updatedAt *time.Time
|
||||
expectedCreatedAt time.Time
|
||||
@@ -382,8 +383,8 @@ func convertTestCase(t reviewTestCase) (func(w http.ResponseWriter, r *http.Requ
|
||||
fmt.Fprint(w, `
|
||||
{
|
||||
"id": 5,
|
||||
"iid": `+strconv.Itoa(t.prID)+`,
|
||||
"project_id": `+strconv.Itoa(t.repoID)+`,
|
||||
"iid": `+strconv.FormatInt(t.prID, 10)+`,
|
||||
"project_id": `+strconv.FormatInt(t.repoID, 10)+`,
|
||||
"title": "Approvals API",
|
||||
"description": "Test",
|
||||
"state": "opened",
|
||||
@@ -397,7 +398,7 @@ func convertTestCase(t reviewTestCase) (func(w http.ResponseWriter, r *http.Requ
|
||||
"user": {
|
||||
"name": "Administrator",
|
||||
"username": "`+t.reviewerName+`",
|
||||
"id": `+strconv.Itoa(t.reviewerID)+`,
|
||||
"id": `+strconv.FormatInt(t.reviewerID, 10)+`,
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon",
|
||||
"web_url": "http://localhost:3000/root"
|
||||
@@ -407,8 +408,8 @@ func convertTestCase(t reviewTestCase) (func(w http.ResponseWriter, r *http.Requ
|
||||
}`)
|
||||
}
|
||||
review := base.Review{
|
||||
IssueIndex: int64(t.prID),
|
||||
ReviewerID: int64(t.reviewerID),
|
||||
IssueIndex: t.prID,
|
||||
ReviewerID: t.reviewerID,
|
||||
ReviewerName: t.reviewerName,
|
||||
CreatedAt: t.expectedCreatedAt,
|
||||
State: "APPROVED",
|
||||
@@ -421,7 +422,7 @@ func TestGitlabGetReviews(t *testing.T) {
|
||||
mux, server, client := gitlabClientMockSetup(t)
|
||||
defer gitlabClientMockTeardown(server)
|
||||
|
||||
repoID := 1324
|
||||
var repoID int64 = 1324
|
||||
ctx := t.Context()
|
||||
downloader := &GitlabDownloader{
|
||||
client: client,
|
||||
@@ -462,8 +463,7 @@ func TestGitlabGetReviews(t *testing.T) {
|
||||
mock, review := convertTestCase(testCase)
|
||||
mux.HandleFunc(fmt.Sprintf("/api/v4/projects/%d/merge_requests/%d/approvals", testCase.repoID, testCase.prID), mock)
|
||||
|
||||
id := int64(testCase.prID)
|
||||
rvs, err := downloader.GetReviews(ctx, &base.Issue{Number: id, ForeignIndex: id})
|
||||
rvs, err := downloader.GetReviews(ctx, &base.Issue{Number: testCase.prID, ForeignIndex: testCase.prID})
|
||||
assert.NoError(t, err)
|
||||
assertReviewsEqual(t, []*base.Review{&review}, rvs)
|
||||
}
|
||||
@@ -519,18 +519,10 @@ func TestNoteToComment(t *testing.T) {
|
||||
downloader := &GitlabDownloader{}
|
||||
|
||||
now := time.Now()
|
||||
makeTestNote := func(id int, body string, system bool) gitlab.Note {
|
||||
makeTestNote := func(id int64, body string, system bool) gitlab.Note {
|
||||
return gitlab.Note{
|
||||
ID: id,
|
||||
Author: struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
}{
|
||||
Author: gitlab.NoteAuthor{
|
||||
ID: 72,
|
||||
Email: "test@example.com",
|
||||
Username: "test",
|
||||
|
||||
@@ -27,6 +27,7 @@ func TestGogsDownloadRepo(t *testing.T) {
|
||||
t.Skipf("visit test repo failed, ignored")
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ctx := t.Context()
|
||||
downloader := NewGogsDownloader(ctx, "https://try.gogs.io", "", "", gogsPersonalAccessToken, "lunnytest", "TESTREPO")
|
||||
repo, err := downloader.GetRepoInfo(ctx)
|
||||
|
||||
@@ -18,10 +18,6 @@ func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m)
|
||||
}
|
||||
|
||||
func timePtr(t time.Time) *time.Time {
|
||||
return &t
|
||||
}
|
||||
|
||||
func assertTimeEqual(t *testing.T, expected, actual time.Time) {
|
||||
assert.Equal(t, expected.UTC(), actual.UTC())
|
||||
}
|
||||
@@ -222,7 +218,7 @@ func assertRepositoryEqual(t *testing.T, expected, actual *base.Repository) {
|
||||
|
||||
func assertReviewEqual(t *testing.T, expected, actual *base.Review) {
|
||||
assert.Equal(t, expected.ID, actual.ID, "ID")
|
||||
assert.Equal(t, expected.IssueIndex, actual.IssueIndex, "IsssueIndex")
|
||||
assert.Equal(t, expected.IssueIndex, actual.IssueIndex, "IssueIndex")
|
||||
assert.Equal(t, expected.ReviewerID, actual.ReviewerID, "ReviewerID")
|
||||
assert.Equal(t, expected.ReviewerName, actual.ReviewerName, "ReviewerName")
|
||||
assert.Equal(t, expected.Official, actual.Official, "Official")
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/hostmatcher"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@@ -130,8 +131,8 @@ func MigrateRepository(ctx context.Context, doer *user_model.User, ownerName str
|
||||
if err1 := uploader.Rollback(); err1 != nil {
|
||||
log.Error("rollback failed: %v", err1)
|
||||
}
|
||||
if err2 := system_model.CreateRepositoryNotice(fmt.Sprintf("Migrate repository from %s failed: %v", opts.OriginalURL, err)); err2 != nil {
|
||||
log.Error("create respotiry notice failed: ", err2)
|
||||
if err2 := system_model.CreateRepositoryNotice(fmt.Sprintf("Migrate repository (%s/%s) from %s failed: %v", ownerName, opts.RepoName, opts.OriginalURL, err)); err2 != nil {
|
||||
log.Error("create repository notice failed: ", err2)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
@@ -217,7 +218,7 @@ func migrateRepository(ctx context.Context, doer *user_model.User, downloader ba
|
||||
// We don't actually need to check the OriginalURL as it isn't used anywhere
|
||||
}
|
||||
|
||||
log.Trace("migrating git data from %s", repo.CloneURL)
|
||||
log.Trace("migrating git data from %s", util.SanitizeCredentialURLs(repo.CloneURL))
|
||||
messenger("repo.migrate.migrating_git")
|
||||
if err = uploader.CreateRepo(ctx, repo, opts); err != nil {
|
||||
return err
|
||||
@@ -327,6 +328,9 @@ func migrateRepository(ctx context.Context, doer *user_model.User, downloader ba
|
||||
messenger("repo.migrate.migrating_issues")
|
||||
issueBatchSize := uploader.MaxBatchInsertSize("issue")
|
||||
|
||||
// because when the migrating is running, some issues maybe removed, so after the next page
|
||||
// some of issue maybe duplicated, so we need to record the inserted issue indexes
|
||||
mapInsertedIssueIndexes := container.Set[int64]{}
|
||||
for i := 1; ; i++ {
|
||||
issues, isEnd, err := downloader.GetIssues(ctx, i, issueBatchSize)
|
||||
if err != nil {
|
||||
@@ -336,6 +340,14 @@ func migrateRepository(ctx context.Context, doer *user_model.User, downloader ba
|
||||
log.Warn("migrating issues is not supported, ignored")
|
||||
break
|
||||
}
|
||||
for i := 0; i < len(issues); i++ {
|
||||
if mapInsertedIssueIndexes.Contains(issues[i].Number) {
|
||||
issues = append(issues[:i], issues[i+1:]...)
|
||||
i--
|
||||
continue
|
||||
}
|
||||
mapInsertedIssueIndexes.Add(issues[i].Number)
|
||||
}
|
||||
|
||||
if err := uploader.CreateIssues(ctx, issues...); err != nil {
|
||||
return err
|
||||
@@ -381,6 +393,7 @@ func migrateRepository(ctx context.Context, doer *user_model.User, downloader ba
|
||||
log.Trace("migrating pull requests and comments")
|
||||
messenger("repo.migrate.migrating_pulls")
|
||||
prBatchSize := uploader.MaxBatchInsertSize("pullrequest")
|
||||
mapInsertedPRIndexes := container.Set[int64]{}
|
||||
for i := 1; ; i++ {
|
||||
prs, isEnd, err := downloader.GetPullRequests(ctx, i, prBatchSize)
|
||||
if err != nil {
|
||||
@@ -390,6 +403,14 @@ func migrateRepository(ctx context.Context, doer *user_model.User, downloader ba
|
||||
log.Warn("migrating pull requests is not supported, ignored")
|
||||
break
|
||||
}
|
||||
for i := 0; i < len(prs); i++ {
|
||||
if mapInsertedPRIndexes.Contains(prs[i].Number) {
|
||||
prs = append(prs[:i], prs[i+1:]...)
|
||||
i--
|
||||
continue
|
||||
}
|
||||
mapInsertedPRIndexes.Add(prs[i].Number)
|
||||
}
|
||||
|
||||
if err := uploader.CreatePullRequests(ctx, prs...); err != nil {
|
||||
return err
|
||||
@@ -457,6 +478,15 @@ func migrateRepository(ctx context.Context, doer *user_model.User, downloader ba
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(mapInsertedPRIndexes) > 0 {
|
||||
// The pull requests migrating process may created head branches in the base repository
|
||||
// because head repository maybe a fork one which will not be migrated. So that we need
|
||||
// to sync branches again.
|
||||
log.Trace("syncing branches after migrating pull requests")
|
||||
if err = uploader.SyncBranches(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if opts.Comments && supportAllComments {
|
||||
|
||||
@@ -77,19 +77,19 @@ type OneDevDownloader struct {
|
||||
}
|
||||
|
||||
// NewOneDevDownloader creates a new downloader
|
||||
func NewOneDevDownloader(_ context.Context, baseURL *url.URL, username, password, repoPath string) *OneDevDownloader {
|
||||
func NewOneDevDownloader(ctx context.Context, baseURL *url.URL, username, password, repoPath string) *OneDevDownloader {
|
||||
httpTransport := NewMigrationHTTPTransport()
|
||||
downloader := &OneDevDownloader{
|
||||
baseURL: baseURL,
|
||||
repoPath: repoPath,
|
||||
client: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: func(req *http.Request) (*url.URL, error) {
|
||||
if len(username) > 0 && len(password) > 0 {
|
||||
Transport: roundTripperFunc(
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
if username != "" && password != "" {
|
||||
req.SetBasicAuth(username, password)
|
||||
}
|
||||
return nil, nil
|
||||
},
|
||||
},
|
||||
return httpTransport.RoundTrip(req.WithContext(ctx))
|
||||
}),
|
||||
},
|
||||
userMap: make(map[int64]*onedevUser),
|
||||
milestoneMap: make(map[int64]string),
|
||||
|
||||
@@ -19,13 +19,11 @@ func TestOneDevDownloadRepo(t *testing.T) {
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
t.Skipf("Can't access test repo, skipping %s", t.Name())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
u, _ := url.Parse("https://code.onedev.io")
|
||||
ctx := t.Context()
|
||||
downloader := NewOneDevDownloader(ctx, u, "", "", "go-gitea-test_repo")
|
||||
if err != nil {
|
||||
t.Fatalf("NewOneDevDownloader is nil: %v", err)
|
||||
}
|
||||
repo, err := downloader.GetRepoInfo(ctx)
|
||||
assert.NoError(t, err)
|
||||
assertRepositoryEqual(t, &base.Repository{
|
||||
|
||||
Reference in New Issue
Block a user