Skip to content

Commit d5ee690

Browse files
authored
chore: enabled autocommit (#41255)
## 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 <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/17945463792> > Commit: 02dea2d > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=17945463792&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Git` > Spec: > <hr>Tue, 23 Sep 2025 12:56:31 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Auto-commit now accepts author name and email so commits reflect the initiating user. * Auto-commit processing can run asynchronously in the background. * **Improvements** * Auto-commit flows will fall back to generated author info when a stored Git profile is unavailable. * Controller now delegates auto-commit to a central service for consistent responses. * Enhanced logging for clearer Git operation traceability. * **Tests** * Updated and un-skipped end-to-end and unit tests covering auto-commit paths. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 903d952 commit d5ee690

File tree

20 files changed

+154
-105
lines changed

20 files changed

+154
-105
lines changed

app/client/cypress/e2e/Regression/ClientSide/Git/GitAutocommit_spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe(
2626
],
2727
},
2828
function () {
29-
it.skip("Check if autocommit progress bar is visible and network requests are properly called", function () {
29+
it("Check if autocommit progress bar is visible and network requests are properly called", function () {
3030
agHelper.GenerateUUID();
3131
cy.get("@guid").then((uid) => {
3232
wsName = "GitAC-" + uid;

app/server/appsmith-server/src/main/java/com/appsmith/server/annotations/GitRoute.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@
1818
ArtifactType artifactType();
1919

2020
GitRouteOperation operation();
21+
22+
String authorName() default "";
23+
24+
String authorEmail() default "";
2125
}

app/server/appsmith-server/src/main/java/com/appsmith/server/aspect/GitRouteAspect.java

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ private static class Context {
142142

143143
// Intermediate Inputs
144144
private String fieldValue;
145+
private String authorName;
146+
private String authorEmail;
145147

146148
// Tasks
147149
private Artifact artifact;
@@ -229,6 +231,14 @@ public Object handleGitRoute(ProceedingJoinPoint joinPoint, GitRoute gitRoute) {
229231
return execute(ctx);
230232
}
231233

234+
String authorName = extractFieldValue(joinPoint, gitRoute.authorName());
235+
String authorEmail = extractFieldValue(joinPoint, gitRoute.authorEmail());
236+
237+
if (StringUtils.hasText(authorName) && StringUtils.hasText(authorEmail)) {
238+
ctx.setAuthorEmail(authorEmail);
239+
ctx.setAuthorName(authorName);
240+
}
241+
232242
String fieldValue = extractFieldValue(joinPoint, gitRoute.fieldName());
233243
ctx.setFieldValue(fieldValue);
234244
return run(ctx, State.ROUTE_FILTER).flatMap(unused -> {
@@ -267,14 +277,15 @@ private Mono<Object> run(Context ctx, State current) {
267277
Outcome.SUCCESS.name(),
268278
result,
269279
duration);
280+
} else {
281+
log.info(
282+
"Operation : {}, State {} : {}, Time: {}ms",
283+
ctx.getGitRoute().operation(),
284+
current,
285+
Outcome.SUCCESS.name(),
286+
duration);
270287
}
271288

272-
log.info(
273-
"Operation : {}, State {} : {}, Time: {}ms",
274-
ctx.getGitRoute().operation(),
275-
current,
276-
Outcome.SUCCESS.name(),
277-
duration);
278289
return run(ctx, config.next(Outcome.SUCCESS));
279290
})
280291
.onErrorResume(e -> {
@@ -460,10 +471,23 @@ private Mono<?> lockKey(Context ctx) {
460471
* @return Mono emitting the Git profile, or error if not configured
461472
*/
462473
private Mono<GitProfile> gitProfile(Context ctx) {
463-
return gitProfileUtils
464-
.getGitProfileForUser(ctx.getFieldValue())
474+
Mono<GitProfile> alternativeGitProfileMono = Mono.defer(() -> Mono.justOrEmpty(getProfileFromArgs(ctx)))
465475
.switchIfEmpty(Mono.error(new AppsmithException(
466476
AppsmithError.INVALID_GIT_CONFIGURATION, "Git profile is not configured")));
477+
478+
return gitProfileUtils.getGitProfileForUser(ctx.getFieldValue()).switchIfEmpty(alternativeGitProfileMono);
479+
}
480+
481+
private GitProfile getProfileFromArgs(Context ctx) {
482+
if (!StringUtils.hasText(ctx.getAuthorEmail()) || !StringUtils.hasText(ctx.getAuthorName())) {
483+
return null;
484+
}
485+
486+
GitProfile gitProfile = new GitProfile();
487+
gitProfile.setAuthorName(ctx.getAuthorName());
488+
gitProfile.setAuthorEmail(ctx.getAuthorEmail());
489+
gitProfile.setUseGlobalProfile(Boolean.TRUE);
490+
return gitProfile;
467491
}
468492

469493
/**

app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitEventHandler.java

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.appsmith.server.git.autocommit;
2+
3+
public interface AutoCommitSolution extends AutoCommitSolutionCE {}

app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitEventHandlerCE.java renamed to app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitSolutionCE.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import com.appsmith.server.events.AutoCommitEvent;
44
import reactor.core.publisher.Mono;
55

6-
public interface AutoCommitEventHandlerCE {
7-
void publish(AutoCommitEvent autoCommitEvent);
6+
public interface AutoCommitSolutionCE {
87

9-
void handle(AutoCommitEvent event);
8+
Mono<Boolean> startApplicationAutoCommit(
9+
String baseArtifactId, String authorName, String authorEmail, AutoCommitEvent event);
1010

1111
Mono<Boolean> autoCommitDSLMigration(AutoCommitEvent autoCommitEvent);
1212

app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitEventHandlerCEImpl.java renamed to app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitSolutionCEImpl.java

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.appsmith.external.git.constants.ce.RefType;
77
import com.appsmith.external.git.handler.FSGitHandler;
88
import com.appsmith.external.git.models.GitResourceType;
9+
import com.appsmith.server.annotations.GitRoute;
910
import com.appsmith.server.configurations.ProjectProperties;
1011
import com.appsmith.server.constants.ArtifactType;
1112
import com.appsmith.server.constants.FieldName;
@@ -18,6 +19,7 @@
1819
import com.appsmith.server.exceptions.AppsmithError;
1920
import com.appsmith.server.exceptions.AppsmithException;
2021
import com.appsmith.server.git.GitRedisUtils;
22+
import com.appsmith.server.git.constants.GitRouteOperation;
2123
import com.appsmith.server.git.dtos.ArtifactJsonTransformationDTO;
2224
import com.appsmith.server.git.resolver.GitArtifactHelperResolver;
2325
import com.appsmith.server.helpers.CollectionUtils;
@@ -29,9 +31,6 @@
2931
import com.appsmith.server.services.GitArtifactHelper;
3032
import lombok.RequiredArgsConstructor;
3133
import lombok.extern.slf4j.Slf4j;
32-
import org.springframework.context.ApplicationEventPublisher;
33-
import org.springframework.context.event.EventListener;
34-
import org.springframework.scheduling.annotation.Async;
3534
import reactor.core.publisher.Flux;
3635
import reactor.core.publisher.Mono;
3736
import reactor.core.scheduler.Schedulers;
@@ -51,8 +50,7 @@
5150

5251
@RequiredArgsConstructor
5352
@Slf4j
54-
public class AutoCommitEventHandlerCEImpl implements AutoCommitEventHandlerCE {
55-
private final ApplicationEventPublisher applicationEventPublisher;
53+
public class AutoCommitSolutionCEImpl implements AutoCommitSolutionCE {
5654
private final GitRedisUtils gitRedisUtils;
5755
private final RedisUtils redisUtils;
5856
private final DSLMigrationUtils dslMigrationUtils;
@@ -66,30 +64,23 @@ public class AutoCommitEventHandlerCEImpl implements AutoCommitEventHandlerCE {
6664
"System generated commit, to support new features in Appsmith %s";
6765

6866
@Override
69-
public void publish(AutoCommitEvent autoCommitEvent) {
70-
applicationEventPublisher.publishEvent(autoCommitEvent);
71-
log.info("published event for auto commit: {}", autoCommitEvent);
72-
}
73-
74-
@Async
75-
@EventListener
76-
@Override
77-
public void handle(AutoCommitEvent event) {
78-
log.info("received event for auto commit: {}", event);
67+
@GitRoute(
68+
artifactType = ArtifactType.APPLICATION,
69+
operation = GitRouteOperation.AUTO_COMMIT_SOLUTION,
70+
fieldName = "baseArtifactId",
71+
authorEmail = "authorEmail",
72+
authorName = "authorName")
73+
public Mono<Boolean> startApplicationAutoCommit(
74+
String baseArtifactId, String authorName, String authorEmail, AutoCommitEvent event) {
75+
log.info("Starting auto-commit process for event: {}", event);
7976
Mono<Boolean> autocommitMigration;
8077
if (Boolean.TRUE.equals(event.getIsServerSideEvent())) {
8178
autocommitMigration = this.autoCommitServerMigration(event);
8279
} else {
8380
autocommitMigration = this.autoCommitDSLMigration(event);
8481
}
8582

86-
autocommitMigration
87-
.subscribeOn(Schedulers.boundedElastic())
88-
.subscribe(
89-
result -> log.info(
90-
"Auto-commit completed successfully for application: {}", event.getApplicationId()),
91-
error -> log.error(
92-
"Error during auto-commit for application: {}", event.getApplicationId(), error));
83+
return autocommitMigration.subscribeOn(Schedulers.boundedElastic());
9384
}
9485

9586
private <T> Mono<T> setProgress(T result, String applicationId, int progress) {

app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitEventHandlerImpl.java renamed to app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitSolutionImpl.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@
88
import com.appsmith.server.helpers.DSLMigrationUtils;
99
import com.appsmith.server.helpers.RedisUtils;
1010
import com.appsmith.server.services.AnalyticsService;
11-
import org.springframework.context.ApplicationEventPublisher;
1211
import org.springframework.stereotype.Component;
1312

1413
@Component
15-
public class AutoCommitEventHandlerImpl extends AutoCommitEventHandlerCEImpl implements AutoCommitEventHandler {
14+
public class AutoCommitSolutionImpl extends AutoCommitSolutionCEImpl implements AutoCommitSolution {
1615

17-
public AutoCommitEventHandlerImpl(
18-
ApplicationEventPublisher applicationEventPublisher,
16+
public AutoCommitSolutionImpl(
1917
GitRedisUtils gitRedisUtils,
2018
RedisUtils redisUtils,
2119
DSLMigrationUtils dslMigrationUtils,
@@ -25,7 +23,6 @@ public AutoCommitEventHandlerImpl(
2523
ProjectProperties projectProperties,
2624
AnalyticsService analyticsService) {
2725
super(
28-
applicationEventPublisher,
2926
gitRedisUtils,
3027
redisUtils,
3128
dslMigrationUtils,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.appsmith.server.git.autocommit.helpers;
2+
3+
import com.appsmith.server.events.AutoCommitEvent;
4+
5+
public interface AutoCommitAsyncEventManager {
6+
7+
void publishAsyncEvent(AutoCommitEvent autoCommitEvent);
8+
9+
void autoCommitPublishEventListener(AutoCommitEvent event);
10+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.appsmith.server.git.autocommit.helpers;
2+
3+
import com.appsmith.server.events.AutoCommitEvent;
4+
import com.appsmith.server.git.autocommit.AutoCommitSolution;
5+
import lombok.RequiredArgsConstructor;
6+
import lombok.extern.slf4j.Slf4j;
7+
import org.springframework.context.ApplicationEventPublisher;
8+
import org.springframework.context.event.EventListener;
9+
import org.springframework.scheduling.annotation.Async;
10+
import org.springframework.stereotype.Component;
11+
import reactor.core.scheduler.Schedulers;
12+
13+
@Component
14+
@Slf4j
15+
@RequiredArgsConstructor
16+
public class AutoCommitAsyncEventManagerImpl implements AutoCommitAsyncEventManager {
17+
18+
private final ApplicationEventPublisher applicationEventPublisher;
19+
private final AutoCommitSolution autoCommitSolution;
20+
21+
@Override
22+
public void publishAsyncEvent(AutoCommitEvent autoCommitEvent) {
23+
log.info("published event for auto commit: {}", autoCommitEvent);
24+
applicationEventPublisher.publishEvent(autoCommitEvent);
25+
}
26+
27+
@Async
28+
@EventListener
29+
@Override
30+
public void autoCommitPublishEventListener(AutoCommitEvent event) {
31+
log.info("received event for auto commit: {}", event);
32+
String baseArtifactId = event.getApplicationId();
33+
String authorName = event.getAuthorName();
34+
String authorEmail = event.getAuthorEmail();
35+
36+
autoCommitSolution
37+
.startApplicationAutoCommit(baseArtifactId, authorName, authorEmail, event)
38+
.subscribeOn(Schedulers.boundedElastic())
39+
.subscribe(
40+
result -> log.info(
41+
"Auto-commit completed successfully for application: {}", event.getApplicationId()),
42+
error -> log.error(
43+
"Error during auto-commit for application: {}", event.getApplicationId(), error));
44+
}
45+
}

0 commit comments

Comments
 (0)