My script for updating custom WP plugins/themes using GitHub Actions

I always use this approach when coding plugins or themes for a single site. I would use a different update mechanism for public plugins used on many sites.

Every custom plugin is hosted in its own GitHub repository. It has at least a `master` and a `staging` branch. When I introduce a new developer to the project I don’t need to share access to the entire WP code; I can share only specific plugins with them.

Inside the project, I have `.github/workflows` folder with a main.yml file containing the GitHub Action script. The action consists of the following steps:


* trigger definition -> on which events should it run
* environment selection -> production or staging
* compiling assets
* uploading to the defined server with rsync
* purging Cloudflare cache


name: WordPress plugin deployer

# Controls when the workflow will run
# Triggers the workflow on push or pull request events but only for the “master” branch
branches: [ “master”, “staging” ]

# Allows you to run this workflow manually from the Actions tab

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
# This workflow contains a single job called “build”
# The type of runner that the job will run on
runs-on: ubuntu-latest
name: ${{ github.ref_name }}
# Steps represent a sequence of tasks that will be executed as part of the job
– uses: actions/checkout@v2

– uses: actions/setup-node@v2
node-version: 12.x

– name: Install dependencies
run: npm install

– name: Build
run: npm run production

– name: Sync
dest: ‘${{secrets.USERNAME}}@${{secrets.IP}}:${{secrets.THEME_PATH}}’
run: |
echo “${{secrets.DEPLOY_KEY}}” > deploy_key
chmod 600 ./deploy_key
rsync -chav –delete \
-e ‘ssh -p ${{secrets.PORT}} -i ./deploy_key -o StrictHostKeyChecking=no’ \
–exclude /deploy_key \
–exclude /.git/ \
–exclude /.github/ \
–exclude /node_modules/ \
./ ${{env.dest}}

– name: Cloudflare Purge Cache
run: curl

I am using five secrets in this script:

|Variable name|Description|
|USERNAME|Linux server user|
|IP|Server IP address|
|PORT|Port where SSH is active, usually 22|
|THEME\_PATH|Absolute path to the theme folder on the server|
|DEPLOY\_KEY|RSA key secret|

These variables are different between projects and environments.

The first thing is to create an environment and then add its secrets. Secrets are defined in the repository’s Settings under Secrets and variables -> Actions tab.

[Secrets for the production environment](

**Environment protection rules**: you can define which branch can trigger a certain environment. Make sure all your environments are protected unless you want a staging branch to be deployed in the production server.



Name environments the same as related branches; this way, you can dynamically trigger different environments in the GitHub action. That is this part `${{ github.ref_name }}`

Let me know what you think about my approach and what you use for updating custom themes and plugins.


1 Comment
  1. That’s really nice, thanks for sharing. How do you approach public plugins? do you handle licencing in a similarly creative way?


This site will teach you how to build a WordPress website for beginners. We will cover everything from installing WordPress to adding pages, posts, and images to your site. You will learn how to customize your site with themes and plugins, as well as how to market your site online.

Buy WordPress Transfer