Skip to content

Commit 0c6a5a8

Browse files
authored
Merge pull request #15 from manicminer/bugfix/pr-cleanup-and-error-handling
PR cleanup and error handling
2 parents 58586b6 + 0a77a76 commit 0c6a5a8

File tree

1 file changed

+66
-72
lines changed

1 file changed

+66
-72
lines changed

project.go

Lines changed: 66 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ func newProject(slugs []string) (*project, error) {
5353
return nil, fmt.Errorf("no matching GitLab project found: %s", slugs[0])
5454
}
5555

56+
p.defaultBranch = "main"
57+
if renameTrunkBranch != "" {
58+
p.defaultBranch = renameTrunkBranch
59+
} else if !renameMasterToMain && p.project.DefaultBranch != "" {
60+
p.defaultBranch = p.project.DefaultBranch
61+
}
62+
5663
return p, nil
5764
}
5865

@@ -64,6 +71,29 @@ type project struct {
6471
githubPath []string
6572
}
6673

74+
func (p *project) createRepo(ctx context.Context, homepage string, repoDeleted bool) error {
75+
if repoDeleted {
76+
logger.Warn("recreating GitHub repository", "owner", p.githubPath[0], "repo", p.githubPath[1])
77+
} else {
78+
logger.Debug("repository not found on GitHub, proceeding to create", "owner", p.githubPath[0], "repo", p.githubPath[1])
79+
}
80+
newRepo := github.Repository{
81+
Name: pointer(p.githubPath[1]),
82+
Description: &p.project.Description,
83+
Homepage: &homepage,
84+
DefaultBranch: &p.defaultBranch,
85+
Private: pointer(true),
86+
HasIssues: pointer(true),
87+
HasProjects: pointer(true),
88+
HasWiki: pointer(true),
89+
}
90+
if _, _, err := gh.Repositories.Create(ctx, p.githubPath[0], &newRepo); err != nil {
91+
return fmt.Errorf("creating github repo: %v", err)
92+
}
93+
94+
return nil
95+
}
96+
6797
func (p *project) migrate(ctx context.Context) error {
6898
cloneUrl, err := url.Parse(p.project.HTTPURLToRepo)
6999
if err != nil {
@@ -72,18 +102,6 @@ func (p *project) migrate(ctx context.Context) error {
72102

73103
logger.Info("mirroring repository from GitLab to GitHub", "name", p.gitlabPath[1], "group", p.gitlabPath[0], "github_org", p.githubPath[0], "github_repo", p.githubPath[1])
74104

75-
user, err := getGithubUser(ctx, p.githubPath[0])
76-
if err != nil {
77-
return fmt.Errorf("retrieving github user: %v", err)
78-
}
79-
80-
var org string
81-
if strings.EqualFold(*user.Type, "organization") {
82-
org = p.githubPath[0]
83-
} else if !strings.EqualFold(*user.Type, "user") || !strings.EqualFold(*user.Login, p.githubPath[0]) {
84-
return fmt.Errorf("configured owner is neither an organization nor the current user: %s", p.githubPath[0])
85-
}
86-
87105
logger.Debug("checking for existing repository on GitHub", "owner", p.githubPath[0], "repo", p.githubPath[1])
88106
_, _, err = gh.Repositories.Get(ctx, p.githubPath[0], p.githubPath[1])
89107

@@ -92,46 +110,21 @@ func (p *project) migrate(ctx context.Context) error {
92110
return fmt.Errorf("retrieving github repo: %v", err)
93111
}
94112

95-
var createRepo, repoDeleted bool
113+
homepage := fmt.Sprintf("https://%s/%s/%s", gitlabDomain, p.gitlabPath[0], p.gitlabPath[1])
114+
96115
if err != nil {
97-
createRepo = true
116+
// Repository not found
117+
if err = p.createRepo(ctx, homepage, false); err != nil {
118+
return err
119+
}
98120
} else if deleteExistingRepos {
99121
logger.Warn("existing repository was found on GitHub, proceeding to delete", "owner", p.githubPath[0], "repo", p.githubPath[1])
100122
if _, err = gh.Repositories.Delete(ctx, p.githubPath[0], p.githubPath[1]); err != nil {
101123
return fmt.Errorf("deleting existing github repo: %v", err)
102124
}
103125

104-
createRepo = true
105-
repoDeleted = true
106-
}
107-
108-
defaultBranch := "main"
109-
if renameTrunkBranch != "" {
110-
defaultBranch = renameTrunkBranch
111-
} else if !renameMasterToMain && p.project.DefaultBranch != "" {
112-
defaultBranch = p.project.DefaultBranch
113-
}
114-
115-
homepage := fmt.Sprintf("https://%s/%s/%s", gitlabDomain, p.gitlabPath[0], p.gitlabPath[1])
116-
117-
if createRepo {
118-
if repoDeleted {
119-
logger.Warn("recreating GitHub repository", "owner", p.githubPath[0], "repo", p.githubPath[1])
120-
} else {
121-
logger.Debug("repository not found on GitHub, proceeding to create", "owner", p.githubPath[0], "repo", p.githubPath[1])
122-
}
123-
newRepo := github.Repository{
124-
Name: pointer(p.githubPath[1]),
125-
Description: &p.project.Description,
126-
Homepage: &homepage,
127-
DefaultBranch: &defaultBranch,
128-
Private: pointer(true),
129-
HasIssues: pointer(true),
130-
HasProjects: pointer(true),
131-
HasWiki: pointer(true),
132-
}
133-
if _, _, err = gh.Repositories.Create(ctx, org, &newRepo); err != nil {
134-
return fmt.Errorf("creating github repo: %v", err)
126+
if err = p.createRepo(ctx, homepage, true); err != nil {
127+
return err
135128
}
136129
}
137130

@@ -168,12 +161,12 @@ func (p *project) migrate(ctx context.Context) error {
168161
return fmt.Errorf("cloning gitlab repo: %v", err)
169162
}
170163

171-
if defaultBranch != p.project.DefaultBranch {
164+
if p.defaultBranch != p.project.DefaultBranch {
172165
if gitlabTrunk, err := p.repo.Reference(plumbing.NewBranchReferenceName(p.project.DefaultBranch), false); err == nil {
173-
logger.Info("renaming trunk branch prior to push", "name", p.gitlabPath[1], "group", p.gitlabPath[0], "gitlab_trunk", p.project.DefaultBranch, "github_trunk", defaultBranch, "sha", gitlabTrunk.Hash())
166+
logger.Info("renaming trunk branch prior to push", "name", p.gitlabPath[1], "group", p.gitlabPath[0], "gitlab_trunk", p.project.DefaultBranch, "github_trunk", p.defaultBranch, "sha", gitlabTrunk.Hash())
174167

175-
logger.Debug("creating new trunk branch", "name", p.gitlabPath[1], "group", p.gitlabPath[0], "github_trunk", defaultBranch, "sha", gitlabTrunk.Hash())
176-
githubTrunk := plumbing.NewHashReference(plumbing.NewBranchReferenceName(defaultBranch), gitlabTrunk.Hash())
168+
logger.Debug("creating new trunk branch", "name", p.gitlabPath[1], "group", p.gitlabPath[0], "github_trunk", p.defaultBranch, "sha", gitlabTrunk.Hash())
169+
githubTrunk := plumbing.NewHashReference(plumbing.NewBranchReferenceName(p.defaultBranch), gitlabTrunk.Hash())
177170
if err = p.repo.Storer.SetReference(githubTrunk); err != nil {
178171
return fmt.Errorf("creating trunk branch: %v", err)
179172
}
@@ -238,9 +231,9 @@ func (p *project) migrate(ctx context.Context) error {
238231
}
239232
}
240233

241-
logger.Debug("setting default repository branch", "owner", p.githubPath[0], "repo", p.githubPath[1], "branch_name", defaultBranch)
234+
logger.Debug("setting default repository branch", "owner", p.githubPath[0], "repo", p.githubPath[1], "branch_name", p.defaultBranch)
242235
updateRepo = github.Repository{
243-
DefaultBranch: &defaultBranch,
236+
DefaultBranch: &p.defaultBranch,
244237
}
245238
if _, _, err = gh.Repositories.Edit(ctx, p.githubPath[0], p.githubPath[1], &updateRepo); err != nil {
246239
return fmt.Errorf("setting default branch: %v", err)
@@ -292,7 +285,6 @@ func (p *project) migrateMergeRequests(ctx context.Context) {
292285
} else {
293286
successCount++
294287
}
295-
// call out to migrateMergeRequest and increment counters
296288
}
297289

298290
skippedCount := totalCount - successCount - failureCount
@@ -309,7 +301,6 @@ func (p *project) migrateMergeRequest(ctx context.Context, mergeRequest *gitlab.
309301
sourceBranchForClosedMergeRequest := fmt.Sprintf("migration-source-%d/%s", mergeRequest.IID, mergeRequest.SourceBranch)
310302
targetBranchForClosedMergeRequest := fmt.Sprintf("migration-target-%d/%s", mergeRequest.IID, mergeRequest.TargetBranch)
311303

312-
var cleanUpBranch bool
313304
var pullRequest *github.PullRequest
314305

315306
logger.Debug("searching for any existing pull request", "owner", p.githubPath[0], "repo", p.githubPath[1], "merge_request_id", mergeRequest.IID)
@@ -463,7 +454,24 @@ func (p *project) migrateMergeRequest(ctx context.Context, mergeRequest *gitlab.
463454
}
464455

465456
// We will clean up these temporary branches after configuring and closing the pull request
466-
cleanUpBranch = true
457+
defer func() {
458+
logger.Debug("deleting temporary branches for closed pull request", "owner", p.githubPath[0], "repo", p.githubPath[1], "pr_number", pullRequest.GetNumber(), "source_branch", mergeRequest.SourceBranch, "target_branch", mergeRequest.TargetBranch)
459+
if err := p.repo.PushContext(ctx, &git.PushOptions{
460+
RemoteName: "github",
461+
RefSpecs: []config.RefSpec{
462+
config.RefSpec(fmt.Sprintf(":refs/heads/%s", mergeRequest.SourceBranch)),
463+
config.RefSpec(fmt.Sprintf(":refs/heads/%s", mergeRequest.TargetBranch)),
464+
},
465+
Force: true,
466+
}); err != nil {
467+
if errors.Is(err, git.NoErrAlreadyUpToDate) {
468+
logger.Trace("branches already deleted on GitHub", "owner", p.githubPath[0], "repo", p.githubPath[1], "pr_number", pullRequest.GetNumber(), "source_branch", mergeRequest.SourceBranch, "target_branch", mergeRequest.TargetBranch)
469+
} else {
470+
sendErr(fmt.Errorf("pushing branch deletions to github: %v", err))
471+
}
472+
}
473+
474+
}()
467475
}
468476

469477
if p.defaultBranch != p.project.DefaultBranch && mergeRequest.TargetBranch == p.project.DefaultBranch {
@@ -563,6 +571,10 @@ func (p *project) migrateMergeRequest(ctx context.Context, mergeRequest *gitlab.
563571
Draft: &mergeRequest.Draft,
564572
}
565573
if pullRequest, _, err = gh.PullRequests.Create(ctx, p.githubPath[0], p.githubPath[1], &newPullRequest); err != nil {
574+
if mergeRequest.State == "closed" && strings.Contains(err.Error(), "No commits between") {
575+
logger.Debug("skipping closed merge request as the change is already present in trunk branch", "owner", p.githubPath[0], "repo", p.githubPath[1], "merge_request_id", mergeRequest.IID)
576+
return nil
577+
}
566578
return fmt.Errorf("creating pull request: %v", err)
567579
}
568580

@@ -613,24 +625,6 @@ func (p *project) migrateMergeRequest(ctx context.Context, mergeRequest *gitlab.
613625
}
614626
}
615627

616-
if cleanUpBranch {
617-
logger.Debug("deleting temporary branches for closed pull request", "owner", p.githubPath[0], "repo", p.githubPath[1], "pr_number", pullRequest.GetNumber(), "source_branch", mergeRequest.SourceBranch, "target_branch", mergeRequest.TargetBranch)
618-
if err = p.repo.PushContext(ctx, &git.PushOptions{
619-
RemoteName: "github",
620-
RefSpecs: []config.RefSpec{
621-
config.RefSpec(fmt.Sprintf(":refs/heads/%s", mergeRequest.SourceBranch)),
622-
config.RefSpec(fmt.Sprintf(":refs/heads/%s", mergeRequest.TargetBranch)),
623-
},
624-
Force: true,
625-
}); err != nil {
626-
if errors.Is(err, git.NoErrAlreadyUpToDate) {
627-
logger.Trace("branches already deleted on GitHub", "owner", p.githubPath[0], "repo", p.githubPath[1], "pr_number", pullRequest.GetNumber(), "source_branch", mergeRequest.SourceBranch, "target_branch", mergeRequest.TargetBranch)
628-
} else {
629-
return fmt.Errorf("pushing branch deletions to github: %v", err)
630-
}
631-
}
632-
}
633-
634628
var comments []*gitlab.Note
635629
opts := &gitlab.ListMergeRequestNotesOptions{
636630
OrderBy: pointer("created_at"),

0 commit comments

Comments
 (0)