From 7334bd587a43d35854a6fbc184cb9062a705c98a Mon Sep 17 00:00:00 2001 From: Claude <4+claude@noreply.git.ihre-ideenfabrik.de> Date: Mon, 27 Apr 2026 17:29:24 +0000 Subject: [PATCH] feat(deploy-rsync): Reusable Workflow fuer rsync-Deploys via SSH Wiederverwendbare Action fuer alle IDF-Repos, die per rsync auf einen Plesk-Server deployen wollen (Flow, Apps, kuenftig weitere). Inputs: ssh_host, ssh_user, deploy_path, optional ref + extra_excludes. Secret: SSH_PRIVATE_KEY (im Caller-Repo zu hinterlegen). Standard-Excludes: .git/, .gitea/, .gitignore, CHANGELOG.md, README.md. --- .gitea/workflows/deploy-rsync.yml | 114 ++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 .gitea/workflows/deploy-rsync.yml diff --git a/.gitea/workflows/deploy-rsync.yml b/.gitea/workflows/deploy-rsync.yml new file mode 100644 index 0000000..e1dbdca --- /dev/null +++ b/.gitea/workflows/deploy-rsync.yml @@ -0,0 +1,114 @@ +name: Reusable Deploy via rsync + +# Wiederverwendbarer Deploy-Workflow fuer IDF-Projekte. +# Repository-Pfad: ideenfabrik/idf-ci/.gitea/workflows/deploy-rsync.yml +# +# Aufruf aus einem Caller-Repo: +# +# jobs: +# deploy: +# uses: ideenfabrik/idf-ci/.gitea/workflows/deploy-rsync.yml@v1 +# with: +# ssh_host: ${{ vars.SSH_HOST }} +# ssh_user: ${{ vars.SSH_USER }} +# deploy_path: ${{ vars.DEPLOY_PATH }} +# ref: ${{ github.event.inputs.ref || github.ref }} +# extra_excludes: | +# kiosk-config.php +# kiosk-config.example.php +# secrets: inherit +# +# Caller-Repo muss hinterlegen: +# Secret SSH_PRIVATE_KEY private Key fuer den Deploy-User +# Variable SSH_HOST Host/IP des Live-Servers +# Variable SSH_USER SSH-Login-User +# Variable DEPLOY_PATH Zielpfad auf dem Server + +on: + workflow_call: + inputs: + ssh_host: + required: true + type: string + description: 'Ziel-Host fuer rsync ueber SSH' + ssh_user: + required: true + type: string + description: 'SSH-Login-User' + deploy_path: + required: true + type: string + description: 'Zielpfad auf dem Server' + ref: + required: false + type: string + default: '' + description: 'Branch/Tag zum Deployen (default: github.ref)' + extra_excludes: + required: false + type: string + default: '' + description: 'Zusaetzliche rsync --exclude Patterns, eine pro Zeile' + secrets: + SSH_PRIVATE_KEY: + required: true + +jobs: + deploy: + runs-on: self-hosted + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref || github.ref }} + + - name: Verify rsync + ssh available + run: | + command -v rsync >/dev/null || { echo "::error::rsync ist auf dem Runner nicht installiert"; exit 1; } + command -v ssh >/dev/null || { echo "::error::ssh ist auf dem Runner nicht installiert"; exit 1; } + rsync --version | head -1 + ssh -V + + - name: Setup SSH key + run: | + mkdir -p ~/.ssh + chmod 700 ~/.ssh + KEY_FILE="$HOME/.ssh/id_ed25519_deploy_${{ github.run_id }}" + printf '%s\n' "${{ secrets.SSH_PRIVATE_KEY }}" > "$KEY_FILE" + chmod 600 "$KEY_FILE" + echo "DEPLOY_KEY_FILE=$KEY_FILE" >> "$GITHUB_ENV" + ssh-keyscan -H "${{ inputs.ssh_host }}" >> ~/.ssh/known_hosts 2>/dev/null + + - name: Deploy via rsync + env: + EXTRA_EXCLUDES: ${{ inputs.extra_excludes }} + run: | + # Standard-Excludes -- gilt fuer alle Deploys + BASE_EXCLUDES=( + --exclude='.git/' + --exclude='.gitea/' + --exclude='.gitignore' + --exclude='CHANGELOG.md' + --exclude='README.md' + ) + + # Caller-spezifische Excludes (multiline -> array) + EXTRA=() + while IFS= read -r line; do + line="${line#"${line%%[![:space:]]*}"}" + line="${line%"${line##*[![:space:]]}"}" + [ -n "$line" ] && EXTRA+=( "--exclude=$line" ) + done <<<"$EXTRA_EXCLUDES" + + rsync -avz "${BASE_EXCLUDES[@]}" "${EXTRA[@]}" \ + -e "ssh -i $DEPLOY_KEY_FILE -o StrictHostKeyChecking=yes" \ + ./ \ + "${{ inputs.ssh_user }}@${{ inputs.ssh_host }}:${{ inputs.deploy_path }}/" + + - name: Cleanup deploy key + if: always() + run: rm -f "$DEPLOY_KEY_FILE" + + - name: Done + run: | + echo "Deployed ${{ github.ref_name }} to ${{ inputs.deploy_path }} on ${{ inputs.ssh_host }}"