ClickOnce and Nant – The Plot Thickens

Turns out that these ClickOnce deployment builds aren’t as piss-easy as I once thought.
Turns out that the builds need to be customised for different environments, nothing new there, but (and here comes the catch), all the environmental settings have to be applied at BUILD TIME!!! Why? I hear you ask, and the answer is: because if you edit the config files post-build it changes some checksum jiggery pokery wotnot and then the thingumyjig goes and fails!!! Typical. (Basically the details you need to configure are held in files you cannot edit post build because the manifest file will do a checsum evaluation and see that someone has edited the file, and throw errors).
So what I’ve decided to do is this….

  1. Copy all configurable files to seperate environmentally named folders pre-build.
  2. Use SED to replace tokens for each environment in these files
  3. Copy 1 of them back to the build folder
  4. Compile
  5. Copy the output to the environmentally named folder

redo steps 3,4,5 for all the environments.
And hey presto, this works.

<target name=”changeconfigs”>
<!–This bit sets up some folders where I’ll do the prep work for each environment–>
<delete dir=”${config.dir}\${project.name}” verbose=”true” if=”${directory::exists(config.dir+’\’+project.name)}” />
<mkdir dir=”${config.dir}\${project.name}\TestArea” />
<mkdir dir=”${config.dir}\${project.name}\DevArea” />
<mkdir dir=”${config.dir}\${project.name}\Staging” />
<mkdir dir=”${config.dir}\${project.name}\UAT” />
<mkdir dir=”${config.dir}\${project.name}\Live” />

<!–This bit moves a tokenised config file to these folders–>
<copy file=”${source.dir}\App_Master.config” tofile=”${config.dir}\${project.name}\TestArea\app.config” />
<copy file=”${source.dir}\App_Master.config” tofile=”${config.dir}\${project.name}\DevArea\app.config” />
<copy file=”${source.dir}\App_Master.config” tofile=”${config.dir}\${project.name}\Staging\app.config” />
<copy file=”${source.dir}\App_Master.config” tofile=”${config.dir}\${project.name}\UAT\app.config” />
<copy file=”${source.dir}\App_Master.config” tofile=”${config.dir}\${project.name}\Live\app.config” />

<!–This bit calls sed, which replaces the tokens with relevant values for each environment, more on sed another time!–>
<exec program=”${sedUAT.exe}” commandline=”${sedParse.dir}” />
<exec program=”${sedTestArea.exe}” commandline=”${sedParse.dir}” />
<exec program=”${sedDevArea.exe}” commandline=”${sedParse.dir}” />
<exec program=”${sedStaging.exe}” commandline=”${sedParse.dir}” />
<exec program=”${sedLive.exe}” commandline=”${sedParse.dir}” />
</target>

<!–This bit copies the edited file back to the build directory–>
<target name=”prepTestArea”>
<delete file=”${source.dir}\app.config” />
<copy file=”${config.dir}\${project.name}\TestArea\app.config” tofile=”${source.dir}\app.config” />
</target>

<!–This bit builds the ClickOnce project–>
<target name=”publishTestArea” >
<msbuild project=”${base.dir}\Proj1\ClickOnce.vbproj”>
<arg value=”/t:Rebuild” />
<arg value=”/property:Configuration=Release”/>
<arg value=”/p:ApplicationVersion=${version.num}”/>
<arg value=”/p:InstallUrl=http://testarea/ClickOnce/”/>
<arg value=”/t:publish”/>
<arg value=”/p:UpdateRequired=true”/>
<arg value=”/p:MinimumRequiredVersion=${version.num}”/>
</msbuild>
</target>

<!–This bit copies the output to an environment-named folder, ready for deployment–>
<target name=”copyfilesTestArea”>
<mkdir dir=”${versioned.dir}\TestArea” />
<copy todir=”${versioned.dir}\TestArea” includeemptydirs=”true”>
<fileset basedir=”${base.dir}\Proj1\bin\Release\”>
<include name=”**.publish\**\*.*” />
</fileset>
</copy>
</target>

REPEAT LAST 3 TARGETS FOR THE OTHER ENVIRONMENTS.

Now that wasn’t too hard, and it doesn’t take up too much extra time.
I suppose I’d better mention some of the arguments I’m passing in the MSBuild calls:

<arg value=”/t:Rebuild” /> – I do this because it must re build the .deploy files each time, or you get the previous builds environment settings left in there because MSBuild decides to skip files that haven changed….

