Skip to content
This repository was archived by the owner on May 9, 2025. It is now read-only.

Commit da924f2

Browse files
committed
fix naming, branch checkout logic and uncompression
1 parent 8fab92a commit da924f2

File tree

7 files changed

+75
-30
lines changed

7 files changed

+75
-30
lines changed

apis/delivery/v1alpha1/sync_types.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ type SyncSpec struct {
3535
Prune bool `json:"prune,omitempty"`
3636

3737
//+optional
38-
Branch string `json:"branch,omitempty"`
38+
TargetBranch string `json:"targetBranch,omitempty"`
39+
//+optional
40+
//+kubebuilder:default:=main
41+
BaseBranch string `json:"baseBranch,omitempty"`
3942
//+optional
4043
AutomaticPullRequestCreation bool `json:"automaticPullRequestCreation,omitempty"`
4144
//+optional

config/crd/bases/delivery.ocm.software_syncs.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ spec:
3737
properties:
3838
automaticPullRequestCreation:
3939
type: boolean
40-
branch:
40+
baseBranch:
41+
default: main
4142
type: string
4243
commitTemplate:
4344
description: CommitTemplate defines the details of the commit to the
@@ -91,6 +92,8 @@ spec:
9192
x-kubernetes-map-type: atomic
9293
subPath:
9394
type: string
95+
targetBranch:
96+
type: string
9497
required:
9598
- commitTemplate
9699
- interval

controllers/delivery/sync_controller.go

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ import (
2020
"k8s.io/apimachinery/pkg/runtime"
2121
"k8s.io/apimachinery/pkg/types"
2222
ctrl "sigs.k8s.io/controller-runtime"
23+
"sigs.k8s.io/controller-runtime/pkg/builder"
2324
"sigs.k8s.io/controller-runtime/pkg/client"
2425
"sigs.k8s.io/controller-runtime/pkg/log"
26+
"sigs.k8s.io/controller-runtime/pkg/predicate"
2527

2628
ocmv1 "github.com/open-component-model/ocm-controller/api/v1alpha1"
2729

@@ -56,7 +58,7 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
5658
)
5759

5860
log := log.FromContext(ctx)
59-
log.V(4).Info("starting reconcile loop for snapshot")
61+
6062
obj := &v1alpha1.Sync{}
6163
if err := r.Get(ctx, req.NamespacedName, obj); err != nil {
6264
if apierrors.IsNotFound(err) {
@@ -142,6 +144,8 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
142144
return ctrl.Result{}, retErr
143145
}
144146

147+
log.V(4).Info("found target snapshot")
148+
145149
repository := &mpasv1alpha1.Repository{}
146150
if err := r.Get(ctx, types.NamespacedName{
147151
Namespace: obj.Namespace,
@@ -153,6 +157,8 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
153157
return ctrl.Result{}, retErr
154158
}
155159

160+
log.V(4).Info("found target repository")
161+
156162
authSecret := &corev1.Secret{}
157163
if err := r.Get(ctx, types.NamespacedName{
158164
Namespace: obj.Namespace,
@@ -164,26 +170,35 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
164170
return ctrl.Result{}, retErr
165171
}
166172

167-
branch := obj.Spec.Branch
168-
if branch == "" && obj.Spec.AutomaticPullRequestCreation {
169-
branch = fmt.Sprintf("branch-%d", time.Now().Unix())
170-
} else if branch == "" && !obj.Spec.AutomaticPullRequestCreation {
173+
log.V(4).Info("found authentication secret")
174+
175+
baseBranch := obj.Spec.BaseBranch
176+
if baseBranch == "" {
177+
baseBranch = "main"
178+
}
179+
targetBranch := obj.Spec.TargetBranch
180+
if targetBranch == "" && obj.Spec.AutomaticPullRequestCreation {
181+
targetBranch = fmt.Sprintf("branch-%d", time.Now().Unix())
182+
} else if targetBranch == "" && !obj.Spec.AutomaticPullRequestCreation {
171183
retErr = fmt.Errorf("branch cannot be empty if automatic pull request creation is not enabled")
172184
conditions.MarkFalse(obj, meta.ReadyCondition, v1alpha1.GitRepositoryPushFailedReason, retErr.Error())
173185

174186
return ctrl.Result{}, retErr
175187
}
176188

189+
log.Info("preparing to push snapshot content", "base", baseBranch, "target", targetBranch)
190+
177191
// trim any trailing `/` and then just add.
178192
log.V(4).Info("crafting artifact URL to download from", "url", snapshot.Status.RepositoryURL)
179193
opts := &pkg.PushOptions{
180-
URL: repository.GetRepositoryURL(),
181-
Message: obj.Spec.CommitTemplate.Message,
182-
Name: obj.Spec.CommitTemplate.Name,
183-
Email: obj.Spec.CommitTemplate.Email,
184-
Snapshot: snapshot,
185-
Branch: branch,
186-
SubPath: obj.Spec.SubPath,
194+
URL: repository.GetRepositoryURL(),
195+
Message: obj.Spec.CommitTemplate.Message,
196+
Name: obj.Spec.CommitTemplate.Name,
197+
Email: obj.Spec.CommitTemplate.Email,
198+
Snapshot: snapshot,
199+
BaseBranch: baseBranch,
200+
TargetBranch: targetBranch,
201+
SubPath: obj.Spec.SubPath,
187202
}
188203

189204
r.parseAuthSecret(authSecret, opts)
@@ -196,10 +211,14 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
196211
return ctrl.Result{}, retErr
197212
}
198213

214+
log.Info("target content pushed with digest", "base", baseBranch, "target", targetBranch, "digest", digest)
215+
199216
obj.Status.Digest = digest
200217

201218
if obj.Spec.AutomaticPullRequestCreation {
202-
if err := r.Provider.CreatePullRequest(ctx, branch, *obj, *repository); err != nil {
219+
log.Info("automatic pull-request creation is enabled, preparing to create a pull request")
220+
221+
if err := r.Provider.CreatePullRequest(ctx, targetBranch, *obj, *repository); err != nil {
203222
retErr = fmt.Errorf("failed to create pull request: %w", err)
204223
conditions.MarkFalse(obj, meta.ReadyCondition, v1alpha1.CreatePullRequestFailedReason, retErr.Error())
205224

@@ -212,13 +231,15 @@ func (r *SyncReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
212231
// block at the very end.
213232
conditions.Delete(obj, meta.ReadyCondition)
214233

234+
log.Info("successfully reconciled sync object")
235+
215236
return result, retErr
216237
}
217238

218239
// SetupWithManager sets up the controller with the Manager.
219240
func (r *SyncReconciler) SetupWithManager(mgr ctrl.Manager) error {
220241
return ctrl.NewControllerManagedBy(mgr).
221-
For(&v1alpha1.Sync{}).
242+
For(&v1alpha1.Sync{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})).
222243
Complete(r)
223244
}
224245

controllers/delivery/sync_controller_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func TestSyncReconciler(t *testing.T) {
6969
RepositoryRef: v1.LocalObjectReference{
7070
Name: repository.Name,
7171
},
72-
Branch: "main",
72+
TargetBranch: "main",
7373
CommitTemplate: &v1alpha1.CommitTemplate{
7474
Name: "Skarlso",
7575
@@ -151,7 +151,7 @@ func TestSyncReconcilerWithAutomaticPullRequest(t *testing.T) {
151151
RepositoryRef: v1.LocalObjectReference{
152152
Name: repository.Name,
153153
},
154-
Branch: "main",
154+
TargetBranch: "main",
155155
CommitTemplate: &v1alpha1.CommitTemplate{
156156
Name: "Skarlso",
157157

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.20
55
require (
66
code.gitea.io/sdk/gitea v0.15.1
77
github.com/Masterminds/semver/v3 v3.2.0
8+
github.com/containers/image/v5 v5.21.1
89
github.com/fluxcd/go-git-providers v0.15.0
910
github.com/fluxcd/pkg/apis/meta v0.19.0
1011
github.com/fluxcd/pkg/runtime v0.27.0
@@ -48,7 +49,6 @@ require (
4849
github.com/cloudflare/circl v1.3.2 // indirect
4950
github.com/containerd/containerd v1.6.18 // indirect
5051
github.com/containerd/stargz-snapshotter/estargz v0.14.1 // indirect
51-
github.com/containers/image/v5 v5.21.1 // indirect
5252
github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a // indirect
5353
github.com/containers/ocicrypt v1.1.5 // indirect
5454
github.com/containers/storage v1.42.0 // indirect

pkg/git.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,16 @@ type Auth struct {
3232

3333
// PushOptions contains settings for a push action.
3434
type PushOptions struct {
35-
Auth *Auth
36-
URL string
37-
Message string
38-
Name string
39-
Email string
40-
Snapshot *ocmv1.Snapshot
41-
Branch string
42-
SubPath string
43-
Prune bool
35+
Auth *Auth
36+
URL string
37+
Message string
38+
Name string
39+
Email string
40+
Snapshot *ocmv1.Snapshot
41+
BaseBranch string
42+
TargetBranch string
43+
SubPath string
44+
Prune bool
4445
}
4546

4647
// Git defines an interface to abstract git operations.

pkg/gogit/git.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"path/filepath"
1212
"time"
1313

14+
"github.com/containers/image/v5/pkg/compression"
1415
"github.com/go-git/go-git/v5"
1516
"github.com/go-git/go-git/v5/plumbing"
1617
"github.com/go-git/go-git/v5/plumbing/object"
@@ -65,7 +66,7 @@ func (g *Git) Push(ctx context.Context, opts *pkg.PushOptions) (string, error) {
6566
cloneOptions := &git.CloneOptions{
6667
URL: opts.URL,
6768
Depth: 1,
68-
ReferenceName: plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", opts.Branch)),
69+
ReferenceName: plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", opts.BaseBranch)),
6970
Auth: auth,
7071
}
7172

@@ -79,6 +80,15 @@ func (g *Git) Push(ctx context.Context, opts *pkg.PushOptions) (string, error) {
7980
return "", fmt.Errorf("failed to create a worktree: %w", err)
8081
}
8182

83+
if opts.TargetBranch != opts.BaseBranch {
84+
if err := w.Checkout(&git.CheckoutOptions{
85+
Branch: plumbing.NewBranchReferenceName(opts.TargetBranch),
86+
Create: true,
87+
}); err != nil {
88+
return "", fmt.Errorf("failed to checkout new branch: %w", err)
89+
}
90+
}
91+
8292
dir = filepath.Join(dir, opts.SubPath)
8393
if err := os.MkdirAll(dir, 0777); err != nil {
8494
return "", fmt.Errorf("failed to create subPath: %w", err)
@@ -94,9 +104,15 @@ func (g *Git) Push(ctx context.Context, opts *pkg.PushOptions) (string, error) {
94104
return "", fmt.Errorf("failed to fetch blob for digest: %w", err)
95105
}
96106

107+
uncompressed, _, err := compression.AutoDecompress(blob)
108+
if err != nil {
109+
return "", fmt.Errorf("failed to auto decompress: %w", err)
110+
}
111+
defer uncompressed.Close()
112+
97113
// we only care about the error if it is NOT a header error. Otherwise, we assume the content
98114
// wasn't compressed.
99-
if err = Untar(blob, dir); err != nil {
115+
if err = Untar(uncompressed, dir); err != nil {
100116
return "", fmt.Errorf("failed to untar content: %w", err)
101117
}
102118

@@ -112,6 +128,7 @@ func (g *Git) Push(ctx context.Context, opts *pkg.PushOptions) (string, error) {
112128
When: time.Now(),
113129
},
114130
}
131+
115132
commit, err := w.Commit("Uploading snapshot to location", commitOpts)
116133
if err != nil {
117134
return "", fmt.Errorf("failed to commit changes: %w", err)

0 commit comments

Comments
 (0)