Skip to content

Commit f71999b

Browse files
authored
chore: inclusive redis-cluster redis-cli (#41239)
## 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 --> > [!IMPORTANT] > 🟣 🟣 🟣 Your tests are running. > Tests running at: <https://github.com/appsmithorg/appsmith/actions/runs/17855114706> > Commit: eded401 > Workflow: `PR Automation test suite` > Tags: `@tag.Git` > Spec: `` > <hr>Fri, 19 Sep 2025 10:02:49 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 - Added support for Redis Cluster URLs in Git-connected features, enabling redis://, rediss://, and redis-cluster:// configurations. - Introduced a configurable Git root path to improve cloning behavior across environments. - Refactor - Unified Redis operations behind a single execution path to ensure consistent behavior and compatibility across connection types. - Streamlined Git initialization and argument handling to reduce edge cases during repository setup. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent f7293cf commit f71999b

File tree

2 files changed

+111
-17
lines changed

2 files changed

+111
-17
lines changed

app/server/appsmith-git/src/main/resources/git.sh

Lines changed: 110 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@ git_clone() {
3434
local private_key="$1"
3535
local remote_url="$2"
3636
local target_folder="$3"
37+
local git_root="$4"
3738

38-
local temp_private_key=$(mktemp /dev/shm/tmp.XXXXXX)
39+
local temp_private_key=$(mktemp ${git_root}tmp.XXXXXX)
3940
trap 'rm -rf "'"$temp_private_key"'"' EXIT ERR
4041

4142
echo "$private_key" > "$temp_private_key"
4243

43-
git -C "$target_folder" init "$target_folder" --initial-branch=none
44+
git -C "$target_folder" init --initial-branch=none
4445
git -C "$target_folder" remote add origin "$remote_url"
4546
GIT_SSH_COMMAND="ssh -i $temp_private_key -o StrictHostKeyChecking=no" git -C "$target_folder" fetch origin
4647
}
@@ -54,10 +55,10 @@ git_clean_up() {
5455
trap 'rm -rf "'"$target_folder"'"' EXIT ERR
5556

5657
## delete the repository from redis
57-
redis-cli -u "$redis_url" DEL "$redis_key"
58+
redis-exec "$redis_url" DEL "$redis_key"
5859

5960
## delete the repository branch_store
60-
redis-cli -u "$redis_url" DEL "$key_value_pair_key"
61+
redis-exec "$redis_url" DEL "$key_value_pair_key"
6162
}
6263

6364
# Uploads git repo to Redis as compressed archive
@@ -72,7 +73,7 @@ git_upload() {
7273
rm -f "$target_folder/.git/index.lock"
7374

7475
upload_branches_to_redis_hash "$target_folder" "$redis_url" "$key_value_pair_key"
75-
tar -cf - -C "$target_folder" . | zstd -q --threads=0 | base64 -w 0 | redis-cli -u "$redis_url" --raw -x SETEX "$redis_key" "$GIT_ARTIFACT_TTL"
76+
tar -cf - -C "$target_folder" . | zstd -q --threads=0 | base64 -w 0 | redis-exec "$redis_url" --raw -x SETEX "$redis_key" "$GIT_ARTIFACT_TTL"
7677
}
7778

7879
upload_branches_to_redis_hash() {
@@ -85,8 +86,8 @@ upload_branches_to_redis_hash() {
8586

8687
log_info "Preparing to upload branch store. Current branches: $branches"
8788

88-
redis-cli -u "$redis_url" DEL "$key_value_pair_key"
89-
redis-cli -u "$redis_url" HSET "$key_value_pair_key" $branches
89+
redis-exec "$redis_url" DEL "$key_value_pair_key"
90+
redis-exec "$redis_url" HSET "$key_value_pair_key" $branches
9091
}
9192

9293
# Downloads git repo from Redis or clones if not cached
@@ -105,8 +106,8 @@ git_download() {
105106
rm -rf "$target_folder"
106107
mkdir -p "$target_folder"
107108

108-
if [ "$(redis-cli -u "$redis_url" --raw EXISTS "$redis_key")" = "1" ]; then
109-
redis-cli -u "$redis_url" --raw GET "$redis_key" | base64 -d | zstd -d --threads=0 | tar -xf - -C "$target_folder"
109+
if [ "$(redis-exec "$redis_url" --raw EXISTS "$redis_key")" = "1" ]; then
110+
redis-exec "$redis_url" --raw GET "$redis_key" | base64 -d | zstd -d --threads=0 | tar -xf - -C "$target_folder"
110111
else
111112
log_warn "Cache miss. Repository: $target_folder with key: $redis_key does not exist in redis."
112113
return 1
@@ -123,11 +124,12 @@ git_clone_and_checkout() {
123124
local author_name="$2"
124125
local private_key="$3"
125126
local remote_url="$4"
126-
local target_folder="$5"
127-
local redis_url="$6"
128-
local key_value_pair_key="$7"
127+
local git_root="$5"
128+
local target_folder="$6"
129+
local redis_url="$7"
130+
local key_value_pair_key="$8"
129131

130-
## branches are after argument 7
132+
## branches are after argument 8
131133

132134
trap 'rm -rf "'"$target_folder"'"' ERR
133135

@@ -138,16 +140,16 @@ git_clone_and_checkout() {
138140
## create the same directory
139141
mkdir -p "$target_folder"
140142

141-
git_clone "$private_key" "$remote_url" "$target_folder"
143+
git_clone "$private_key" "$remote_url" "$target_folder" "$git_root"
142144
git -C "$target_folder" config user.name "$author_name"
143145
git -C "$target_folder" config user.email "$author_email"
144146
git -C "$target_folder" config fetch.parallel 4
145147
git -C "$target_folder" reflog expire --expire=now --all
146148
git -C "$target_folder" gc --prune=now --aggressive
147149

148-
# This provides all the arguments from arg 5 onwards to the function git_co_from_redis.
150+
# This provides all the arguments from arg 6 onwards to the function git_co_from_redis.
149151
# This includes the target folder, redis url, key value pair key, and all branch names from db.
150-
git_checkout_from_branch_store ${@:5}
152+
git_checkout_from_branch_store ${@:6}
151153
}
152154

153155
git_checkout_from_branch_store() {
@@ -159,7 +161,7 @@ git_checkout_from_branch_store() {
159161
# fetch raw value
160162
log_info "Searching Redis branch-store for key : $key_value_pair_key"
161163
local raw
162-
raw=$(redis-cli -u "$redis_url" --raw HGETALL "$key_value_pair_key" | sed 's/\"//g')
164+
raw=$(redis-exec "$redis_url" --raw HGETALL "$key_value_pair_key" | sed 's/\"//g')
163165

164166
# error handling: empty or missing key
165167
if [[ -z "$raw" ]]; then
@@ -253,3 +255,94 @@ git_merge_branch() {
253255
git -C "$target_folder" checkout "$destination_branch"
254256
git -C "$target_folder" merge "$source_branch" --strategy=recursive --allow-unrelated-histories --no-edit
255257
}
258+
259+
# Redis CLI wrapper that handles different URL schemes
260+
# Usage: redis-exec <redis-url> [redis-cli-args...]
261+
# Supports: redis://, rediss://, redis-cluster://
262+
redis-exec() {
263+
local url="$1"
264+
265+
if [[ -z "$url" ]]; then
266+
log_error "redis-exec: missing Redis URL"
267+
log_error "Usage: redis-exec <redis-url> [redis-cli-args...]"
268+
return 1
269+
fi
270+
271+
case "$url" in
272+
redis://*|rediss://*)
273+
# Standard Redis URL - pass directly to redis-cli -u
274+
redis-cli -u "$url" "${@:2}"
275+
;;
276+
redis-cluster://*)
277+
# Cluster URL - extract components and use cluster mode
278+
local stripped="${url#redis-cluster://}"
279+
280+
# Split into authority and path parts
281+
local authority="${stripped%%/*}"
282+
local path_part="${stripped#*/}"
283+
if [[ "$path_part" == "$stripped" ]]; then
284+
path_part="" # No path present
285+
fi
286+
287+
# Extract credentials from authority (user:pass@host:port)
288+
local credentials=""
289+
local host_port="$authority"
290+
if [[ "$authority" == *"@"* ]]; then
291+
credentials="${authority%%@*}"
292+
host_port="${authority##*@}"
293+
fi
294+
295+
# Parse credentials
296+
local username=""
297+
local password=""
298+
if [[ -n "$credentials" ]]; then
299+
if [[ "$credentials" == *":"* ]]; then
300+
username="${credentials%%:*}"
301+
password="${credentials##*:}"
302+
else
303+
password="$credentials" # Only password provided
304+
fi
305+
fi
306+
307+
# Extract host and port
308+
local host="${host_port%:*}"
309+
local port="${host_port##*:}"
310+
311+
# If no port specified, default to 6379
312+
if [[ "$port" == "$host" ]]; then
313+
port="6379"
314+
fi
315+
316+
# Extract database number from path
317+
local database=""
318+
if [[ -n "$path_part" && "$path_part" =~ ^[0-9]+(\?.*)?$ ]]; then
319+
database="${path_part%%\?*}" # Remove query params if present
320+
fi
321+
322+
# Build redis-cli command
323+
local cmd_args=("-c" "-h" "$host" "-p" "$port")
324+
325+
# Add authentication if present
326+
if [[ -n "$username" && -n "$password" ]]; then
327+
cmd_args+=("--user" "$username" "--pass" "$password")
328+
elif [[ -n "$password" ]]; then
329+
cmd_args+=("-a" "$password")
330+
fi
331+
332+
# Add database selection if specified
333+
if [[ -n "$database" ]]; then
334+
cmd_args+=("-n" "$database")
335+
fi
336+
337+
# Add remaining arguments
338+
cmd_args+=("${@:2}")
339+
340+
redis-cli "${cmd_args[@]}"
341+
;;
342+
*)
343+
log_error "redis-exec: unsupported URL scheme: $url"
344+
log_error "Supported schemes: redis://, rediss://, redis-cluster://"
345+
return 1
346+
;;
347+
esac
348+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ private Mono<?> clone(Context ctx) {
572572
ctx.getGitProfile().getAuthorName(),
573573
ctx.getGitKey(),
574574
ctx.getGitMeta().getRemoteUrl(),
575+
gitServiceConfig.getGitRootPath(),
575576
ctx.getRepoPath(),
576577
redisUrl,
577578
ctx.getBranchStoreKey());

0 commit comments

Comments
 (0)