Drupal 7: Implementing a Subversion pre-commit hook to integrate with Drupal
In this article I’ll show an example of how to implement a Subversion pre-commit hook to integrate with Drupal. Pre-commit hooks can be used to execute any arbitrary code, such as deployment procedures, archiving databases, etc. For this example, I will show how to check for the creation of a subversion tag and archive the database.
To get started I created a local subversion repository.
# create folder for subversion repositories
$ mkdir /var/subversion
# create the subversion repository
$ svnadmin create /var/subversion/project
Upon creating a new local svn repository, a hooks directory will be created. Example: /var/subversion/project/hooks
Inside this directory will be a bunch of sample scripts ending in “.tmpl” which contain example hook scripts. Here are the contents of the example pre-commit hook without comments:
$ cat pre-commit.tmpl | egrep -iv "(^#|^$)"
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook
$SVNLOOK log -t "$TXN" "$REPOS" | \
grep "[a-zA-Z0-9]" > /dev/null || exit 1
commit-access-control.pl "$REPOS" "$TXN" commit-access-control.cfg || exit 1
exit 0
As noted in the pre-commit.tmpl file, there are 2 arguments being passed to the pre-commit script:
[1] REPOS-PATH (the path to this repository)
[2] TXN-NAME (the name of the txn about to be committed)
I created a new file called “pre-commit” and added the following contents:
#!/bin/bash
/var/www/vhosts/project.vm/scripts/svn-pre-commit.php "$1" "$2"
I then made the file executable.
$ chmod ug+w pre-commit
The above script simply passes the arguments to a PHP script contained with the Drupal project.
In my scripts folder (/var/www/vhosts/project.vm/scripts), I created the PHP script “svn-pre-commit.php” with the following contents:
#!/usr/bin/php
<?php
// get args
$repo = $argv[1];
// define path to mysql backups
$mysql_backups_path = '/var/www/vhosts/project.vm/database';
// define path to drupal docroot
$drupal_docroot_path = '/var/www/vhosts/project.vm/htdocs';
// get changed path
// example output:
// A tags/20110503/
$svn_look = `svnlook changed $repo`;
// define pattern to break apart svnlook changed
$pattern = '/^\s*([A-Za-z])\s*(.*)$/';
// execute preg match
preg_match($pattern, $svn_look, $matches);
$svn_action = $matches[1];
$svn_changed_path = $matches[2];
// check if a tag is being created
if ($svn_action == 'A' && substr($svn_changed_path, 0, 5)=='tags/') {
// get tag name
$exploded = explode('/', $svn_changed_path);
$tag_name = $exploded[1];
// change dir to drupal docroot
chdir($drupal_docroot_path);
// backup mysql database using drush
`/var/www/drush/drush sql-dump > {$mysql_backups_path}/tag_{$tag_name}.sql`;
}
I also made this script executable:
$ chmod ug+w svn-pre-commit.php
Now assuming that my Drupal site is integrated with the subversion repository, and development is at a point to deploy/create a new tag, I executed the following command to create the subversion tag:
$ svn cp file:///var/subversion/project/trunk file:///var/subversion/project/tags/beta-0.1 -m "creating beta 0.1 tag"
To verify, I entered the directory containing my database dumps to checkout the result:
$ cd /var/www/vhosts/project.vm/database
$ ls -1
tag_beta-0.1.sql