#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" TARGET_HOST="${SYNC_TARGET_HOST:-devone.aplikasi.web.id}" REMOTE_USER="${SYNC_REMOTE_USER:-one}" REMOTE_PATH="${SYNC_REMOTE_PATH:-/home/one/project/one/one-api-lab/}" PRIVATE_KEY_PATH="${SYNC_PRIVATE_KEY_PATH:-/Users/fajrihardhitamurti/id_rsa}" STATE_FILE="${SYNC_STATE_FILE:-$ROOT_DIR/.git/devone-last-synced-head}" MODE="${1:-commit}" log() { printf '[devone-sync] %s\n' "$*" } fail() { printf '[devone-sync] %s\n' "$*" >&2 exit 1 } if ! git -C "$ROOT_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then exit 0 fi branch="$(git -C "$ROOT_DIR" symbolic-ref --quiet --short HEAD 2>/dev/null || true)" if [[ "$branch" != "main" ]]; then exit 0 fi [[ -f "$PRIVATE_KEY_PATH" ]] || fail "Private key not found: $PRIVATE_KEY_PATH" current_head="$(git -C "$ROOT_DIR" rev-parse HEAD)" if [[ -f "$STATE_FILE" ]] && [[ "$(cat "$STATE_FILE")" == "$current_head" ]]; then exit 0 fi tmpdir="$(mktemp -d)" trap 'rm -rf "$tmpdir"' EXIT changed_list="$tmpdir/changed-files.z" skipped_list="$tmpdir/skipped-files.txt" case "$MODE" in commit) git -C "$ROOT_DIR" diff-tree --no-commit-id --root --diff-filter=ACM --name-only -r -z HEAD > "$changed_list" git -C "$ROOT_DIR" diff-tree --no-commit-id --root --diff-filter=DR --summary -r HEAD > "$skipped_list" || true ;; merge) if git -C "$ROOT_DIR" rev-parse -q --verify ORIG_HEAD >/dev/null 2>&1; then git -C "$ROOT_DIR" diff --diff-filter=ACM -z --name-only ORIG_HEAD HEAD > "$changed_list" git -C "$ROOT_DIR" diff --diff-filter=DR --summary ORIG_HEAD HEAD > "$skipped_list" || true else git -C "$ROOT_DIR" diff-tree --no-commit-id --root --diff-filter=ACM -r -z HEAD > "$changed_list" git -C "$ROOT_DIR" diff-tree --no-commit-id --root --diff-filter=DR --summary -r HEAD > "$skipped_list" || true fi ;; *) fail "Unknown mode: $MODE" ;; esac if [[ ! -s "$changed_list" ]]; then if [[ -s "$skipped_list" ]]; then log "Skipping delete/rename changes for devone sync:" sed 's/^/[devone-sync] /' "$skipped_list" fi printf '%s\n' "$current_head" > "$STATE_FILE" exit 0 fi SSH_CMD="ssh -i $PRIVATE_KEY_PATH -o BatchMode=yes -o StrictHostKeyChecking=accept-new" destination="${REMOTE_USER}@${TARGET_HOST}:${REMOTE_PATH%/}/" log "Syncing changed files to $destination" if rsync -az --from0 --files-from="$changed_list" --relative --progress --human-readable --exclude='.git/' --exclude='.DS_Store' -e "$SSH_CMD" "$ROOT_DIR/" "$destination"; then printf '%s\n' "$current_head" > "$STATE_FILE" if [[ -s "$skipped_list" ]]; then log "Skipped delete/rename changes for devone sync:" sed 's/^/[devone-sync] /' "$skipped_list" fi log "Done: $current_head" else fail "Sync failed" fi