Logo Cinquin Andy Signature

Automating WordPress Plugin Deployment: Git to SVN

Développeur Freelance - Logo

The sites and the associated resources.

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

Pasted image 20250205202348.png
Pasted image 20250205202405.png

3. Adding Secrets

Configure these three secret variables:
  • GH_TOKEN: Your personal GitHub token
  • SVN_USERNAME: Your WordPress.org username
  • SVN_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

  1. 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
  2. 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 !

DEVELOP YOUR PROJECTS TOGETHER

An idea, a project? I'm here to answer your questions and help you.
I'd be delighted to discuss your project with you!