Skip to content

Dashboard v3/onboard fixing #232

Dashboard v3/onboard fixing

Dashboard v3/onboard fixing #232

name: Deploy WordPress Test Environment on Pull Request
on:
pull_request:
types: [opened, synchronize]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Get the branch name
run: |
echo "Branch name: ${{ github.head_ref }}"
- name: Configure SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY_LINODE }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan ${{ secrets.SSH_HOST_LINODE }} >> ~/.ssh/known_hosts
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} 'echo SSH successfully configured'
- name: Set environment variables
run: |
echo "INSTANCE_ID=${{ github.event.number }}" >> $GITHUB_ENV
echo "WORDPRESS_PORT=$((3000 + ${{ github.event.number }}))" >> $GITHUB_ENV
- name: Generate GitHub App Token for PR Comment
if: ${{ github.event.action == 'opened' }}
id: generate_token_pr
uses: tibdex/github-app-token@v1
with:
app_id: '967897'
installation_id: '53709773'
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Comment on PR
if: ${{ github.event.action == 'opened' }}
uses: actions/github-script@v6
with:
github-token: ${{ steps.generate_token_pr.outputs.token }}
script: |
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: 'WordPress instance for this PR is available at https://pr-${{ github.event.number }}.rapidload.live'
});
- name: Create dynamic Nginx config
if: ${{ github.event.action == 'opened' }}
run: |
INSTANCE_ID=${{ github.event.number }}
WORDPRESS_PORT=$((3000 + INSTANCE_ID))
CONFIG_FILE_NAME="pr-${INSTANCE_ID}.rapidload.live.conf"
LOCAL_CONFIG_FILE_PATH="./${CONFIG_FILE_NAME}"
REMOTE_CONFIG_FILE_PATH="/root/${CONFIG_FILE_NAME}" # Updated to root directory
TARGET_CONFIG_FILE_PATH="/etc/nginx/conf/vhosts/${CONFIG_FILE_NAME}" # Update Nginx path if required
# Create the Nginx config file locally
cat <<EOF > ${LOCAL_CONFIG_FILE_PATH}
server {
listen 443;
server_name pr-${INSTANCE_ID}.rapidload.live;
ssl_certificate /etc/nginx/ssl/selfsigned.crt;
ssl_certificate_key /etc/nginx/ssl/selfsigned.key;
location / {
proxy_pass http://localhost:${WORDPRESS_PORT};
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
server {
listen 80;
server_name pr-${INSTANCE_ID}.rapidload.live;
location / {
proxy_pass http://localhost:${WORDPRESS_PORT};
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
EOF
# Copy the config file to the remote server's /root directory
scp -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa ${LOCAL_CONFIG_FILE_PATH} root@${{ secrets.SSH_HOST_LINODE }}:${REMOTE_CONFIG_FILE_PATH}
# Move the config file to the target directory using sudo
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} "sudo mv ${REMOTE_CONFIG_FILE_PATH} ${TARGET_CONFIG_FILE_PATH}"
- name: Restart Nginx
if: ${{ github.event.action == 'opened' }}
run: |
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} 'sudo systemctl restart nginx' # Updated restart command
- name: Add DNS A Record to Cloudflare
if: ${{ github.event.action == 'opened' }}
run: |
CF_API_TOKEN=${{ secrets.CF_API_TOKEN }}
ZONE_ID=${{ secrets.CF_ZONE_ID }}
RECORD_NAME=pr-${{ github.event.number }}
RECORD_CONTENT=${{ secrets.SSH_HOST_LINODE }}
curl -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"type": "A",
"name": "'"${RECORD_NAME}"'",
"content": "'"${RECORD_CONTENT}"'",
"ttl": 1,
"proxied": true
}'
- name: Create dynamic docker-compose file
if: ${{ github.event.action == 'opened' }}
run: |
INSTANCE_ID=${{ github.event.number }}
WORDPRESS_PORT=$((3000 + INSTANCE_ID))
WP_USERNAME=${{ secrets.WP_USERNAME }}
WP_PASSWORD=${{ secrets.WP_PASSWORD }}
SSH_HOST=${{ secrets.SSH_HOST_LINODE }}
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${SSH_HOST} <<EOF
export INSTANCE_ID=${INSTANCE_ID}
export WORDPRESS_PORT=${WORDPRESS_PORT}
export WP_USERNAME=${WP_USERNAME}
export WP_PASSWORD=${WP_PASSWORD}
# Create instance directory
mkdir -p /root/wp-${INSTANCE_ID}
# Copy the template to the instance directory
cp /root/docker-compose-template.yml /root/wp-${INSTANCE_ID}/docker-compose.yml
# Modify the copied template file
sed -i "s/wordpress_data_instance_id/wordpress_data_${INSTANCE_ID}/g" /root/wp-${INSTANCE_ID}/docker-compose.yml
sed -i "s/wordpress_data:/wordpress_data_${INSTANCE_ID}:/g" /root/wp-${INSTANCE_ID}/docker-compose.yml
sed -i "s/wordpress_instance_id/wordpress_${INSTANCE_ID}/g" /root/wp-${INSTANCE_ID}/docker-compose.yml
sed -i "s/mariadb_data_instance_id/mariadb_data_${INSTANCE_ID}/g" /root/wp-${INSTANCE_ID}/docker-compose.yml
sed -i "s/mariadb_data:/mariadb_data_${INSTANCE_ID}:/g" /root/wp-${INSTANCE_ID}/docker-compose.yml
sed -i "s/mariadb_instance_id/mariadb_${INSTANCE_ID}/g" /root/wp-${INSTANCE_ID}/docker-compose.yml
sed -i "s/wordpress_port/${WORDPRESS_PORT}/g" /root/wp-${INSTANCE_ID}/docker-compose.yml
sed -i "s/wp_username/${WP_USERNAME}/g" /root/wp-${INSTANCE_ID}/docker-compose.yml
sed -i "s/wp_password/${WP_PASSWORD}/g" /root/wp-${INSTANCE_ID}/docker-compose.yml
EOF
- name: Clean up unused Docker networks
if: ${{ github.event.action == 'opened' }}
run: |
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << EOF
sudo docker network prune -f
EOF
- name: Deploy WordPress
if: ${{ github.event.action == 'opened' }}
run: |
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << EOF
INSTANCE_ID=${{ github.event.number }}
WORDPRESS_PORT=$((3000 + INSTANCE_ID))
export INSTANCE_ID WORDPRESS_PORT
# Get the container IDs
WP_CONTAINER=\$(sudo docker ps -q --filter "name=wordpress_\${INSTANCE_ID}")
DB_CONTAINER=\$(sudo docker ps -q --filter "name=mariadb_\${INSTANCE_ID}")
echo "WP_CONTAINER ID: \${WP_CONTAINER}"
echo "DB_CONTAINER ID: \${DB_CONTAINER}"
# Stop and remove any existing Docker services using the same ports
# if [ ! -z "\$WP_CONTAINER" ]; then
# sudo docker stop \${WP_CONTAINER}
# sudo docker rm \${WP_CONTAINER}
# fi
# if [ ! -z "\$DB_CONTAINER" ]; then
# sudo docker stop \${DB_CONTAINER}
# sudo docker rm \${DB_CONTAINER}
# fi
# Start the new services
sudo docker-compose -f /root/wp-\${INSTANCE_ID}/docker-compose.yml up -d
sleep 30 # wait for the services to start
sudo docker-compose -f /root/wp-\${INSTANCE_ID}/docker-compose.yml logs wordpress
EOF
- name: Set up environment and grant permissions
if: ${{ github.event.action == 'opened' }}
run: |
ssh -v -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << EOF
set -x
INSTANCE_ID=${{ github.event.number }}
DOMAIN="pr-${INSTANCE_ID}.rapidload.live"
WP_CONTAINER=\$(sudo docker ps -q --filter "name=wordpress_\${INSTANCE_ID}")
# Grant 666 permissions to wp-config.php to cache folder
sudo docker exec -u root -i \${WP_CONTAINER} sh -c "chmod 666 /bitnami/wordpress/wp-config.php"
EOF
- name: Update domain in wp-config.php
if: ${{ github.event.action == 'opened' }}
run: |
ssh -v -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << EOF
set -x
INSTANCE_ID=${{ github.event.number }}
DOMAIN="pr-${INSTANCE_ID}.rapidload.live"
WP_CONTAINER=\$(sudo docker ps -q --filter "name=wordpress_\${INSTANCE_ID}")
echo "update domain for : \${WP_CONTAINER}"
sudo docker exec -u root -i \${WP_CONTAINER} sh -c "sed -i 's/127.0.0.1/\${DOMAIN}/g; s|http://|https://|g' /bitnami/wordpress/wp-config.php"
EOF
- name: Update RAPIDLOAD_DEV_MODE in wp-config.php
if: ${{ github.event.action == 'opened' }}
run: |
ssh -v -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << EOF
set -x
INSTANCE_ID=${{ github.event.number }}
WP_CONTAINER=\$(sudo docker ps -q --filter "name=wordpress_\${INSTANCE_ID}")
echo "update RAPIDLOAD_DEV_MODE for : \${WP_CONTAINER}"
sudo docker exec -u root -i \${WP_CONTAINER} sh -c 'sed -i "/^\/\*\* Sets up WordPress vars and included files. \*\//i if ( ! defined( \x27RAPIDLOAD_DEV_MODE\x27 ) ) { define( \x27RAPIDLOAD_DEV_MODE\x27, true ); }" /bitnami/wordpress/wp-config.php'
sudo docker exec -u root -i \${WP_CONTAINER} sh -c "grep -A 2 'RAPIDLOAD_DEV_MODE' /bitnami/wordpress/wp-config.php"
EOF
- name: Update WP_CACHE in wp-config.php
if: ${{ github.event.action == 'opened' }}
run: |
ssh -v -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << EOF
set -x
INSTANCE_ID=${{ github.event.number }}
WP_CONTAINER=\$(sudo docker ps -q --filter "name=wordpress_\${INSTANCE_ID}")
echo "update WP_CACHE for : \${WP_CONTAINER}"
sudo docker exec -u root -i \${WP_CONTAINER} sh -c 'sed -i "/^\/\*\* Sets up WordPress vars and included files. \*\//i if ( ! defined( \x27WP_CACHE\x27 ) ) { define( \x27WP_CACHE\x27, true ); }" /bitnami/wordpress/wp-config.php'
sudo docker exec -u root -i \${WP_CONTAINER} sh -c "grep -A 2 'WP_CACHE' /bitnami/wordpress/wp-config.php"
EOF
- name: Update robots.txt in Docker container
if: ${{ github.event.action == 'opened' }}
run: |
ssh -v -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << 'EOF'
INSTANCE_ID=${{ github.event.number }}
WP_CONTAINER=$(sudo docker ps -q --filter "name=wordpress_${INSTANCE_ID}")
# Create or update robots.txt to prevent Google indexing
sudo docker exec -u root -i ${WP_CONTAINER} sh -c "echo -e 'User-agent: *\nDisallow: /' > /bitnami/wordpress/robots.txt"
EOF
- name: Clone or Update WordPress Plugin Repository in Docker Container
run: |
ssh -v -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << 'EOF'
INSTANCE_ID=${{ github.event.number }}
WP_CONTAINER=$(sudo docker ps -q --filter "name=wordpress_${INSTANCE_ID}")
PLUGIN_PATH=/bitnami/wordpress/wp-content/plugins/autoptimize-unusedcss
PLUGIN_DIR=/bitnami/wordpress/wp-content/plugins
sudo docker exec -u root -i ${WP_CONTAINER} sh -c "
if [ -d ${PLUGIN_PATH} ]; then
echo 'Plugin directory exists. Running git pull...'
cd ${PLUGIN_PATH}
git config --global --add safe.directory /bitnami/wordpress/wp-content/plugins/autoptimize-unusedcss
git clean -f
git reset --hard HEAD
git pull origin ${{ github.head_ref }}
else
cd ${PLUGIN_DIR}
echo 'Cloning plugin repository...'
git config --global http.postBuffer 524288000
git clone --depth 1 -b ${{ github.head_ref }} --single-branch https://github.com/shakee93/autoptimize-unusedcss.git ${PLUGIN_PATH}
fi
"
if [ $? -eq 0 ]; then
echo "Plugin repository updated successfully in ${WP_CONTAINER}"
else
echo "Failed to update plugin repository in ${WP_CONTAINER}"
exit 1
fi
EOF
- name: Run npm build in Docker Container
run: |
ssh -v -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << 'EOF'
INSTANCE_ID=${{ github.event.number }}
WP_CONTAINER=$(sudo docker ps -q --filter "name=wordpress_${INSTANCE_ID}")
PLUGIN_PATH=/bitnami/wordpress/wp-content/plugins/autoptimize-unusedcss/includes/admin/page-optimizer
sudo docker exec -u root -i ${WP_CONTAINER} sh -c "
cd ${PLUGIN_PATH}
if [ -f package.json ]; then
echo 'Running npm install...'
npm install
echo 'Running npm run build...'
npm run build
else
echo 'package.json not found in ${PLUGIN_PATH}'
fi
"
if [ $? -eq 0 ]; then
echo "npm run build executed successfully in ${WP_CONTAINER}"
else
echo "Failed to run npm build in ${WP_CONTAINER}"
fi
EOF
- name: Activate Plugin in Docker Container
if: ${{ github.event.action == 'opened' }}
run: |
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << 'EOF'
INSTANCE_ID=${{ github.event.number }}
WP_CONTAINER=$(sudo docker ps -q --filter "name=wordpress_${INSTANCE_ID}")
if [ -n "${WP_CONTAINER}" ]; then
sudo docker exec -i ${WP_CONTAINER} sh -c "wp plugin activate autoptimize-unusedcss --allow-root"
if [ $? -eq 0 ]; then
echo "Plugin unusedcss activated successfully in ${WP_CONTAINER}"
else
echo "Failed to activate plugin unusedcss in ${WP_CONTAINER}"
fi
sudo docker exec -i ${WP_CONTAINER} sh -c "wp rapidload update_db --allow-root"
sudo docker exec -i ${WP_CONTAINER} sh -c "wp option update siteurl 'https://pr-${{ github.event.number }}.rapidload.live' --allow-root"
sudo docker exec -i ${WP_CONTAINER} sh -c "wp option update home 'https://pr-${{ github.event.number }}.rapidload.live' --allow-root"
sudo docker exec -i ${WP_CONTAINER} sh -c "wp search-replace 'http://127.0.0.1' 'https://pr-${{ github.event.number }}.rapidload.live' --all-tables --allow-root"
sudo docker exec -i ${WP_CONTAINER} sh -c "wp rapidload connect '${{ secrets.RAPIDLOAD_LICENSE_KEY }}' --uucss=1 --cpcss=1 --url='https://pr-${{ github.event.number }}.rapidload.live' --allow-root"
else
echo "No container found with name wordpress_${INSTANCE_ID}"
fi
EOF
- name: Disable plugin upload capability
if: ${{ github.event.action == 'opened' }}
run: |
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << 'EOF'
INSTANCE_ID=${{ github.event.number }}
WP_CONTAINER=$(sudo docker ps -q --filter "name=wordpress_${INSTANCE_ID}")
# Remove the 'upload_plugins' capability from the 'administrator' role
sudo docker exec -u root -i ${WP_CONTAINER} sh -c "echo \"define('DISALLOW_FILE_MODS', true);\" >> /bitnami/wordpress/wp-config.php"
EOF
- name: Grant permission to daemon user
if: ${{ github.event.action == 'opened' }}
run: |
ssh -v -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << EOF
set -x
INSTANCE_ID=${{ github.event.number }}
DOMAIN="pr-${INSTANCE_ID}.rapidload.live"
WP_CONTAINER=\$(sudo docker ps -q --filter "name=wordpress_\${INSTANCE_ID}")
# Grant permission to daemon user
sudo docker exec -u root \$WP_CONTAINER sh -c 'chown -R daemon:daemon /bitnami/wordpress'
EOF
- name: Clean up old Docker containers and volumes
#if: ${{ github.event.action == 'opened' }}
run: |
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ secrets.SSH_HOST_LINODE }} << 'EOF'
# Remove Docker containers older than 30 days
old_containers=$(sudo docker ps -a --filter "status=exited" --format "{{.ID}} {{.CreatedAt}}" | while read id created; do
if [ $(date -d "$created" +%s) -lt $(date -d '30 days ago' +%s) ]; then
echo $id
fi
done)
if [ ! -z "$old_containers" ]; then
echo "Removing old containers: $old_containers"
sudo docker rm $old_containers
else
echo "No old containers found."
fi
# Remove dangling Docker volumes older than 30 days
old_volumes=$(sudo docker volume ls -q --filter "dangling=true" | while read volume; do
created=$(sudo docker volume inspect -f '{{.CreatedAt}}' $volume | head -n 1 | sed 's/\(.*\)+0000 UTC/\1/')
if [ $(date -d "$created" +%s) -lt $(date -d '30 days ago' +%s) ]; then
echo $volume
fi
done)
if [ ! -z "$old_volumes" ]; then
echo "Removing old volumes: $old_volumes"
sudo docker volume rm $old_volumes
else
echo "No old volumes found."
fi
EOF