ALT.NET manage software teams 101 with SvnManager Post Create Script and Zend Framework

As a custom software development vendor in Dallas, Texas, we end up with several projects at a time. The faster we can build the team, and the various stages of development, the more responsive we can be to the client. These stages include creating the initial repository to centralize client code with correct security rights, and setting up the TeamCity build environment to push out to various environments for dev, test, staging, UAT, and production, Our automation scripts play a vital role in making our software shop successful, by removing headaches, improving response rates, freeing up time for vital members of the team, and providing consistency across projects.

Automation allows software vendors to be more responsive, provide customers transparency, remove developer roadblocks quickly, and reduce risk to deployment. While this article helps in automating the setup of a new team, it is merely a preliminary step for what is needed to run a successful shop.

SVNManager

SVNManager solves management of SVN repositories and team member access problems. Here are a couple of screenshots showing the major functionality exposed by SVNManager after installation.

svnmanager user administration

svnmanager group administration

svnmanager repository administration

SVNManager Post Create Script and Zend Framework

SVNManager can be extended by uncommenting the variable called: ‘$post_create_script’. This is a hook that allows external programs to run once a repository has been created. locating post_create_script

Once a repository has been created, RepositoryModule/DataModule.php on line 101 checks to see if the variable “is set”, to determine whether to execute the value using php’s exec function. The input sent to the external program is the complete path to the new repository.

SVNManager config.php

           $post_create_script = "/bin/bash /var/www/postcreatescript";

        

We have used a bash entry script to copy our template hooks into the hooks folder of the new repository. The only thing missing here is the command to import an initial check-in using: svnadmin load $1 < template .

postcreatescript

           #!/bin/bash
cp -R /var/www/repo-template/* $1/hooks/

        

We wanted a centralize location to maintain the hooks. So the copies of hooks copied into each individual repository simply redirect the command to our centralized location. We could have also solved this with a symbolic link but we choose the following:

post-commit

           #!/bin/sh
REPOS="$1"
REV="$2"
/var/svn/hooks/post-commit-main $REV $REPOS

        

post-commit-main

           #!/bin/sh
/usr/bin/php /var/svn/hooks/post-commit-email $1 $2
#more cli scripts to execute

        

post-commit-email - the goal with this script is to build transparency among developers, regarding what and who is making changes in the repository. This also encourages team members to integrate promptly, as soon as updates become available. This post commit email sends an email, to all users with access, through SVNManager, using group or user privileges to repository.

          <?php
$includePath = array();
$includePath[] = '/var/svn/hooks';
$includePath[] = get_include_path();
$includePath = implode(PATH_SEPARATOR,$includePath);
set_include_path($includePath);

require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();



/**
 * The repository and the revision number are passed as arguments
 */
$repository = isset($argv[2]) ? $argv[2] : '';
$revision = isset($argv[1]) ? $argv[1] : '';
$repositoryName = basename($repository);



/**
 * Lookup author, commit message and what has changed using svnlook
 */
$output = array();
exec('svnlook author ' . $repository, $output);
$author = implode("\r\n",$output);

$output = array();
exec('svnlook changed ' . $repository, $output);
$changed = implode("\r\n",$output);

$output = array();
exec('svnlook log ' . $repository, $output);
$log = implode("\r\n",$output);

/**
 * Grab the diff of the commit

$diff = '';
$fp = popen('svnlook diff ' . $repository, "r");
while(!feof($fp)) {
  $diff .= fread($fp, 1024);
  flush();
}
pclose($fp);
*/

$today = date("D F j, Y, g:i a");

$body = "
Author: $author
Date:  $today
Revision: $revision

Log:
$log

Changed:
$changed
";

$subject = "[SVN] $repositoryName commit";


/**
 * The email headers. Change it to your email address
 */
$headers = 'From: your-svn@domain.com' . "\r\n" .
    'Reply-To: your-email@domain.com' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();





$dbh = new PDO("mysql:host=localhost;dbname=svnmanager", "your-mysql-username", "your-mysql-password");
$dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sth = $dbh->prepare ("
	SELECT u.email FROM repositories as r
		INNER JOIN repo_descriptions as rd ON rd.repo_id = r.id
		INNER JOIN groupprivileges as gp ON gp.repositoryid = r.id
		INNER JOIN groups as g ON g.id = gp.groupid
		INNER JOIN usersgroups as ug ON ug.groupid = g.id
		INNER JOIN users as u ON u.id = ug.userid
		WHERE r.name = :moduleName
	UNION
	SELECT u.email FROM repositories as r
		INNER JOIN repo_descriptions as rd ON rd.repo_id = r.id
		INNER JOIN userprivileges as up ON up.repositoryid = r.id
		INNER JOIN users as u ON u.id = up.userid
		WHERE r.name = :moduleName
	UNION
	SELECT u.email FROM repositories as r
		INNER JOIN users as u ON u.id = r.ownerid
		WHERE r.name = :moduleName
	");

$sth->bindValue (":moduleName", $repositoryName);

$sth->execute ();


while ($row = $sth->fetch (PDO::FETCH_ASSOC))
{
      $config = array('auth' => 'login',
	              'username' => 'your-username',
	              'password' => 'your-password');
      $transport = new Zend_Mail_Transport_Smtp('your-smtp-server.com', $config);

      $mail = new Zend_Mail();
      $mail->setBodyText($body);
      $mail->setFrom('your-email@domain.com', 'Your Name');
      $mail->addTo($row["email"], $row["email"]);
      $mail->setSubject($subject);
      $mail->send($transport);

}
?>