Jenkins: An Example Project

In this post I'll provide a more detailed example of setting up a project in Jenkins, albeit on a smaller scale than what you would expect to encounter in a real-world situation.  I'm also not going into the specifics of some of the steps (for example, I'm not providing detailed explanations of the batch commands to run MSBuild or NUnit); my primary objective is to give you some idea of the general workflow of a Jenkins project and how its different components can fit together.

The particular scenario covered here involves a small solution consisting of a C# .NET application that's a basic calculator with several methods for basic mathematical operations, along with a library of NUnit tests that check those methods.  The code is maintained in a local Subversion repository.  In my walk-through I'll create a Jenkins job to handle building, testing, and reporting test results whenever there's a change to the SVN repository.

Clicking "New Item" brings up the page below.  In this case, I'm creating a Freestyle Project named "Silly Calc Project".


After clicking OK I'm presented with the main configuration screen for the project.  The page is broken up into a few sections by default.  For this example, the first section where I'll make changes is the Source Code Management section, where I can specify information to integrate a version control system with the project.  CVS and SVN repositories are supported by default; for other version control systems like git, search available Jenkins plug-ins using appropriate keywords.  Here I'm specifying that my repository is an SVN repository and providing its path.  This example uses the svn protocol, but Jenkins supports other protocols including http and https (see this page for more info about supported URL formats).


The Build Triggers section of the configuration page allows me to specify when Jenkins will start processing a build-- or really any job, since a project does not necessarily require a build step.  Default (included with Jenkins "out of the box") build triggers allow me to use other projects as a cue for when to start building this one, kick off the build on a regular scheduled basis, or build when a change is detected in the version control system.  Settings for the third option are illustrated here.


The Build Periodically and Poll SCM options use a syntax based on cron to specify how frequently a build/process is triggered (Build Periodically) or the version control system is polled for changes (Poll SCM).  Jenkins provides some inline help on this syntax (accessed via the help icon next to the text box where the cron expression is entered) or you can Google "cron" to find other explanations online-- Jenkins itself has a link to this Wikipedia entry.  Expressions consists of five parts, corresponding to (from left to right) minutes in an hour, hours in a day based on a 24-hour clock, days in a month, months, and days of the week.  The particular expression above instructs Jenkins to poll SVN from Monday through Friday (corresponding to "1-5" specified for days of the week) in five minute intervals ("H/5" specified for the minutes portion of the expression-- see the suggested cron explanations for details on the meaning of "H" in this case), with no additional restrictions based on hour, day of the month, or month in the year (specified by the "*" wild card character for those parts of the expression).

Now that I've specified when I want my job to start, I have to specify exactly what I want Jenkins to do in the Build configuration section.  When I click on the "Add build step" button, I see build options for Ant and Maven (Java-based build utilities) along with the ability to add shell or Windows batch commands.  This provides a lot of flexibility with Jenkins-- almost any task you can run via a batch command can be performed as part of a project.  Since my sample project was built using C# .NET I need to use a batch command to compile using MSBuild.


It's possible to add more than one batch command, and in this example I still need to add a command to run my NUnit tests once the build is complete.


Note how the paths to the solution (in the MSBuild command-- SillyCalc.sln) and the test library (in the NUnit command-- SillyCalcTest\bin\debug\SillyCalcTest.dll) are not fully qualified.  Each Jenkins project has an associated workspace folder.  Many commands and settings-- like the paths in these Windows batch commands-- are evaluated relative to this workspace folder (Jenkins Help will clearly specify when this is the case).

Finally, I want to publish the results of my tests, a Post-build Action.  Unfortunately, if I click on the "Add post-build action" button with a new Jenkins installation, I see that it's possible to publish JUnit reports, but there's no option available for NUnit reports.  This is one of those cases where the huge library of plug-ins pays off.  A quick search on "NUnit" in the Available tab of the Plugin Manager finds the NUnit plugin.  Once installation of the plug-in is finished, "Publish NUnit test result report" magically appears as an available Post-build Action in the project configuration page.


As with the batch commands above, the path to the NUnit report is relative to the workspace folder.  Given my settings, the report is generated in the workspace folder itself, so I only have to specify the file name.

So now that my Jenkins project is set up, it should detect any errors (as determined by my NUnit tests) that might be introduced in my code.  As an example, say I inadvertently change my calculator's add() method, replacing a + operator with a * operator, and check in the "bad" change to my SVN repository.  After a few minutes Jenkins will 1) poll SVN and recognize that a change was checked in, 2) check out the code in the repository, 3) run MSBuild on the solution, 4) run my NUnit tests on the newly generated build, and 5) publish test results so they're visible within Jenkins:


Again, this is a simple example; in truth this type of error probably would have been caught quickly enough with manual unit testing for a small application of this size.  But extrapolate this scenario out to a large project with many moving parts and interdependencies and many developers or even teams of developers, and you may see the potential benefits of using Jenkins for automation.