Skip to content

Commit abb3ab1

Browse files
committed
fix(traits): gitops, idempotent push
Closes #6412
1 parent 9f943f0 commit abb3ab1

File tree

4 files changed

+39
-8
lines changed

4 files changed

+39
-8
lines changed

docs/modules/ROOT/pages/running/gitops.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ spec:
3232
container:
3333
requestMemory: 256Mi
3434
gitops:
35+
enabled: true
3536
url: https://github.com/my-org/my-camel-apps.git
3637
secret: my-gh-token
3738
branchPush: cicd-listener
@@ -154,6 +155,7 @@ spec:
154155
- my-env=dev
155156
...
156157
gitops:
158+
enabled: true
157159
url: https://github.com/my-org/my-camel-apps.git
158160
secret: my-gh-token
159161
branchPush: cicd-listener-test
@@ -174,6 +176,7 @@ spec:
174176
properties:
175177
- my-env=test
176178
gitops:
179+
enabled: true
177180
url: https://github.com/my-org/my-camel-apps.git
178181
secret: my-gh-token
179182
branchPush: cicd-listener-prod

pkg/controller/integrationplatform/kamelets.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
"strings"
3030

3131
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
32-
"knative.dev/pkg/ptr"
32+
"k8s.io/utils/ptr"
3333

3434
"github.com/apache/camel-k/v2/pkg/client"
3535
"github.com/apache/camel-k/v2/pkg/util"
@@ -234,8 +234,8 @@ func loadKamelet(path string, platform *v1.IntegrationPlatform) (*v1.Kamelet, er
234234
Kind: platform.Kind,
235235
Name: platform.Name,
236236
UID: platform.UID,
237-
Controller: ptr.Bool(true),
238-
BlockOwnerDeletion: ptr.Bool(true),
237+
Controller: ptr.To(true),
238+
BlockOwnerDeletion: ptr.To(true),
239239
},
240240
}
241241
kamelet.SetOwnerReferences(references)

pkg/trait/gitops.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/apache/camel-k/v2/pkg/util/io"
3131
"github.com/go-git/go-git/v5/config"
3232
"github.com/go-git/go-git/v5/plumbing"
33+
corev1 "k8s.io/api/core/v1"
3334
"k8s.io/utils/ptr"
3435

3536
git "github.com/go-git/go-git/v5"
@@ -117,7 +118,10 @@ func (t *gitOpsTrait) pushGitOpsItInGitRepo(ctx context.Context, it *v1.Integrat
117118
nowDate := time.Now().Format("20060102-150405")
118119
branchName := t.BranchPush
119120
if branchName == "" {
120-
branchName = "cicd/candidate-release-" + nowDate
121+
// NOTE: this is important to guarantee idempotency. We make sure not to create
122+
// more than one branch from different reconciliation cycles.
123+
branchNameDate := it.Status.DeploymentTimestamp.Format("20060102-150405")
124+
branchName = "cicd/candidate-release-" + branchNameDate
121125
}
122126
commitMessage := "feat(ci): build completed on " + nowDate
123127
branchRef := plumbing.NewBranchReferenceName(branchName)
@@ -175,9 +179,26 @@ func (t *gitOpsTrait) pushGitOpsItInGitRepo(ctx context.Context, it *v1.Integrat
175179
RefSpecs: []config.RefSpec{
176180
config.RefSpec(branchRef + ":" + branchRef),
177181
},
182+
// Note: this is needed to make the task idempotent without returning any error.
183+
// Even if more parallel reconciliations are kicked off, we always push the same content,
184+
// possibly more than once, without risking to raise an error.
185+
Force: true,
178186
}
179187

180-
return repo.Push(gitPushOptions)
188+
err = repo.Push(gitPushOptions)
189+
if err != nil {
190+
return err
191+
}
192+
193+
// Publish a condition to notify the change was pushed to the branch
194+
it.Status.SetCondition(
195+
v1.IntegrationConditionType("GitPushed"),
196+
corev1.ConditionTrue,
197+
"PushedToGit",
198+
"Integration changes pushed to branch "+branchName,
199+
)
200+
201+
return nil
181202
}
182203

183204
// gitConf returns the git repo configuration where to pull the project from. If no value is provided, then, it takes

pkg/trait/gitops_test.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,19 @@ import (
2626
"time"
2727

2828
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
29-
"knative.dev/pkg/ptr"
29+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3030

3131
"github.com/go-git/go-git/v5/plumbing/object"
3232
"github.com/stretchr/testify/assert"
3333
"github.com/stretchr/testify/require"
34+
"k8s.io/utils/ptr"
3435

3536
git "github.com/go-git/go-git/v5"
3637
)
3738

3839
func TestGitOpsAddAction(t *testing.T) {
3940
trait, _ := newGitOpsTrait().(*gitOpsTrait)
40-
trait.Enabled = ptr.Bool(true)
41+
trait.Enabled = ptr.To(true)
4142
env := &Environment{
4243
Integration: &v1.Integration{
4344
Status: v1.IntegrationStatus{
@@ -72,12 +73,18 @@ func TestGitOpsPushRepoDefault(t *testing.T) {
7273
Git: conf,
7374
Sources: []v1.SourceSpec{v1.NewSourceSpec("Test.java", "bogus, irrelevant for test", v1.LanguageJavaSource)},
7475
}
76+
now := metav1.Now().Rfc3339Copy()
7577
it.Status = v1.IntegrationStatus{
76-
Image: "my-img-recently-baked",
78+
Image: "my-img-recently-baked",
79+
DeploymentTimestamp: &now,
7780
}
7881

7982
err = trait.pushGitOpsItInGitRepo(context.TODO(), &it, tmpGitDir, "fake")
8083
require.NoError(t, err)
84+
assert.Contains(t,
85+
it.Status.GetCondition(v1.IntegrationConditionType("GitPushed")).Message,
86+
"Integration changes pushed to branch cicd/candidate-release",
87+
)
8188

8289
lastCommitMessage, err := getLastCommitMessage(tmpGitDir)
8390
require.NoError(t, err)

0 commit comments

Comments
 (0)