Branched deploys to WP Engine with GitHub Actions

Damon Cook Avatar

·

It should be no surprise that WP Engine sites come with multiple environments: production, staging, and development. Today I want to show how to set up a simple deployment process for your WP Engine site. We’ll cover the following concepts:

By the end of this tutorial, you’ll be able to push changes to a designated branch, and it will automatically deploy those changes to a respective WP Engine environment.

GitHub branchWP Engine environment
mainproduction
stage staging
Each branch deploys to a WP Engine environment

We’re going to start from the very beginning. Let me introduce you to my new client: Qorp. Qorp has engaged my expertise in creating a new WordPress site for them and they’re eager to get their site launched on WP Engine’s hosting platform.

I’ve had several meetings with Qorp, and we’ve nailed down the requirements for the site. I’ve already started creating a sandbox site on my computer using WP Engine’s Local. I’ve made good progress dialing in a WordPress theme and even created a simple WordPress plugin to register a simple custom block I’m developing for their site.

Now, I need to take my sandbox site in Local, put it under version control, and deploy the code to the client’s staging environment for them to review.

Initialize Git for our Local WordPress site

Let’s start using Local’s “Open site shell” to open our command line tool. You can access this by either right-clicking on the site or directly below the site title; there is also an “Open site shell” option.

Screenshot of Local app with "Open site shell" menu items highlighted

Once our command line tool opens, it will drop us into the root of our WordPress site’s installation on our local computer’s hard drive. We’ll want to move into the wp-content/ directory. So, type cd wp-content and Enter to drop into the wp-content/ directory. Now we can run git init to initialize Git version control in our wp-content/ directory. Now the entire directory is under version control. 💥

Smart Plugin Manager

However, we don’t want the entire wp-content/ directory under version control because we’ll utilize WP Engine’s Smart Plugin Manager to maintain the updates on most of our everyday plugins, like Yoast SEO and Safe SVG.

Smart Plugin Manager automates the overhead of updating our WordPress plugins and is smart enough to detect critical errors during the upgrade process and roll back if anything is detected. We can assure Qorp that their site will always be up to date with the latest WordPress core files and the latest WordPress plugin updates, which should help both parties feel confident and secure.

Repo organization and .gitignore

We can create a .gitignore file in our wp-content/ directory to tell Git what we want to ignore in our version control.

Current WordPress site directory structureDo we want to version control?
wp-content/index.phpNo
wp-content/plugins/wordpress-seo/No
wp-content/plugins/safe-svgNo
wp-content/plugins/qorp-pluginYes
wp-content/themes/qorp-themeYes
wp-content/themes/twentytwentythreeNo
wp-content/themes/twentytwentytwoNo
wp-content/upgradeNo
wp-content/uploadsNo
Comparing the current WordPress folder structure vs. what we want to version control

We’ll use the table above and create our .gitignore file based on this desired structure. First, type touch .gitignore to create a new .gitignore file and open it in your code editor of choice (😉 I recommend VS Code, and if you already have it installed, then type code . to open the current directory).

Here is what we’ll want in our .gitignore to properly organize our ignore folders and files.

.gitignore

#--------------------------- # Themes #--------------------------- # Ignore all themes /themes/* # Except this one theme !/themes/qorp-theme #--------------------------- # Plugins # Check out WPE's Smart # Plugin Manager (SMP) #--------------------------- # Ignore all plugins /plugins/* # Except this one plugin !/plugins/qorp-plugin #--------------------------- # MU plugins: these are # managed by the platform. #--------------------------- /mu-plugins/ #--------------------------- # Uploads directory #--------------------------- /uploads/ #--------------------------- # Upgrade files #--------------------------- /upgrade/
Code language: Dockerfile (dockerfile)

With this .gitignore saved, we should see our VS Code update to show the following folders ignored in the Explorer.

VS Code Explorer with empty .gitignore file

Screenshot of VS Code editor with file structure highlighted

VS Code Explorer with ideal.gitignore file

Screenshot of VS Code editor with folder structure

We’ll need to commit our changes and push them up to our GitHub remote repository, which we assume you already created with your GitHub account.

First, we’ll add our remote repository: git remote add origin https://github.com/[your-username]/[your-repo].git. Be sure to replace that last string with your remote GitHub URL.

Next, we’ll commit our work and push it up to this newly added remote with the following commands:

Commit and push to remote GitHub repo

git add -A git commit -m '💥 initial commit' git push -u origin main
Code language: Dockerfile (dockerfile)

Integrate GitHub Actions into repo

Now we have our repository organized and pushed to the remote. Next, we’ll start incorporating our GitHub Actions.

Generate SSH key

For our GitHub Actions to be able to interact with our WP Engine site, we need to utilize an SSH key.

Generate a new SSH key. Be sure to replace the last bit with your own file name.
Hit enter or return to leave the passphrase blank.

