diff --git a/api/v1alpha1/imageupdateautomation_types.go b/api/v1alpha1/imageupdateautomation_types.go index 9ebc3d1..fefc9fc 100644 --- a/api/v1alpha1/imageupdateautomation_types.go +++ b/api/v1alpha1/imageupdateautomation_types.go @@ -94,6 +94,13 @@ type ImageUpdateAutomationStatus struct { // made). // +optional LastAutomationRunTime *metav1.Time `json:"lastAutomationRunTime,omitempty"` + // LastPushCommit records the SHA1 of the last commit made by the + // controller, for this automation object + // +optional + LastPushCommit string `json:"lastPushCommit,omitempty"` + // LastPushTime records the time of the last pushed change. + // +optional + LastPushTime *metav1.Time `json:"lastPushTime,omitempty"` // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty"` // +optional diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 57ad3f2..4e43a1c 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -141,6 +141,10 @@ func (in *ImageUpdateAutomationStatus) DeepCopyInto(out *ImageUpdateAutomationSt in, out := &in.LastAutomationRunTime, &out.LastAutomationRunTime *out = (*in).DeepCopy() } + if in.LastPushTime != nil { + in, out := &in.LastPushTime, &out.LastPushTime + *out = (*in).DeepCopy() + } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]v1.Condition, len(*in)) diff --git a/config/crd/bases/image.toolkit.fluxcd.io_imageupdateautomations.yaml b/config/crd/bases/image.toolkit.fluxcd.io_imageupdateautomations.yaml index d7907db..e04601c 100644 --- a/config/crd/bases/image.toolkit.fluxcd.io_imageupdateautomations.yaml +++ b/config/crd/bases/image.toolkit.fluxcd.io_imageupdateautomations.yaml @@ -187,6 +187,14 @@ spec: description: LastHandledReconcileAt holds the value of the most recent reconcile request value, so a change can be detected. type: string + lastPushCommit: + description: LastPushCommit records the SHA1 of the last commit made + by the controller, for this automation object + type: string + lastPushTime: + description: LastPushTime records the time of the last pushed change. + format: date-time + type: string observedGeneration: format: int64 type: integer diff --git a/controllers/imageupdateautomation_controller.go b/controllers/imageupdateautomation_controller.go index 8636c47..7ce9e5d 100644 --- a/controllers/imageupdateautomation_controller.go +++ b/controllers/imageupdateautomation_controller.go @@ -199,12 +199,17 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(req ctrl.Request) (ctrl.Resu r.event(auto, events.EventSeverityInfo, "no updates made") log.V(debug).Info("no changes made in working directory; no commit") statusMessage = "no updates made" + if lastCommit, lastTime := auto.Status.LastPushCommit, auto.Status.LastPushTime; lastCommit != "" { + statusMessage = fmt.Sprintf("%s; last commit %s at %s", statusMessage, lastCommit[:7], lastTime.Format(time.RFC3339)) + } } else { return failWithError(err) } } else { r.event(auto, events.EventSeverityInfo, "committed and pushed change "+rev) log.Info("pushed commit to origin", "revision", rev) + auto.Status.LastPushCommit = rev + auto.Status.LastPushTime = &metav1.Time{Time: now} statusMessage = "committed and pushed " + rev } diff --git a/controllers/update_test.go b/controllers/update_test.go index 972c1e6..e3de794 100644 --- a/controllers/update_test.go +++ b/controllers/update_test.go @@ -36,7 +36,7 @@ import ( . "github.com/onsi/gomega" "github.com/otiai10/copy" corev1 "k8s.io/api/core/v1" - // apimeta "k8s.io/apimachinery/pkg/api/meta" + apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" @@ -241,6 +241,11 @@ var _ = Describe("ImageUpdateAutomation", func() { Expect(err).ToNot(HaveOccurred()) Expect(commit.Message).To(Equal(commitMessage)) + var newObj imagev1.ImageUpdateAutomation + Expect(k8sClient.Get(context.Background(), updateKey, &newObj)).To(Succeed()) + Expect(newObj.Status.LastPushCommit).To(Equal(head.Hash().String())) + Expect(newObj.Status.LastPushTime).ToNot(BeNil()) + compareRepoWithExpected(repoURL, branch, "testdata/appconfig-setters-expected", func(tmp string) { replaceMarker(tmp, policyKey) }) @@ -319,6 +324,7 @@ var _ = Describe("ImageUpdateAutomation", func() { }, timeout, time.Second).Should(BeTrue()) // check that the annotation was recorded as seen Expect(newUpdate.Status.LastHandledReconcileAt).To(Equal(ts)) + expectCommittedAndPushed(newUpdate.Status.Conditions) // check that a new commit was made compareRepoWithExpected(repoURL, branch, "testdata/appconfig-setters-expected", func(tmp string) { @@ -329,6 +335,12 @@ var _ = Describe("ImageUpdateAutomation", func() { }) }) +func expectCommittedAndPushed(conditions []metav1.Condition) { + rc := apimeta.FindStatusCondition(conditions, meta.ReadyCondition) + Expect(rc).ToNot(BeNil()) + Expect(rc.Message).To(ContainSubstring("committed and pushed")) +} + func replaceMarker(path string, policyKey types.NamespacedName) { // NB this requires knowledge of what's in the git // repo, so a little brittle