Thursday 7 November 2013

Jenkins and Promoted Builds

I have been revisiting at the automated build system that we use at work. It is a automated representation of the old manual builds system that existed 18-months ago.

For many reasons I have been unhappy with the situation, which represents a compromise on the purity of the system against what we could do in the time.

At the same time we are moving to Subversion, and I want to be able to remove svn  at a later date and replace it with another if required. The use of a different SCM is not the difficulty here!

The situation is that we have a live branch of code, and a development branch of code. Developments go into the 'dev' branch, are tested and QAed and the promoted to the live code. Previously we have used a 'holding' level were code can be checked in at anytime. 

We are going to used Promoted Builds in Jenkins to make this happen. Referring to the blog entry from CloudBees - Another Look at the Jenkins Promoted Builds Plugin, I have setup the standard svn structures for 'live' and 'dev'.

There are eight Jenkins jobs (there could be less, but I like pipelining), breaking down the pipeline of builds, 1 pipeline is the standard CI builds for the 'dev' branch. This consists of Build -> Test -> Deploy pipeline.



CI pipeline
Developers will commit changes to the code repository and that triggers the initial build job - development2. Once this has been successful, it will trigger the development2-tests job, which runs tests, gathers code-coverage statistics. When these pass, it then triggers the development2-deploy task, which copies the builds to the server holding the developer test environments.

A second pipeline (promoting and deploying to QA) is triggered by a manual promotion from the development2 build. This allows the code to be recompiled in release conditions, and deployed to the QA staging area.



The final pipeline (promoting and rebuilding the live system) is triggered by a second manual promotion from the development2 build. This allows the code to be merged into the live branch, and then rebuilt and deployed. The 'live' is not the code that gets delivered to the client, the QAed code goes out the door. It is just there to represent the fully tested code.







Monday 14 February 2011

Prism 4.0 learnings

I have started to plan to use Prism 4.0 in one of my organisations internal applications. Previously I created a shell application and several modules that implement a standard interface. Having looked at Prism, much of this is already done via the templates that are available.

I'll post some thoughts, problems and examples when I have something concrete.

Monday 10 January 2011

Extended ListView WPF Custom Control (Part 1)

I am trying to write a WPF control that can be used in my projects to provide a standardised look and feel for data that is presented via grids. I'll put my thoughts down here, as a aid to my fading memory.

First I'll create the control, descended from ContentControl (as it will contain further content)

namespace Controls
{
using System;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;
using System.ComponentModel;

public class ListViewExtended : ContentControl
{
static ListViewExtended()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ListViewExtended),
new FrameworkPropertyMetadata(typeof(ListViewExtended)));
}
}
}


This is really simple, and is a standard setup, next the difficult bit is creating the correct XAML template, this looks (in the initial version anyway), like this:





This can be used as follows:















I'll tidy this up and add a screenshot later, and then extend the example to show it doing what I want it actually to do in the next post

Saturday 11 December 2010

MVVM RelayCommands and BackgroundWorker

This is largely cribbed from elsewhere, but I wanted to have a system where a RelayCommand starts off an asynchronous update of the Model.

First we have to have a flag to hold the idle status
public bool IsIdle ( get; set; }
The RelayCommand command needs to bind its CanExecute to this property

_getCommandData = new RelayCommand (
() => GetTimeSheet(),
() => IsIdle);

This means that the WPF item bound to this command (in this case a button), is disabled when the idle status is set to false.

So in order to use this, and to not bung up the main UI thread, we need to run the command in a BackgroundWorker thread

protected void DoWork(Action work)
{
idle = false;
var worker = new BackgroundWorker();
worker.DoWork += (sender, e) => work();
worker.RunWorkerCompleted += (sender, e) => Idle = true;
worker.RunWorkerAsync();
}

public void GetTimeSheet()
{
DoWork (delegate() {
_model.GetTimeSheet();
TimeSheetData = _model.TimeSheetData;
});
}

Saturday 6 March 2010

TLBs and Delphi

We register the capabilities of Delphi applications using TLB files. However, from reading MSDN documentation, "Installation package authors are strongly advised against using the TypeLib table. Instead, they should register type libraries by using the Registry table". Does anyone have any advice on how to do this in a 'Delphi' way for Windows 7?

Saturday 27 February 2010

Delphi/Surround/Cruisecontrol.net howto (updated)

This is a further draft of what I had to do to get CruiseControl.Net and Delphi to play nicely - I will fill out further the details later!

  1. Configured IIS in Windows (see here)
  2. Install CruiseControl.Net 3.5 RC1 (see release notes) - Make sure that the user that the CruiseControl.Net is being run by is able to see and use Delphi (i.e. probably not by default)
  3. Install CCTray
  4. Set the BDS environment setting to point to where Delphi lives (this may have been done when Delphi was installed)
  5. Create a definitions.xml file that has all of the required defaults, for accessing Surround, MSBuild, etc.
  6. Create a project to test. It is difficult to post a real example, as this is code that my company owns, rather than me, but an example could be pulled out and added to this article.
  7. Setup connection to Seapine Surround. I had a real problem with using Delphi and Surround, as by default the code is checked out as readonly, and Delphi needs to write to the working directory (especially when building typelibraries, etc). I have not spent too much time fiddling with it as I have a patch for the CruiseControl.NET source.
  8. Setup the MSBuild section to build the application (in the definitions.xml file)
  9. Setup the configuration to be managed by CruiseControl.NET and Surround, so that the files can be just checked out, modified and then checked in again - this avoids having to access the server machine.
  10. Each developer now gets emailed whenever a build fails, and we can see the running of tests as well, after each build, see below.
  11. Modify the DUnit tests to output XML.

This I did using the code from the link above, and changed the base UnitTest program code to look like this:

var
res : TTestResult;

...

if IsConsole then
if ParamCount <> 0 then
if (copy(ParamStr(1), 0, 5) = '/xml=') then
res := XMLTestRunner.RunRegisteredTests(copy(ParamStr(1), 6, length(ParamStr(1)) -5))
else
res := TextTestRunner.RunRegisteredTests
else
res := TextTestRunner.RunRegisteredTests
else
GUITestRunner.RunRegisteredTests;

if (res.ErrorCount <> 0) then
halt (1);

Other things I have done ...

  • Modify (legally I'm not sure if I can publish it) the code from Run-Time Systems Cyclomatic Complexity Calculator for Delphi so that it outputs the results as an XML file - it actually does this already internally, but doesn't write the results out.
  • Create a task to generate developer documentation using doc-o-matic as a task.

Saturday 2 January 2010

MVC Framework in Delphi

A real world example can be found here on Joanna Carter's pages.