<arg value=”/property:Configuration=Release”/> – Obvious

<arg value=”/p:ApplicationVersion=${version.num}”/> – ClickOnce apps have a version stamped on them for various reasons, one of them being for use in automatic upgrades – people with installshield knowledge will know what a joke that can be!

<arg value=”/p:InstallUrl=http://testarea/ClickOnce/”/> – A pretty important one this, it stamps the URL for the download onto the manifest or application file.

<arg value=”/t:publish”/> – just calls the publish task, I do this because this makes the setup.exe

<arg value=”/p:UpdateRequired=true”/>
<arg value=”/p:MinimumRequiredVersion=${version.num}”/> – These 2 together mean the app will do a forced upgrade when a new version becomes available

So far, so good. My next trick will hopefully be how to get 2 installations working side-by-side. Currently it doesn’t work because one will overwrite the other. I’m working on it okay!!??

Installing Go (crusie) build agents on linux

This is just an easy at-a-glance reference for installing the Go cruise agent on Linux because I’ve done it a few times and just want to have the instructions in one place. I’m using centos for my OS, but these instructions are true for most rpm supporting linux varieties.

Download the rpm:

You have to download the agent from the website here. Copy this to somewhere sensible on the target box, like /tmp for example.

Create User and Extract rpm:

After following the standard instructions a couple of times I noticed that the group and user “cruise” were not being created correctly on my servers. This could be an issue with the rpm I was using or an issue with the VM servers. Either way, to get around this issue I just manually create the group and user before extracting the rpm:

useradd cruise
groupadd cruise
useradd -G cruise cruise

Next I just install the rpm as root:

sudo rpm -i cruise-agent-2.0.0-11407.noarch.rpm

N.B. The latest rpm at this point in time is actually “go-agent-2.1.0-11943.noarch.rpm”.

The files are installed here:

/etc/default/cruise-agent

/var/lib/cruise-agent

/var/log/cruise-agent

/usr/share/cruise-agent

Connecting the Agent with the Server:

The file /etc/default/cruise-agent needs to be edited so that the cruise agent knows how to connect to the cruise server.

Open this file in vim or something similar. it should look like this:

CRUISE_SERVER=192.168.xxx.xx
export CRUISE_SERVER
CRUISE_SERVER_PORT=8153
export CRUISE_SERVER_PORT
AGENT_WORK_DIR=/var/lib/cruise-agent
export AGENT_WORK_DIR
DAEMON=Y
VNC=N

Simply change the IP address of the CRUISE_SERVER to the IP address of the cruise server! You might also need to change the port number if you’ve installed your cruise server to a non default port.

Next you need to start the agent:

/etc/init.d/cruise-agent start

And that’s about it. You should now see the agent appear in your agents list on the cruise server. Put a tick next to it and click enable and this will add the new agent to your cruise-config.xml, where you can assign resources or add it as an environment.

 

 

 

 

JDepend design metrics in CI

This article is intended to give the reader enough information to understand what JDepend is, what it does, and how to use it in a maven build. It’s a kind of cheat sheet, if you like.

What is it?

JDepend is more of a design metric than a code metric, it gives you information about your classes with regards to how they’re related to each other. Using this information you should be able to identify any unwanted or dubious dependencies.

How does it do that?

It traverses Java class files and generates design quality metrics, such as:

  • Number of Classes and Interfaces
  • Afferent Couplings (Ca) – What is this?? Someone probably feels very proud of themselves for coming up with this phrase. Afferent coupling means the number of other packages which depend on the package being measured, in a nutshell. JDepend define this as a measure of a package’s “responsibility”
  • Efferent Couplings (Ce) – Sort of the opposite of Ca. It’s a measure of the number of other packages that your package depends on
  • Abstractness (A) – The ratio of abstract classes to total classes.
  • Instability (I) – The ratio of efferent coupling (Ce) to total coupling (Ce + Ca)
  • Distance from the Main Sequence (D) – this sounds fairly wishy-washy and I’ve never paid any attention to it. It’s defined as: “an indicator of the package’s balance between abstractness and stability”. Meh.

 

To use JDepend with Maven you’ll need Maven 2.0 or higher and JDK 1.4 or higher. You don’t need to install anything, as maven will sort this out for you by downloading it at build time.

Here’s a snippet from one of my project POMs, it comes from in the <reporting> section:


 

