Quick Tip: Deploying a Plugin From Git to WordPress.org

Quick Tip: Deploying a Plugin From Git to WordPress.org

You’re developing a plugin on GitHub, and now you’re ready to deploy it to WordPress.org… uh-oh, WordPress.org plugin development is done via SVN. Now what? Not to worry, there’s a script for that.

Recently I’ve been developing a plugin for WordPress that I wanted to release on the WordPress.org plugin directory. I prefer to use Git as my version control software these days (I used to use SVN), but the plugin directory uses SVN. Luckily, there’s a nice script available on GitHub called “Github to WordPress Plugin Directory Deployment Script” to allow me to develop with Git, and then deploy directly to the SVN repository on WordPress.org when I’m ready to release the lastest version.

This version of the script is from Ben Balter, which was forked from a similar script by Brent Shepherd, which was forked from a script by Dean Clatworthy. Each of them has made various improvements on the one before, and I’ve found the end result to be really useful.

I’ve created my own fork of this script which I use, so it has my SVN username.


The Script

#! /bin/bash
#
# Script to deploy from Github to WordPress.org Plugin Repository
# A modification of Dean Clatworthy's deploy script as found here: https://github.com/deanc/wordpress-plugin-git-svn
# The difference is that this script lives in the plugin's git repo & doesn't require an existing SVN repo.
# Source: https://github.com/thenbrent/multisite-user-management/blob/master/deploy.sh

#prompt for plugin slug
echo -e "Plugin Slug: \c"
read PLUGINSLUG

# main config, set off of plugin slug
CURRENTDIR=`pwd`
CURRENTDIR="$CURRENTDIR/$PLUGINSLUG"
MAINFILE="$PLUGINSLUG.php" # this should be the name of your main php file in the wordpress plugin

# git config
GITPATH="$CURRENTDIR/" # this file should be in the base of your git repository

# svn config
SVNPATH="/tmp/$PLUGINSLUG" # path to a temp SVN repo. No trailing slash required and don't add trunk.
SVNURL="http://plugins.svn.wordpress.org/$PLUGINSLUG/" # Remote SVN repo on WordPress.org, with no trailing slash
SVNUSER="benbalter" # your svn username

# Let's begin...
echo ".........................................."
echo 
echo "Preparing to deploy WordPress plugin"
echo 
echo ".........................................."
echo 

# Check version in readme.txt is the same as plugin file
NEWVERSION1=`grep "^Stable tag" $GITPATH/readme.txt | awk -F' ' '{print $3}'`
echo "readme version: $NEWVERSION1"
NEWVERSION2=`grep "^Version" $GITPATH/$MAINFILE | awk -F' ' '{print $2}'`
echo "$MAINFILE version: $NEWVERSION2"

if [ "$NEWVERSION1" != "$NEWVERSION2" ]; then echo "Versions don't match. Exiting...."; exit 1; fi

echo "Versions match in readme.txt and PHP file. Let's proceed..."

cd $GITPATH
echo -e "Enter a commit message for this new version: \c"
read COMMITMSG
git commit -am "$COMMITMSG"

echo "Tagging new version in git"
git tag -a "$NEWVERSION1" -m "Tagging version $NEWVERSION1"

echo "Pushing latest commit to origin, with tags"
git push origin master
git push origin master --tags

echo 
echo "Creating local copy of SVN repo ..."
svn co $SVNURL $SVNPATH

echo "Ignoring github specific files and deployment script"
svn propset svn:ignore "deploy.sh
README.md
.git
.gitignore" "$SVNPATH/trunk/"

#export git -> SVN
echo "Exporting the HEAD of master from git to the trunk of SVN"
git checkout-index -a -f --prefix=$SVNPATH/trunk/

#if submodule exist, recursively check out their indexes
if [ -f ".gitmodules" ]
then
echo "Exporting the HEAD of each submodule from git to the trunk of SVN"
git submodule init
git submodule update
git submodule foreach --recursive 'git checkout-index -a -f --prefix=$SVNPATH/trunk/$path/'
fi

