forked from fluxcd/image-automation-controller
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes regression in which we fail to push to a branch after switching to a branch, if origin is ahead of local. Fixed by setting the upstream commit as the local branch target. Regression introduced in fluxcd#330, and partially addressed in fluxcd#369. Signed-off-by: Sanskar Jaiswal <[email protected]>
- Loading branch information
Sanskar Jaiswal
committed
Jun 2, 2022
1 parent
e862a1b
commit 8d6ecfb
Showing
3 changed files
with
117 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,9 @@ import ( | |
|
||
"github.com/go-logr/logr" | ||
libgit2 "github.com/libgit2/git2go/v33" | ||
"k8s.io/apimachinery/pkg/types" | ||
|
||
. "github.com/onsi/gomega" | ||
|
||
"github.com/fluxcd/pkg/gittestserver" | ||
"github.com/fluxcd/source-controller/pkg/git/libgit2/managed" | ||
|
@@ -165,3 +168,88 @@ func TestPushRejected(t *testing.T) { | |
t.Error("push to a forbidden branch is expected to fail, but succeeded") | ||
} | ||
} | ||
|
||
func Test_switchToBranch(t *testing.T) { | ||
g := NewWithT(t) | ||
gitServer, err := gittestserver.NewTempGitServer() | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
gitServer.AutoCreate() | ||
|
||
g.Expect(gitServer.StartHTTP()).To(Succeed()) | ||
g.Expect(initGitRepo(gitServer, "testdata/appconfig", "master", "/appconfig.git")).To(Succeed()) | ||
|
||
repoURL := gitServer.HTTPAddressWithCredentials() + "/appconfig.git" | ||
repo, err := clone(repoURL, "master") | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
defer repo.Free() | ||
|
||
head, err := repo.Head() | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
defer head.Free() | ||
target := head.Target() | ||
|
||
// register transport options and update remote to transport url | ||
transportOptsURL := "http://" + randStringRunes(5) | ||
managed.AddTransportOptions(transportOptsURL, managed.TransportOptions{ | ||
TargetURL: repoURL, | ||
}) | ||
defer managed.RemoveTransportOptions(transportOptsURL) | ||
repo.Remotes.SetUrl("origin", transportOptsURL) | ||
|
||
// calling switchToBranch with a branch that doesn't exist on origin | ||
// should result in the branch being created and switched to. | ||
switchToBranch(repo, context.TODO(), "not-on-origin", repoAccess{}) | ||
|
||
head, err = repo.Head() | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
name, err := head.Branch().Name() | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
g.Expect(name).To(Equal("not-on-origin")) | ||
|
||
cc, err := repo.LookupCommit(head.Target()) | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
defer cc.Free() | ||
g.Expect(cc.Id().String()).To(Equal(target.String())) | ||
|
||
// create a branch with the HEAD commit and push it to origin | ||
_, err = repo.CreateBranch("test", cc, false) | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
origin, err := repo.Remotes.Lookup("origin") | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
defer origin.Free() | ||
|
||
g.Expect(origin.Push([]string{"refs/heads/test:refs/heads/test"}, &libgit2.PushOptions{})).To(Succeed()) | ||
|
||
// push a new commit to the test branch. this is done to test whether we properly | ||
// sync our local branch with the remote branch, before switching. | ||
policyKey := types.NamespacedName{ | ||
Name: "policy", | ||
Namespace: "ns", | ||
} | ||
commitID := commitInRepo(g, repoURL, "test", "Install setter marker", func(tmp string) { | ||
g.Expect(replaceMarker(tmp, policyKey)).To(Succeed()) | ||
}) | ||
|
||
// calling switchToBranch with a branch that exists should make sure to fetch latest | ||
// for that branch from origin, and then switch to it. | ||
switchToBranch(repo, context.TODO(), "test", repoAccess{}) | ||
head, err = repo.Head() | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
name, err = head.Branch().Name() | ||
|
||
g.Expect(err).ToNot(HaveOccurred()) | ||
g.Expect(name).To(Equal("test")) | ||
g.Expect(head.Target().String()).To(Equal(commitID.String())) | ||
|
||
// push a commit after switching to the test branch, to check if the local | ||
// branch is synced with origin. | ||
replaceMarker(repo.Workdir(), policyKey) | ||
sig := &libgit2.Signature{ | ||
Name: "Testbot", | ||
Email: "[email protected]", | ||
When: time.Now(), | ||
} | ||
_, err = commitWorkDir(repo, "test", "update policy", sig) | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
g.Expect(push(context.TODO(), repo.Workdir(), "test", repoAccess{})).To(Succeed()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -904,7 +904,7 @@ func configureManagedTransportOptions(repo *libgit2.Repository, repoURL string) | |
}, nil | ||
} | ||
|
||
func commitInRepo(g *WithT, repoURL, branch, msg string, changeFiles func(path string)) { | ||
func commitInRepo(g *WithT, repoURL, branch, msg string, changeFiles func(path string)) *libgit2.Oid { | ||
repo, err := clone(repoURL, branch) | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
defer repo.Free() | ||
|
@@ -916,21 +916,18 @@ func commitInRepo(g *WithT, repoURL, branch, msg string, changeFiles func(path s | |
Email: "[email protected]", | ||
When: time.Now(), | ||
} | ||
_, err = commitWorkDir(repo, branch, msg, sig) | ||
id, err := commitWorkDir(repo, branch, msg, sig) | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
|
||
cleanup, err := configureManagedTransportOptions(repo, repoURL) | ||
if err != nil { | ||
panic(err) | ||
} | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
defer cleanup() | ||
origin, err := repo.Remotes.Lookup(originRemote) | ||
if err != nil { | ||
panic(fmt.Errorf("cannot find origin: %v", err)) | ||
} | ||
g.Expect(err).ToNot(HaveOccurred()) | ||
defer origin.Free() | ||
|
||
g.Expect(origin.Push([]string{branchRefName(branch)}, &libgit2.PushOptions{})).To(Succeed()) | ||
return id | ||
} | ||
|
||
// Initialise a git server with a repo including the files in dir. | ||
|