Skip to content

Instantly share code, notes, and snippets.

@webaxones
Last active August 31, 2024 21:48
Show Gist options
  • Save webaxones/54a9aee13bd9152e900ef30a0fcef3ed to your computer and use it in GitHub Desktop.
Save webaxones/54a9aee13bd9152e900ef30a0fcef3ed to your computer and use it in GitHub Desktop.
GitHub workflow to build a WordPress Bedrock site and deploy it to a shared server using SSH
# This GitHub workflow will build a WordPress Bedrock site and deploy it to a shared server (french one: O2Switch, but URLs can be adapted) using SSH
# Actions secrets are used to store sensitive information:
# - SSH_PRIVATE_KEY: The private key used to authenticate with the remote server
# - REMOTE_HOST: The hostname of the remote server
# - REMOTE_USER: The username used to authenticate with the remote server
# - REMOTE_PROD_TARGET: The path on the remote server where the site will be deployed to
# - REMOTE_PREPROD_TARGET: The path on the remote server where the site will be deployed to
# - URL_ENCODED_PASSWORD: The password used to authenticate with the remote server, URL encoded (e.g. using https://www.urlencoder.org/)
# Workflow triggers on pushes to the develop and master branches:
# - On the develop branch, the site is deployed to the preprod target
# - On the master branch, the site is deployed to the prod target
name: Build and Deploy
on:
push:
branches: [ develop, master ]
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Install composer dependencies
- id: build-php
name: "Install dependencies"
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
- run: composer install --prefer-dist --no-dev -o
# Get the public IP of the runner
- name: Public IP
id: ip
uses: haythem/public-ip@v1.3
# Whitelist the public IP of the runner on the remote server by adding it to the SSH whitelist and wait 65 seconds for the IP to be whitelisted
- shell: bash
run: |
curl -sX GET 'https://${{ secrets.REMOTE_USER }}:${{ secrets.URL_ENCODED_PASSWORD }}@${{ secrets.REMOTE_HOST }}:2083/frontend/o2switch/o2switch-ssh-whitelist/index.live.php' | fgrep 'index.live.php' | fgrep 'index.live.php?r=remove&address=' | cut -d '"' -f 2 | while read ipToRemove
do
curl -sX GET 'https://${{ secrets.REMOTE_USER }}:${{ secrets.URL_ENCODED_PASSWORD }}@${{ secrets.REMOTE_HOST }}:2083/frontend/o2switch/o2switch-ssh-whitelist/'$ipToRemove > /dev/null 2>&1
done
curl -X POST \
-d 'whitelist[address]=${{ steps.ip.outputs.ipv4 }}' \
-d 'whitelist[port]=22' \
'https://${{ secrets.REMOTE_USER }}:${{ secrets.URL_ENCODED_PASSWORD }}@${{ secrets.REMOTE_HOST }}:2083/frontend/o2switch/o2switch-ssh-whitelist/index.live.php?r=add' > /dev/null 2>&1
curl -sX GET 'https://${{ secrets.REMOTE_USER }}:${{ secrets.URL_ENCODED_PASSWORD }}@${{ secrets.REMOTE_HOST }}:2083/frontend/o2switch/o2switch-ssh-whitelist/index.live.php' | fgrep -q '${{ steps.ip.outputs.ipv4 }}' && echo "IP whitelisted"
sleep 65
# Deploy the develop branch to the preprod target
- name: 'Deploy on develop branch'
if: ${{ github.ref == 'refs/heads/develop' }}
uses: easingthemes/ssh-deploy@main
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
ARGS: "-rlgoDzvc -i --delete-after"
SOURCE: "./"
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
TARGET: ${{ secrets.REMOTE_PREPROD_TARGET }}
EXCLUDE: "/dist/, /node_modules/, ./auth.json"
SCRIPT_BEFORE: |
whoami
ls -al
SCRIPT_AFTER: |
whoami
ls -al
echo $RSYNC_STDOUT
# Deploy the master branch to the production target
- name: 'Deploy on master branch'
if: ${{ github.ref == 'refs/heads/master' }}
uses: easingthemes/ssh-deploy@main
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
ARGS: "-rlgoDzvc -i --delete-after"
SOURCE: "./"
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
TARGET: ${{ secrets.REMOTE_PROD_TARGET }}
EXCLUDE: "/dist/, /node_modules/, ./auth.json"
SCRIPT_BEFORE: |
whoami
ls -al
SCRIPT_AFTER: |
whoami
ls -al
echo $RSYNC_STDOUT
@madrzejewski
Copy link

Petite mise à jour de l'outil d'autorisation SSH dans le cPanel.

Supposant qu'on déclare ça avant de lancer les commandes :

SERVER="le-serveur.o2switch.net"
LOGIN="toto4242"
# Le mot de passe doit être urlencodé
# Version 1, si "JQ" installé : printf %s 'le mot de passe' | jq -sRr @uri
# Version 2, si PHP installé : php -r "echo urlencode('Le mot de passe');"
# Version 3, si OK avec un site tiers : https://www.urlencoder.org/fr/
PASSWORD='Le mot de passe'
ENDPOINT='frontend/o2switch/o2switch-ssh-whitelist/index.live.php'

Lister les adresses IP en liste blanche / récupérer son IP / obtenir le count des adresses déjà en WL

