← All posts

Streamlining WordPress Deployments with WP-CLI and GitHub Actions

Streamlining WordPress Deployments with WP-CLI and GitHub Actions

For years, deploying WordPress applications felt like a recurring exercise in caution and manual repetition. SSHing into a server, pulling code, clearing caches, maybe even running database updates – it was a process ripe for human error and generally a time sink. As our projects grew more complex, particularly with custom plugins and themes, I realized the need for a robust, automated deployment pipeline. This is where WP-CLI and GitHub Actions truly shine, transforming a tedious chore into a seamless, reliable background operation.

My approach typically involves a simple CI/CD workflow that triggers on a push to the main branch. The core idea is to leverage GitHub Actions to securely connect to the remote server, transfer updated code, and then execute a series of WP-CLI commands directly on the live environment. This ensures that post-deployment tasks, such as flushing object caches or rebuilding rewrite rules, are handled consistently every single time. It’s not just about pushing files; it’s about maintaining the operational integrity of the WordPress instance.

A typical GitHub Actions workflow for this might look something like this, defined in a `.github/workflows/deploy.yml` file. First, we set up our environment and ensure we have a deploy key for SSH access. The `checkout` action retrieves our repository, and then we establish the SSH connection. For security, I always store sensitive information like SSH private keys and server details as GitHub Secrets. This keeps them out of the public repository and securely encrypted.

After establishing the SSH connection, the next step involves using `rsync` to transfer only the changed files from our repository to the WordPress installation on the remote server. This is far more efficient than a full transfer and minimizes downtime. Once the code is in place, the real magic of WP-CLI begins. Instead of manually running commands, we execute them remotely via SSH. This could involve `wp core update`, `wp plugin update --all`, `wp theme update --all`, ensuring all core components and extensions are up-to-date with a single command. More critically, I always include `wp rewrite flush` to refresh permalinks and `wp cache flush` to clear any object cache layers, preventing stale content or routing issues immediately after a code deployment.

Here’s a simplified snippet of what the deployment part of your GitHub Actions YAML might contain:

- name: Deploy with SSH and WP-CLI uses: appleboy/[email protected] with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USERNAME }} key: ${{ secrets.SSH_PRIVATE_KEY }} port: 22 script: | cd /var/www/html/your-wordpress-site # Sync updated code rsync -avz --delete /home/runner/work/your-repo/your-repo/wp-content/themes/your-theme/ \ ./wp-content/themes/your-theme/ rsync -avz --delete /home/runner/work/your-repo/your-repo/wp-content/plugins/your-plugin/ \ ./wp-content/plugins/your-plugin/

# Run WP-CLI commands wp plugin update --all --allow-root wp theme update --all --allow-root wp rewrite flush --allow-root wp cache flush --allow-root # If you have custom database migrations # wp db migrate --allow-root

The `--allow-root` flag is often necessary when WP-CLI is run via SSH without a specific WordPress user context, but always ensure your server permissions are correctly configured. This setup has been invaluable for me, not just for speed, but for the sheer confidence it brings to each deployment. No more forgotten cache clears or mismatched plugin versions. With WP-CLI and GitHub Actions, my WordPress deployments are robust, repeatable, and entirely automated, letting me focus on development, not deployment headaches.