echo "Changing directory to SVN and committing to trunk"
cd $SVNPATH/trunk/
# Add all new files that are not set to be ignored
svn status | grep -v "^.[ \t]*\..*" | grep "^?" | awk '{print $2}' | xargs svn add
svn commit --username=$SVNUSER -m "$COMMITMSG"

echo "Creating new SVN tag & committing it"
cd $SVNPATH
svn copy trunk/ tags/$NEWVERSION1/
cd $SVNPATH/tags/$NEWVERSION1
svn commit --username=$SVNUSER -m "Tagging version $NEWVERSION1"

echo "Removing temporary directory $SVNPATH"
rm -fr $SVNPATH/

echo "*** FIN ***"

Usage

I use this script by having it sitting in my /wp-content/plugins/ directory. Then when I’m ready to deply one of my plugins, from the Terminal, I run ./deploy.sh. The script then prompts me for the slug of my plugin, which I provide. It checks that the plugin version matches the “Stable” version in my plugin’s readme.txt, and then goes about it’s business doing the deployment.


What Does It Actually Do?

In essence, the script does the following steps:

  1. Creates a tag for the release version in your Git repository
  2. Creates a temporary SVN checkout of your plugin’s repository from WordPress.org
  3. Exports the contents of your Git repository into the SVN repository
  4. Commits these changes to the SVN repository
  5. Creates a tag in the SVN repository and commits that
  6. Removes the temporary SVN checkout from your development machine

That’s it! Well, there are a few other things in there such as recursively checking out so it supports submodules, etc. as well, but that’s the crux of it.

Enjoy!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Pingback: Quick Tip: Deploying a Plugin From Git to WordPress.org - Red Free Hosting | Red Free Hosting

  • http://www.themer.me/ Norris

    The best tip ever! Thank you a million :).
    I’m no good with SVN, so this is just what I needed :)

    • http://wp.tutsplus.com/ Japh
      Author

      My pleasure, @justnorris:disqus! Glad you’ll find it useful :)

  • http://roadha.us/ haliphax

    Excellent. I’ve been looking for a way to break away from maintaining both repos for plugins with git-svn, and this looks like it’ll do the trick quite nicely!

    • http://wp.tutsplus.com/ Japh
      Author

      Brilliant, @haliphax:disqus! It certainly takes a lot of the headache out of having to continue with both VCSs.

  • wycks

    I recommend checking out http://subgit.com/ it will do everything automatically, so you never have to deal with svn.

    • http://wp.tutsplus.com/ Japh
      Author

      Thanks for the suggestion, @wycks:disqus :)

      • wycks

        The intro of the site is kinda poor, but basically you can just use git and it will auto mirror everything in SVN or vice-versa.

  • http://twitter.com/GaryJ Gary Jones

    Another variant is my own https://github.com/GaryJones/wordpress-plugin-git-flow-svn-deploy – that takes mostly Ben’s code, adds in some wp.org plugin repo asset handling, and tweaks it to account for commits made via git-flow. The README has more details.

    • http://wp.tutsplus.com/ Japh
      Author

      Excellent! Thanks for the addition, @twitter-14137938:disqus :)

  • Pingback: Grab Media Introduces the GrabPress Plugin for Increased Video Engagement … | Open Knowledge

  • http://stephenharris.info/ Stephen Harris

    J F Kaiser (http://unserkaiser.com/) were just discussing this very snippet (and @twitter-14137938:disqus variant) the other day. I had recently posted about another attempt at using git-svn (while trying to retain your git history, but squashing everything you send to svn) – but this definitely seems to be the way forward! (Might also tie in nicely with scripts I use to automatically validate & compress javascript files in my plug-ins).

    • http://wp.tutsplus.com/ Japh
      Author

      Excellent! I’m pleased to hear the timing was good :)

      I love the idea of using something like this script, along with others, to make a complete automated deployment.

  • Pingback: The WordPress Weekend Roundup - WP Daily