When publishing your plugin to the official WordPress repository, you HAVE to use SVN. As for September 2019, WordPress doesn't support GIT repos.
Using SVN instead of GIT (as your code version control) wouldn’t be more than a mere inconvenience if it wasn’t for the fact that WordPress’ SVN is not meant to be used as a code version control. You need to use something else for this, like GIT.
From WordPress’ official page (opens new window):
SVN and the Plugin Directory are a release repository. Unlike Git, you shouldn’t commit every small change, as doing so can degrade performance. Please only push finished changes to your SVN repository.
So, if you want to have a code version control (you should have one), you need to set it up separately. Even if you like SVN more than GIT, you must set an additional SVN repo just for your code version control. You can’t use WordPress’ SVN for code control.
In this tutorial, I will show you how to use GIT and SVN together, in an organized way. GIT for code control and SVN for publishing only.
I am 100% sure you are working in a structure like this:
my-project
└── wp-content
└── plugins
└── my-plugin
└── my-plugin.php
The my-project
folder is a full WordPress installation, used as a shell for your plugin development.
my-plugin
is your actual plugin folder. It’s where all development happens.
And obviously, my-plugin/my-plugin.php
is the plugin’s entry-point.
Our final folder structure will be:
my-project
├── working-env
│ └── wp-content
│ └── plugins
│ └── my-plugin
│ ├── .git
│ └── my-plugin.php
└── svn
├── assets
├── branches
├── tags
└── trunk
├── .git
└── my-plugin.php
The working-env
folder is our WP installation, just renamed. It is still where we do all our work. Notice that we have initialized GIT on my-plugin
, which means the plugin folder is the only thing on GIT. We don’t need to keep the whole WP instance on version control nor make backups of it. In case we need to restore the project (ex. install it in a new machine), we re-create “working-env” from a brand new WP installation and clone the GIT repo in the “my-plugin” folder.
The svn
folder is only used for deployment. It has the 4 standard SVN folders: assets, branches, tags, and trunk. This structure is automatically generated by WordPress once we clone the SVN repository. We don’t need to keep this folder on GIT nor make backups of it. Even if we destroy the entire “svn” folder, we can always restore it from the SVN repo. A quick explanation about its structure: the assets
folder contains images displayed on the plugin’s page (screenshots, banners and plugin icon). The trunk
folder is the current stable version that is available for download on WP.
The workflow is: we work on “my-plugin” (“working-env”) and once is tested and ready for deploy, we update the “trunk” folder (with “my-plugin” files), and we call the svn command to submit.
Once your first version is tested and ready to be published, we need to set up the readme.txt
file (as per WP’s official guide (opens new window)).
We don’t have our GIT and SVN set up yet, but don’t worry – we will do after preparing our code for publishing.
Read the rules for publishing. It only takes a few seconds and you will discover a lot of things that are not allowed (like having a jQuery library on your plugin): https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/ (opens new window)
Our plugin must have a name and it must follow these rules:
readme.txt
(most IMPORTANT step!!!)Before publishing your plugin, you MUST edit the readme.txt
file. It seems a silly thing to do, but this file actually governs many aspects of the plugin.
The readme file defines the plugin name, version and other control information used for updates and repository management. This file is also the first thing the users will see when looking for plugins on the WP directory (description, screenshots, etc).
If you created your plugin with WP-CLI, you should have a “readme.txt” file with a full example ready to be edited.
WARNING
Important fields you NEED to set:
For a complete list of all fields (and for a full example): https://developer.wordpress.org/plugins/wordpress-org/how-your-readme-txt-works/ (opens new window)
Test your final readme.txt
file here:
https://wordpress.org/plugins/developers/readme-validator/ (opens new window)
Once your readme.txt is ready, let’s create an empty SVN repository on WordPress:
my-plugin.zip
(change “my-plugin” to your plugin’s name);WARNING
It can take a few days for your plugin be reviewed. Once approved, you will receive SVN credentials on your email.
WARNING
Once approved, the SVN repo will be empty. They won’t prefill it with your plugin.
While you wait your plugin be approved, let’s set GIT on wp-content/plugins/my-plugin
.
If you have used wp-cli
, you don’t need to do anything: there will be a .gitignore in your folder. If you haven’t used it, then you will need one:
.DS_Store
wp-cli.local.yml
node_modules/
vendor/
*.zip
*.tar.gz
composer.lock
*.log
phpunit.xml
phpcs.xml
.phpcs.xml
PS: I prefer to remove the composer.lock
line as I want it on git control. As per official Composer documentation, composer.lock
should be in the version control as well as composer.json
(but never vendor
).
cd wp-content/plugins/my-plugin
git init
git add -a
git commit -m "my first commit"
On GitHub, follow the second set of instructions, "Push an existing repository...":
cd wp-content/plugins/my-plugin
git remote add origin https://github.com/username/new_repo
git push -u origin master
my-project
to my-project\working-env
mv my-project working-env
mkdir my-project
mv working-env my-project
Check the structure:
cd my-project
ls
working-env
Once the plugin has been approved and you get the SVN credentials on your email:
cd my-project
svn checkout --depth immediates https://plugins.svn.wordpress.org/your-plugin-name svn
Update code (should be empty, but just in case):
cd svn
# /svn
svn update --set-depth infinity assets
svn update --set-depth infinity trunk
Structure of my-project/svn
:
# /svn
ls
/assets/
/branches/
/tags/
/trunk/
PS: assets
is where you put the icon/banner/screenshots for your WP’s plugin page. It is not where you put your plugin’s JS/CSS/images.
.wordpress-org
)It’s a good idea to have this folder even if you don’t have yet screenshots / icon / a banner for your plugin page on WP’s directory.
# /working-env/wp-content/plugins/my-plugin
mkdir .wordpress-org
Now, make sure this folder is not going to be sent to SVN inside our code tree (we will manually push them to /assets
along trunk and others).
Open .distignore
and add the line .wordpress-org
anywhere (at beginning or bottom for example):
# /working-env/wp-content/plugins/my-plugin
nano .distignore
# .distignore
.wordpress-org
...
PS: You can name this .wordpress-org
folder anything you want actually, but I prefer .wordpress-org
because it is used by many other plugins.
.distignore
While you have .distignore
opened, remove these two lines:
vendor
node_modules
While sending these folders to SVN can cause security issues to your plugin, the security issues are for dev dependencies only and we are going to manually re-generate these folders on production mode, so it is safe to send them to SVN.
Also, add files/folders that you want to have on GitHub but not on SVN. Examples:
.github
(GitHub files, like GitHub Action Workflow files);.vscode
(VSCode editor settings);Steps:
.wordpress-org
folder;screenshot-#.jpg (or png)
WARNING
Valid file names: screenshot-1.jpg
, screenshot-2.png
.
Invalid file names: main-screen-1.jpg
, menu-items.png
.
Change “Screenshots” section on readme.txt
:
== Screenshots ==
1. This is a screenshot description
2. This is a description for the second screenshot
TIP
Official Guide: https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#screenshots (opens new window)
Icon (official guide here (opens new window)):
.wordpress-org
folder;icon-256x256.png
– see guide for different formats);readme.txt
changes;Banner:
Go to the project root:
cd my-project
ls
working-env
svn
Get a clean copy from GIT and save it as temp-git
. This will be the production version, with no dev code:
# /
git clone https://github.com/username/my-repo-name temp-git
Our root structure will be:
# /
ls
working-env
svn
temp-git
Compile production code for your project:
# /
cd temp-git
composer install --no-dev
npm install --production
Sync SVN/production code (copy code to trunk
, ignoring files in .distignore
):
# /
cd svn
rsync -rc --exclude-from="../temp-git/.distignore" "../temp-git/" trunk/ --delete --delete-excluded
Copy files from .wordpress-org
to SVN (plugin’s screenshots, icons, banner):
# /svn
rsync -rc "../temp-git/.wordpress-org" assets/ --delete
Add files to the SVN control:
# /svn
svn add . --force
svn status | grep '^\!' | sed 's/! *//' | xargs -I% svn rm %@
Create your first version tag (ex. 0.0.1
):
# /svn
svn cp "trunk" "tags/0.0.1"
Fix screenshots MIME types (to avoid downloading them when clicking):
# /svn
svn propset svn:mime-type image/png assets/*.png || true
svn propset svn:mime-type image/jpeg assets/*.jpg || true
Submit your SVN to WP:
# /svn
svn ci -m 'Adding first version of my plugin'
Remove svn
and git-temp
folders as they won’t be used anymore:
# /svn
cd ..
# /
rm -Rf temp-git
rm -Rf svn
TIP
Congratulations! Your plugin is now publicly available for download.
Do your changes to working-env
and test them. Once you are ready, you can proceed.
In this example, let’s change the version from 1.0.0
to 1.0.1
.
Change 2 files: readme.txt
and my-plugin.php
. Don’t forget to add a Changelog entry to readme.txt
.
Go to my-plugin
folder:
cd working-env/wp-content/plugins/my-plugin
Add files, commit, and push:
git add -i
git commit -m "some changes"
git push origin master
Follow step 11, changing the version number to your current version number.
To receive email notifications when your users submit support requests:
Done!