Monday, March 25, 2019

Speaking at Louisville .NET meetup,remotely speak and presenting Best practice of .NET Core CI/CD on Azure DevOps

Hi my blog audiences! Oh boy, another speaking time!

In February, I had speaking arrangements with Louisville .NET meetup, and Chad Green, the meetup's owner. Since December 2018, he had announced opportunity to speak for his meetup.

This is the Louisville .NET meetup page on

I'm honored, and at the same time feel so privileged to speak for his meetup, particularly knowing that English is not my first language. The topic I presented was about "Best practices of .NET Core 2.1 CI/CD using Azure DevOps".

This is the landing page of the event:

In this context, I focused on Azure DevOps Service. Yes, Azure DevOps Service is a rebrand from VSTS (also known before as Visual Studio Online).

NOTE: For those who wonders, the on-premise TFS will be named as Azure DevOps Server, and it will be released under the name of Azure DevOps Server 2019.

Thanks to Chad, he agreed to use Skype to speak and present for them (by sharing my desktop screen).

Here is the audience at that time (taken from my desktop screen: (on Skype)

The presentation

I had prepared the material and the talk before, including a github repo (link below) to specifically contain the presentation, the sample and demo.

The best practices for .NET Core 2.1 CI/CD are mostly concluded into these 3 main ideas (and also topics):

  1. Build and test locally first, without Visual Studio 2017 at all. It is recommended to use command prompt. Then use the knowledge and experience later to create CI on Azure DevOps
  2. Prepare and Implement Azure DevOps CI/CD.
  3. DOs and DON'Ts of Azure DevOps CI/CD 

The first topic is important, because Visual Studio 2017 always hides all of the mechanics that happened when you compile a solution. It is using MSBUILD, but the actual running sequence is always this:

  1. Restore and resolve all nuget packages using the .NET TFM information. For example: .NET Core 2.1 TFM is "netcoreapp2.1". The restore and resolve done at each project. The way nuget execute is closely related to the MSBUILD version used AND the VS 2017 used.
  2. Compile the projects in the solution, and check with resolved nuget packages
  3. If the RID specified, then "dotnet build" will tell MSBUILD to generate the necessary RID as well. Often, RID is liked with the OS used as target runtime OS.

Point #1 is important, because Nuget-MSBUILD-.NETCoreSDK-VS2017 usually has linked "train release" toolchain that we can't ignore.

For example:

Also getting used to know TFM is important, because .NET Core SDK project is editable from Visual Studio, and many tutorials from Microsoft shown these.

For more information on list of .NET Core TFM, please visit this official documentation:

By default, "dotnet build"  always use the latest SDK to compile. This will cause problem if you have many versions of .NET Core 2.1 SDK on your machine! The reason is quite trivial: the compilation and the assembly resolution will be different with your targeted TFM.

The way to minimize this is using "global.json" file that contains the .NET Core SDK you want to use, and put this on the solution folder.

For example:

  "sdk": {
    "version": "2.1.503"

For more information on global.json syntax and usage, visit this official documentation:

For more on my presentation, visit my repo of dotnetcore CI/CD sample:

Get the code

In my own Azure DevOps account, I have setup a sample CI to be shown as public, so the audience can follow my demo and presentation later.

The Azure Pipelines builds log for this meetup is available at:

So? Fork my repo and start doing DevOps now! :)