@@ -223,6 +223,14 @@ func (r *ApplicationDefinitionReconciler) Reconcile(ctx context.Context, req ctr
223223 // 7. Determine final phase and update status if needed
224224 r .determineFinalPhase (state , allReady ) // Update phase based on errors and readiness
225225 state .appDef .Status .Components = mapToSliceComponentStatus (state .componentStatuses ) // Update components status list
226+
227+ // Update LastChangeID in status if reconciliation was successful
228+ if allReady && state .firstError == nil {
229+ if changeID , exists := state .appDef .Annotations [appv1 .AnnotationChangeID ]; exists && changeID != "" {
230+ state .appDef .Status .LastChangeID = changeID
231+ }
232+ }
233+
226234 _ , statusUpdateErr := r .updateStatusIfNeeded (ctx , state .appDef , state .originalStatus )
227235 if statusUpdateErr != nil {
228236 // Distinguish between conflicts (expected, will retry) and other errors
@@ -811,7 +819,8 @@ func (r *ApplicationDefinitionReconciler) updateStatusIfNeeded(ctx context.Conte
811819 if currentApp .Status .Phase == originalStatus .Phase &&
812820 conditionsEqual (currentApp .Status .Conditions , originalStatus .Conditions ) &&
813821 componentStatusesEqual (currentApp .Status .Components , originalStatus .Components ) &&
814- currentApp .Status .ObservedGeneration == originalStatus .ObservedGeneration {
822+ currentApp .Status .ObservedGeneration == originalStatus .ObservedGeneration &&
823+ currentApp .Status .LastChangeID == originalStatus .LastChangeID {
815824 logger .V (1 ).Info ("Status unchanged, skipping update." )
816825 return false , nil // No changes detected
817826 }
@@ -1045,6 +1054,14 @@ func (r *ApplicationDefinitionReconciler) recordEvent(app *appv1.ApplicationDefi
10451054 recorder := r .getEventRecorder (app )
10461055
10471056 if wr , ok := recorder .(* webrecorder.WebhookEventRecorder ); ok {
1057+ // Get current change ID from annotations
1058+ currentChangeID := app .Annotations [appv1 .AnnotationChangeID ]
1059+
1060+ // Check if this change ID has already been processed
1061+ if app .Status .LastChangeID == currentChangeID {
1062+ // Skip sending duplicate webhook event for the same change ID
1063+ return
1064+ }
10481065 annotations := map [string ]string {
10491066 webrecorder .PhaseKey : phase ,
10501067 webrecorder .StatusKey : status ,
@@ -1061,6 +1078,14 @@ func (r *ApplicationDefinitionReconciler) recordEventf(app *appv1.ApplicationDef
10611078 recorder := r .getEventRecorder (app )
10621079
10631080 if wr , ok := recorder .(* webrecorder.WebhookEventRecorder ); ok {
1081+ // Get current change ID from annotations
1082+ currentChangeID := app .Annotations [appv1 .AnnotationChangeID ]
1083+
1084+ // Check if this change ID has already been processed
1085+ if app .Status .LastChangeID == currentChangeID {
1086+ // Skip sending duplicate webhook event for the same change ID
1087+ return
1088+ }
10641089 annotations := map [string ]string {
10651090 webrecorder .PhaseKey : phase ,
10661091 webrecorder .StatusKey : status ,
0 commit comments