Continuous Integration Challenges using VSTS

Introduction

I got a chance to implement CI (Continuous integration) using VSTS (Visual Studio Team Services) lately, the last time I did CI was with CruiseControl and that was such a pain. I must say we live in a world of luxuries where we can get any off the shelf service which does the work in no time. VSTS is a similar kind of cloud product which lets you implement CI in hours if not minutes from scratch. I had to dig deep into the documents to overcome some challenges. Hence, I thought I should write about them.

Background

So, my task was to deploy an Asp.net MVC web application on test environment and then to staging slot environment with an approval of manager (QA manager / Dev Manager) and then switch the staging slot with production with an approval. We were using Microsoft Azure App service for all of our deployments.

 

Challenges

Accessing Private Nuget feed

The first challenge I faced was configuring private Nuget package feed hosted on different visual studio online account. I tried multiple ways mentioned in their help document and online blogs but nothing worked.

In Nuget restore task there is a section “Feeds to use”. In that section there are two options (i) Feed(s) I select here and (ii) Feeds in my Nuget.config.  Clearly, if your feeds are coming outside the VSTS account then you need to select second option and configure your external account and Nuget.config in your source repository. This is what I exactly did but unfortunately it didn’t work. It always failed during build process and cannot access my private Nuget feed from other Visual studio account. I raised this issue with Microsoft but not much of the help.

Solution:

I couldn’t find a proper solution for this problem so finally we had to move some of our feeds to the same account which we were using for the CI and then it worked like a charm. However, our problem got solved but it’s something which should be fixed. I did that in early 2018 so this might already got fixed when you read it.

 

Web.config substitution

Second challenge was relating web.config transformation. We had to deploy on multiple environments and hence configuration could not be the same for all environments.

Initially I thought it’s an easy task and I’ll create multiple dependent web.configs one for each environment and then the transformation will be done at the time of deployment. But I soon realized that it’s not that easy as it seems b/c it was not doing as expected. After lots of hit and trial I found out that by default web.config transformation occurs during build process and once it’s done it does not occur again during release process.

In build definition you can define a variable “BuildConfiguration” and sets a value with the environment name (its default value is “release”). So, at the time of build it transform the web.config to that release one and never performs the transformation again during release process.

 

Solution:

Well, the solution was to stop build definition to do the transformation and let release process to apply all the transformations.

To achieve this, first we had to ungroup all web.config files in the project. If there is any dependent web.<environment>.config file in your project then build process will perform the transformation.

The old way of ungrouping/denesting files is to edit the project file. The default settings is like below.

 

<Content Include=”Web.config”>

<SubType>Designer</SubType>

</Content>

<Content Include=”Web.Debug.config”>

<DependentUpon>Web.config</DependentUpon>

</Content>

<Content Include=”Web.Release.config”>

<DependentUpon>Web.config</DependentUpon>

</Content>

WebConfigGrouping

What you need to do first is remove the grouping of web.config files by editing the project file and remove <DependentUpon> tags and select “Copy to Output Directory” property to “Copy If newer”.

 

<Content Include=”Web.config”>

<SubType>Designer</SubType>

</Content>

<Content Include=”Web.Debug.config”>

<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

</Content>

<Content Include=”Web.Release.config”>

<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

</Content>

Create all required web.config files like in my case I created three (i) web.test.config (ii) web.staging.config and (iii) web.production.config. The important point is the name of the files should be same to the name of the environments in your release definition.

Next, in all of your environments in release definitions set the “XML transformation” true and also “XML variable substitution” true if you want to replace some values at the release definition time.

VSTSXmlTransform

For variable substitution you can specify all your variables in “Variables” menu with their values and scopes (name of the environment). Variable substitution can applies to appSettings and applicationSettings, connectionstrings and configsections elements in web.config.

 

Refer to this url for detail information on xml and variable substitution https://docs.microsoft.com/en-us/vsts/build-release/tasks/transforms-variable-substitution?view=vsts

Conclusion

Continuous Integration with Visual Studio Team Services is fun and easy to automate your build and deployment process on cloud. However, there are few elements which you need to consider while using this service. Above I mentioned couple of them which I faced during the process and I hope it’ll help someone in their implementation.

The Journey Begins

Thanks for joining me!

Good company in a journey makes the way seem shorter. — Izaak Walton

post

I am an IT professional based in London. I’m in the industry for more than a decade now and have worked on many small to large size projects in multiple companies.

The main purpose of this site is to contribute to the community by sharing unique experiences either technical or non-technical, and to pour out all what in my heart and curious mind.

I’m sure you’ll be pleased after visiting my site because

Visits always give pleasure – if not the arrival, the departure. — Portuguese Proverb