Skip to content

Commit 24b77d3

Browse files
committed
controllers: GitRepository ref
1 parent b27c82d commit 24b77d3

File tree

2 files changed

+70
-175
lines changed

2 files changed

+70
-175
lines changed

controllers/gitrepository_controller_test.go

Lines changed: 61 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package controllers
1818

1919
import (
2020
"context"
21+
"fmt"
2122
"net/url"
2223
"os"
2324
"path"
@@ -49,7 +50,7 @@ var _ = Describe("GitRepositoryReconciler", func() {
4950
indexInterval = time.Second * 1
5051
)
5152

52-
Context("GitRepsoitory", func() {
53+
Context("GitRepository", func() {
5354
var (
5455
namespace *corev1.Namespace
5556
gitServer *testserver.GitServer
@@ -75,205 +76,68 @@ var _ = Describe("GitRepositoryReconciler", func() {
7576
Expect(err).NotTo(HaveOccurred(), "failed to delete test namespace")
7677
})
7778

78-
It("Creates artifacts for", func() {
79-
err = gitServer.StartHTTP()
80-
Expect(err).NotTo(HaveOccurred())
81-
82-
By("Creating a new git repository with a single commit")
83-
u, err := url.Parse(gitServer.HTTPAddress())
84-
Expect(err).NotTo(HaveOccurred())
85-
u.Path = path.Join(u.Path, "repository.git")
86-
87-
fs := memfs.New()
88-
r, err := git.Init(memory.NewStorage(), fs)
89-
Expect(err).NotTo(HaveOccurred())
90-
91-
_, err = r.CreateRemote(&config.RemoteConfig{
92-
Name: "origin",
93-
URLs: []string{u.String()},
94-
})
95-
Expect(err).NotTo(HaveOccurred())
96-
97-
ff, err := fs.Create("fixture")
98-
Expect(err).NotTo(HaveOccurred())
99-
_ = ff.Close()
100-
101-
wt, err := r.Worktree()
102-
Expect(err).NotTo(HaveOccurred())
103-
104-
_, err = wt.Add(fs.Join("fixture"))
105-
Expect(err).NotTo(HaveOccurred())
106-
107-
cHash, err := wt.Commit("Sample", &git.CommitOptions{Author: &object.Signature{
108-
Name: "John Doe",
109-
110-
When: time.Now(),
111-
}})
112-
Expect(err).NotTo(HaveOccurred())
113-
114-
err = r.Push(&git.PushOptions{})
115-
Expect(err).NotTo(HaveOccurred())
116-
117-
By("Creating a new resource for the repository")
118-
key := types.NamespacedName{
119-
Name: "gitrepository-sample-" + randStringRunes(5),
120-
Namespace: namespace.Name,
121-
}
122-
created := &sourcev1.GitRepository{
123-
ObjectMeta: metav1.ObjectMeta{
124-
Name: key.Name,
125-
Namespace: key.Namespace,
126-
},
127-
Spec: sourcev1.GitRepositorySpec{
128-
URL: u.String(),
129-
Interval: metav1.Duration{Duration: indexInterval},
130-
},
131-
}
132-
Expect(k8sClient.Create(context.Background(), created)).Should(Succeed())
133-
134-
By("Expecting artifact and revision")
135-
got := &sourcev1.GitRepository{}
136-
Eventually(func() bool {
137-
_ = k8sClient.Get(context.Background(), key, got)
138-
return got.Status.Artifact != nil && storage.ArtifactExist(*got.Status.Artifact)
139-
}, timeout, interval).Should(BeTrue())
140-
Expect(got.Status.Artifact.Revision).To(Equal("master/" + cHash.String()))
141-
142-
By("Pushing a change to the repository")
143-
ff, err = fs.Create("fixture2")
144-
Expect(err).NotTo(HaveOccurred())
145-
_ = ff.Close()
146-
147-
_, err = wt.Add(fs.Join("fixture2"))
148-
Expect(err).NotTo(HaveOccurred())
149-
150-
cHash, err = wt.Commit("Sample", &git.CommitOptions{Author: &object.Signature{
151-
Name: "John Doe",
152-
153-
When: time.Now(),
154-
}})
155-
Expect(err).NotTo(HaveOccurred())
156-
157-
err = r.Push(&git.PushOptions{})
158-
Expect(err).NotTo(HaveOccurred())
159-
160-
By("Expecting new artifact revision and GC")
161-
Eventually(func() bool {
162-
now := &sourcev1.GitRepository{}
163-
_ = k8sClient.Get(context.Background(), key, now)
164-
return now.Status.Artifact.Revision != got.Status.Artifact.Revision &&
165-
!storage.ArtifactExist(*got.Status.Artifact)
166-
}, timeout, interval).Should(BeTrue())
167-
168-
By("Expecting git clone error")
169-
updated := &sourcev1.GitRepository{}
170-
Expect(k8sClient.Get(context.Background(), key, updated)).Should(Succeed())
171-
updated.Spec.URL = "https://invalid.com"
172-
Expect(k8sClient.Update(context.Background(), updated)).Should(Succeed())
173-
Eventually(func() bool {
174-
_ = k8sClient.Get(context.Background(), key, updated)
175-
for _, c := range updated.Status.Conditions {
176-
if c.Reason == sourcev1.GitOperationFailedReason &&
177-
strings.Contains(c.Message, "git clone error") {
178-
return true
179-
}
180-
}
181-
return false
182-
}, timeout, interval).Should(BeTrue())
183-
Expect(updated.Status.Artifact).ToNot(BeNil())
184-
185-
By("Expecting to delete successfully")
186-
got = &sourcev1.GitRepository{}
187-
Eventually(func() error {
188-
_ = k8sClient.Get(context.Background(), key, got)
189-
return k8sClient.Delete(context.Background(), got)
190-
}, timeout, interval).Should(Succeed())
191-
192-
By("Expecting delete to finish")
193-
Eventually(func() error {
194-
return k8sClient.Get(context.Background(), key, &sourcev1.GitRepository{})
195-
}).ShouldNot(Succeed())
196-
197-
By("Expecting GC on delete")
198-
exists := func(path string) bool {
199-
// wait for tmp sync on macOS
200-
time.Sleep(time.Second)
201-
_, err := os.Stat(path)
202-
return err == nil
203-
}
204-
Eventually(exists(got.Status.Artifact.Path), timeout, interval).ShouldNot(BeTrue())
205-
})
206-
20779
type refTestCase struct {
208-
reference *sourcev1.GitRepositoryRef
209-
createBranches []string
210-
createTags []string
80+
reference *sourcev1.GitRepositoryRef
81+
createRefs []string
82+
83+
waitForReason string
21184

212-
waitForReason string
21385
expectStatus corev1.ConditionStatus
21486
expectMessage string
21587
expectRevision string
21688
}
21789

218-
DescribeTable("Reference test configuration", func(t refTestCase) {
90+
DescribeTable("Git references tests", func(t refTestCase) {
21991
err = gitServer.StartHTTP()
220-
defer os.RemoveAll(gitServer.Root())
22192
defer gitServer.StopHTTP()
22293
Expect(err).NotTo(HaveOccurred())
22394

22495
u, err := url.Parse(gitServer.HTTPAddress())
22596
Expect(err).NotTo(HaveOccurred())
226-
u.Path = path.Join(u.Path, "repository.git")
97+
u.Path = path.Join(u.Path, fmt.Sprintf("repository-%s.git", randStringRunes(5)))
22798

22899
fs := memfs.New()
229100
gitrepo, err := git.Init(memory.NewStorage(), fs)
230101
Expect(err).NotTo(HaveOccurred())
231102

232-
remote, err := gitrepo.CreateRemote(&config.RemoteConfig{
233-
Name: "origin",
234-
URLs: []string{u.String()},
235-
})
236-
Expect(err).NotTo(HaveOccurred())
237-
238-
ff, err := fs.Create("fixture")
239-
Expect(err).NotTo(HaveOccurred())
240-
_ = ff.Close()
241-
242103
wt, err := gitrepo.Worktree()
243104
Expect(err).NotTo(HaveOccurred())
244105

106+
ff, _ := fs.Create("fixture")
107+
_ = ff.Close()
245108
_, err = wt.Add(fs.Join("fixture"))
246109
Expect(err).NotTo(HaveOccurred())
247110

248-
cHash, err := wt.Commit("Sample", &git.CommitOptions{Author: &object.Signature{
111+
commit, err := wt.Commit("Sample", &git.CommitOptions{Author: &object.Signature{
249112
Name: "John Doe",
250113
251114
When: time.Now(),
252115
}})
253116
Expect(err).NotTo(HaveOccurred())
254-
err = remote.Push(&git.PushOptions{})
255-
Expect(err).NotTo(HaveOccurred())
256117

257-
for _, branch := range t.createBranches {
258-
ref := plumbing.NewHashReference(plumbing.ReferenceName("refs/heads/"+branch), cHash)
259-
err = gitrepo.Storer.SetReference(ref)
260-
Expect(err).NotTo(HaveOccurred())
261-
err = remote.Push(&git.PushOptions{})
262-
Expect(err).NotTo(HaveOccurred())
263-
}
118+
gitrepo.Worktree()
264119

265-
for _, tag := range t.createTags {
266-
ref := plumbing.NewHashReference(plumbing.ReferenceName("refs/tags/"+tag), cHash)
267-
err = gitrepo.Storer.SetReference(ref)
268-
Expect(err).NotTo(HaveOccurred())
269-
err = remote.Push(&git.PushOptions{
270-
RefSpecs: []config.RefSpec{"refs/tags/*:refs/tags/*"},
271-
})
120+
for _, ref := range t.createRefs {
121+
hRef := plumbing.NewHashReference(plumbing.ReferenceName(ref), commit)
122+
err = gitrepo.Storer.SetReference(hRef)
272123
Expect(err).NotTo(HaveOccurred())
273124
}
274125

126+
remote, err := gitrepo.CreateRemote(&config.RemoteConfig{
127+
Name: "origin",
128+
URLs: []string{u.String()},
129+
})
130+
Expect(err).NotTo(HaveOccurred())
131+
132+
err = remote.Push(&git.PushOptions{
133+
RefSpecs: []config.RefSpec{"refs/heads/*:refs/heads/*", "refs/tags/*:refs/tags/*"},
134+
})
135+
Expect(err).NotTo(HaveOccurred())
136+
137+
t.reference.Commit = strings.Replace(t.reference.Commit, "<commit>", commit.String(), 1)
138+
275139
key := types.NamespacedName{
276-
Name: "gitrepository-sample-" + randStringRunes(5),
140+
Name: fmt.Sprintf("git-ref-test-%s", randStringRunes(5)),
277141
Namespace: namespace.Name,
278142
}
279143
created := &sourcev1.GitRepository{
@@ -307,12 +171,12 @@ var _ = Describe("GitRepositoryReconciler", func() {
307171
Expect(cond.Message).To(ContainSubstring(t.expectMessage))
308172
Expect(got.Status.Artifact == nil).To(Equal(t.expectRevision == ""))
309173
if t.expectRevision != "" {
310-
Expect(got.Status.Artifact.Revision).To(Equal(t.expectRevision + "/" + cHash.String()))
174+
Expect(got.Status.Artifact.Revision).To(Equal(t.expectRevision + "/" + commit.String()))
311175
}
312176
},
313177
Entry("branch", refTestCase{
314178
reference: &sourcev1.GitRepositoryRef{Branch: "some-branch"},
315-
createBranches: []string{"some-branch"},
179+
createRefs: []string{"refs/heads/some-branch"},
316180
waitForReason: sourcev1.GitOperationSucceedReason,
317181
expectStatus: corev1.ConditionTrue,
318182
expectRevision: "some-branch",
@@ -325,7 +189,7 @@ var _ = Describe("GitRepositoryReconciler", func() {
325189
}),
326190
Entry("tag", refTestCase{
327191
reference: &sourcev1.GitRepositoryRef{Tag: "some-tag"},
328-
createTags: []string{"some-tag"},
192+
createRefs: []string{"refs/tags/some-tag"},
329193
waitForReason: sourcev1.GitOperationSucceedReason,
330194
expectStatus: corev1.ConditionTrue,
331195
expectRevision: "some-tag",
@@ -338,14 +202,14 @@ var _ = Describe("GitRepositoryReconciler", func() {
338202
}),
339203
Entry("semver", refTestCase{
340204
reference: &sourcev1.GitRepositoryRef{SemVer: "1.0.0"},
341-
createTags: []string{"v1.0.0"},
205+
createRefs: []string{"refs/tags/v1.0.0"},
342206
waitForReason: sourcev1.GitOperationSucceedReason,
343207
expectStatus: corev1.ConditionTrue,
344208
expectRevision: "v1.0.0",
345209
}),
346210
Entry("semver range", refTestCase{
347211
reference: &sourcev1.GitRepositoryRef{SemVer: ">=0.1.0 <1.0.0"},
348-
createTags: []string{"0.1.0", "0.1.1", "0.2.0", "1.0.0"},
212+
createRefs: []string{"refs/tags/0.1.0", "refs/tags/0.1.1", "refs/tags/0.2.0", "refs/tags/1.0.0"},
349213
waitForReason: sourcev1.GitOperationSucceedReason,
350214
expectStatus: corev1.ConditionTrue,
351215
expectRevision: "0.2.0",
@@ -362,6 +226,33 @@ var _ = Describe("GitRepositoryReconciler", func() {
362226
expectStatus: corev1.ConditionFalse,
363227
expectMessage: "no match found for semver: 1.0.0",
364228
}),
229+
Entry("commit", refTestCase{
230+
reference: &sourcev1.GitRepositoryRef{
231+
Commit: "<commit>",
232+
},
233+
waitForReason: sourcev1.GitOperationSucceedReason,
234+
expectStatus: corev1.ConditionTrue,
235+
expectRevision: "master",
236+
}),
237+
Entry("commit in branch", refTestCase{
238+
reference: &sourcev1.GitRepositoryRef{
239+
Branch: "some-branch",
240+
Commit: "<commit>",
241+
},
242+
createRefs: []string{"refs/heads/some-branch"},
243+
waitForReason: sourcev1.GitOperationSucceedReason,
244+
expectStatus: corev1.ConditionTrue,
245+
expectRevision: "some-branch",
246+
}),
247+
Entry("invalid commit", refTestCase{
248+
reference: &sourcev1.GitRepositoryRef{
249+
Branch: "master",
250+
Commit: "invalid",
251+
},
252+
waitForReason: sourcev1.GitOperationFailedReason,
253+
expectStatus: corev1.ConditionFalse,
254+
expectMessage: "git commit 'invalid' not found: object not found",
255+
}),
365256
)
366257
})
367258
})

internal/git/checkout.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef) CheckoutStrategy {
4343
case ref.Tag != "":
4444
return &CheckoutTag{tag: ref.Tag}
4545
case ref.Commit != "":
46-
return &CheckoutCommit{branch: ref.Branch, commit: ref.Commit}
46+
strategy := &CheckoutCommit{branch: ref.Branch, commit: ref.Commit}
47+
if strategy.branch == "" {
48+
strategy.branch = defaultBranch
49+
}
50+
return strategy
4751
case ref.Branch != "":
4852
return &CheckoutBranch{branch: ref.Branch}
4953
default:
@@ -81,7 +85,7 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, auth tr
8185
}
8286
commit, err := repo.CommitObject(head.Hash())
8387
if err != nil {
84-
return nil, "", fmt.Errorf("git commit not found: %w", err)
88+
return nil, "", fmt.Errorf("git commit '%s' not found: %w", head.Hash(), err)
8589
}
8690
return commit, fmt.Sprintf("%s/%s", c.branch, head.Hash().String()), nil
8791
}
@@ -112,7 +116,7 @@ func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, auth trans
112116
}
113117
commit, err := repo.CommitObject(head.Hash())
114118
if err != nil {
115-
return nil, "", fmt.Errorf("git commit not found: %w", err)
119+
return nil, "", fmt.Errorf("git commit '%s' not found: %w", head.Hash(), err)
116120
}
117121
return commit, fmt.Sprintf("%s/%s", c.tag, head.Hash().String()), nil
118122
}
@@ -143,7 +147,7 @@ func (c *CheckoutCommit) Checkout(ctx context.Context, path, url string, auth tr
143147
}
144148
commit, err := repo.CommitObject(plumbing.NewHash(c.commit))
145149
if err != nil {
146-
return nil, "", fmt.Errorf("git commit not found: %w", err)
150+
return nil, "", fmt.Errorf("git commit '%s' not found: %w", c.commit, err)
147151
}
148152
err = w.Checkout(&git.CheckoutOptions{
149153
Hash: commit.Hash,
@@ -217,7 +221,7 @@ func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, auth tr
217221

218222
commit, err := repo.CommitObject(plumbing.NewHash(commitRef))
219223
if err != nil {
220-
return nil, "", fmt.Errorf("git commit not found: %w", err)
224+
return nil, "", fmt.Errorf("git commit '%s' not found: %w", commitRef, err)
221225
}
222226
err = w.Checkout(&git.CheckoutOptions{
223227
Hash: commit.Hash,

0 commit comments

Comments
 (0)