<plugin>

    <groupId>org.codehaus.mojo</groupId>

    <artifactId>jdepend-maven-plugin</artifactId>

    <configuration>

        <targetJdk>1.6</targetJdk>

        <outputDirectory>build/maven/${pom.artifactId}/target/jdepend-reports</outputDirectory>

    </configuration>

</plugin>

 

What you’ll get is a JDepend entry under the project reports section of your maven site, like this:

project-reports-page

Maven Project Reports Page

 

And this is what the actual report looks like (well, some of it):

jdepend-report

jdepend report

Summary:

JDepend isn’t something I personally use very heavily, but I can understand how it could be used to good effect as a general measure of how closely related your classes are, which, in certain circumstances could prompt you to redesign or refactor your code.

I don’t think this sort of information is required on a per commit basis, so I’d be tempted to only include it in my nightly reports. However, I also use Sonar, and that has a built-in measure of afferent coupling, so if you’re only interested in that measurement and you’re already running Sonar, then JDepend is probably a bit of an unnecessary overhead. Also, Sonar itself has some good plugins which can provide architectural and design governance features, at least one of which I know implemented JDepend.

Sonar errors with Maven 2.2.1

I’m running maven 2.2.1 and trying to get my build to work with sonar 2.7, but I keep getting this error:

“Error resolving version for ‘org.codehaus.mojo:sonar-maven-plugin’: Plugin requires Maven version 3.0”

The Sonar FAQ rather unhelpfully says:
“This error means that you’re using Maven 2.0.10 or Maven 2.0.11.”
Er, no I’m not, actually!

The suggested workaround is to use 1.0-beta-2 in my POM, but when I do that I get:

“Unable to find resource ‘org.codehaus.mojo:sonar-maven-plugin:maven-plugin:1.0-beta-2′”

It’s one of those maven errors that says it can’t find it in the central repo even though it’s right there in front of your eyes…

Anyway, as a second workaround, I’ve referenced version 1.0-beta-1 and it seems to pick this up fine.

Hope this helps.

Build issue with maven-project-info-reports-plugin

Yesterday had a whole bunch of issues with some of my Maven plugins. I’ll list some details here for reference.

I’m running maven 2.2.1 and (I’ve suddenly just noticed) java 1.5.

The first error I recieved was:

Deprecated API called – not org.apache.maven.doxia.sink.Sink
instance and no SinkFactory available. Please update this plugin.

Which I thought was coming from my maven-jxr-plugin. So I simply commented it out, it’s not that important to me.

Next up I got:

A required class is missing org/apache/maven/reporting/AbstractMavenReport

Which, after a little googling, appeared to have something to do with the maven-project-info-reports-plugin. So I decided to upgrade to the latest version of maven-project-info-reports-plugin. No joy. Maven claimed it couldnd locate version 2.3.1 from ANY repository, despite the fact that it was there in the maven central repo AND I installed it in my own repo. I think this was the error it gave me:

unable to load the mojo org.apache.maven.plugins:maven-project-info-reports-plugin

So to fix this I randomly tried referencing an older version of the plugin (namely v 2.1.1) and it seems to work now. My plugin reference now looks like this in my POM:


<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-project-info-reports-plugin</artifactId>
    <version>2.1.1</version>
    <configuration>
           <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
    </configuration>
</plugin>


 

Right, I'm going to go update my java to 1.6, which it what it should have been all along, and hope that this wasn't the cause of all my woes yesterday 🙂

Build Pipelines Using Hudson/Jenkins or Bamboo

I’m currently working with the Go CI system from Thoughtworks. One of the things I really like about it is the way that you can have a build “pipeline”. What this means is that you can have a build job which is broken down into, let’s say, 3 different steps:

  1. Checkout and build code, and run unit tests
  2. Package and deploy to a test server
  3. Run acceptance test suite

The way they’ve set this up is pretty decent, it means that every check-in build can be setup to do all of those steps. But you don’t want to wait an hour just to get some feedback on your commit, so Go handles this by giving feedback at the end of each step, rather than having to wait to the end of the whole job.

In the past, when I’ve used Bamboo or Hudson, I’ve setup separate jobs for the check-in builds (which mainly just run unit tests and some light static analysis) and the nightly builds (which do the same, but also include much more static analysis as well as run automated functional tests).

However, it is possible to mimic the Go behaviour using Hudson/Jenkins or Bamboo.  These all support the practice of dependent builds. Hudson jobs have a “Build after other projects are built” option for example. So, to recreate what Go does, you can create separate jobs/plans which run in series. For example:

