Skip to content

Commit 2df1b40

Browse files
zmotsoMykolaMarusenko
authored andcommitted
feat: Support creation git branch from another branch (#214)
Add support for using branch names in CodebaseBranch.spec.fromCommit field.
1 parent c3d3f9b commit 2df1b40

File tree

11 files changed

+347
-56
lines changed

11 files changed

+347
-56
lines changed

api/v1/codebasebranch_types.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ type CodebaseBranchSpec struct {
1818
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
1919
BranchName string `json:"branchName"`
2020

21-
// The new branch will be created starting from the selected commit hash.
21+
// FromCommit is a commit hash or branch name.
22+
// The new branch will be created starting from the selected commit hash or branch name.
23+
// If a branch name is provided, the new branch will be created from the latest commit of that branch.
24+
// +optional
2225
FromCommit string `json:"fromCommit"`
2326

2427
// Version of the branch. It's required for versioning type "semver".

config/crd/bases/v2.edp.epam.com_codebasebranches.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ spec:
7272
description: Name of Codebase associated with.
7373
type: string
7474
fromCommit:
75-
description: The new branch will be created starting from the selected
76-
commit hash.
75+
description: |-
76+
FromCommit is a commit hash or branch name.
77+
The new branch will be created starting from the selected commit hash or branch name.
78+
If a branch name is provided, the new branch will be created from the latest commit of that branch.
7779
type: string
7880
pipelines:
7981
additionalProperties:
@@ -95,7 +97,6 @@ spec:
9597
required:
9698
- branchName
9799
- codebaseName
98-
- fromCommit
99100
- release
100101
type: object
101102
status:

controllers/codebasebranch/chain/check_commit_hash.go renamed to controllers/codebasebranch/chain/check_reference.go

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ import (
1515
"github.com/epam/edp-codebase-operator/v2/pkg/util"
1616
)
1717

18-
// CheckCommitHashExists is chain element for checking commit hash existence.
19-
type CheckCommitHashExists struct {
18+
// CheckReferenceExists is chain element for checking if a reference (branch or commit) exists.
19+
type CheckReferenceExists struct {
2020
Next handler.CodebaseBranchHandler
2121
Client client.Client
2222
Git git.Git
2323
}
2424

25-
// ServeRequest is a method for checking CodebaseBranch FromCommit hash existence.
26-
func (c CheckCommitHashExists) ServeRequest(ctx context.Context, codebaseBranch *codebaseApi.CodebaseBranch) error {
27-
log := ctrl.LoggerFrom(ctx).WithName("check-commit-hash-exists")
25+
// ServeRequest is a method for checking if the reference (branch or commit) exists.
26+
func (c CheckReferenceExists) ServeRequest(ctx context.Context, codebaseBranch *codebaseApi.CodebaseBranch) error {
27+
log := ctrl.LoggerFrom(ctx).WithName("check-reference-exists")
2828

2929
if codebaseBranch.Status.Git == codebaseApi.CodebaseBranchGitStatusBranchCreated {
30-
log.Info("Branch is already created in git. Skip checking commit hash existence")
30+
log.Info("Branch is already created in git. Skip checking reference existence")
3131

3232
return c.next(ctx, codebaseBranch)
3333
}
@@ -88,20 +88,16 @@ func (c CheckCommitHashExists) ServeRequest(ctx context.Context, codebaseBranch
8888
}
8989
}
9090

91-
exists, err := c.Git.CommitExists(workDir, codebaseBranch.Spec.FromCommit)
91+
err := c.Git.CheckReference(workDir, codebaseBranch.Spec.FromCommit)
9292
if err != nil {
93-
return c.processErr(codebaseBranch, fmt.Errorf("failed to check commit hash %s: %w", codebaseBranch.Spec.FromCommit, err))
94-
}
95-
96-
if !exists {
97-
return c.processErr(codebaseBranch, fmt.Errorf("commit %s doesn't exist", codebaseBranch.Spec.FromCommit))
93+
return c.processErr(codebaseBranch, fmt.Errorf("reference %s doesn't exist: %w", codebaseBranch.Spec.FromCommit, err))
9894
}
9995

10096
return c.next(ctx, codebaseBranch)
10197
}
10298

10399
// next is a method for serving next chain element.
104-
func (c CheckCommitHashExists) next(ctx context.Context, codebaseBranch *codebaseApi.CodebaseBranch) error {
100+
func (c CheckReferenceExists) next(ctx context.Context, codebaseBranch *codebaseApi.CodebaseBranch) error {
105101
err := handler.NextServeOrNil(ctx, c.Next, codebaseBranch)
106102
if err != nil {
107103
return fmt.Errorf("failed to serve next chain element: %w", err)
@@ -111,7 +107,7 @@ func (c CheckCommitHashExists) next(ctx context.Context, codebaseBranch *codebas
111107
}
112108

113109
// processErr is a method for processing error in chain.
114-
func (c CheckCommitHashExists) processErr(codebaseBranch *codebaseApi.CodebaseBranch, err error) error {
110+
func (c CheckReferenceExists) processErr(codebaseBranch *codebaseApi.CodebaseBranch, err error) error {
115111
if err == nil {
116112
return nil
117113
}
@@ -121,7 +117,7 @@ func (c CheckCommitHashExists) processErr(codebaseBranch *codebaseApi.CodebaseBr
121117
return err
122118
}
123119

124-
func (CheckCommitHashExists) setFailedFields(
120+
func (CheckReferenceExists) setFailedFields(
125121
codebaseBranch *codebaseApi.CodebaseBranch,
126122
actionType codebaseApi.ActionType,
127123
message string,

controllers/codebasebranch/chain/check_commit_hash_test.go renamed to controllers/codebasebranch/chain/check_reference_test.go

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package chain
22

33
import (
44
"context"
5+
"errors"
56
"testing"
67

78
"github.com/go-logr/logr"
@@ -18,7 +19,7 @@ import (
1819
gitServerMocks "github.com/epam/edp-codebase-operator/v2/pkg/git/mocks"
1920
)
2021

21-
func TestCheckCommitHashExists_ServeRequest(t *testing.T) {
22+
func TestCheckReferenceExists_ServeRequest(t *testing.T) {
2223
scheme := runtime.NewScheme()
2324
err := codebaseApi.AddToScheme(scheme)
2425
require.NoError(t, err)
@@ -84,17 +85,77 @@ func TestCheckCommitHashExists_ServeRequest(t *testing.T) {
8485
testifymock.Anything,
8586
).Return(nil)
8687
mGit.On(
87-
"CommitExists",
88+
"CheckReference",
8889
testifymock.Anything,
8990
testifymock.Anything,
90-
).Return(true, nil)
91+
).Return(nil)
9192

9293
return mGit
9394
},
9495
wantErr: require.NoError,
9596
},
9697
{
97-
name: "failed, commit doesn't exist",
98+
name: "success, branch reference exists",
99+
codebaseBranch: &codebaseApi.CodebaseBranch{
100+
ObjectMeta: metav1.ObjectMeta{
101+
Name: "test",
102+
Namespace: "default",
103+
},
104+
Spec: codebaseApi.CodebaseBranchSpec{
105+
CodebaseName: "test-codebase",
106+
BranchName: "feature",
107+
FromCommit: "main",
108+
},
109+
},
110+
objects: []runtime.Object{
111+
&codebaseApi.Codebase{
112+
ObjectMeta: metav1.ObjectMeta{
113+
Name: "test-codebase",
114+
Namespace: "default",
115+
},
116+
Spec: codebaseApi.CodebaseSpec{
117+
GitServer: "test-git-server",
118+
},
119+
},
120+
&codebaseApi.GitServer{
121+
ObjectMeta: metav1.ObjectMeta{
122+
Name: "test-git-server",
123+
Namespace: "default",
124+
},
125+
Spec: codebaseApi.GitServerSpec{
126+
NameSshKeySecret: "test-ssh-key",
127+
},
128+
},
129+
&coreV1.Secret{
130+
ObjectMeta: metav1.ObjectMeta{
131+
Name: "test-ssh-key",
132+
Namespace: "default",
133+
},
134+
},
135+
},
136+
gitClient: func() git.Git {
137+
mGit := gitServerMocks.NewMockGit(t)
138+
mGit.On(
139+
"CloneRepositoryBySsh",
140+
testifymock.Anything,
141+
testifymock.Anything,
142+
testifymock.Anything,
143+
testifymock.Anything,
144+
testifymock.Anything,
145+
testifymock.Anything,
146+
).Return(nil)
147+
mGit.On(
148+
"CheckReference",
149+
testifymock.Anything,
150+
testifymock.Anything,
151+
).Return(nil)
152+
153+
return mGit
154+
},
155+
wantErr: require.NoError,
156+
},
157+
{
158+
name: "failed, reference doesn't exist",
98159
codebaseBranch: &codebaseApi.CodebaseBranch{
99160
ObjectMeta: metav1.ObjectMeta{
100161
Name: "test",
@@ -103,7 +164,7 @@ func TestCheckCommitHashExists_ServeRequest(t *testing.T) {
103164
Spec: codebaseApi.CodebaseBranchSpec{
104165
CodebaseName: "test-codebase",
105166
BranchName: "main",
106-
FromCommit: "bfba920bd3bdebc9ae1c4475d70391152645b2a4",
167+
FromCommit: "non-existent",
107168
},
108169
},
109170
objects: []runtime.Object{
@@ -144,21 +205,20 @@ func TestCheckCommitHashExists_ServeRequest(t *testing.T) {
144205
testifymock.Anything,
145206
).Return(nil)
146207
mGit.On(
147-
"CommitExists",
208+
"CheckReference",
148209
testifymock.Anything,
149210
testifymock.Anything,
150-
).Return(false, nil)
211+
).Return(errors.New("reference not found"))
151212

152213
return mGit
153214
},
154215
wantErr: func(t require.TestingT, err error, _ ...any) {
155216
require.Error(t, err)
156-
157-
require.Contains(t, err.Error(), "commit bfba920bd3bdebc9ae1c4475d70391152645b2a4 doesn't exist")
217+
require.Contains(t, err.Error(), "reference non-existent doesn't exist")
158218
},
159219
},
160220
{
161-
name: "skip, commit hash is empty",
221+
name: "skip, reference is empty",
162222
codebaseBranch: &codebaseApi.CodebaseBranch{
163223
ObjectMeta: metav1.ObjectMeta{
164224
Name: "test",
@@ -194,7 +254,7 @@ func TestCheckCommitHashExists_ServeRequest(t *testing.T) {
194254
}
195255
for _, tt := range tests {
196256
t.Run(tt.name, func(t *testing.T) {
197-
c := CheckCommitHashExists{
257+
c := CheckReferenceExists{
198258
Client: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(tt.objects...).Build(),
199259
Git: tt.gitClient(),
200260
}

deploy-templates/crds/v2.edp.epam.com_codebasebranches.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ spec:
7272
description: Name of Codebase associated with.
7373
type: string
7474
fromCommit:
75-
description: The new branch will be created starting from the selected
76-
commit hash.
75+
description: |-
76+
FromCommit is a commit hash or branch name.
77+
The new branch will be created starting from the selected commit hash or branch name.
78+
If a branch name is provided, the new branch will be created from the latest commit of that branch.
7779
type: string
7880
pipelines:
7981
additionalProperties:
@@ -95,7 +97,6 @@ spec:
9597
required:
9698
- branchName
9799
- codebaseName
98-
- fromCommit
99100
- release
100101
type: object
101102
status:

docs/api.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -332,20 +332,22 @@ CodebaseBranchSpec defines the desired state of CodebaseBranch.
332332
Name of Codebase associated with.<br/>
333333
</td>
334334
<td>true</td>
335-
</tr><tr>
336-
<td><b>fromCommit</b></td>
337-
<td>string</td>
338-
<td>
339-
The new branch will be created starting from the selected commit hash.<br/>
340-
</td>
341-
<td>true</td>
342335
</tr><tr>
343336
<td><b>release</b></td>
344337
<td>boolean</td>
345338
<td>
346339
Flag if branch is used as "release" branch.<br/>
347340
</td>
348341
<td>true</td>
342+
</tr><tr>
343+
<td><b>fromCommit</b></td>
344+
<td>string</td>
345+
<td>
346+
FromCommit is a commit hash or branch name.
347+
The new branch will be created starting from the selected commit hash or branch name.
348+
If a branch name is provided, the new branch will be created from the latest commit of that branch.<br/>
349+
</td>
350+
<td>false</td>
349351
</tr><tr>
350352
<td><b>pipelines</b></td>
351353
<td>map[string]string</td>

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ require (
1313
github.com/cespare/xxhash/v2 v2.3.0
1414
github.com/epam/edp-cd-pipeline-operator/v2 v2.25.1
1515
github.com/epam/edp-common v0.0.0-20230710145648-344bbce4120e
16-
github.com/go-git/go-git/v5 v5.16.0
16+
github.com/go-git/go-git/v5 v5.16.2
1717
github.com/go-logr/logr v1.4.2
1818
github.com/go-resty/resty/v2 v2.16.5
1919
github.com/jarcoal/httpmock v1.4.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,8 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN
248248
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
249249
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
250250
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
251-
github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ=
252-
github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
251+
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
252+
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
253253
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
254254
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
255255
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=

0 commit comments

Comments
 (0)