curl -sX GET "https://$LOGIN:$PASSWORD@$SERVER:2083/$ENDPOINT?r=list" | jq
{
  "success": true,
  "data": {
    "ip": "10.20.0.20",
    "list": [
      {
        "address": "1.2.3.4",
        "direction": "out",
        "port": 22,
        "updateDate": "21/08/2024"
      },
      {
        "address": "1.2.3.4",
        "direction": "in",
        "port": 22,
        "updateDate": "21/08/2024"
      },
      {
        "address": "2.3.4.5",
        "direction": "out",
        "port": 22,
        "updateDate": "21/08/2024"
      },
      {
        "address": "2.3.4.5",
        "direction": "in",
        "port": 22,
        "updateDate": "21/08/2024"
      },
      {
        "address": "2.2.2.2",
        "direction": "out",
        "port": 22,
        "updateDate": "29/08/2024"
      },
      {
        "address": "2.2.2.2",
        "direction": "in",
        "port": 22,
        "updateDate": "29/08/2024"
      }
    ],
    "count": 3
  }
}

Ajouter une adresse en liste blanche

Note importante : J'ai rendu l'appel bloquant, donc ça ne rend la main que lorsque le réglage est bien effectif dans le parefeu du serveur.
Ça signifie qu'il n'est plus nécessaire d'inclure un sleep 60 après l'appel.
J'ai raccourci le délai de prise en compte également, maintenant ça prend 7-8 secondes environs (contre 1 minute dans le pire des cas auparavant).

curl -sX POST -d 'whitelist[address]=3.3.3.3' -d 'whitelist[port]=22' "https://$LOGIN:$PASSWORD@$SERVER:2083/$ENDPOINT?r=add" | jq
{
  "success": true,
  "message": "L'autorisation a été ajoutée avec succès."
}

Supprimer une adresse IP de la liste blanche

Note : penser le faire pour le in & out sur la direction sinon ça ne décrémente pas le count.

curl -sX GET "https://$LOGIN:$PASSWORD@$SERVER:2083/$ENDPOINT?r=remove&address=1.2.3.4&direction=in&port=22" | jq
{
  "success": true,
  "message": "L'autorisation a été supprimée avec succès, elle sera effective d'ici quelques minutes (~5mins)."
}

@DamChtlv
Copy link

DamChtlv commented Aug 31, 2024

Merci @madrzejewski Trop cool ! Les temps de deploy réduit de moitié ✨
Je suis revenu dessus parce que depuis quelques jours mes deploy ne passaient plus 😅

Je me demande si il est possible de ton côté de gérer 2 params dans direction, par exemple : direction=in,out ça réduirait à un seul call :)

Sinon pour ceux qui passent par là, il faut modifier cette partie / step : # Whitelist the public IP of the runner ... par celle-ci :

# Whitelist the public IP of the runner on the remote server by adding it to the SSH whitelist and wait 65 seconds for the IP to be whitelisted
- name: Whitelist IP on hosting & delete github old ones (o2switch)
  shell: bash
  run: |
    ENDPOINT='frontend/o2switch/o2switch-ssh-whitelist/index.live.php'

    echo "Get actual whitelisted IPs..."
    UNIQUE_IPS=$(curl -sX GET "https://${{ secrets.REMOTE_USER }}:${{ secrets.URL_ENCODED_PASSWORD }}@${{ secrets.REMOTE_HOST }}:2083/$ENDPOINT?r=list" | jq -r '.data.list[] | .address' | sort -u)
    for address in $UNIQUE_IPS; do
      if [[ $address == "${{ secrets.IP_TO_KEEP }}" ]]; then
          echo "Keep this IP, go to the next..."
          continue
      fi
      echo "Delete this github IP: $address (in & out)"
      curl -sX GET "https://${{ secrets.REMOTE_USER }}:${{ secrets.URL_ENCODED_PASSWORD }}@${{ secrets.REMOTE_HOST }}:2083/$ENDPOINT?r=remove&address=$address&direction=in&port=22" | jq
      sleep 3
      curl -sX GET "https://${{ secrets.REMOTE_USER }}:${{ secrets.URL_ENCODED_PASSWORD }}@${{ secrets.REMOTE_HOST }}:2083/$ENDPOINT?r=remove&address=$address&direction=out&port=22" | jq
      sleep 3
    done
    echo "All non-whitelisted IPs deleted!"

    echo "Attempt to whitelist IP..."
    curl -sX POST -d 'whitelist[address]=${{ steps.ip.outputs.ipv4 }}' -d 'whitelist[port]=22' "https://${{ secrets.REMOTE_USER }}:${{ secrets.URL_ENCODED_PASSWORD }}@${{ secrets.REMOTE_HOST }}:2083/$ENDPOINT?r=add" | jq

J'ai quand même ajouté des sleep 3 entre les 2 appels cURL pour supprimer l'IP avec le in & avec le out (j'ai eu un cas où ça avait planté après les 2 calls & il se passait plus rien)

J'ai également ajouté la possibilité de définir une IP que l'on ne souhaite pas supprimer côté o2 (votre IP fixe personnelle par exemple) via un secret (ici c'est secrets.IP_TO_KEEP)

Et le résultat du log que vous devez avoir au moment de l'action :

Get actual whitelisted IPs...
Delete this github IP: *REDACTED* (in & out)
{
  "success": true,
  "message": "L'autorisation a été supprimée avec succès, elle sera effective d'ici quelques minutes (~5mins)."
}
{
  "success": true,
  "message": "L'autorisation a été supprimée avec succès, elle sera effective d'ici quelques minutes (~5mins)."
}
Keep this IP, go to the next...
All non-whitelisted IPs deleted!
Attempt to whitelist IP...
{
  "success": true,
  "message": "L'autorisation a été ajoutée avec succès."
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment