Skip to content

chore: made discard changes async after ref creation#41785

Open
sondermanish wants to merge 1 commit intoreleasefrom
chore/async-discard
Open

chore: made discard changes async after ref creation#41785
sondermanish wants to merge 1 commit intoreleasefrom
chore/async-discard

Conversation

@sondermanish
Copy link
Copy Markdown
Contributor

@sondermanish sondermanish commented May 8, 2026

Description

Tip

Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team).

Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR.

Fixes #Issue Number
or
Fixes Issue URL

Warning

If no issue exists, please create an issue first, and check with the maintainers if the issue is valid.

Automation

/ok-to-test tags="@tag.Git"

🔍 Cypress test results

Caution

🔴 🔴 🔴 Some tests have failed.
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/25646779287
Commit: 5be2cab
Cypress dashboard.
Tags: @tag.Git
Spec:
The following are new failures, please fix them before merging the PR:

  1. cypress/e2e/Regression/ClientSide/Git/GitSync/MergeViaRemote_spec.ts
List of identified flaky tests.
Mon, 11 May 2026 02:37:38 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Git discard changes operations now process asynchronously, improving responsiveness
    • Added control to optionally skip validation and publishing during discard operations
  • Tests

    • Added test coverage for async discard changes event handling

@sondermanish sondermanish requested a review from a team as a code owner May 8, 2026 18:08
@sondermanish sondermanish added the ok-to-test Required label for CI label May 8, 2026
@sondermanish
Copy link
Copy Markdown
Contributor Author

/build-deploy-preview skip-tests=true

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Walkthrough

This PR introduces an asynchronous event-driven architecture for git discard-changes operations. A new GitDiscardChangesEvent DTO and GitDiscardChangesAsyncEventManager interface enable non-blocking cleanup workflows. Branch creation now publishes discard events asynchronously instead of blocking on synchronous cleanup, improving responsiveness. The discard API gains a control flag for validation/publish behavior, with full test coverage of event publishing, listening, and delegation flows.

Changes

Async Discard Event Architecture

Layer / File(s) Summary
Data Contracts
app/server/appsmith-server/src/main/java/com/appsmith/server/events/GitDiscardChangesEvent.java
New DTO carries artifact metadata (artifactId, artifactType, gitType), author information, and isValidateAndPublish flag into async event pipeline.
Interface Contracts
app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/helpers/GitDiscardChangesAsyncEventManager.java, app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCE.java
GitDiscardChangesAsyncEventManager interface declares event publishing, listening, and async discard methods. CentralGitServiceCE adds discardChanges overload with Boolean isValidateAndPublish parameter.
Event Manager Implementation
app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/helpers/GitDiscardChangesAsyncEventManagerImpl.java
Spring component implements async event publishing via ApplicationEventPublisher, defines @EventListener async handler scheduling work on boundedElastic, and exposes @GitRoute-mapped discardChanges delegating to CentralGitService.
Dependency Injection
app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceImpl.java, app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCECompatibleImpl.java, app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java
GitDiscardChangesAsyncEventManager propagated through constructor chain: CentralGitServiceImplCentralGitServiceCECompatibleImplCentralGitServiceCEImpl.
Branch Creation Integration
app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java
Branch creation replaces synchronous discard cleanup with async event publication; returns newly created artifact immediately while event publishing failures are best-effort.
API Extension
app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java
New discardChanges overload accepts Boolean isValidateAndPublish flag; existing overload delegates with TRUE default.
Tests
app/server/appsmith-server/src/test/java/com/appsmith/server/git/central/helpers/GitDiscardChangesAsyncEventManagerImplTest.java
Verifies event publishing (no transformation), async listener invocation with parameter capture, and routed discard delegation to CentralGitService.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

✨ Events now fly where sync once crawled,
Discard changes answered by the call,
Async branches bloom without delay,
While cleanup works the background way 🎭

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.70% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning PR description lacks critical details: no issue reference provided, motivation/context missing, dependencies unlisted, and implementation specifics absent. Add a valid issue number/URL (currently shows placeholder), provide context on why async discard was needed, list any dependencies, and briefly summarize the implementation approach.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: making discard changes async after reference creation, which aligns with the core modifications in the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/async-discard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label May 8, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/25571612871.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41785.
recreate: .
base-image-tag: .

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java (1)

2342-2355: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Normalize nullable isValidateAndPublish before branching.

With the new nullable flag, null currently takes the non-validate path (publishArtifact) at Line 2414, which can silently bypass validation. Default this to true to preserve legacy behavior.

