This post is going to talk about continuous deployment on Visual Studio Team Services (VSTS) for .NET Core applications. With VSTS, we can manage projects, codes, builds, tests, and releases. However, it doesn’t fully support .NET Core applications at the time of this writing. More specifically, all necessary environment has been ready but the official build steps by Microsoft are not ready. Therefore, we’re writing our own PowerShell scripts for both continuous integration (CI) and continuous deployment (CD), and integrate them with VSTS build/release pipelines.

The complete PowerShell scripts can be found at:

Build Steps – Part 1

For .NET Core application in CI, we should run the following steps in our build pipeline:

  • Restore – dotnet restore
  • Build – dotnet build
  • Test – dotnet test

In a real world example, there are always more than one .NET Core library project in one .NET Core solution. Therefore, we need some PowerShell scripts for each build step.

dotnet restore – Restore NuGet Package

This is simple. In a PowerShell script, we only need one line of code:

So we’ve restored all necessary NuGet package libraries. Let’s move on.

dotnet build – Build Solution

Within the solution, there are two different directories – src and test. Each contains one or more projects. Not all projects are related to the .NET Core application we are building. Therefore, we need to filter out projects for build like:

Each .NET Core project must have project.json, so we only take projects that include that file. Once we find all project directories to build, build them by iterating the $projects value. Let’s look at the script below:

The $projects variable contains a list of directories that contain project.json. Therefore, we simply iterate each project and build it using the dotnet build command.

Now, we’ve restored NuGet package libraries followed by building entire .NET Core projects. Let’s move onto the next step.

dotnet test – Run Tests

Projects under the test directory are considered for tests. Therefore, unlike the previous step, we this time only take directories from the test directory like:

Once all necessary directories are populated, iterate $projects and run dotnet test like:

All tests are passed! We’re good to publish package for the .NET Core application. Let’s move onto the next step.

Build Steps – Part 2

This part is a sort of bridge between CI and CD. In order to deploy application to Azure, we need an artifact and tooling. We need additional steps within the build pipeline:

  • Publish – dotnet publish
  • Package – zip artifact
  • Tooling – copy WAWSDeploy

dotnet publish – Publish Package

The term publish used here is a bit confusing because, in Visual Studio, publish actually includes two distinctive steps – publish and deploy. In this post, we’re separating deploy from publish, which will be dealt at the next section. For publish, we don’t need the whole .NET Core projects, but only need application project. Let’s have a look at the script below:

We explicitly give a name to get the project directory. With this details, run the following script:

As we run this script at the solution root level, $PWD points to that directory and we point $output to store published artifact. Once we run this script, we’ll be able to see a new directory under the artifacts.

Package – Zip Artifact

As we can see in the picture above, the publish merely means that all relevant dependencies are compiled in one place. So, it’s always a good idea to put everything in one .zip file for deployment. Let’s have a look at the following script for zipping:

$BuildStagingDirectory takes an environment variable, $(Build.StagingDirectory), from VSTS, which refers to the local path on VSTS where artifacts are copied to before deployment.

Once the zip file is ready, it’s time for deployment. Oh, wait. We need a tooling. Let’s move on.

WAWSDeploy – Deploy Artifact

Before performing actual deployment, we need a tool for that, called WAWSDeploy. We can still use msdeploy.exe, but its bunch of parameters are overwhelming.

Actually, in order to deploy applications to Azure, there is a much easier way, if we use WAWSDeploy. With this, we can simply download publish settings file from Azure Web app and pass it to WAWSDeploy as a parameter.

Therefore, in order to use WAWSDeploy for deployment, we also need to copy this to the artifact directory at the same time when the artifact is copied.

Now we’re really ready for deployment!

Release Steps

Once everything is done in the build pipeline as CI, it triggers CD process. For .NET Core apps, the release pipeline in the CD process has two steps:

  • Prepare Tooling – unzip WAWSDeploy
  • Release – run WAWSDeploy

Prepare Tooling

$PackagePath takes an environment variable, $(System.DefaultWorkingDirectory), from VSTS, where artifacts are downloaded during deployment of a release. Running this scrpt will extract for deployment. We now have one last step.

Release Application

As stated above, we’re going to use a publish settings file directly downloaded from Azure web app. There is a cmdlet for this. Let’s have a look at the script:

We’re all set! Now, we just push a new commit to a repository on VSTS, it will trigger the build pipeline for CI then, if build and test is successful, activate release pipeline for CD. Once everything is done, we’ll be able to see the actual API application deployed to Azure web app. How easy!

I used VSTS in this post, but these PowerShell scripts can be used any CI/CD service as long as the service supports PowerShell and .NET Core environment.

Visual Studio Online
, , ,

Join the conversation! 1 Comment

  1. Nice post on CI/CD using VSTS.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: