# Copyright (C) 2026 Moko Consulting # SPDX-License-Identifier: GPL-3.0-or-later # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: MokoStandards-API.Deployment # REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API # PATH: /templates/workflows/shared/pull-from-dev.yml.template # VERSION: 04.06.12 # BRIEF: Download files from dev server into repo src/ directory name: Pull from Dev Server on: workflow_dispatch: inputs: remote_path: description: 'Remote path to download (overrides DEV_PULL_PATH variable)' required: false type: string default: '' target_dir: description: 'Local directory to save to' required: false type: string default: 'src' branch: description: 'Branch to commit to' required: false type: string default: 'dev' dry_run: description: 'Preview only (no commit)' required: false type: boolean default: true # ────────────────────────────────────────────────────────────── # Required secrets and variables: # # SECRETS (org or repo level): # DEV_SSH_KEY — SSH private key for dev server access # DEV_SSH_PASSWORD — OR password auth (if not using key) # # VARIABLES (org or repo level): # DEV_SSH_HOST — Dev server hostname (e.g., dev.mokoconsulting.tech) # DEV_SSH_PORT — SSH port (default: 22) # DEV_SSH_USERNAME — SSH user # DEV_PULL_PATH — Remote path to download (e.g., /var/www/html/plugins/system/mokojoomtos) # ────────────────────────────────────────────────────────────── permissions: contents: write jobs: pull-from-dev: name: Pull from Dev Server runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 with: ref: ${{ inputs.branch }} - name: Validate configuration run: | MISSING="" [ -z "${{ vars.DEV_SSH_HOST }}" ] && MISSING="${MISSING} DEV_SSH_HOST" [ -z "${{ vars.DEV_SSH_USERNAME }}" ] && MISSING="${MISSING} DEV_SSH_USERNAME" REMOTE="${{ inputs.remote_path || vars.DEV_PULL_PATH }}" [ -z "$REMOTE" ] && MISSING="${MISSING} DEV_PULL_PATH" if [ -n "$MISSING" ]; then echo "ERROR: Missing required variables:${MISSING}" echo "Set these as org or repo variables in Gitea Actions settings." exit 1 fi echo "remote_path=${REMOTE}" >> $GITHUB_OUTPUT echo "Config OK — pulling from ${{ vars.DEV_SSH_USERNAME }}@${{ vars.DEV_SSH_HOST }}:${REMOTE}" id: config - name: Setup SSH run: | mkdir -p ~/.ssh chmod 700 ~/.ssh if [ -n "${{ secrets.DEV_SSH_KEY }}" ]; then echo "${{ secrets.DEV_SSH_KEY }}" > ~/.ssh/dev_key chmod 600 ~/.ssh/dev_key echo "Auth: SSH key" else echo "Auth: password (sshpass)" sudo apt-get install -y sshpass -qq fi # Disable host key checking for automation echo "Host *" > ~/.ssh/config echo " StrictHostKeyChecking no" >> ~/.ssh/config echo " UserKnownHostsFile /dev/null" >> ~/.ssh/config chmod 600 ~/.ssh/config - name: Download from dev server id: download run: | HOST="${{ vars.DEV_SSH_HOST }}" PORT="${{ vars.DEV_SSH_PORT || '22' }}" USER="${{ vars.DEV_SSH_USERNAME }}" REMOTE="${{ steps.config.outputs.remote_path }}" LOCAL="${{ inputs.target_dir }}" echo "Downloading: ${USER}@${HOST}:${REMOTE} → ${LOCAL}/" # Build rsync command SSH_CMD="ssh -p ${PORT}" if [ -f ~/.ssh/dev_key ]; then SSH_CMD="${SSH_CMD} -i ~/.ssh/dev_key" fi # Rsync from remote to local (mirror mode, delete extra local files) rsync -avz --delete \ -e "${SSH_CMD}" \ "${USER}@${HOST}:${REMOTE}/" \ "${LOCAL}/" \ --exclude='.git' \ --exclude='.gitignore' \ --exclude='node_modules' \ --exclude='vendor' \ --exclude='cache' \ --exclude='tmp' \ --exclude='log' \ 2>&1 | tee /tmp/rsync.log CHANGED=$(git status --porcelain "${LOCAL}/" | wc -l) echo "changed=${CHANGED}" >> $GITHUB_OUTPUT echo "Files changed: ${CHANGED}" - name: Show diff if: steps.download.outputs.changed != '0' run: | echo "=== Changed files ===" git status --short "${{ inputs.target_dir }}/" echo "" echo "=== Diff summary ===" git diff --stat "${{ inputs.target_dir }}/" - name: Commit and push if: steps.download.outputs.changed != '0' && inputs.dry_run != true run: | git config user.name "gitea-actions[bot]" git config user.email "gitea-actions[bot]@noreply.git.mokoconsulting.tech" git add "${{ inputs.target_dir }}/" git commit -m "chore(sync): pull latest from dev server Source: ${{ vars.DEV_SSH_USERNAME }}@${{ vars.DEV_SSH_HOST }}:${{ steps.config.outputs.remote_path }} Files changed: ${{ steps.download.outputs.changed }} Triggered by: ${{ gitea.actor }}" git push origin ${{ inputs.branch }} echo "Pushed to ${{ inputs.branch }}" - name: Summary run: | echo "## Pull from Dev Server" echo "" if [ "${{ inputs.dry_run }}" = "true" ]; then echo "**DRY RUN** — no changes committed" fi echo "- Source: \`${{ vars.DEV_SSH_USERNAME }}@${{ vars.DEV_SSH_HOST }}:${{ steps.config.outputs.remote_path }}\`" echo "- Target: \`${{ inputs.target_dir }}/\`" echo "- Changed files: ${{ steps.download.outputs.changed }}" - name: Cleanup if: always() run: rm -f ~/.ssh/dev_key