Web Development

WordPress Deploy Workflow con Git

Guida completa al deploy automatico di WordPress custom themes con GitHub Actions, SSH e rsync

WordPress Custom Theme: Deploy Workflow con GitHub Actions

Setup Guidato Step-by-Step

Last edited: February 5, 2026


πŸ“‹ Indice

  1. Setup Iniziale Progetto
  2. Configurazione Git e GitHub
  3. Setup SSH e Secrets
  4. Deploy Automatico DEV (Staging)
  5. Deploy Automatico PROD
  6. Workflow Quotidiano
  7. Troubleshooting

1. Setup Iniziale Progetto

1.1 Clona Starter Template in Local

Prerequisito: Hai giΓ  WordPress installato in Local by Flywheel

# Vai nella cartella themes del tuo WordPress locale
cd ~/Local\ Sites/nomesito/app/public/wp-content/themes/

# Clona lo starter template
git clone https://github.com/LoudAgency/starter-template-wp.git nome-tema-custom

# Entra nella cartella
cd nome-tema-custom

# Rimuovi la connessione al repository template
rm -rf .git

1.2 Personalizza il Tema

Modifica style.css con info del cliente:

nano style.css
/*
Theme Name: Nome Tema Cliente
Theme URI: https://sitocliente.com
Author: Loud Agency
Author URI: https://loud-agency.info
Description: Tema custom per Cliente XYZ
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: nome-tema-cliente
*/

Attiva il tema in WordPress:

# Vai su: http://nomesito.local/wp-admin
# Aspetto β†’ Temi β†’ Attiva "Nome Tema Cliente"

1.3 Setup Ambiente DEV (Staging) su Server

Crea directory e configurazione DEV:

# Connetti al server
ssh loudy@93.186.247.130

# Crea directory per ambiente DEV
mkdir -p /home/loudy/dev.loud-agency.info/nomesito/wp-content/themes/nome-tema-custom

# Crea wp-config.php per DEV (se necessario)
# Database DEV separato da PROD

Verifica path completo tema su DEV:

/home/loudy/dev.loud-agency.info/nomesito/wp-content/themes/nome-tema-custom/

1.4 Setup Ambiente PROD su Server

Verifica path tema su PROD:

# Connetti al server
ssh loudy@93.186.247.130

# Verifica path PROD
ls -la /home/loudy/public_html/nomesito/wp-content/themes/

# Path completo tema PROD:
/home/loudy/public_html/nomesito/wp-content/themes/nome-tema-custom/

Se tema non esiste ancora su PROD, crealo:

# Crea cartella tema vuota (sarΓ  popolata al primo deploy)
mkdir -p /home/loudy/public_html/nomesito/wp-content/themes/nome-tema-custom

2. Configurazione Git e GitHub

2.1 Inizializza Git nel Tema

# Vai nella cartella del tema (NON root WordPress)
cd ~/Local\ Sites/nomesito/app/public/wp-content/themes/nome-tema-custom/

# Inizializza Git
git init

# Crea branch staging (sviluppo)
git checkout -b staging

2.2 Crea .gitignore nel Tema

# Nella cartella del tema
cat > .gitignore << 'EOF'
# Dependencies
node_modules/

