If you develop WordPress plugins with Git or GitHub, receiving an SVN repository from WordPress.org can feel like entering a different world.
You may already have your source code organized. Your plugin works. Your GitHub repository is clean. Your release ZIP is ready.
Then WordPress.org gives you an address like:https://plugins.svn.wordpress.org/your-plugin/
Now what?
The important thing to understand is that WordPress.org SVN is primarily a publishing and release system—not where you need to do your everyday plugin development.
WordPress explicitly recommends against committing every small development change to its SVN repository. Each SVN push causes plugin ZIP files to be rebuilt, so WordPress recommends pushing finished changes when you’re actually ready to release them.
Once you understand that distinction, WordPress SVN becomes much easier to work with.
What Is SVN?
SVN stands for Subversion.
Like Git, Subversion is a version-control system. It tracks files and revisions and allows changes to be committed to a central repository.
WordPress.org uses Subversion as the publishing repository for plugins in the official Plugin Directory. Once your plugin has passed the WordPress.org review process, you’re granted an SVN repository for publishing it.
You can therefore have two separate systems serving different purposes:
Git / GitHub
│
│ Development
│ Source control
│ Branches
│ Pull requests
│
▼
Finished Plugin
│
│ Release
▼
WordPress.org SVN
│
▼
WordPress Plugin Directory
You don’t have to abandon GitHub because WordPress.org uses SVN.
In fact, using Git for development and WordPress SVN for finished releases is a very sensible workflow.
Understanding the WordPress SVN Repository
When WordPress.org creates your plugin repository, its primary structure is:
your-plugin/
│
├── assets/
├── tags/
└── trunk/
These three directories have very different jobs. WordPress creates them by default and defines assets for directory artwork, trunk for plugin code, and tags for releases.
Understanding these folders is probably the most important part of learning WordPress SVN.
/trunk — Your Current Plugin Code
Your current plugin code belongs in:/trunk/
For example:
trunk/
├── your-plugin.php
├── readme.txt
├── includes/
├── languages/
└── assets/
The main plugin PHP file and readme.txt should be directly inside trunk.
Don’t do this:
trunk/
└── your-plugin/
├── your-plugin.php
└── readme.txt
WordPress specifically warns that putting the plugin itself inside another directory beneath trunk will break its ZIP generation. Subdirectories within the plugin for includes, CSS, JavaScript, and similar resources are fine; the extra top-level plugin wrapper is the problem.
Think: WRONG
trunk/my-plugin/my-plugin.php
RIGHT
trunk/my-plugin.php
/tags — Your Published Versions
The tags directory contains individual releases of your plugin.
If your plugin has versions 1.0.0, 1.1.0 and 1.2.0, you might see:
tags/
├── 1.0.0/
├── 1.1.0/
└── 1.2.0/
Each directory represents a version.
For example:
tags/
└── 1.2.0/
├── your-plugin.php
├── readme.txt
├── includes/
└── languages/
WordPress recommends that release tags look like version numbers and strongly encourages proper versioning.
In other words:
tags/2.3.1/ ✓
tags/3.0.0/ ✓
tags/new/ ✗
tags/final/ ✗
tags/great-release/ ✗
/assets — Your WordPress.org Artwork
The repository-level:
/assets/
directory is different from an assets folder that might exist inside your actual plugin.
WordPress.org uses this repository directory for Plugin Directory presentation assets such as:
- icons;
- banners;
- screenshots.
WordPress recommends keeping these assets outside trunk so they aren’t unnecessarily included in the downloadable plugin ZIP.
A repository might therefore look like:
your-plugin/
│
├── assets/
│ ├── icon-128x128.png
│ ├── icon-256x256.png
│ ├── banner-772x250.png
│ ├── banner-1544x500.png
│ └── screenshot-1.png
│
├── tags/
│ └── 1.2.0/
│
└── trunk/
├── your-plugin.php
├── readme.txt
└── ...
Your First SVN Checkout
Once WordPress.org has approved your plugin and provided the SVN repository, you need a local working copy.
Using the command line, that looks like:
svn checkout https://plugins.svn.wordpress.org/your-plugin/ your-plugin-svn
You may also see the abbreviated command:
svn co https://plugins.svn.wordpress.org/your-plugin/ your-plugin-svn
co means checkout.
This creates a local working copy of the WordPress.org repository. WordPress’s documentation uses this same checkout process for beginning a new plugin repository.
You can then enter it:
cd your-plugin-svn
and you’ll have your repository structure locally.
Add Your Plugin to Trunk
Copy the contents of your production plugin into:trunk/
Again, you want:
trunk/your-plugin.php
rather than:trunk/your-plugin/your-plugin.php
Once the files are there, tell SVN that the new files should be tracked.
For example
svn add trunk/*
SVN may respond with something resembling:
A trunk/your-plugin.php
A trunk/readme.txt
A trunk/includes
A means the item has been added.
It hasn’t been published yet.
You’ve simply told SVN:
Include these files in the next commit.
Check Your SVN Status Before Publishing
One of the most useful SVN commands is:
svn status
or:
svn stat
You might see:
M trunk/your-plugin.php
A trunk/includes/new-feature.php
D trunk/includes/old-file.php
These status indicators tell you what’s about to change.
For example:
M = Modified
A = Added
D = Deleted
This is an important habit:
Always inspect your pending SVN changes before publishing.
You can also inspect the actual differences with:
svn diff
WordPress recommends using svn stat and svn diff when reviewing changes to an existing plugin before committing them.
Update Your Local SVN Working Copy
Before preparing a new release, synchronize your local repository with WordPress.org:
svn update
or:
svn up
This retrieves remote changes and brings your working copy up to date.
A clean result may simply say:
At revision 1234567.
This step is particularly important if more than one person can commit to the plugin.
You don’t want to prepare a release against an outdated local working copy.
Version Numbers Matter
Suppose you’re releasing:
2.4.0
Several pieces of the release need to agree.
Your main plugin PHP header should contain:
Version: 2.4.0
Your readme.txt should contain:
Stable tag: 2.4.0
And the release should exist as:
tags/2.4.0/
Think of the release identity as:
Plugin PHP
Version: 2.4.0
│
▼
readme.txt
Stable tag: 2.4.0
│
▼
WordPress SVN
tags/2.4.0/
These should remain synchronized.
WordPress specifically identifies a mismatch between the Stable Tag and the version in the main plugin file as a common issue.
How WordPress Uses Stable Tag
This part of SVN publishing is worth understanding because it explains some otherwise confusing behavior.
WordPress.org first examines:
trunk/readme.txt
and reads:
Stable tag: 2.4.0
If that stable tag exists, WordPress then looks for:
tags/2.4.0/
Once WordPress finds that tagged release, the tagged version becomes important for the Plugin Directory’s parsing.
The actual plugin version displayed by WordPress.org comes from the main plugin PHP file, not simply from the name of the SVN tag directory.
That’s why version synchronization matters.
Create a Release Tag
WordPress recommends creating releases from trunk.
Suppose your finished release is version:
2.4.0
After updating trunk, create the release with:
svn copy trunk tags/2.4.0
or:
svn cp trunk tags/2.4.0
You should see SVN mark the new tag for addition.
The advantage of using svn copy instead of an ordinary filesystem copy is that Subversion preserves the repository relationship and history.
WordPress specifically recommends creating tags from trunk using svn cp.
Commit the Release
Once you’ve checked everything, commit it:
svn commit -m "Release version 2.4.0"
or:
svn ci -m "Release version 2.4.0"
WordPress requires a commit message for SVN check-ins.
Depending on your authentication setup, SVN may request your WordPress.org credentials.
WordPress.org also supports an SVN-specific password associated with your account, and your WordPress.org username is case-sensitive for SVN authentication.
Don’t Use WordPress SVN Like GitHub
This is one of the biggest mistakes new plugin developers can make.
You may be accustomed to doing this in Git:
Commit
Commit
Commit
Commit
Push
Pull request
Merge
Commit
Commit
Don’t reproduce your normal development history in WordPress.org SVN.
WordPress says its SVN and Plugin Directory infrastructure should be treated as a release repository and advises against pushing every small change. Each push causes plugin ZIP files to be rebuilt.
A healthier workflow is:
DEVELOPMENT
Git / GitHub
│
├── feature work
├── fixes
├── commits
├── branches
└── testing
│
▼
RELEASE READY
│
▼
WordPress SVN
│
├── update trunk
├── create tag
├── commit
└── verify
Develop in Git. Release through WordPress SVN.
Updating an Existing Plugin
Suppose version 2.4.0 is currently published and you’re preparing 2.5.0.
A sensible manual workflow looks like:
1. Finish 2.5.0 in your development repository
↓
2. Test the production plugin
↓
3. Update the PHP version to 2.5.0
↓
4. Update readme.txt
Stable tag: 2.5.0
↓
5. Add the 2.5.0 changelog
↓
6. svn update
↓
7. Replace/update trunk with the release
↓
8. Review svn status + svn diff
↓
9. svn copy trunk tags/2.5.0
↓
10. Commit the release
↓
11. Verify WordPress.org
That’s the core WordPress SVN release cycle.
What About README.md?
This is another area that can confuse developers coming from GitHub.
GitHub commonly uses:
README.md
WordPress.org primarily relies on:
readme.txt
WordPress notes that while other readme formats can work in some situations, readme.txt receives priority and should follow the WordPress.org readme format.
It’s therefore completely reasonable for a project to maintain:
README.md
for GitHub and:
readme.txt
for WordPress.org.
They serve related but different publishing environments.
Can I Change Only readme.txt?
Sometimes you’re not releasing new plugin code at all.
Maybe you’ve spotted:
- a typo;
- a description problem;
- an incorrect compatibility statement;
- documentation that needs clarification.
This is where understanding the Stable Tag becomes especially important.
If trunk/readme.txt points to a version under /tags/, changing only the description in trunk/readme.txt may not change the live Plugin Directory page, because WordPress can be reading the readme associated with the stable tagged release instead.
So when a documentation-only change doesn’t appear, don’t immediately assume SVN failed.
Check which readme.txt WordPress.org is actually using.
This is one of those small details that can save a lot of head-scratching.
Don’t Upload Plugin ZIP Files to SVN
Your WordPress.org SVN repository should contain the actual plugin files.
Don’t put:
my-plugin-2.4.0.zip
inside the SVN repository.
WordPress explicitly advises against uploading ZIP or other compressed release files into the repository.
WordPress generates the downloadable plugin package from the repository.
Don’t Put Development Files Into a Release
Before publishing, check that your release doesn’t accidentally contain development-only material.
WordPress’s guidance is simple: don’t put anything in SVN that you aren’t prepared to deploy to plugin users.
That’s another reason to maintain a deliberate production packaging step rather than blindly copying an entire development repository into SVN.
Always Tag WordPress Plugin Releases
Although developers historically used trunk in different ways, WordPress now strongly recommends properly tagged releases.
WordPress describes tagging as the fully supported method for ensuring the correct versions are presented and delivered to users.
So instead of relying on
Stable tag: trunk
prefer:
Stable tag: 2.5.0
with:
tags/2.5.0/
WordPress explicitly says that using trunk as the Stable Tag is not the recommended or fully supported approach and has caused problems with automatic updates.
Verify the Release After Committing
Publishing isn’t finished simply because SVN says:
Committed revision 1234567.
Go to the WordPress.org Plugin Directory and verify the release.
Check:
- the version number;
- description;
- changelog;
- Tested up to information;
- screenshots;
- icon and banners;
- downloadable ZIP;
- plugin contents;
- and whether WordPress installations recognize the new version.
WordPress.org processing isn’t necessarily instantaneous. WordPress notes that SVN pushes rebuild plugin ZIP files and updates can sometimes take time to propagate.
A Typical WordPress SVN Command Cheat Sheet
Here are the commands you’ll use most often:
# Check out the repository
svn checkout https://plugins.svn.wordpress.org/your-plugin/ your-plugin-svn# Enter the repository
cd your-plugin-svn# Get the latest remote changes
svn update# See pending changes
svn status# Inspect differences
svn diff# Add new files
svn add trunk/*# Create a release tag
svn copy trunk tags/2.5.0# Commit everything
svn commit -m "Release version 2.5.0"
These few commands cover a surprising amount of the normal WordPress.org publishing workflow.
Do You Actually Need an SVN Client?
Technically, no.
You can publish entirely through the command line.
But that doesn’t mean it’s the most convenient approach—especially if you’re maintaining several WordPress plugins.
A traditional SVN GUI can make Subversion easier to navigate, but WordPress plugin publishing has additional concepts beyond generic SVN:
Plugin ZIP
↓
Version validation
↓
readme.txt
↓
Stable Tag
↓
SVN working copy
↓
trunk
↓
release tag
↓
directory artwork
↓
credentials
↓
commit
↓
WordPress.org verification
That’s why a WordPress-specific publishing tool can be more useful than a generic SVN client.
An Easier Way to Use WordPress SVN
WordPress Plugin Publisher was created because we encountered this exact problem.
After building several WordPress plugins, repeatedly preparing releases and moving them through WordPress.org SVN became a workflow of its own.
So we built a native macOS application around the publishing process.
Instead of manually managing every SVN operation, WordPress Plugin Publisher organizes the release into synchronized steps.
Create Release
Publisher builds and validates the plugin release before it reaches the repository.
Connect the WordPress.org Repository
Connect the permanent SVN working copy associated with your plugin.
Publisher understands the WordPress.org repository structure:
assets/
tags/
trunk/
Prepare Repository
The finished plugin release is staged into trunk, the version release is prepared under tags, and existing WordPress.org directory artwork can be preserved when it doesn’t need to change.
Publishing Intelligence
Before publication, Publisher checks the pieces involved in the release so you can see whether the plugin is actually ready to publish.
Publish & Verify
Publisher commits the prepared release through WordPress.org SVN and verifies the published state.
The workflow becomes:
CREATE RELEASE
│
▼
PREPARE REPOSITORY
│
▼
PUBLISHING INTELLIGENCE
│
▼
PUBLISH RELEASE
│
▼
VERIFY
And because the steps stay synchronized in the Publisher interface, you can see where a release stands without piecing together the state from several SVN commands.
SVN Publishing Without Becoming an SVN Expert
SVN isn’t inherently difficult.
The challenge is that most WordPress plugin developers don’t build plugins because they want to manage Subversion repositories.
They want to build plugins.
If you only release occasionally and enjoy the command line, WordPress’s SVN tools may be all you need.
If you’re maintaining multiple plugins, publishing frequently, or simply want a safer visual workflow, that’s where WordPress Plugin Publisher is designed to help.
Keep Git for development. Keep WordPress SVN for releases. Let Publisher manage the path between them.
Publish your next WordPress plugin release without wrestling with SVN.
WordPress Plugin Publisher for macOS
7-day free trial. Then $69/year.