ssh-keygen -t ed25519 -f ~/.ssh/wpengine_qorp
Code language: JavaScript (javascript)

Add public SSH key to WP Engine portal

We need to add your newly generated SSH key to the WP Engine user portal.

  1. Visit the User Portal > Profile > SSH Keys area
  2. Click the ‘Create SSH key’ button (top, right side)
  3. We’ll need to copy your newly created SSH key’s public file. Open your command line tool and run the following command to copy the public key to your clipboard: pbcopy < ~/.ssh/wpengine_qorp.pub (Be sure to replace the last bit with your file name)
  4. Paste the public key into the ‘New SSH key’ modal and click the ‘Add SSH key’ button

You should now see your SSH key among the ‘My SSH keys’.

Add private SSH key to GitHub repo

  1. Go to your GitHub repo’s Settings tab > Secrets > Actions
  2. Click the ‘New repository secret’ button (top, right side)
  3. We’ll need to copy your newly created SSH key’s private file contents. Open your command line tool and run the following command to copy the private key to your clipboard: pbcopy < ~/.ssh/wpengine_qorp (Be sure to replace the last bit with your file name)
  4. Paste the private key into the ‘Secret’ field and the ‘Name’ field should be: WPE_SSHG_KEY_PRIVATE and click the ‘Add secret’ to save.
Screenshot of GitHub repo's Settings > Actions Secrets screen
Screenshot of GitHub repo’s Settings > Secrets > Actions screen

Add WP Engine GitHub Actions

We’re almost done. We have our GitHub repository organized, our SSH keys generated and installed on WP Engine’s portal, and our private SSH key is saved in our repo’s Action Secrets. Now, we have to write and add our GitHub repo’s workflow action, which makes all the magic 🪄 happen.

Lucky for us, the existing Deploy WordPress to WP Engine GitHub Actions are readily available and well documented.

We’ll add a .github/workflows directory within the root of our repository (Hint: we’re using wp-content/ as the root in this tutorial). We’ll then want to add two YAML files into this new directory:

Screenshot of VS Code with workflows directory highlighted in Explorer
  • .github/workflows/main.yml 👈 handles the deploy to our production site
  • .github/workflows/stage.yml 👈 handles the deploy to our staging site

main.yml

name: Deploy to production on: push: branches: - main jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: GitHub Action Deploy to WP Engine uses: wpengine/github-action-wpe-site-deploy@v3 with: # Deploy vars WPE_SSHG_KEY_PRIVATE: ${{ secrets.WPE_SSHG_KEY_PRIVATE }} WPE_ENV: qorp # Deploy Options REMOTE_PATH: "wp-content/" PHP_LINT: TRUE CACHE_CLEAR: TRUE
Code language: TypeScript (typescript)

stage.yml

name: Deploy to staging on: push: branches: - stage jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: GitHub Action Deploy to WP Engine uses: wpengine/github-action-wpe-site-deploy@v3 with: # Deploy vars WPE_SSHG_KEY_PRIVATE: ${{ secrets.WPE_SSHG_KEY_PRIVATE }} WPE_ENV: qorpstg # Deploy Options REMOTE_PATH: "wp-content/" PHP_LINT: TRUE CACHE_CLEAR: TRUE
Code language: TypeScript (typescript)

Some key takeaways from the main.yml and stage.yml files:

  • Line 5: represents the GitHub branch that is associated with deploy. Further reading: GitHub Docs > Using workflows > Workflow Syntax: Using filters
  • Line 15: WPE_SSHG_KEY_PRIVATE – This points to the repo’s Action Secret variable that we added above: “Add private SSH key to GitHub repo.”
  • Line 16: WPE_ENV – This must match the WP Engine environment and represent your target environment.

Here is a full list and description of all of the deploy options for the Deploy WordPress to WP Engine workflow.

With those files added to your repository, you need to commit and push them up to trigger your first deployment:

Commit, push and your first deploy will be triggered

git add -A git commit -m "➕ ADD: GitHub Action workflows" git push
Code language: Dockerfile (dockerfile)

If you want to also deploy to your staging site then run the following commands to create a new stage branch, push and deploy:

Create stage branch, push and deploy to staging environment

git checkout -b stage git push -u origin stage
Code language: Nginx (nginx)

Verifying GitHub Actions

You can view pending, successful and failed deploys by visiting your repo’s Actions tab.

GitHub Actions tab with overview of workflows run

Conclusion

Having continuous deployment set up with GitHub Actions can keep things running smoothly. In another upcoming tutorial, we’ll demonstrate how to leverage tools like Composer to manage dependencies and even run code linting to inspect your code for consistency and bugs.

Also, keep in mind that there are many different ways to organize and deploy code. Let us know how you’re maintaining your ideal workflow—tag me on Twitter @dcook.