Job 1: Checks out code, compiles and runs unit tests.

Job 2: Runs coverage report and other static analysis tools such as CPD, PMD and FindBugs

Job 3: Packages up distributable, deploys it and initiates automated tests (e.g. using Selenium)

The developers will get their compile & unit test feedback as quickly as usual, but the process of running a much more exhaustive system will have been spawned as well. No need to wait for the results of the nightly builds to get the full build reports 🙂

Sonar now supports Ant

Great news for Ant users, the new version of Sonar (2.6) now includes support for Ant. Previously it only supported Maven, which was a bit of a pity because it’s such a good tool, so it’s really good to hear that you can now get all the goodness of Sonar with Ant as well. There’s also talk of support for gradle too.

There’s a new Sonar Ant task so you can add Sonar to your ant scripts (details here).

Here’s the link to the release page for version 2.6 of Sonar.

 

Maven 2 – An Overview

Here’s a high level Maven2 cheat sheet which just explains what Maven 2 is and the steps that are executed when Maven does a build.

What is Maven?
It’s a build tool, basically! It also manages dependencies and produces build reports. It uses xml syntax to create build files (called POMs), and the build files support the concept of inheritance. Maven uses plugins to extend basic functionality and perform cool tricks. It’s mainly used in the Java world but apparently there’s also a .Net plugin (I haven’t actually tried it though).

Why Use Maven?
I would recommend using maven if you need a build tool which will:

  • Take over dependency management
  • Enforce a (fairly) rigid format and practice on developers

The dependency management system uses repositories to store binaries. You can have external (third party) binaries as well as internal dependencies. You can reference them from external repositories (like the maven central repository) or you can put them in your own repository. I actually really like the way Maven enforces it’s own best practices on things like naming conventions and project structures, it’s a real time-saver in the long run.

Installing Maven
Installing maven is a doddle. Simply download it from here. Check the installation pre-requisites (you basically need JDK installed).

For instructions on installing maven on Mac OSX look here

For instructions on installing maven on Windows look here

For instructions on installing Maven on Linux you basically do the same as you do for Mac OSX. That is:

Extract the archive you downloaded.

Add an environment variable called M2_HOME and point it to your Maven directory (I installed mine in /home/maven/maven2).

Add the bin directory ${M2-HOME}/bin to your PATH

Add these to your bash_profile by simply adding these 2 lines:

export M2_HOME=/home/maven/maven2

export PATH=${M2_HOME}/bin:${PATH}

To confirm Maven is installed on your system, simply type: mvn -version

What Happens When I Run a Build?
A lot. And it varies between different types of builds. You’ll need to have a POM file for your project in order to be able to run a build, and I’m going to assume you’ve already got one. If you haven’t, try checking out this post for a couple of examples to get you started.
When you run Maven, it steps through a series of phases in a build lifecycle. You can also call goals defined in plugins. So essentially it works like this:

A lifecycle is a sequence of phases, phases can call plugins, plugins contain goals.

Clear? Yeah, it’s not exactly crystal, but stick with it.

There are 3 basic lifecycles: clean, default and site. You call these when you do a bild, like this:

mvn clean deploy site-deploy

I’ll explain exactly what’s happening in this command a little later, but first I’ll briefly explain what each of the three lifecycles do:

Clean, as the name suggests, does the cleaning work – it deletes the build output directory.

Default does all the build work. It compiles the code and the tests, runs the unit tests, packages up the build, and deploys it to the repository.

The Site lifecycle generates all of the build reports and uploads them to a site for your project.

So, back to our mvn command:

mvn clean deploy site-deploy

What’s actually happening here is we’re calling the clean lifecycle by passing the command “clean”. So far so easy.

