diff --git a/do-rsync/action.yml b/do-rsync/action.yml new file mode 100644 index 0000000..206aac0 --- /dev/null +++ b/do-rsync/action.yml @@ -0,0 +1,121 @@ +name: rsync 동기화 +description: rsync를 설치하고 로컬 디렉터리를 원격 서버로 동기화 + +inputs: + host: + required: true + description: 원격 서버 호스트 + port: + required: false + default: "22" + description: SSH 포트 + user: + required: true + description: SSH 사용자 + key-path: + required: false + default: "" + description: SSH 개인키 경로 (비어있으면 ~/.ssh/deploy_key) + source: + required: false + default: "./" + description: 동기화할 로컬 경로 + target: + required: true + description: 원격 대상 경로 + options: + required: false + default: "-az --delete" + description: rsync 옵션 + excludes: + required: false + default: "" + description: 추가 제외 패턴 (한 줄에 하나씩) + default-excludes: + required: false + default: "true" + description: 기본 제외 패턴 사용 여부 (.git/, .gitea/, .env*, .DS_Store, README.md, CLAUDE.md, *.ori|origin|bak|back) + +runs: + using: composite + steps: + - name: rsync 설치 + shell: bash + run: | + set -eu + + # rsync가 이미 설치되어 있으면 건너뜁니다. + if command -v rsync >/dev/null 2>&1; then + exit 0 + fi + + # 패키지 매니저에 따라 rsync를 설치합니다. + if command -v apt-get >/dev/null 2>&1; then + apt-get update + apt-get install -y rsync + elif command -v apk >/dev/null 2>&1; then + apk add --no-cache rsync + elif command -v yum >/dev/null 2>&1; then + yum install -y rsync + else + echo "rsync install failed: unsupported runner image" + exit 1 + fi + + - name: 파일 동기화 + shell: bash + env: + DEPLOY_HOST: ${{ inputs.host }} + DEPLOY_PORT: ${{ inputs.port }} + DEPLOY_USER: ${{ inputs.user }} + KEY_PATH_INPUT: ${{ inputs.key-path }} + SOURCE_PATH: ${{ inputs.source }} + TARGET_PATH: ${{ inputs.target }} + RSYNC_OPTIONS: ${{ inputs.options }} + USER_EXCLUDES: ${{ inputs.excludes }} + USE_DEFAULT_EXCLUDES: ${{ inputs.default-excludes }} + run: | + set -eu + + # SSH 키 경로 설정 (입력값이 없으면 기본값 사용) + KEY_PATH="$KEY_PATH_INPUT" + if [ -z "$KEY_PATH" ]; then + KEY_PATH="$HOME/.ssh/deploy_key" + fi + + EXCLUDE_ARGS=() + + # 기본 제외 패턴 추가 + if [ "$USE_DEFAULT_EXCLUDES" = "true" ]; then + for pattern in \ + ".git/" \ + ".gitea/" \ + ".claude/" \ + ".DS_Store" \ + "README.md" \ + "CLAUDE.md" \ + "*.ori" \ + "*.origin" \ + "*.bak" \ + "*.back" + do + EXCLUDE_ARGS+=(--exclude "$pattern") + done + fi + + # 사용자 지정 제외 패턴 추가 + if [ -n "$USER_EXCLUDES" ]; then + while IFS= read -r pattern; do + pattern="${pattern#"${pattern%%[![:space:]]*}"}" + pattern="${pattern%"${pattern##*[![:space:]]}"}" + [ -z "$pattern" ] && continue + EXCLUDE_ARGS+=(--exclude "$pattern") + done <<< "$USER_EXCLUDES" + fi + + # shellcheck disable=SC2086 + rsync $RSYNC_OPTIONS \ + -e "ssh -i $KEY_PATH -p $DEPLOY_PORT -o IdentitiesOnly=yes" \ + --rsync-path="rsync" \ + "${EXCLUDE_ARGS[@]+"${EXCLUDE_ARGS[@]}"}" \ + "$SOURCE_PATH" "$DEPLOY_USER@$DEPLOY_HOST:$TARGET_PATH"