# Build artifacts (se usi framework CSS)
css/frameworks/*/output.css
css/frameworks/*/*.min.css
css/frameworks/*/*.map

# Development files
css.backup/
docs/
CLAUDE.md
*.md~

# MacOS
.DS_Store
.AppleDouble
.LSOverride
._*

# IDE
.vscode/
.idea/
*.sublime-*

# Logs
*.log

# Environment
.env
.env.local

# Temporary
*.tmp
*.temp
*.swp
*~
EOF

2.3 Crea Repository GitHub

Step 1: Vai su https://github.com/new

Step 2: Configurazione repository

Repository name: nome-tema-custom
Description: WordPress Custom Theme - Deploy automation
Visibility: πŸ”’ Private

❌ NON aggiungere README
❌ NON aggiungere .gitignore
❌ NON aggiungere license

Step 3: Clicca "Create repository"


2.4 Collega Tema a GitHub

# Nella cartella del tema
cd ~/Local\ Sites/nomesito/app/public/wp-content/themes/nome-tema-custom/

# Aggiungi remote GitHub
git remote add origin git@github.com:LoudAgency/nome-tema-custom.git

# Primo commit
git add .
git commit -m "chore: initial commit"

# Push su staging
git push -u origin staging

# Crea branch main (per PROD)
git checkout -b main
git push -u origin main

# Torna su staging per sviluppo
git checkout staging

Verifica setup:

git remote -v
# origin  git@github.com:LoudAgency/nome-tema-custom.git (fetch)
# origin  git@github.com:LoudAgency/nome-tema-custom.git (push)

git branch
# * staging
#   main

3. Setup SSH e Secrets

3.1 Genera Chiave SSH

# Genera chiave SSH per deploy
ssh-keygen -t ed25519 -C "deploy-loudy" -f ~/.ssh/loudy-deploy -N ""

# Mostra chiave pubblica
cat ~/.ssh/loudy-deploy.pub

3.2 Aggiungi Chiave al Server

Metodo raccomandato:

# Copia chiave su server
ssh-copy-id -i ~/.ssh/loudy-deploy.pub loudy@93.186.247.130

Test chiave:

ssh -i ~/.ssh/loudy-deploy loudy@93.186.247.130 "echo 'SSH OK'"
# Output: SSH OK βœ…

3.3 Configura SSH Config (Opzionale)

# Apri/crea file config
nano ~/.ssh/config

Aggiungi:

Host loudy
  HostName 93.186.247.130
  User loudy
  IdentityFile ~/.ssh/loudy-deploy
  StrictHostKeyChecking no
  ServerAliveInterval 60

Fix permessi:

chmod 600 ~/.ssh/config

3.4 Configura GitHub Secrets

Step 1: Ottieni chiave privata

cat ~/.ssh/loudy-deploy
# Copia TUTTO (da -----BEGIN a -----END inclusi)

Step 2: Vai su GitHub Secrets

https://github.com/LoudAgency/nome-tema-custom/settings/secrets/actions

Step 3: Crea 3 Secrets per DEV

NameValue
SSH_HOST_DEV93.186.247.130
SSH_USER_DEVloudy
SSH_KEY_DEVContenuto completo di ~/.ssh/loudy-deploy

3.5 Crea 3 Secrets per PROD

NameValue
SSH_HOST_PROD93.186.247.130 (o IP server cliente)
SSH_USER_PRODloudy (o user server cliente)
SSH_KEY_PRODStesso contenuto di SSH_KEY_DEV se stesso server

4. Deploy Automatico DEV (Staging)

4.1 Crea Cartella Workflows

# Nella cartella del tema
cd ~/Local\ Sites/nomesito/app/public/wp-content/themes/nome-tema-custom/

mkdir -p .github/workflows

4.2 Crea File deploy-staging.yml

nano .github/workflows/deploy-staging.yml

Contenuto file:

name: Deploy to Staging

on:
  push:
    branches:
      - staging
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup SSH
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_KEY_DEV }}" > ~/.ssh/deploy_key
          chmod 600 ~/.ssh/deploy_key
          ssh-keyscan -H ${{ secrets.SSH_HOST_DEV }} >> ~/.ssh/known_hosts

      - name: Clean unwanted files on STAGING
        run: |
          ssh -i ~/.ssh/deploy_key \
            ${{ secrets.SSH_USER_DEV }}@${{ secrets.SSH_HOST_DEV }} \
            "cd $REMOTE_PATH_DEV && \
             rm -rf .git .gitignore node_modules docs css.backup .github CLAUDE.md .DS_Store package-lock.json package.json"
        env:
          REMOTE_PATH_DEV: /home/loudy/dev.loud-agency.info/nomesito/wp-content/themes/nome-tema-custom

      - name: Deploy theme to STAGING
        run: |
          rsync -avz --delete \
            --exclude='.git' \
            --exclude='.gitignore' \
            --exclude='node_modules' \
            --exclude='css.backup' \
            --exclude='docs' \
            --exclude='.DS_Store' \
            --exclude='CLAUDE.md' \
            --exclude='.github' \
            --exclude='package.json' \
            --exclude='package-lock.json' \
            -e "ssh -i ~/.ssh/deploy_key -p 22 -o StrictHostKeyChecking=no" \
            ./ \
            ${{ secrets.SSH_USER_DEV }}@${{ secrets.SSH_HOST_DEV }}:$REMOTE_PATH_DEV/
        env:
          REMOTE_PATH_DEV: /home/loudy/dev.loud-agency.info/nomesito/wp-content/themes/nome-tema-custom

      - name: Clear PHP opcode cache
        run: |
          ssh -i ~/.ssh/deploy_key \
            ${{ secrets.SSH_USER_DEV }}@${{ secrets.SSH_HOST_DEV }} \
            "find $REMOTE_PATH_DEV -name '*.php' -exec touch {} \;"

          echo "βœ… Deploy to STAGING completed at $(date)"
          echo "πŸ”— https://dev.loud-agency.info/nomesito/"
        env:
          REMOTE_PATH_DEV: /home/loudy/dev.loud-agency.info/nomesito/wp-content/themes/nome-tema-custom

⚠️ IMPORTANTE: Modifica la variabile REMOTE_PATH_DEV con il tuo path reale


4.3 Commit e Push Workflow

git add .github/workflows/deploy-staging.yml
git commit -m "ci: add staging deployment workflow"
git push origin staging

4.4 Verifica Deploy

Step 1: Vai su GitHub Actions

https://github.com/LoudAgency/nome-tema-custom/actions

Step 2: Verifica workflow completato (βœ…)

Step 3: Test sito DEV

https://dev.loud-agency.info/nomesito/

5. Deploy Automatico PROD

5.1 Crea File deploy-production.yml

# Nella cartella del tema
nano .github/workflows/deploy-production.yml

Contenuto file:

name: Deploy to Production

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup SSH
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_KEY_PROD }}" > ~/.ssh/deploy_key
          chmod 600 ~/.ssh/deploy_key
          ssh-keyscan -H ${{ secrets.SSH_HOST_PROD }} >> ~/.ssh/known_hosts

      - name: Clean unwanted files on PRODUCTION
        run: |
          ssh -i ~/.ssh/deploy_key \
            ${{ secrets.SSH_USER_PROD }}@${{ secrets.SSH_HOST_PROD }} \
            "cd $REMOTE_PATH_PROD && \
             rm -rf .git .gitignore node_modules docs css.backup .github CLAUDE.md .DS_Store package-lock.json package.json"
        env:
          REMOTE_PATH_PROD: /home/loudy/public_html/nomesito/wp-content/themes/nome-tema-custom

      - name: Deploy theme to PRODUCTION
        run: |
          rsync -avz --delete \
            --exclude='.git' \
            --exclude='.gitignore' \
            --exclude='node_modules' \
            --exclude='css.backup' \
            --exclude='docs' \
            --exclude='.DS_Store' \
            --exclude='CLAUDE.md' \
            --exclude='.github' \
            --exclude='package.json' \
            --exclude='package-lock.json' \
            -e "ssh -i ~/.ssh/deploy_key -p 22 -o StrictHostKeyChecking=no" \
            ./ \
            ${{ secrets.SSH_USER_PROD }}@${{ secrets.SSH_HOST_PROD }}:$REMOTE_PATH_PROD/
        env:
          REMOTE_PATH_PROD: /home/loudy/public_html/nomesito/wp-content/themes/nome-tema-custom

      - name: Clear PHP opcode cache
        run: |
          ssh -i ~/.ssh/deploy_key \
            ${{ secrets.SSH_USER_PROD }}@${{ secrets.SSH_HOST_PROD }} \
            "find $REMOTE_PATH_PROD -name '*.php' -exec touch {} \;"

          echo "πŸŽ‰ PRODUCTION DEPLOYMENT SUCCESSFUL"
          echo "⏰ Deployed at: $(date)"
          echo "πŸ”— https://nomesito.com/"
        env:
          REMOTE_PATH_PROD: /home/loudy/public_html/nomesito/wp-content/themes/nome-tema-custom

⚠️ IMPORTANTE: Modifica la variabile REMOTE_PATH_PROD con il tuo path reale


5.2 Commit Workflow (Ma NON Deploy Ancora!)

# Assicurati di essere su staging
git checkout staging

# Commit workflow
git add .github/workflows/deploy-production.yml
git commit -m "ci: add production deployment workflow"
git push origin staging

⚠️ NON fare merge in main ancora! Prima testa bene su DEV.


5.3 Quando Pronto per PROD

# Dopo test approfonditi su DEV:

# 1. Merge staging β†’ main
git checkout main
git pull origin main
git merge staging

# 2. Verifica cosa stai deployando
git log --oneline -5

# 3. Deploy in PRODUZIONE
git push origin main

# ⚠️ Questo deploya automaticamente in PROD!

# 4. Verifica sito PROD
# Apri: https://nomesito.com/
# CTRL+SHIFT+R (hard refresh)

# 5. Torna su staging per sviluppo
git checkout staging

6. Workflow Quotidiano

6.1 Sviluppo Feature Normale

# 1. Assicurati di essere su staging
cd ~/Local\ Sites/nomesito/app/public/wp-content/themes/nome-tema-custom/
git checkout staging
git pull origin staging

# 2. Sviluppa in Local
# Modifica file tema...

# 3. Test in Local
# http://nomesito.local

# 4. Commit modifiche
git add .
git commit -m "feat: nuova funzionalitΓ  X"

# 5. Push β†’ Deploy automatico su DEV
git push origin staging

# 6. Attendi 10-15 secondi

# 7. Verifica su DEV
# https://dev.loud-agency.info/nomesito/
# CTRL+SHIFT+R

# 8. Test con cliente/team su DEV

# 9. Se approvato β†’ Vai a 6.2 (Deploy PROD)

6.2 Deploy in Produzione

# Dopo test approfonditi su DEV:

# 1. Merge staging β†’ main
git checkout main
git pull origin main
git merge staging

# 2. Verifica merge
git log --oneline -5

# 3. Push β†’ Deploy automatico PROD
git push origin main

# ⚠️ ATTENZIONE: Deploy in PRODUZIONE!

# 4. Verifica PROD
# https://nomesito.com/
# CTRL+SHIFT+R

# 5. Monitor errori
# Testa funzionalitΓ  critiche

# 6. Torna su staging
git checkout staging

6.3 Hotfix Urgente in PROD

# 1. Crea branch da main
git checkout main
git pull origin main
git checkout -b hotfix/nome-fix

# 2. Fai fix in Local
# Modifica file necessari

# 3. Test Local

# 4. Commit
git add .
git commit -m "hotfix: correzione urgente X"

# 5. Merge in main
git checkout main
git merge hotfix/nome-fix

# 6. Deploy PROD
git push origin main

# 7. Merge anche in staging (importante!)
git checkout staging
git merge main
git push origin staging

# 8. Cleanup branch
git branch -d hotfix/nome-fix

6.4 Se Usi Node.js / SASS (Build Locale)

# IMPORTANTE: Buildi PRIMA di pushare

# 1. Sviluppa in Local

# 2. Build CSS/JS
npm run build  # o comando equivalente

# 3. Commit file buildati
git add css/style.css  # file di output
git commit -m "feat: nuova feature + build"

# 4. Push β†’ Deploy
git push origin staging

# βœ… Sul server arrivano file giΓ  buildati

7. Troubleshooting

7.1 GitHub Actions Fallisce

Diagnosi:

# 1. Vai su GitHub Actions log
# https://github.com/LoudAgency/nome-tema-custom/actions
# Click su workflow fallito β†’ Leggi errore

# 2. Test SSH manuale da locale
ssh -i ~/.ssh/loudy-deploy loudy@93.186.247.130 "echo 'SSH OK'"

# 3. Verifica permessi cartella tema su server
ssh loudy@93.186.247.130
ls -la /home/loudy/dev.loud-agency.info/nomesito/wp-content/themes/nome-tema-custom/

Fix comuni:

ErroreSoluzione
Permission denied (publickey)Verifica SSH_KEY_DEV in GitHub Secrets
No such file or directoryVerifica path in workflow YAML
rsync: command not foundInstalla rsync su server

7.2 Sito Rotto Dopo Deploy

Rollback immediato:

# Opzione A: Git revert (raccomandato)
git revert HEAD
git push origin staging  # o main se PROD

# Opzione B: Git reset (se NON hai ancora pushato)
git reset --hard HEAD~1

# Opzione C: Deploy commit precedente
git log --oneline -10  # trova hash commit buono
git checkout abc1234   # sostituisci con hash
git push origin staging --force  # ⚠️ usa con cautela

7.3 Conflitti Git Durante Merge

# Durante merge staging β†’ main

# 1. Git ti avvisa di conflitti
# CONFLICT (content): Merge conflict in style.css

# 2. Apri file in conflitto
code style.css

# 3. Cerca markers:
# <<<<<<< HEAD
# Codice su main
# =======
# Codice su staging
# >>>>>>> staging

# 4. Risolvi manualmente (scegli o combina codice)

# 5. Rimuovi markers

# 6. Commit risoluzione
git add style.css
git commit -m "fix: resolve merge conflicts"

7.4 GitHub Actions Non Si Attiva

Checklist:

# βœ… 1. Verifica Actions abilitato
# GitHub β†’ Settings β†’ Actions β†’ General
# Allow all actions

# βœ… 2. Verifica branch corretto nel workflow
# deploy-staging.yml β†’ branches: - staging
# deploy-production.yml β†’ branches: - main

# βœ… 3. Verifica path workflow
# File deve essere in: .github/workflows/deploy-staging.yml

# βœ… 4. Verifica YAML valido
# Usa: https://www.yamllint.com/

# βœ… 5. Test manual trigger
# GitHub β†’ Actions β†’ [Workflow name] β†’ Run workflow

7.5 File Indesiderati su Server

Cleanup manuale:

# Connetti al server
ssh loudy@93.186.247.130

# Vai nella cartella tema
cd /home/loudy/dev.loud-agency.info/nomesito/wp-content/themes/nome-tema-custom/

# Rimuovi file dev
rm -rf .git .gitignore node_modules docs .github CLAUDE.md package.json package-lock.json

7.6 CSS/JS Non Si Aggiorna Dopo Deploy

Soluzione:

# 1. Hard refresh browser
# CTRL+SHIFT+R (Windows/Linux)
# CMD+SHIFT+R (Mac)

# 2. Clear cache server (se caching attivo)
ssh loudy@93.186.247.130
# Varia in base al caching usato (WP Super Cache, W3 Total Cache, etc)

# 3. Verifica file buildato in Git
git status
# Assicurati che css/style.css sia committato

# 4. Verifica rsync ha trasferito file
ssh loudy@93.186.247.130
ls -lh /path/to/theme/css/style.css
# Controlla data modifica

πŸ“Š Riepilogo Architettura

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              PRODUZIONE (PROD)                       β”‚
β”‚  Server: loudy@93.186.247.130                       β”‚
β”‚  Path: /public_html/nomesito/wp-content/themes/... β”‚
β”‚  URL: https://nomesito.com                          β”‚
β”‚  Branch: main                                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β–²
                         β”‚ git push origin main
                         β”‚ (Deploy automatico via GitHub Actions)
                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              LOCAL (Sviluppo)                        β”‚
β”‚  Software: Local by Flywheel                        β”‚
β”‚  Path: ~/Local Sites/nomesito/.../themes/nome-tema β”‚
β”‚  URL: http://nomesito.local                         β”‚
β”‚  Branch: staging (dev) + main (release)            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
                         β”‚ git push origin staging
                         β”‚ (Deploy automatico via GitHub Actions)
                         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              DEV (Staging)                           β”‚
β”‚  Server: loudy@93.186.247.130                       β”‚
β”‚  Path: /dev.loud-agency.info/nomesito/wp-content/  β”‚
β”‚  URL: https://dev.loud-agency.info/nomesito        β”‚
β”‚  Branch: staging                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

         GitHub Repository (Private)
         ────────────────────────────
         staging β†’ Auto deploy DEV
         main β†’ Auto deploy PROD

βœ… Checklist Setup Completo

Prima di iniziare nuovo progetto, verifica:

☐ WordPress installato in Local by Flywheel
☐ Tema custom creato (cartella + style.css)
☐ Ambiente DEV configurato su server
☐ Ambiente PROD configurato su server (o verifica esistente)
☐ Git inizializzato nella cartella del tema
☐ .gitignore creato nel tema
☐ Repository GitHub creato (Private)
☐ Branch staging e main creati e pushati
☐ SSH key generata e aggiunta al server
☐ GitHub Secrets configurati (6 totali: DEV + PROD)
☐ File .github/workflows/deploy-staging.yml creato
☐ File .github/workflows/deploy-production.yml creato
☐ Test deploy su DEV completato con successo
☐ Path corretti nei workflow YAML (nome tema, directory server)

🎯 Comandi Rapidi

Deploy DEV (quotidiano):

git add .
git commit -m "feat: descrizione"
git push origin staging

Deploy PROD (dopo approvazione):

git checkout main
git merge staging
git push origin main
git checkout staging

Hotfix urgente:

git checkout main
git checkout -b hotfix/nome
# ... fix ...
git checkout main && git merge hotfix/nome
git push origin main
git checkout staging && git merge main && git push origin staging

Verifica stato:

git status
git log --oneline -5
git remote -v

πŸš€ Fine Setup

Sistema pronto per gestione professionale WordPress custom theme!

Ricorda:

  • Sviluppa sempre su staging
  • Testa sempre su DEV prima di PROD
  • Fai build locale prima di pushare (se usi Node.js/SASS)
  • Verifica GitHub Actions dopo ogni push

Guida creata da: Fabio Pantano - Loud Agency Ultimo aggiornamento: February 5, 2026