Skip to content

Migrate Gogs pulls as issue #14394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 63 additions & 21 deletions modules/migrations/gogs.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (f *GogsDownloaderFactory) New(ctx context.Context, opts base.MigrateOption
}

log.Trace("Create gogs downloader. BaseURL: %s RepoOwner: %s RepoName: %s", baseURL, fields[0], fields[1])
return NewGogsDownloader(ctx, baseURL, opts.AuthUsername, opts.AuthPassword, opts.AuthToken, fields[0], fields[1]), nil
return NewGogsDownloader(ctx, baseURL, opts.AuthUsername, opts.AuthPassword, opts.AuthToken, fields[0], fields[1], opts.PullRequests), nil
}

// GitServiceType returns the type of git service
Expand All @@ -61,16 +61,19 @@ func (f *GogsDownloaderFactory) GitServiceType() structs.GitServiceType {
// from gogs via API
type GogsDownloader struct {
base.NullDownloader
ctx context.Context
client *gogs.Client
baseURL string
repoOwner string
repoName string
userName string
password string
openIssuesFinished bool
openIssuesPages int
transport http.RoundTripper
ctx context.Context
client *gogs.Client
baseURL string
repoOwner string
repoName string
userName string
password string
// gog specific workarounds
issueDownloadMode int
skipPages int
issueIndexes map[int64]bool
pullsAsIssue bool
transport http.RoundTripper
}

// SetContext set context
Expand All @@ -79,14 +82,17 @@ func (g *GogsDownloader) SetContext(ctx context.Context) {
}

// NewGogsDownloader creates a gogs Downloader via gogs API
func NewGogsDownloader(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GogsDownloader {
func NewGogsDownloader(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string, pullsAsIssue bool) *GogsDownloader {
var downloader = GogsDownloader{
ctx: ctx,
baseURL: baseURL,
userName: userName,
password: password,
repoOwner: repoOwner,
repoName: repoName,
// gog specific workarounds
issueIndexes: make(map[int64]bool),
pullsAsIssue: pullsAsIssue,
}

var client *gogs.Client
Expand Down Expand Up @@ -182,12 +188,17 @@ func (g *GogsDownloader) GetLabels() ([]*base.Label, error) {
// GetIssues returns issues according start and limit, perPage is not supported
func (g *GogsDownloader) GetIssues(page, _ int) ([]*base.Issue, bool, error) {
var state string
if g.openIssuesFinished {
state = string(gogs.STATE_CLOSED)
page -= g.openIssuesPages
} else {
switch g.issueDownloadMode {
case 0: // download open issues
state = string(gogs.STATE_OPEN)
g.openIssuesPages = page
case 1: // download close issues
state = string(gogs.STATE_CLOSED)
page -= g.skipPages
default: // download pulls as issues
if !g.pullsAsIssue {
return nil, true, nil
}
return g.getPullRequests(page - g.skipPages)
}

issues, isEnd, err := g.getIssues(page, state)
Expand All @@ -196,10 +207,8 @@ func (g *GogsDownloader) GetIssues(page, _ int) ([]*base.Issue, bool, error) {
}

if isEnd {
if g.openIssuesFinished {
return issues, true, nil
}
g.openIssuesFinished = true
g.issueDownloadMode++
g.skipPages = page
}

return issues, false, nil
Expand All @@ -220,12 +229,45 @@ func (g *GogsDownloader) getIssues(page int, state string) ([]*base.Issue, bool,
if issue.PullRequest != nil {
continue
}
g.issueIndexes[issue.Index] = true
allIssues = append(allIssues, convertGogsIssue(issue))
}

return allIssues, len(issues) == 0, nil
}

// getPullRequests returns pull requests as issue
func (g *GogsDownloader) getPullRequests(page int) ([]*base.Issue, bool, error) {
index := int64(page)
if g.issueIndexes[index] {
// next index
return nil, false, nil
}

gogsIssue, err := g.client.GetIssue(g.repoOwner, g.repoName, index)
if err != nil {
if err.Error() == "404 Not Found" {
return nil, true, nil
}
return nil, false, err
}

issue := convertGogsIssue(gogsIssue)

issue.Title = "[Pull] " + issue.Title
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can actually just create PRs with missing heads or even just make fake ones ourselves

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have no base and no head

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☝️ with this all you get is a broken pull

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cat7373 you as one who potentially use this migrator ... what are your thoughts about it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zeripath tested to create pull with only issue information: get failed: Unsupported scheme:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I forgot we don't have a base. We have a head it's simply refs/pulls/xxx/head - the base is the issue.

if gogsIssue.PullRequest != nil && gogsIssue.PullRequest.HasMerged {
issue.State = "closed"
issue.Title += " (Merged)"
}

return []*base.Issue{issue}, false, nil
}

// GetPullRequests is a dummy since pulls are migrated as issue
func (g *GogsDownloader) GetPullRequests(_, _ int) ([]*base.PullRequest, bool, error) {
return nil, true, nil
}

// GetComments returns comments according issueNumber
func (g *GogsDownloader) GetComments(issueNumber int64) ([]*base.Comment, error) {
var allComments = make([]*base.Comment, 0, 100)
Expand Down
2 changes: 1 addition & 1 deletion modules/migrations/gogs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestGogsDownloadRepo(t *testing.T) {
return
}

downloader := NewGogsDownloader(context.Background(), "https://try.gogs.io", "", "", gogsPersonalAccessToken, "lunnytest", "TESTREPO")
downloader := NewGogsDownloader(context.Background(), "https://try.gogs.io", "", "", gogsPersonalAccessToken, "lunnytest", "TESTREPO", false)
repo, err := downloader.GetRepoInfo()
assert.NoError(t, err)

Expand Down
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ migrate_items_milestones = Milestones
migrate_items_labels = Labels
migrate_items_issues = Issues
migrate_items_pullrequests = Pull Requests
migrate_items_pullrequests_as_issues = Pull Requests (As Issues)
migrate_items_merge_requests = Merge Requests
migrate_items_releases = Releases
migrate_repo = Migrate Repository
Expand Down
6 changes: 3 additions & 3 deletions templates/repo/migrate/gogs.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,19 @@
<label>{{.i18n.Tr "repo.migrate_items_issues" | Safe}}</label>
</div>
</div>
<!-- Gogs do not support it
<div class="inline field">
<label></label>
<div class="ui checkbox">
<input name="pull_requests" type="checkbox" {{if .pull_requests}} checked{{end}}>
<label>{{.i18n.Tr "repo.migrate_items_merge_requests" | Safe}}</label>
<label>{{.i18n.Tr "repo.migrate_items_pullrequests_as_issues" | Safe}}</label>
</div>
<!-- Gogs do not support it
<div class="ui checkbox">
<input name="releases" type="checkbox" {{if .releases}} checked{{end}}>
<label>{{.i18n.Tr "repo.migrate_items_releases" | Safe}}</label>
</div>
-->
</div>
-->
</div>

<div class="ui divider"></div>
Expand Down