Automating WordPress Plugin Deployment: Git to SVN
Posted on - February 6, 2025 by Andy Cinquin
SvnWordpressGitGithub actions
WordPress Plugin Deployment Automation: Git to SVN
Introduction
WordPress still uses SVN (Subversion) for its official plugin repository, while most modern developers prefer Git and GitHub for their daily workflow. This difference can create friction when deploying plugin updates, often requiring manual actions to synchronize code between Git and SVN.
This solution completely automates the process using GitHub Actions. With each push to the main branch, the system automatically increments the version, creates a GitHub release, and synchronizes the code with the WordPress.org SVN repository. No more juggling between two versioning systems or performing repetitive manual actions: a simple push triggers the entire deployment chain.
GitHub Secrets Configuration
1. Creating the GitHub Token
- Generate a personal token in your GitHub account settings
- Add necessary repository access rights
- This token can be reused on other projects if needed
2. GitHub Configuration


3. Adding Secrets
Configure these three secret variables:
GH_TOKEN
: Your personal GitHub tokenSVN_USERNAME
: Your WordPress.org usernameSVN_PASSWORD
: Your WordPress.org password
Note: Configuration can be done at organization or repository level depending on your reuse needs.
Configuration Files
1. Deployment Workflow
# File: .github/workflows/deploy.yml
name: Deploy WordPress Plugin
on:
push:
branches:
- main
paths:
- 'package.json'
- 'auto-alt-text-for-images.php'
- 'readme.txt'
jobs:
build-and-deploy:
name: Build and Deploy Plugin
runs-on: ubuntu-latest
if: "contains(github.event.head_commit.message, '✨ Release version')"
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install SVN
run: |
sudo apt-get update
sudo apt-get install -y subversion
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
tools: composer, wp-cli
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Get version from commit message
id: get_version
run: |
VERSION=$(echo "${{ github.event.head_commit.message }}" | grep -oP '✨ Release version \K[0-9]+\.[0-9]+\.[0-9]+')
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Install dependencies
run: |
composer install --no-dev --optimize-autoloader
npm ci
- name: Generate POT file
run: |
mkdir -p languages
wp i18n make-pot . languages/auto-alt-text-for-images.pot --domain=auto-alt-text-for-images --allow-root
- name: Create ZIP archive
run: composer run zip
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: release/auto-alt-text-for-images.zip
body_path: CHANGELOG.md
name: ${{ steps.get_version.outputs.version }}
tag_name: ${{ steps.get_version.outputs.version }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout WordPress SVN repository
env:
SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
run: |
svn checkout "https://plugins.svn.wordpress.org/auto-alt-text-for-images" \
--username "$SVN_USERNAME" \
--password "$SVN_PASSWORD" \
--no-auth-cache \
--non-interactive \
--trust-server-cert \
svn
- name: Prepare SVN
working-directory: svn
run: |
VERSION=${{ steps.get_version.outputs.version }}
rm -rf trunk/* tags/$VERSION
rm -rf assets/*
cp -r ../assets/* assets/
svn add assets/* --force
cp -r ../includes trunk/
cp -r ../languages trunk/
cp -r ../templates trunk/
cp ../auto-alt-text-for-images.php trunk/
cp ../README.md trunk/
cp ../readme.txt trunk/
cp ../uninstall.php trunk/
svn add trunk/* --force
mkdir -p tags/$VERSION
cp -r trunk/* tags/$VERSION/
svn add tags/$VERSION --force
svn status | grep '^\!' | sed 's/! *//' | xargs -I% svn rm %@
- name: Commit to SVN
working-directory: svn
env:
SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
run: |
VERSION=${{ steps.get_version.outputs.version }}
svn commit -m "Release version $VERSION" \
--username "$SVN_USERNAME" \
--password "$SVN_PASSWORD" \
--no-auth-cache \
--non-interactive \
--trust-server-cert
- name: Notify on success
if: success()
run: |
echo "Plugin successfully deployed to WordPress.org and GitHub!"
echo "Version ${{ steps.get_version.outputs.version }} is now live!"
2. Version Bump Workflow
# File: .github/workflows/version-bump.yml
name: Version Bump
on:
push:
branches:
- main
paths-ignore:
- '.github/workflows/**'
jobs:
version-bump:
name: Create New Version
runs-on: ubuntu-latest
permissions:
contents: write
if: "!contains(github.event.head_commit.message, '✨ Release version')"
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GH_TOKEN }}
fetch-depth: 0
- name: Read current version
id: version
run: |
CURRENT_VERSION=$(grep -Po '"version": "\K[^"]*' package.json)
echo "current_version=${CURRENT_VERSION}" >> $GITHUB_OUTPUT
- name: Increment version
id: bump_version
run: |
IFS='.' read -r -a version_parts <<< "${{ steps.version.outputs.current_version }}"
new_patch=$((version_parts[2] + 1))
NEW_VERSION="${version_parts[0]}.${version_parts[1]}.$new_patch"
echo "new_version=${NEW_VERSION}" >> $GITHUB_OUTPUT
- name: Update version numbers
run: |
NEW_VERSION="${{ steps.bump_version.outputs.new_version }}"
sed -i "s/\"version\": \".*\"/\"version\": \"$NEW_VERSION\"/" package.json
sed -i "s/Version: .*/Version: $NEW_VERSION/" auto-alt-text-for-images.php
sed -i "s/define( 'FORVOYEZ_VERSION', '.*' );/define( 'FORVOYEZ_VERSION', '$NEW_VERSION' );/" auto-alt-text-for-images.php
sed -i "s/Stable tag: .*/Stable tag: $NEW_VERSION/" readme.txt
- name: Commit and tag new version
run: |
NEW_VERSION="${{ steps.bump_version.outputs.new_version }}"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
git pull origin main
git add package.json auto-alt-text-for-images.php readme.txt
git commit -m "✨ Release version $NEW_VERSION ✨"
git tag $NEW_VERSION
git push origin main && git push origin $NEW_VERSION
System Operation
-
On each push to main:
- The system checks if version files have been modified
- Automatically increments the version
- Creates a special release commit
- Pushes changes with a tag
-
The release commit triggers:
- GitHub release creation
- WordPress.org SVN synchronization
- Documentation update
A simple push to the main branch is now sufficient to trigger the entire deployment chain. Versions are managed automatically, and everything stays synchronized between GitHub and WordPress.org!
🚀 Thanks for reading!
If you enjoyed this article, feel free to share it around.
💡 Got an idea? Let's talk !☕