feat: implement history and rollback support for source hydrator (#27327)#27465
feat: implement history and rollback support for source hydrator (#27327)#27465liketosweep wants to merge 6 commits into
Conversation
❌ Preview Environment undeployed from BunnyshellAvailable commands (reply to this comment):
|
667a2b3 to
91244d8
Compare
|
The only remaining failures are pre-existing |
91244d8 to
519d10b
Compare
|
Hi, processRequestedAppOperation treats any Sync operation on a SourceHydrator-enabled app as a rollback and returns early, preventing the normal sync loop from running. This breaks regular Sync requests (and retry flows that clear revision), and can cause unintended commits/incorrect success reporting. Severity: action required | Category: correctness How to fix: Gate rollback by explicit marker Agent prompt to fix - you can give this to your LLM of choice:
We noticed a couple of other issues in this PR as well - happy to share if helpful. Found by Qodo code review |
There was a problem hiding this comment.
Have you tested this locally?
The guard in processRequestedAppOperation has no discriminator between a rollback and a regular sync, so it would break normal syncs for any SourceHydrator-enabled app.
There are also a few more issues. The RollbackApp method added to the Dependencies interface (and its delegation in appcontroller_hydrator.go) is never actually called by the hydrator and looks like dead code, no guard against empty revision, and missing unit tests.
Please verify in your local env and attach some results.
519d10b to
901264d
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #27465 +/- ##
==========================================
- Coverage 63.58% 63.47% -0.11%
==========================================
Files 417 417
Lines 57062 57171 +109
==========================================
+ Hits 36283 36291 +8
- Misses 17386 17486 +100
- Partials 3393 3394 +1 ☔ View full report in Codecov by Sentry. |
4f6a097 to
eb97cbd
Compare
|
@choejwoo Thanks for the review. The implementation has been refactored to address the architectural and safety concerns: Rollback Discriminator: Added an Interface Cleanup: Removed the dead Defensive Guard & Coverage: Implemented a strict check against empty revisions in the hydrator path to prevent nil pointer panics (using
|
eb97cbd to
9dcd99f
Compare
|
@pbhatnagar-oss I have updated the implementation to address this. The All CI checks, including unit and integration tests, are now passing. Ready for another review! |
…oproj#27327) Signed-off-by: liketosweep <liketosweep@gmail.com>
…ext) Signed-off-by: liketosweep <liketosweep@gmail.com>
Signed-off-by: liketosweep <liketosweep@gmail.com>
Signed-off-by: liketosweep <liketosweep@gmail.com>
Signed-off-by: liketosweep <liketosweep@gmail.com>
Signed-off-by: liketosweep <liketosweep@gmail.com>
9dcd99f to
1910c4d
Compare

What was the issue
The
Rollbackaction in the History & Rollback UI had no effect on applications with Source Hydrator enabled. Triggering a rollback silently fell through the standard sync loop with no commit made to thesyncBranch, forcing users to manually intervene via Git. This created significant friction duringgitops-promoter+ Source Hydrator onboarding workflows.Fixes #27327
Why was it there
processRequestedAppOperationin the Application Controller had no interception logic for Source Hydrator rollback operations — rollback requests fell straight into the standard sync loop, which has no mechanism to fetch historical manifests and commit them tosyncPath. Additionally, thehydrator.Dependenciesinterface had noRollbackAppmethod, meaning there was no defined contract for the hydrator to perform this operation at all.My Approach to Solve It
Controller Interception: Added a guard block in
controller/appcontroller.goinsideprocessRequestedAppOperationthat detects when a Source Hydrator app has a pending rollback operation. The block checksctrl.hydrator != nil && app.Spec.SourceHydrator != nil && app.Operation != nil && app.Operation.Sync != nil, routes toRollbackApp, setsOperationStatetoSucceededorFailedaccordingly, and returns early — fully short-circuiting the standard sync loop.RollbackApp Implementation: Implemented
RollbackAppincontroller/hydrator/hydrator.go. It resolves the targethydratedRevisionfrom the operation, fetches the historical manifests fromsyncSource(notdrySource), and commits them directly tosyncBranchatsyncPathvia the commit server — replaying stored hydrated state rather than re-rendering from dry source, which would be unsafe ifApplication.spechad changed since the target revision.Interface & Delegation: Added
RollbackAppto thehydrator.Dependenciesinterface and added the corresponding delegation method on*ApplicationControllerincontroller/appcontroller_hydrator.goto satisfy the interface contract.Mock Update: Added
RollbackApptocontroller/hydrator/mocks/Dependencies.goto keep the testify mock in sync with the updatedDependenciesinterface, resolving thego vetfailure inhydrator_test.go.Scope Isolation: The rollback exclusively operates on the single application that triggered it. Sibling applications sharing the same
syncBranchare unaffected — no cross-app side effects.Result of the Fix
Users can now natively trigger rollbacks on Source Hydrator applications directly from the UI or CLI. The controller intercepts the operation, fetches the exact historical manifest state, and commits it to
syncBranch— bypassing the standard hydration cycle entirely. The Application status reflects the outcome cleanly:All
go vetchecks pass acrosscontroller/...andserver/application/....gofmtapplied to all changed files.Closes #27327