July Architect article updated

Based on the comments received, I have updated my last month's article in the Architect column. In the end of the article, you will now find a 5-step summary on how to structure your source control repository in order to support:

  • Domain-driven design philosophy
  • Distributed application development
  • Structured, repeatable, and traceable release process

Thank you for reading Modelus Blog!

July Architect: How to organize your code in Source Control System

Problem Statement

One of the first questions facing development teams is deciding how to organize their code in a source control system. In this article, I will describe an approach that we have applied successfully at multiple organizations over the last decade. I hope it will help you and your team make your development environment and processes leaner and more efficient.


First, let's understand what capabilities we are looking for from our source control system:

  • Support of the domain-driven design philosophy
  • Support of a distributed application development
  • Support of a structured, repeatable, and traceable release process

Release Unit

Our source control system is organized around release units. Release Unit can be thought of as a collection of folders and files that are released (and thus, reused) together. It is a job of application architecture to break down a large monolithic application into multiple release units so that they can be tackled independently by different development teams.

Pull and Push Release Unit Dependencies

We recognize two types of dependencies between release units: Push and Pull. Let's assume that Release Unit A depends on Release Unit B. Push dependency means that every time B is changed, it is automatically integrated with A. Pull dependency means that B is integrated into A when A's development team decides to pull a new version of B into A.

An example of Pull Dependency: an application that depends on a shared domain. Even though a new version of the shared domain may be released each month, it does not force the application to be integrated, tested, and redeployed on a monthly basis. Instead, the application integrates with the shared domain only when the application development team decides to pull a new version of the shared domain into the application.

An example of Push Dependency: a web application that depends on the portal's header and footer. Every time, the new header and footer are implemented, each web application is automatically integrated with the new header and footer code.

Implementing Release Unit

We recommend to store a release unit in its own source control folder with the following layout:

/trunk - contains the latest version of the release unit code (may be in progress)
/tags - contains read-only copies of the code (e.g., previous releases of the code into production or test environments)
/branches - contains branch copies of the code

Implementing Pull Dependency

Create /lib folder in your release unit's trunk and place all release unit's pull dependencies there. Configure your release unit to automatically integrate with the dependencies placed in the lib folder. Next month, I will demonstrate how to set up a sample .NET solution structure with pull dependencies.

Implementing Push Dependency

Configure your release unit to link and automatically check out or export all its push dependencies. In Subversion, this can be achieved by using the svn-externals property.

Organizing Release Units

Even a medium-sized organization is likely to have hundreds or even thousands release units in their source control repository. In order to keep the repository manageable and easy to navigate, group release units belonging to the same bounded domain contexts together. For example, you may have a set of release units stored in the Accounting folder, another set stored in the HR folder, and another set stored in the Finance folder. You will need to refer to your domain context map in order to learn what bounded contexts exist in your organization.

5-Step Summary

  1. Structure source control to represent your domain context map
  2. Develop your applications using multiple release units
  3. For each release unit, assign ownership to a dedicated development team
  4. Integrate release units via Push and Pull dependencies
  5. Establish standard integration and release processes for all release units

Contact me if you have any questions or comments. Happy coding!

Team City 4.0 supports relative URL in the svn:externals property of Subversion 1.5

In my September post, I wrote that we upgraded our development environment from Subversion 1.4 to Subversion 1.5. We were hoping to use relative URL's in svn:externals property - the feature introduced in Subversion 1.5. We use svn:externals to connect to shared non-compilable release units, such as common styles, images, script libraries, content, etc. We immediately found out that although Team City 3.2, our build and integration server at the time, supported Subversion 1.5, it did not recognize relative URL's in svn:externals. We have recently upgraded our build server to Team City 4.0 and it does support relative URL's in svn:externals!

Contact me if you have any questions on how to structure your Subversion repository. Happy coding!

From Subversion 1.4 to Subversion 1.5

Last week, we upgraded our development environment from Subversion 1.4 running on Apache 2.0 to Subversion 1.5 running on Apache 2.2. The primary reason for this upgrade is the support of relative URLs in the svn:externals property introduced in the new version of Subversion. 

The upgrade process was smooth and easy. Here are the steps we followed:   

  1. Stopped our existing Apache Server
  2. Backed up our Subversion repository 
  3. Downloaded and installed Apache 2.2.9
  4. Downloaded and installed Subverstion 1.5.2
  5. Configured httpd.conf configuration file for our new Apache server and started the server
  6. Upgraded our repository by executing svnadmin upgrade
  7. Upgraded our indexes by executing svn-populate-node-origins-index
  8. Upgraded client tools - we installed Tortoise 1.5.3 and Ankh 2.0
  9. Upgraded Team City automated build and continuous integration server to the latest version 3.1.2
A couple of notes... 
  • In the past, in order to use Windows authentication with Subversion we had to write a custom mod_auth_sspi.so. We did not have to do anything for 1.5. Loading modules in the correct order and referencing them from the Subversion application folder did the trick for us:     
LoadModule sspi_auth_module modules/mod_auth_sspi.so
LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module C:/Apps/svn-win32-1.5.2/bin/mod_dav_svn.so
LoadModule authz_svn_module C:/Apps/svn-win32-1.5.2/bin/mod_authz_svn.so               
<Location /svn>
DAV svn
SVNPath C:\Dev\Repository

     AuthName "SVN Server"
     AuthType SSPI
     SSPIAuth On
     SSPIAuthoritative On
AuthzSVNAccessFile "C:/Repository/conf/authz"
     SSPIOfferBasic on
     Require valid-user     

  • Team City 3.1.2 does support Subversion 1.5, but unfortunately does not support relative URL's in the svn:externals property. 

Welcome to ModelBlog

Thank you for visiting ModelBlog. We hope the time you spend with us will be both entertaining and worth your while. Have fun!