Skip to main content
Orchestrating WordPress Deployments with WP-CLI and GitHub Actions

Orchestrating WordPress Deployments with WP-CLI and GitHub Actions

I've spent countless hours navigating FTP clients, manually sifting through plugin updates, and holding my breath during database migrations.

I’ve spent countless hours navigating FTP clients, manually sifting through plugin updates, and holding my breath during database migrations. It’s a rite of passage for many WordPress developers, but an unnecessary one in the era of robust CI/CD. When we talk about advanced WordPress development from an infrastructure perspective, automating these critical, repetitive tasks is foundational. Today, I want to share how I’ve leveraged WP-CLI alongside GitHub Actions to build reliable, automated deployment pipelines, turning hours of manual work into seconds of execution.

At its core, WP-CLI is an indispensable tool for anyone serious about WordPress development. It allows you to manage almost every aspect of a WordPress installation directly from the command line. From updating core, themes, and plugins to managing users, clearing caches, or even importing/exporting database snapshots, WP-CLI makes programmatic control over WordPress possible. This power is exactly what we need when building an automated deployment. Imagine needing to update a custom plugin, run its database migration script, and then flush the site cache — all with a single command on your server. WP-CLI enables this through simple commands like wp plugin update my-custom-plugin, wp db update, or wp cache flush.

Our goal is to execute these WP-CLI commands automatically whenever specific conditions are met, such as pushing new code to a main branch. This is where GitHub Actions steps in. GitHub Actions provides a flexible platform for automating workflows directly within your repository. We can define a YAML file that specifies a series of steps to be executed on a virtual machine, including SSHing into our staging or production server and running our WP-CLI commands.

Here’s a simplified GitHub Actions workflow I use for deploying to a staging environment. This example assumes your entire WordPress project, including custom plugins and themes, is version-controlled and pushed to a main branch.

name: Deploy WordPress Site to Staging

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

- name: Deploy to Staging Server via SSH
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SSH_HOST_STAGING }}
          username: ${{ secrets.SSH_USERNAME_STAGING }}
          key: ${{ secrets.SSH_PRIVATE_KEY_STAGING }}
          script: |
            cd /var/www/html/staging.mysite.com # Adjust to your WordPress root
            git pull origin main
            composer install --no-dev --prefer-dist # Run if your project uses Composer
            wp db update --allow-root # Runs any pending database updates
            wp cache flush --allow-root # Clears all caches
            echo "Deployment to staging complete!"

Let’s break down what’s happening here. The workflow is triggered by a push to the main branch. The deploy job runs on an ubuntu-latest virtual machine. First, actions/checkout@v3 clones your repository onto the runner. Then, the appleboy/ssh-action@master action is used to establish an SSH connection to your staging server. Crucially, sensitive information like host, username, and key are stored securely as GitHub Secrets, preventing them from being exposed in your repository.

Once connected via SSH, the script navigates to the WordPress root directory on the server. git pull origin main fetches the latest code changes. If your custom plugins or theme dependencies are managed via Composer, composer install ensures they are up-to-date. The WP-CLI commands wp db update and wp cache flush are then executed. The --allow-root flag here is used because the SSH connection might be established as a user that is not the web server user; in a production environment, you’d typically configure sudoers for the deploy user to run wp commands without needing --allow-root or direct root access for enhanced security. This ensures any database schema changes from your custom code are applied and all persistent caches are cleared, preventing stale content or functional issues.

This setup transforms the deployment process. A simple git push to your main branch initiates a robust, repeatable series of actions, drastically reducing the chance of human error and freeing up valuable development time. You can extend this further with pre-deployment checks, post-deployment notifications, or even multi-stage deployments. This level of automation isn’t just a convenience; it’s a cornerstone of professional, scalable WordPress engineering.