.NET Core with Angular Continuous Integration and Deployment with Azure DevOps

What is it?

Working on an one-man projects is easy, you build it on your own machine and deploy it manually to your server environment. This is a method I used to use for quite some time, but I now have noticed that setting up an CICD pipeline benefits also the one-man projects.

Microsofts Azure DevOps Pipelines are an awesome way to have a build and release pipeline.

CICD steps

What I want?

  • Create awesome code
  • Develop, debug and verify this on my own machine
  • Create and push the git commit to a github (private) repository
  • Azure DevOps runs the build pipeline
  • Azure DevOps triggers the release pipeline, this pipeline holds after the acceptance environment
  • Manually approve the production environment in the release pipeline

How does this look like?

Default overview page of a project
Build pipeline overview
Release pipeline overview
Github service connection

Setting up the Build pipeline

The build pipeline holds the configuration to build the project(s) in my solution. In this case there are three separate projects that need to be build every time

  • Backend project (aka the API)
  • Front end project
  • Public webpage project
In order to accomplish this, a YML file has to be created, Azure DevOps helps with a nice wizzard
It then gives some options to get started with the build pipeline configuration
An example YML template

The pipeline configration I use has the following steps:

  • dotnet publish the .NET Core project
  • dotnet test all the test projects
  • npm install all the npm dependencies for the Angular app
  • npm build the Angular app
  • archive the output of the .NET Core project and Angular app together in one zip file
  • upload this zip file to my servers environment
When my build pipeline has finished, the log looks like this

Setting up the release pipeline

The release pipeline is responsible for deploying my just build projects on one of my servers. In order to do this, some service connections have to be made. These service connections are used to login on my servers from Azure DevOps and perform some actions.

My release pipeline overview
My pipeline has one agent job that runs in a hosted agent pool, this agent job has one task ‘Run shell inline on remote machine’

The ‘Run shell inline on remote machine’ does the following:

  • Log on with the service connection settings on my server
  • Stop the kestrel (responsible for running the API) service
  • Remove old files and empties working directories
  • Get the latest zip file containing the build projects from my server
  • Extract the content of this zip file in the working directory
  • Move the extraced .NET Core api and Angular app to its designated directories
  • Replace values in a config file (i.e.deploy date, environment name and build number)
  • Remove old files
  • Start the kestrel (responsible for running the API) service
Overview of the SSH task in my release pipeline
Logs of the pipeline look like this


It takes some time to setup the pipelines, and don’t forget that you also have to configure your server environment to support this. But when this is done, the benefit of never having to troubleshoot a build when your machine was reset/reinstalled/KIA is astonishing.

It takes my build pipeline around 6 minutes to complete, after this I have a zip file with that I can use to go back in time if needed.
Next the release pipeline takes a wooping 6 seconds to complete, I cannot beat that with login in manually, executing commands, upload files and replease configuration values even if I was superman.

As I use this in private Github repositories, the Azure DevOps Pipelines comes with 1 free parallel job and 1800 minutes per month of running time.
It takes less than 7 minutes for a complete run on my current project, so I can have more then 250 complete runs per month (or 8 per day, every day of the month).

I am so pleased with this setup that I have started using it in many more of my private projects as well. The delay of setting it up is completely irrelevant as the benefits are overwhelming.