Suggested patch
 protected Mono<? extends Artifact> discardChanges(
         Artifact branchedArtifact, GitType gitType, Boolean isValidateAndPublish, Boolean shouldHydratePackages) {
+    final boolean validateAndPublish = !Boolean.FALSE.equals(isValidateAndPublish);
     ArtifactType artifactType = branchedArtifact.getArtifactType();
@@
-                                        if (!TRUE.equals(isValidateAndPublish)) {
+                                        if (!validateAndPublish) {
                                             return gitArtifactHelper.publishArtifact(artifactFromLastCommit, true);
                                         }

Also applies to: 2414-2426

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java`
around lines 2342 - 2355, Normalize the nullable isValidateAndPublish flag to
default true before branching: in discardChanges(String branchedArtifactId, ...)
(and the other discardChanges overload that takes an Artifact), replace usages
of the nullable Boolean with a primitive boolean computed as boolean
validateAndPublish = (isValidateAndPublish == null) ? true :
isValidateAndPublish; then pass that normalized value (boxed if needed) into the
subsequent discardChanges(...) / publishArtifact(...) calls (references:
discardChanges(branchedArtifact, gitType, isValidateAndPublish),
publishArtifact) so null no longer takes the non-validate path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/helpers/GitDiscardChangesAsyncEventManagerImpl.java`:
- Around line 31-32: The class GitDiscardChangesAsyncEventManagerImpl is logging
the entire discard event (the 'event' object) which contains PII like
authorName; update the log.info calls that reference 'event' to instead log only
non-PII fields (for example event.getApplicationId(), event.getBranchName(),
event.getCommitId()/change count or a boolean status) and explicitly omit or
mask authorName, and apply the same change to the second log.info in this class
(both occurrences that currently pass the whole event). Use explicit
getters/properties in the log message so only allowed fields are emitted and
avoid serializing the full event object.

In
`@app/server/appsmith-server/src/test/java/com/appsmith/server/git/central/helpers/GitDiscardChangesAsyncEventManagerImplTest.java`:
- Line 108: The test in GitDiscardChangesAsyncEventManagerImplTest uses a
1-second timeout on the latch (assertThat(latch.await(1,
TimeUnit.SECONDS)).isTrue();) which is flaky under CI; increase the async wait
budget by changing the timeout value to a larger duration (e.g., 5 or 10
seconds) in that assertion so the scheduler-based async path has more time to
complete.

---

Outside diff comments:
In
`@app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java`:
- Around line 2342-2355: Normalize the nullable isValidateAndPublish flag to
default true before branching: in discardChanges(String branchedArtifactId, ...)
(and the other discardChanges overload that takes an Artifact), replace usages
of the nullable Boolean with a primitive boolean computed as boolean
validateAndPublish = (isValidateAndPublish == null) ? true :
isValidateAndPublish; then pass that normalized value (boxed if needed) into the
subsequent discardChanges(...) / publishArtifact(...) calls (references:
discardChanges(branchedArtifact, gitType, isValidateAndPublish),
publishArtifact) so null no longer takes the non-validate path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4447ea99-e2f8-41d1-8c31-b1e9e4e2f7ec

📥 Commits

Reviewing files that changed from the base of the PR and between 9ab4a39 and 5be2cab.

📒 Files selected for processing (8)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/events/GitDiscardChangesEvent.java
  • app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCE.java
  • app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCECompatibleImpl.java
  • app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java
  • app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceImpl.java
  • app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/helpers/GitDiscardChangesAsyncEventManager.java
  • app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/helpers/GitDiscardChangesAsyncEventManagerImpl.java
  • app/server/appsmith-server/src/test/java/com/appsmith/server/git/central/helpers/GitDiscardChangesAsyncEventManagerImplTest.java

Comment on lines +31 to +32
log.info("published event for git discard changes: {}", event);
applicationEventPublisher.publishEvent(event);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid logging full discard event payload (contains user identifiers).

Line 31 and Line 39 log the whole event object, which includes authorName. Prefer structured logs with non-PII fields only.

Suggested patch
-        log.info("published event for git discard changes: {}", event);
+        log.info(
+                "Published git discard changes event for artifactId={}, artifactType={}, gitType={}",
+                event.getArtifactId(),
+                event.getArtifactType(),
+                event.getGitType());
@@
-        log.info("received event for git discard changes: {}", event);
+        log.info(
+                "Received git discard changes event for artifactId={}, artifactType={}, gitType={}",
+                event.getArtifactId(),
+                event.getArtifactType(),
+                event.getGitType());

Also applies to: 39-40

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/helpers/GitDiscardChangesAsyncEventManagerImpl.java`
around lines 31 - 32, The class GitDiscardChangesAsyncEventManagerImpl is
logging the entire discard event (the 'event' object) which contains PII like
authorName; update the log.info calls that reference 'event' to instead log only
non-PII fields (for example event.getApplicationId(), event.getBranchName(),
event.getCommitId()/change count or a boolean status) and explicitly omit or
mask authorName, and apply the same change to the second log.info in this class
(both occurrences that currently pass the whole event). Use explicit
getters/properties in the log message so only allowed fields are emitted and
avoid serializing the full event object.


manager.discardChangesEventListener(event);

assertThat(latch.await(1, TimeUnit.SECONDS)).isTrue();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Increase async wait budget to reduce test flakes.

Line 108 uses a 1-second latch timeout for a scheduler-based async path; this can intermittently fail under CI load.

Suggested patch
-        assertThat(latch.await(1, TimeUnit.SECONDS)).isTrue();
+        assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assertThat(latch.await(1, TimeUnit.SECONDS)).isTrue();
assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/server/appsmith-server/src/test/java/com/appsmith/server/git/central/helpers/GitDiscardChangesAsyncEventManagerImplTest.java`
at line 108, The test in GitDiscardChangesAsyncEventManagerImplTest uses a
1-second timeout on the latch (assertThat(latch.await(1,
TimeUnit.SECONDS)).isTrue();) which is flaky under CI; increase the async wait
budget by changing the timeout value to a larger duration (e.g., 5 or 10
seconds) in that assertion so the scheduler-based async path has more time to
complete.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

Deploy-Preview-URL: https://ce-41785.dp.appsmith.com

@sondermanish sondermanish self-assigned this May 11, 2026
@sondermanish sondermanish added ok-to-test Required label for CI and removed ok-to-test Required label for CI labels May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok-to-test Required label for CI skip-changelog Adding this label to a PR prevents it from being listed in the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant