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: eded40175d45e1294c0b3cb2a3efcd9496373844
> 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 -->
This commit is contained in:
Manish Kumar 2025-09-19 16:25:16 +05:30 committed by GitHub
parent f7293cfa05
commit f71999b14f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 111 additions and 17 deletions

View File

@ -34,13 +34,14 @@ git_clone() {
local private_key="$1" local private_key="$1"
local remote_url="$2" local remote_url="$2"
local target_folder="$3" local target_folder="$3"
local git_root="$4"
local temp_private_key=$(mktemp /dev/shm/tmp.XXXXXX) local temp_private_key=$(mktemp ${git_root}tmp.XXXXXX)
trap 'rm -rf "'"$temp_private_key"'"' EXIT ERR trap 'rm -rf "'"$temp_private_key"'"' EXIT ERR
echo "$private_key" > "$temp_private_key" echo "$private_key" > "$temp_private_key"
git -C "$target_folder" init "$target_folder" --initial-branch=none git -C "$target_folder" init --initial-branch=none
git -C "$target_folder" remote add origin "$remote_url" git -C "$target_folder" remote add origin "$remote_url"
GIT_SSH_COMMAND="ssh -i $temp_private_key -o StrictHostKeyChecking=no" git -C "$target_folder" fetch origin GIT_SSH_COMMAND="ssh -i $temp_private_key -o StrictHostKeyChecking=no" git -C "$target_folder" fetch origin
} }
@ -54,10 +55,10 @@ git_clean_up() {
trap 'rm -rf "'"$target_folder"'"' EXIT ERR trap 'rm -rf "'"$target_folder"'"' EXIT ERR
## delete the repository from redis ## delete the repository from redis
redis-cli -u "$redis_url" DEL "$redis_key" redis-exec "$redis_url" DEL "$redis_key"
## delete the repository branch_store ## delete the repository branch_store
redis-cli -u "$redis_url" DEL "$key_value_pair_key" redis-exec "$redis_url" DEL "$key_value_pair_key"
} }
# Uploads git repo to Redis as compressed archive # Uploads git repo to Redis as compressed archive
@ -72,7 +73,7 @@ git_upload() {
rm -f "$target_folder/.git/index.lock" rm -f "$target_folder/.git/index.lock"
upload_branches_to_redis_hash "$target_folder" "$redis_url" "$key_value_pair_key" upload_branches_to_redis_hash "$target_folder" "$redis_url" "$key_value_pair_key"
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" tar -cf - -C "$target_folder" . | zstd -q --threads=0 | base64 -w 0 | redis-exec "$redis_url" --raw -x SETEX "$redis_key" "$GIT_ARTIFACT_TTL"
} }
upload_branches_to_redis_hash() { upload_branches_to_redis_hash() {
@ -85,8 +86,8 @@ upload_branches_to_redis_hash() {
log_info "Preparing to upload branch store. Current branches: $branches" log_info "Preparing to upload branch store. Current branches: $branches"
redis-cli -u "$redis_url" DEL "$key_value_pair_key" redis-exec "$redis_url" DEL "$key_value_pair_key"
redis-cli -u "$redis_url" HSET "$key_value_pair_key" $branches redis-exec "$redis_url" HSET "$key_value_pair_key" $branches
} }
# Downloads git repo from Redis or clones if not cached # Downloads git repo from Redis or clones if not cached
@ -105,8 +106,8 @@ git_download() {
rm -rf "$target_folder" rm -rf "$target_folder"
mkdir -p "$target_folder" mkdir -p "$target_folder"
if [ "$(redis-cli -u "$redis_url" --raw EXISTS "$redis_key")" = "1" ]; then if [ "$(redis-exec "$redis_url" --raw EXISTS "$redis_key")" = "1" ]; then
redis-cli -u "$redis_url" --raw GET "$redis_key" | base64 -d | zstd -d --threads=0 | tar -xf - -C "$target_folder" redis-exec "$redis_url" --raw GET "$redis_key" | base64 -d | zstd -d --threads=0 | tar -xf - -C "$target_folder"
else else
log_warn "Cache miss. Repository: $target_folder with key: $redis_key does not exist in redis." log_warn "Cache miss. Repository: $target_folder with key: $redis_key does not exist in redis."
return 1 return 1
@ -123,11 +124,12 @@ git_clone_and_checkout() {
local author_name="$2" local author_name="$2"
local private_key="$3" local private_key="$3"
local remote_url="$4" local remote_url="$4"
local target_folder="$5" local git_root="$5"
local redis_url="$6" local target_folder="$6"
local key_value_pair_key="$7" local redis_url="$7"
local key_value_pair_key="$8"
## branches are after argument 7 ## branches are after argument 8
trap 'rm -rf "'"$target_folder"'"' ERR trap 'rm -rf "'"$target_folder"'"' ERR
@ -138,16 +140,16 @@ git_clone_and_checkout() {
## create the same directory ## create the same directory
mkdir -p "$target_folder" mkdir -p "$target_folder"
git_clone "$private_key" "$remote_url" "$target_folder" git_clone "$private_key" "$remote_url" "$target_folder" "$git_root"
git -C "$target_folder" config user.name "$author_name" git -C "$target_folder" config user.name "$author_name"
git -C "$target_folder" config user.email "$author_email" git -C "$target_folder" config user.email "$author_email"
git -C "$target_folder" config fetch.parallel 4 git -C "$target_folder" config fetch.parallel 4
git -C "$target_folder" reflog expire --expire=now --all git -C "$target_folder" reflog expire --expire=now --all
git -C "$target_folder" gc --prune=now --aggressive git -C "$target_folder" gc --prune=now --aggressive
# This provides all the arguments from arg 5 onwards to the function git_co_from_redis. # This provides all the arguments from arg 6 onwards to the function git_co_from_redis.
# This includes the target folder, redis url, key value pair key, and all branch names from db. # This includes the target folder, redis url, key value pair key, and all branch names from db.
git_checkout_from_branch_store ${@:5} git_checkout_from_branch_store ${@:6}
} }
git_checkout_from_branch_store() { git_checkout_from_branch_store() {
@ -159,7 +161,7 @@ git_checkout_from_branch_store() {
# fetch raw value # fetch raw value
log_info "Searching Redis branch-store for key : $key_value_pair_key" log_info "Searching Redis branch-store for key : $key_value_pair_key"
local raw local raw
raw=$(redis-cli -u "$redis_url" --raw HGETALL "$key_value_pair_key" | sed 's/\"//g') raw=$(redis-exec "$redis_url" --raw HGETALL "$key_value_pair_key" | sed 's/\"//g')
# error handling: empty or missing key # error handling: empty or missing key
if [[ -z "$raw" ]]; then if [[ -z "$raw" ]]; then
@ -253,3 +255,94 @@ git_merge_branch() {
git -C "$target_folder" checkout "$destination_branch" git -C "$target_folder" checkout "$destination_branch"
git -C "$target_folder" merge "$source_branch" --strategy=recursive --allow-unrelated-histories --no-edit git -C "$target_folder" merge "$source_branch" --strategy=recursive --allow-unrelated-histories --no-edit
} }
# Redis CLI wrapper that handles different URL schemes
# Usage: redis-exec <redis-url> [redis-cli-args...]
# Supports: redis://, rediss://, redis-cluster://
redis-exec() {
local url="$1"
if [[ -z "$url" ]]; then
log_error "redis-exec: missing Redis URL"
log_error "Usage: redis-exec <redis-url> [redis-cli-args...]"
return 1
fi
case "$url" in
redis://*|rediss://*)
# Standard Redis URL - pass directly to redis-cli -u
redis-cli -u "$url" "${@:2}"
;;
redis-cluster://*)
# Cluster URL - extract components and use cluster mode
local stripped="${url#redis-cluster://}"
# Split into authority and path parts
local authority="${stripped%%/*}"
local path_part="${stripped#*/}"
if [[ "$path_part" == "$stripped" ]]; then
path_part="" # No path present
fi
# Extract credentials from authority (user:pass@host:port)
local credentials=""
local host_port="$authority"
if [[ "$authority" == *"@"* ]]; then
credentials="${authority%%@*}"
host_port="${authority##*@}"
fi
# Parse credentials
local username=""
local password=""
if [[ -n "$credentials" ]]; then
if [[ "$credentials" == *":"* ]]; then
username="${credentials%%:*}"
password="${credentials##*:}"
else
password="$credentials" # Only password provided
fi
fi
# Extract host and port
local host="${host_port%:*}"
local port="${host_port##*:}"
# If no port specified, default to 6379
if [[ "$port" == "$host" ]]; then
port="6379"
fi
# Extract database number from path
local database=""
if [[ -n "$path_part" && "$path_part" =~ ^[0-9]+(\?.*)?$ ]]; then
database="${path_part%%\?*}" # Remove query params if present
fi
# Build redis-cli command
local cmd_args=("-c" "-h" "$host" "-p" "$port")
# Add authentication if present
if [[ -n "$username" && -n "$password" ]]; then
cmd_args+=("--user" "$username" "--pass" "$password")
elif [[ -n "$password" ]]; then
cmd_args+=("-a" "$password")
fi
# Add database selection if specified
if [[ -n "$database" ]]; then
cmd_args+=("-n" "$database")
fi
# Add remaining arguments
cmd_args+=("${@:2}")
redis-cli "${cmd_args[@]}"
;;
*)
log_error "redis-exec: unsupported URL scheme: $url"
log_error "Supported schemes: redis://, rediss://, redis-cluster://"
return 1
;;
esac
}

View File

@ -572,6 +572,7 @@ public class GitRouteAspect {
ctx.getGitProfile().getAuthorName(), ctx.getGitProfile().getAuthorName(),
ctx.getGitKey(), ctx.getGitKey(),
ctx.getGitMeta().getRemoteUrl(), ctx.getGitMeta().getRemoteUrl(),
gitServiceConfig.getGitRootPath(),
ctx.getRepoPath(), ctx.getRepoPath(),
redisUrl, redisUrl,
ctx.getBranchStoreKey()); ctx.getBranchStoreKey());