Next up is “deploy”. Where has this come from? Well, deploy is a phase in the Default lifecycle. In fact, it’s the last phase in the default lifecycle (for a full list of all the phases that run in all 3 lifecycles take a look here. Because it’s the last phase in the default lifecycle, it automatically includes the execution of all of the others, so simply by calling “deploy” we are ensuring that the phases for compiling our source code, compiling our tests, running our tests and packaging our code are also run. It’s a bit like using the “depends” feature in ant targets, but it’s implicit. In other words, it’s a shortcut way of making sure all the phases in the default lifecycle are executed.

Finally we have site-deploy, and again this is the final phase of the site lifecycle, so we’re implicitly calling the other preceeding site phases.

The Maven Release Plugin
The Release plugin is commonly used when making an official Release Candidate build. In a nutshell it increments the build version and tags your code in SCM. It has 2 main goals. relase:prepare and release:perform.

Release:prepare does the following:

  • It checks that your source is up to date
  • It checks the POM to make sure there’s no occurances of the word SNAPSHOT in the dependencies section (the idea here being that you should never make a release build using snapshot dependencies)
  • It removes the word SNAPSHOT from your version
  • It compiles the code to make sure it works
  • It tags the code and commits the POM to scm
  • It then increments the version and re-adds “SNAPSHOT”, and commits this back to the original SCM location (i.e. not the tags location)

Once this completes successfully, release:perform is executed. Release:perform checks out the code from the tag location, and then runs the standard maven goals “deploy site-deploy” which has the effect of recompiling the code, running the tests, packaging and uploading etc etc (see above for detail on what the deploy phase actually does).

Summary
In general, I think Maven is a good build tool, it does a lot of the hard work for you. It’s far from easy to understand and follow though, unless you’re prepared to dedicate a bit of time to reading through the documentation.

In the past, I’ve spent quite a  bit of time and effort creating build systems using Ant, which, through my own design, have enforced some standards and best practices on the build process, and at the end of the day, I ended up with something fairly identical to what you get with Maven. I would definitely use Maven again, especially if standardisation and repository management were on my to-do list.

Maven POM Templates

Maven uses POM (Project Object Model) files to define its build and deploy tasks. You can end up with a lot of POM files (one for every app or api for instance) so I encourage the use of parent POMs, because they support inheritance and will end up saving a lot of typing and replication.
Here are a couple of examples of an application POM and its parent POM:

First, the app POM:

<?xml version="1.0" encoding="UTF-8"?>
<modelVersion>4.0.0</modelVersion>
<groupId>...</groupId> <!-- e.g. org.apache.maven -->
<artifactId>APPNAME</artifactId>
<packaging>PACKAGETYPE</packaging> <!-- e.g. jar -->
<version>...</version> <!-- e.g. 1.0.0.0-SNAPSHOT -->
<name>APPNAME</name>

<description>Description about this application</description>

<!-- The properties can be added to for each individual pom, 
this is just an example. You can add your own properties here -->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <org.springframework.version>3.0.2.RELEASE</org.springframework.version>
    <org.slf4j.version>1.6.0</org.slf4j.version>
  </properties>

<!-- list the parent pom here - if there is one -->
<parent>
  <groupId>...</groupId><!-- Group ID of Parent POM -->
  <artifactId>...</artifactId><!-- Name of parent pom file -->
  <version>1.0.0.0</version>
</parent>

<developers>
  <developer>
    <id>1</id>
    <name>NAME</name>
    <email>EMAIL@EMAIL.COM</email>
    <organization>MYCOMPANY</organization>
    <organizationUrl>http://www.mycompany.com</organizationUrl>
  </developer>
</developers>

<profiles>
<!-- This section is optional  -->
</profiles>

<dependencies>
<!-- List all app specific dependencies here -->
<!-- use RELEASE as the version if you always want it to use the latest version, but note that this is NOT supported in Maven 3 -->
  <dependency>
    <groupId>BLA.BLA.BLA</groupId>
    <artifactId>foo-api</artifactId>
    <version>RELEASE</version>
  </dependency>
</dependencies>

<build>
  <plugins>

<!-- you might need to enter some specific plugins here, however it will be better to have them in parent pom-->

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-ejb-plugin</artifactId>
      <version>2.1</version>
      <configuration>
        <ejbVersion>3.0</ejbVersion>
      </configuration>
    </plugin>
  </plugins>
</build>

</project>

 

And now for the parent POM:

<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>...</groupId>
<artifactId>parentpom</artifactId>
<packaging>pom</packaging>
<name>Master POM for apps</name>
<version>1.0.0.0</version>

<description>
This is parent pom for apps, where all the generic configurations are defined
</description>

<ciManagement>
  <system>Bamboo</system>
  <url>http://mybuildserver</url>
  <notifiers>
    <notifier>
      <address>admin@jamesbetteley.com</address>
    </notifier>
  </notifiers>
</ciManagement>

<licenses>
  <license>
  <name>myname</name>
  <url>http://www.myname/licenses/LICENSE.txt</url>
  <distribution>http://mybuildserver:8080/my-repo/</distribution>
  </license>
</licenses>

<organization>
  <name>MyCompany</name>
  <url>http://www.mycompany.com</url>
</organization>

<issueManagement>
  <system>GForge</system> <!-- list your issue management system here -->
  <url>http://My.gforge.url/</url>
</issueManagement>

<developers>
  <developer>
    <id>1</id>
    <name>James Betteley</name>
    <email>james.betteley@jamesbetteley.com</email>
    <organization>mycompany</organization>
    <organizationUrl>http://www.mycompany.com</organizationUrl>
  </developer>
</developers>

<scm> <!-- your source control information -->
  <connection>scm:svn:http://127.0.0.1/svn/my-project</connection>
  <developerConnection>scm:svn:https://127.0.0.1/svn/my-project</developerConnection>
  <tag>HEAD</tag>
  <url>http://127.0.0.1/websvn/my-project</url>
</scm>

<properties> <!-- You can define your own properties here, like this one -->
  <halt.on.fail>false</halt.on.fail>
</properties>

<!--	Build Configuration and Plugin Definition-->

<build>
  <finalName>${artifactId}-${version}</finalName>
  <outputDirectory>build/maven/${artifactId}/target/classes</outputDirectory>
  <testOutputDirectory>build/maven/${artifactId}/target/test-classes</testOutputDirectory>
  <directory>build/maven/${artifactId}/target</directory>
  <resources>
    <resource>
    <directory>src/main/java</directory>
      <includes>
        <include>**/*.xml</include>
      </includes>
    </resource>
    <resource>
    <directory>src/main/resources</directory>
    </resource>
</resources>
  <testResources>
    <testResource>
    <directory>src/test/java</directory>
    <includes>
      <include>**/*.xml</include>
      <include>**/*.properties</include>
    </includes>
    </testResource>
    <testResource>
    <directory>src/test/resources</directory>
    </testResource>
  </testResources>
<extensions>
  <extension>
    <groupId>org.apache.maven.wagon</groupId>
    <artifactId>wagon-ssh-external</artifactId>
    <version>1.0-alpha-5</version>
  </extension>
</extensions>

<pluginManagement>
<!-- List all the optional plugins here, for example, 
the war plugin. Child POMs can override these. -->
<!-- For a child to inherit these, 
it must reference them from within their plugin section -->
  <plugins>
    <plugin>
      <artifactId>maven-war-plugin</artifactId>
      <executions>
        <execution>
        <phase>package</phase>
        <goals>
          <goal>war</goal>
        </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</pluginManagement>

<plugins> <!-- define all plugins that are common to your app poms. 
All of these will be inherited by the child poms -->
  <plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <source>1.6</source>
    <target>1.6</target>
  </configuration>
  </plugin>
  <plugin>
  <artifactId>another-plugin</artifactId>
  <configuration>
    <source>etc</source>
    <target>etc</target>
  </configuration>
  </plugin>
</plugins>
</build>

<repositories>
  <repository>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
    <id>Central</id>
      <url>http://repo1.maven.org/maven2</url>
  </repository>
  <repository>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
    <id>3rd-Party-Repository</id>
      <url>http://mybuildserver:8080/maven-repo</url>
  </repository>
  <repository>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
    <id>my-Repository</id>
      <url>http://mybuildserver:8080/my-repo</url>
  </repository>
  <repository>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
    <id>my-Snapshot-Repository</id>
      <url>http://mybuildserver:8080/my-snap</url>
  </repository>
</repositories>



<distributionManagement>
  <repository>
  <id>my-Repository</id>
    <url>sftp://mybuildserver/home/maven/my-repo</url>
  </repository>
  <snapshotRepository>
  <id>my-Snapshot-Repository</id>
    <url>sftp://mybuildserver/home/maven/my-snap</url>
  </snapshotRepository>
  <site>
  <id>my-Reports-Repository</id>
    <url>sftp://mybuildserver/home/maven/maven-sites/${groupId}</url>
  </site>
</distributionManagement>

<reporting> <!-- List your reporting plugins here, such as cobertura	-->
<outputDirectory>build/maven/${artifactId}/target/site</outputDirectory>
<plugins>

  <plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>cobertura-maven-plugin</artifactId>
  <version>2.4</version>
    <configuration>
      <formats>
        <format>html</format>
        <format>xml</format>
      </formats>
    </configuration>
  </plugin>
</plugins>
</reporting>

</project>