Skip to content

Commit a7c712b

Browse files
fix: gh-app merge (#5600)
Signed-off-by: francois poinsot <[email protected]>
1 parent 710fb06 commit a7c712b

File tree

2 files changed

+58
-5
lines changed

2 files changed

+58
-5
lines changed

server/events/github_app_working_dir.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,16 @@ type GithubAppWorkingDir struct {
2121

2222
// Clone writes a fresh token for Github App authentication
2323
func (g *GithubAppWorkingDir) Clone(logger logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, error) {
24-
baseRepo := &p.BaseRepo
24+
g.fixReposURL(&p, &headRepo)
25+
return g.WorkingDir.Clone(logger, headRepo, p, workspace)
26+
}
2527

28+
func (g *GithubAppWorkingDir) MergeAgain(logger logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (bool, error) {
29+
g.fixReposURL(&p, &headRepo)
30+
return g.WorkingDir.MergeAgain(logger, headRepo, p, workspace)
31+
}
32+
33+
func (g *GithubAppWorkingDir) fixReposURL(p *models.PullRequest, headRepo *models.Repo) {
2634
// Realistically, this is a super brittle way of supporting clones using gh app installation tokens
2735
// This URL should be built during Repo creation and the struct should be immutable going forward.
2836
// Doing this requires a larger refactor however, and can probably be coupled with supporting > 1 installation
@@ -31,10 +39,9 @@ func (g *GithubAppWorkingDir) Clone(logger logging.SimpleLogging, headRepo model
3139
// git will then pick up credentials from the credential store which is set in vcs.WriteGitCreds.
3240
// Git credentials will then be rotated by vcs.GitCredsTokenRotator
3341
replacement := "://"
34-
baseRepo.CloneURL = strings.Replace(baseRepo.CloneURL, "://:@", replacement, 1)
35-
baseRepo.SanitizedCloneURL = strings.Replace(baseRepo.SanitizedCloneURL, redactedReplacement, replacement, 1)
42+
p.BaseRepo.CloneURL = strings.Replace(p.BaseRepo.CloneURL, "://:@", replacement, 1)
43+
p.BaseRepo.SanitizedCloneURL = strings.Replace(p.BaseRepo.SanitizedCloneURL, redactedReplacement, replacement, 1)
3644
headRepo.CloneURL = strings.Replace(headRepo.CloneURL, "://:@", replacement, 1)
37-
headRepo.SanitizedCloneURL = strings.Replace(baseRepo.SanitizedCloneURL, redactedReplacement, replacement, 1)
45+
headRepo.SanitizedCloneURL = strings.Replace(p.BaseRepo.SanitizedCloneURL, redactedReplacement, replacement, 1)
3846

39-
return g.WorkingDir.Clone(logger, headRepo, p, workspace)
4047
}

server/events/github_app_working_dir_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,49 @@ func TestClone_GithubAppSetsCorrectUrl(t *testing.T) {
9898

9999
Ok(t, err)
100100
}
101+
102+
// Similar to `Clone()`
103+
// `MergeAgain()` should set the repo URL correctly
104+
func TestMergeAgain_GithubAppSetsCorrectUrl(t *testing.T) {
105+
logger := logging.NewNoopLogger(t)
106+
107+
RegisterMockTestingT(t)
108+
109+
workingDir := eventMocks.NewMockWorkingDir()
110+
111+
credentials := vcsMocks.NewMockGithubCredentials()
112+
113+
ghAppWorkingDir := events.GithubAppWorkingDir{
114+
WorkingDir: workingDir,
115+
Credentials: credentials,
116+
GithubHostname: "some-host",
117+
}
118+
119+
baseRepo, _ := models.NewRepo(
120+
models.Github,
121+
"runatlantis/atlantis",
122+
"https://github.com/runatlantis/atlantis.git",
123+
124+
// user and token have to be blank otherwise this proxy wouldn't be invoked to begin with
125+
"",
126+
"",
127+
)
128+
129+
headRepo := baseRepo
130+
131+
modifiedBaseRepo := baseRepo
132+
// remove credentials from both urls since we want to use the credential store
133+
modifiedBaseRepo.CloneURL = "https://github.com/runatlantis/atlantis.git"
134+
modifiedBaseRepo.SanitizedCloneURL = "https://github.com/runatlantis/atlantis.git"
135+
136+
When(credentials.GetToken()).ThenReturn("token", nil)
137+
When(workingDir.MergeAgain(Any[logging.SimpleLogging](), Eq(modifiedBaseRepo), Eq(models.PullRequest{BaseRepo: modifiedBaseRepo}),
138+
Eq("default"))).ThenReturn(false, nil)
139+
140+
_, err := ghAppWorkingDir.MergeAgain(logger, headRepo, models.PullRequest{BaseRepo: baseRepo}, "default")
141+
142+
// MergeAgain
143+
workingDir.VerifyWasCalledOnce().MergeAgain(logger, modifiedBaseRepo, models.PullRequest{BaseRepo: modifiedBaseRepo}, "default")
144+
145+
Ok(t, err)
146+
}

0 commit comments

Comments
 (0)