From d75b11c785b8958046cb0dd7fa87e9731deaedea Mon Sep 17 00:00:00 2001 From: Luiz Filho Date: Wed, 8 Nov 2023 10:20:05 -0300 Subject: [PATCH] Setting lastest revision to pipeline status --- Makefile | 2 +- api/v1alpha1/pipeline_types.go | 4 ++++ charts/pipeline-controller/Chart.yaml | 2 +- .../crds/pipelines.weave.works_pipelines.yaml | 4 ++++ .../pipelines.weave.works_pipelines.yaml | 4 ++++ controllers/leveltriggered/controller.go | 22 +++++++++++++++++++ controllers/leveltriggered/controller_test.go | 22 +++++++++++++++++++ 7 files changed, 58 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index acb1b53..5727cd8 100644 --- a/Makefile +++ b/Makefile @@ -113,7 +113,7 @@ build: generate fmt vet ## Build manager binary. .PHONY: run run: manifests generate fmt vet ## Run a controller from your host. - go run ./main.go --log-level debug + go run ./main.go --enable-level-triggered true --log-level debug .PHONY: docker-build docker-build: ## Build docker image with the manager. diff --git a/api/v1alpha1/pipeline_types.go b/api/v1alpha1/pipeline_types.go index b2773d0..2f6a5fd 100644 --- a/api/v1alpha1/pipeline_types.go +++ b/api/v1alpha1/pipeline_types.go @@ -137,6 +137,10 @@ type PipelineStatus struct { // +optional Conditions []metav1.Condition `json:"conditions,omitempty"` + // LatestRevision is the latest revision that's been promoted to the environments. + // +optional + LatestRevision string `json:"latestRevision,omitempty"` + // Environments holds environment statuses. // +optional Environments map[string]*EnvironmentStatus `json:"environments"` diff --git a/charts/pipeline-controller/Chart.yaml b/charts/pipeline-controller/Chart.yaml index 34b3dc6..0ce8021 100755 --- a/charts/pipeline-controller/Chart.yaml +++ b/charts/pipeline-controller/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: pipeline-controller description: Pipeline-controller Helm chart for Weave GitOps Enterprise type: application -version: "0.22.0" +version: "0.23.0" appVersion: "v0.0.31" diff --git a/charts/pipeline-controller/crds/pipelines.weave.works_pipelines.yaml b/charts/pipeline-controller/crds/pipelines.weave.works_pipelines.yaml index 96a1b44..98431e4 100644 --- a/charts/pipeline-controller/crds/pipelines.weave.works_pipelines.yaml +++ b/charts/pipeline-controller/crds/pipelines.weave.works_pipelines.yaml @@ -432,6 +432,10 @@ spec: type: object description: Environments holds environment statuses. type: object + latestRevision: + description: LatestRevision is the latest revision that's been promoted + to the environments. + type: string observedGeneration: description: ObservedGeneration is the last observed generation. format: int64 diff --git a/config/crd/bases/pipelines.weave.works_pipelines.yaml b/config/crd/bases/pipelines.weave.works_pipelines.yaml index 96a1b44..98431e4 100644 --- a/config/crd/bases/pipelines.weave.works_pipelines.yaml +++ b/config/crd/bases/pipelines.weave.works_pipelines.yaml @@ -432,6 +432,10 @@ spec: type: object description: Environments holds environment statuses. type: object + latestRevision: + description: LatestRevision is the latest revision that's been promoted + to the environments. + type: string observedGeneration: description: ObservedGeneration is the last observed generation. format: int64 diff --git a/controllers/leveltriggered/controller.go b/controllers/leveltriggered/controller.go index 1b394d0..61fc784 100644 --- a/controllers/leveltriggered/controller.go +++ b/controllers/leveltriggered/controller.go @@ -232,6 +232,10 @@ func (r *PipelineReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c return ctrl.Result{}, fmt.Errorf("error removing pending condition: %w", err) } + if err := r.setLatestRevision(ctx, pipeline, latestRevision); err != nil { + return ctrl.Result{}, fmt.Errorf("error setting latest revision: %w", err) + } + for _, env := range pipeline.Spec.Environments[1:] { // if all targets run the latest revision and are ready, we can skip this environment if checkAllTargetsRunRevision(pipeline.Status.Environments[env.Name], latestRevision) && checkAllTargetsAreReady(pipeline.Status.Environments[env.Name]) { @@ -253,6 +257,24 @@ func (r *PipelineReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c return ctrl.Result{}, nil } +func (r *PipelineReconciler) setLatestRevision(ctx context.Context, pipeline v1alpha1.Pipeline, revision string) error { + pipeline.Status.LatestRevision = revision + + fmt.Println("setting latest revision to", revision) + if err := r.patchStatus(ctx, client.ObjectKeyFromObject(&pipeline), pipeline.Status); err != nil { + r.emitEventf( + &pipeline, + corev1.EventTypeWarning, + "SetStatus", "Failed to set LatestRevision status for pipeline %s/%s: %s", + pipeline.GetNamespace(), pipeline.GetName(), + err, + ) + return err + } + + return nil +} + func (r *PipelineReconciler) setPendingCondition(ctx context.Context, pipeline v1alpha1.Pipeline, reason, message string) error { condition := metav1.Condition{ Type: conditions.PromotionPendingCondition, diff --git a/controllers/leveltriggered/controller_test.go b/controllers/leveltriggered/controller_test.go index a91e87e..35139c2 100644 --- a/controllers/leveltriggered/controller_test.go +++ b/controllers/leveltriggered/controller_test.go @@ -122,6 +122,28 @@ func TestReconcile(t *testing.T) { g.Expect(targetStatus.Revision).To(Equal(appRevision)) }) + t.Run("sets the lastestRevision status field", func(t *testing.T) { + g := testingutils.NewGomegaWithT(t) + name := "pipeline-" + rand.String(5) + ns := testingutils.NewNamespace(ctx, g, k8sClient) + t.Cleanup(deleteObjectCleanup(ctx, g, ns)) + + const appRevision = "v1.0.1" + + hr := createApp(ctx, k8sClient, g, name, ns.Name) + setAppRevisionAndReadyStatus(ctx, g, hr, appRevision) + + pipeline := newPipeline(name, ns.Name, nil) + g.Expect(k8sClient.Create(ctx, pipeline)).To(Succeed()) + + checkCondition(ctx, g, client.ObjectKeyFromObject(pipeline), meta.ReadyCondition, metav1.ConditionTrue, v1alpha1.ReconciliationSucceededReason) + + g.Eventually(func() string { + p := getPipeline(ctx, g, client.ObjectKeyFromObject(pipeline)) + return p.Status.LatestRevision + }, "5s", "0.2s").Should(Equal(appRevision)) + }) + t.Run("promotes revision to all environments", func(t *testing.T) { g := testingutils.NewGomegaWithT(t) mockStrategy := setStrategyRegistry(t, pipelineReconciler)