Use Github Actions to publish WordPress plugins on the repository

GitHub Actions opened a new opportunity for developers to create automation. Nothing special, you would say, but actually, it is. When I saw about this for the first time I said: “Finally a CI built-in directly in Github.”. A long-awaited feature. Having git + CI in my favorite service.

Right now it’s still in beta, but very soon will be available for everyone.

So, how do we use it to publish WordPress plugins on Or why should we use Github Actions for this?

OK. As you already know, WordPress forces us to use SVN. But if you are like me, you’ll prefer to use Github for Version Control. And using two Version Control systems is not an easy thing because you will have to upload the code from Github to WordPress SVN manually.

Not saying that if your code is compiled using some sort of tools like Webpack, you’ll have to download it on your computer, then compile and later check out the SVN repo and add the new code. Ugh! Not developer-friendly at all.

Let’s start the work.

Change git repo structure:

To make this possible, well change the repository structure a bit. This is my personal choice, but of course, you are free to choose your structure.


We have 2 folders and as follows:

  • src folder will contain all your plugin files.
  • assets folder will contain the images used on plugin page.

All is good so far.

Add Github Actions configuration:

Create a new file .github/workflows/main.yml. This file will include the rules for our CI. Add the following content:

name: CI

      - "*.*.*"

    runs-on: ubuntu-latest

      - uses: actions/checkout@master
      - name: Deploy
        run: chmod +x ./ && ./
          SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
          SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}

So what does this? First of all, it will be executed only when a new git tag is created. This will usually happen when you create releases, and the nice part is that this is what you’ll use to define the plugin versions.

Next, it will create an environment based on the Ubuntu image(Linux).

Then inside will check out the code and run the scripts from the file. This file does not exist yet, but we’ll create it right away.

Before switching to, we must set up 2 important environment variables. Your username and password. To do this, open the Settings->Secrets and add your credentials under these 2 secret variables:


It’s all ready. Now let’s add This file is responsible to upload the plugin code to

#!/usr/bin/env bash

# Get the plugin slug from this git repository.

# Get the current release version
TAG=$(sed -e "s/refs\/tags\///g" <<< $GITHUB_REF)

# Replace the version in these 2 files.
sed -i -e "s/__STABLE_TAG__/$TAG/g" ./src/readme.txt
sed -i -e "s/__STABLE_TAG__/$TAG/g" "./src/$PLUGIN_SLUG.php"

# Get the SVN data from in a folder named `svn`
svn co --depth immediates "$PLUGIN_SLUG" ./svn

svn update --set-depth infinity ./svn/trunk
svn update --set-depth infinity ./svn/assets
svn update --set-depth infinity ./svn/tags/$TAG

# Copy files from `src` to `svn/trunk`
cp -R ./src/* ./svn/trunk

# Copy the images from `assets` to `svn/assets`
cp -R ./assets/* ./svn/assets

# 3. Switch to SVN directory
cd ./svn

# Prepare the files for commit in SVN
svn add --force trunk
svn add --force assets

# Create the version tag in svn
svn cp trunk tags/$TAG

# Prepare the tag for commit
svn add --force tags

# Commit files to
svn ci  --message "Release $TAG" \
        --username $SVN_USERNAME \
        --password $SVN_PASSWORD \

I added comments before each step to make it clear how things are done. But you should notice that there is a replacement involved in. We replace __STABLE_TAG__ with the current release version.

To make this possible, readme.txt and the main plugin file must not define the version but use this string instead. Example:

__STABLE_TAG__ is just an example. You could extend this idea and add the exact version numbers, then replace them with regex, for example:

/Version: \d+\.\d+\.\d+/g

The repository name, slug, and main plugin file must share the same name. Again, you are free to change this in “”.
GitHub repo: repo:
And the plugin entry file is: ‘src/example-plugin.php’

Now you can continue to push the code on GitHub as you usually do and when you feel that you are ready to publish a new release, go to the “Releases” tab and create a new one using the Semantic Versioning rules.

See the following screenshot as an example:

That’s it. Now you can forget about SVN and all that stuff. The Github is all you need 😉

A sample repository is available on GitHub 🙂

Member since January 2, 2019

As a seasoned WordPress developer with expertise in various tech stacks and languages, I bring years of experience to every project I undertake. My passion for coding and dedication to delivering exceptional work ensures that every project I undertake is of the highest quality. I specialize in creating custom themes, developing plugins, and building full-scale web systems. By staying up-to-date with the latest industry trends and best practices, I am able to incorporate cutting-edge solutions into my work.


  • Oliver 4 years ago

    Amazing! I implemented this in some of my plugins and it’s love it. Thank you for providing such educational content.

Your email address will not be published. Required fields are marked *