Integrating Jenkins With Octopus Deploy

Jenkins can easily produce deployable NuGet packages for Octopus Deploy. You should start by adding OctoPack package to the project you want to deploy.

Install-Package OctoPack

I’m getting MSBuild to generate the assembly versions so I don’t have to manually increment them. OctoPack will use the same version for creating the deployable package(unless you use a nuspec file or specify it with a command line parameter). We will edit AssemblyInfo.cs to make this work.

1
2
[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyFileVersion("1.0.0.0")]

We commented out AssemblyFileVersionAttribute becase MSBuild can’t generate it for us. This way it will use the same version for the file version too.

Next I’ll create a Jenkins project. Setup your source control and MSBuild plugin. I will use Git plugin for this demo. Source code is on a public repo on GitHub so you can use the same parameters if you want to make a test deploy. It’s an ASP.NET MVC 4 project so make sure that Visual Studio 2012 is installed or the necessary files are copied to the server.

Once you configured the plugins, create the project with the following parameters:

SimpleMvcSitemap.Sample

The parameters you may want to copy(don’t forget to clone octopus branch):

https://github.com/uhaciogullari/SimpleMvcSitemap.git
SimpleMvcSitemap.Sample\SimpleMvcSitemap.Sample.csproj
/p:Configuration=Release;RunOctoPack=true

Try to build the project. It should fail with the OctoPack error below, otherwise there’s a configuration error with your plugins or the project.

OctoPack cannot be run because NuGet packages were restored prior to the build running, and the targets file was unavailable when the build started. Please build the project again to include these packages in the build. You may also need to make sure that your build server does not delete packages prior to each build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568.

Build the project again and it should succeed. You can find the package OctoPack created in project’s obj\octopacked folder. If you can verify that it’s there, go on and install Octopus Deploy. Once it’s up, create an API Key from http://your-octopus-server/app#/users/me. We will use it to publish the packages to the built-in NuGet repository. Change the MSBuild parameters in your Jenkins project to this (replace the API key and the Octopus URL):

/p:Configuration=Release;RunOctoPack=true;OctoPackPublishApiKey=YOURAPIKEY;OctoPackPublishPackageToHttp=http://your-octopus-server/nuget/packages

After a successful build you should see that the built-in NuGet repository has the package. You can check it from http://your-octopus-server/app#/configuration/feeds/feeds-builtin/test.

Package test

There’s one last thing we have to fix. When you only change a view in an MVC project, MSBuild won’t generate a new version number thinking that the assembly has not changed at all. Although I have not tested it, it will be probably same for the content files. This wouldn’t be a problem if Octopus Deploy would allow overwriting packages. In fact it silently drops the packages with the same version number. It is planned to be fixed soon but it still won’t allow overwriting. We have to force MSBuild to create a new version number in each build. That can be done with rebuilding the project. Just update the MSBuild parameter like this:

/t:Rebuild /p:Configuration=Release;RunOctoPack=true;OctoPackPublishApiKey=YOURAPIKEY;OctoPackPublishPackageToHttp=http://your-octopus-server/nuget/packages

That’s all, you can go on and deploy the packages.

Strategy Pattern With Dependency Injection

Strategy pattern is one of the most useful design patterns in OOP. It lets you select an algoritm’s implementation at runtime. However most of the examples you will find online won’t make sense if you are using dependency injection. Here’s one of them:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public interface IPaymentMethod
{
    PaymentResult Process(PaymentRequest request);
}

public class CashOnDelivery : IPaymentMethod
{
    public PaymentResult Process(PaymentRequest request)
    {
        Console.WriteLine("Pay with cash on delivery");
        return null;
    }
}

public class CreditCardPayment : IPaymentMethod
{
    public PaymentResult Process(PaymentRequest request)
    {
        Console.WriteLine("Pay with credit card");
        return null;
    }
}

public interface IPaymentService
{
    PaymentResult Pay(string paymentMethodName, PaymentRequest request);
}

public class PaymentService : IPaymentService
{
    public PaymentResult Pay(string paymentMethodName, PaymentRequest request)
    {
        IPaymentMethod paymentMethod = null;

        if (paymentMethodName == "Cash")
        {
            paymentMethod = new CashOnDelivery();
        }
        else if (paymentMethodName == "CreditCard")
        {
            paymentMethod = new CreditCardPayment();
        }
        else
        {
            //default implementation
        }

        return paymentMethod.Process(request);
    }
}

This example has a few problems:

  • PaymentService class is tightly coupled to the implementations of IPaymentMethod.
  • We are using new keyword to create instances instead of letting them be resolved by the DI container. It will get worse if we don’t have default constructors for these types. Service Locator is out of the question!
  • Open/closed principle will be clearly violated once we have to create new payment methods.

We have to find a way to resolve the implementations by DI container. We can start by adding an identifier to the strategy interface to move the selection outside of the client code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public interface IPaymentMethod
{
    string Name { get; }
    PaymentResult Process(PaymentRequest request);
}

public class CashOnDelivery : IPaymentMethod
{
    public CashOnDelivery()
    {
        Name = "Cash";
    }

    public string Name { get; private set; }

    public PaymentResult Process(PaymentRequest request)
    {
        Console.WriteLine("Pay with cash on delivery");
        return null;
    }
}

public class CreditCardPayment : IPaymentMethod
{
    public CreditCardPayment()
    {
        Name = "CreditCard";
    }

    public string Name { get; private set; }

    public PaymentResult Process(PaymentRequest request)
    {
        Console.WriteLine("Pay with credit card");
        return null;
    }
}

We added a simple name property to the strategy interface. It will make our selection code much simpler. You can use a method here if your selection logic is more complex.

Selecting a strategy is really easy now but we can make use of an another abstraction to keep the client code simpler.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface IPaymentMethodResolver
{
    IPaymentMethod Resolve(string name);
}

public class PaymentMethodResolver : IPaymentMethodResolver
{
    private readonly IEnumerable<IPaymentMethod> _paymentMethods;

    public PaymentMethodResolver(IEnumerable<IPaymentMethod> paymentMethods)
    {
        _paymentMethods = paymentMethods;
    }

    public IPaymentMethod Resolve(string name)
    {
        IPaymentMethod paymentMethod = _paymentMethods.FirstOrDefault(item => item.Name == name);
        if (paymentMethod == null)
        {
            throw new ArgumentException("Payment method not found", name);
        }
        return paymentMethod;
    }
}

Resolve method is pretty simple and we get the payment method implementations by constructor injection. The only thing left to do is registration. Any decent DI container will let you inject multiple implementations of an interface as a collection. Here’s how you can do it with Castle Windsor.

1
2
3
4
5
6
7
8
9
container.Register(
    Component.For<IPaymentService>().ImplementedBy<PaymentService>(),
    Component.For<IPaymentMethodResolver>().ImplementedBy<PaymentMethodResolver>(),
    Classes.FromThisAssembly().IncludeNonPublicTypes().BasedOn<IPaymentMethod>()
           .WithService.FromInterface()
    );

CollectionResolver collectionResolver = new CollectionResolver(container.Kernel);
container.Kernel.Resolver.AddSubResolver(collectionResolver);

It’s done. Now the PaymentService looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class PaymentService : IPaymentService
{
    private readonly IPaymentMethodResolver _paymentMethodResolver;

    public PaymentService(IPaymentMethodResolver paymentMethodResolver)
    {
        _paymentMethodResolver = paymentMethodResolver;
    }

    public PaymentResult Pay(string paymentMethodName, PaymentRequest request)
    {
       IPaymentMethod paymentMethod = _paymentMethodResolver.Resolve(paymentMethodName);
       return paymentMethod.Process(request);
    }
}