Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / DevOps

Setting Up a Build and Release Pipeline for ASP.NET Core 3.1 and Angular 10 in Azure DevOps

2.94/5 (6 votes)
22 Nov 2020CPOL10 min read 26.2K  
A brief introduction of the benefits of continuous integration and delivery, why is it important to have it setup on the start of a project, describe the elements and its phases as well as list the common mistakes in setting up a build and release pipeline.
In this post, we will demonstrate how continuous and delivery is setup using Azure DevOps by having an end to end tutorial from setting the code repository using Git, creating a build and release pipeline using YAML and Azure ARM templates. As a result, this will produce an Azure App Service with Angular 10 as the front end and ASP.NET Core 3.1 and Azure SQL in the backend.

Prerequisites

The following are the tools needed to for this tutorial:

Overview

In this post, we will illustrate a brief introduction of the benefits of continuous integration and delivery, why is it important to have it setup on the start of a project, describe the elements and its phases as well as list the common mistakes in setting up a build and release pipeline.

This will also demonstrate how continuous and delivery is setup using Azure DevOps by having an end to end tutorial from setting the code repository using Git, creating a build and release pipeline using YAML and Azure ARM templates. As a result, this will produce an Azure App Service with Angular 10 as the front end and ASP.NET Core 3.1 and Azure SQL in the backend.

Benefits of Continuous Integration and Delivery

  • Faster release
  • Smaller Code Changes
  • Test Reliability
  • Maintainability
  • Fault Isolations
  • History Logging
  • Team Accountability

Why Is It Important to Have the CI/CD Pipelines Setup Before Start of the Project?

Having a continuous integration and delivery setup before the project starts will lay out all the tasks needed to build and deploy. Early in the project, we would be able to determine what are the components and dependencies we need in order to deliver the software.

Elements of CI/CD Pipeine

Image 1

Source Phase

Source code repository is the primary component in order to run a build pipeline. A change in code triggers the CI/CD tool to run a build.

Pushing and pulling codes as well as synchronizing local Git repositories to remote repositories are the activities involved in source control. In addition to this, commenting on commits, branching, merging and tagging are also effective ways of managing the repositories and having a structured trackable source files as a result.

Build Phase

This is where we combine all the code components and dependencies in order to compile and build a package for delivery and deployment.

Activities involved in the Build phase are adding a set of tasks such as compiling, testing, getting dependencies and publishing in order to produce a quality software package.

Test Phase

The Test phase will be included on the Build in most cases such as running Unit or Integration test.

Testing should always include critical testable functions on the code and producing a Failed or Passed results that can be publish from the continuous integration tools such as DevOps. With this, we can decide whether to continue the release to different environments.

Deploy Phase

Once the package is ready and verified, and it passed all the automated test cases. This is now ready to be deployed to Test, UAT, or Production environment.

Example Continuous Integration and Delivery Tools

Source Control

  • Azure Repos
  • BitBucket
  • GitHub
  • GitLab

Build/Test

  • Azure DevOps
  • Jenkins
  • CircleCi
  • Shippable
  • Travis Ci

Deploy/Ship

  • Azure DevOps
  • Docker

The following is an example of an end-to-end Continuous Integration and Continuous Delivery pipeline using Azure DevOps. A simple Angular 10, ASP.NET Core 3.1 CRUD web application using SQL Server as the backend database to manage product details.

Image 2

Instructions

Download the source from https://github.com/romvoid/ProductAppSample then extract to a folder on your machine. We will be using Azure DevOps entirely for this tutorial such as Azure Repository, Build and Release Pipeline.

Please follow the below steps to define the CI/CD in Azure DevOps: https://dev.azure.com/{youraccount}/{yourproject}/_git/ProductAppSample

Source Control

Create an Azure Repo by clicking the + plus sign on the left pane then select New repository.

Image 3

Enter repository name, then click Create. A repo will be created with the default branch as master.

Image 4

Now we will upload the ProductAppSample source files to Azure DevOps. Open the ProductAppSample in Visual Studio 2019.

Right click on the Solution, then select Create Git Repository…

Image 5

After creating a Git Repository, the solution, project and files will have a lock icon on left meaning it has now added to the local git.

Image 6

Now, we will publish the source files to Azure the Repo. Go to View menu then select Team Explorer.

Click on the Home dropdown then select Sync. Since we have not publish the source files to any Git service. It will let you choose the Git Service you want to use, select Push to Azure DevOps services, then on Publish Git Repo:

Image 7

It will prompt you to login using your Microsoft Azure DevOps account. Once, logged in, click the Publish Repository button.

Image 8

Go back to the Azure DevOps Repos, you will now see that the source files have uploaded to the ProductAppSample repository.

Image 9

BUILD

On the ProductAppSample Repo, click on Set up build. This will show a list of predefined templates for the build pipeline. Select the Starter pipeline.

Image 10

This will now open the YAML editor. Notice that it create a file named azure-pipelines.yml, which can be added to the source files to the root of the repository. Build definitions will now be added as code. You may also use the Classic Editor that will show the Visual Designer. The advantage of using YAML is that it can be managed like any other source files. You can still see the task templates by clicking on the Show assistant button on the right.

Image 11

Now we will add the tasks we need in order to run ASP.NET Core 3.1 Angular build. Click on the Show Assistant button. Then delete the tasks just beneath the steps:

Image 12

Under pool, replace the code with the following, take note of the alignment.

vmImage: 'windows-latest'
   demands: npm

   variables:
     BuildConfiguration: 'Release'
     RestoreBuildProjects: '**/*.csproj'
     TestProjects: '**/*[Tt]ests/*.csproj'
     ArtifactName: 'ProductAppSample'

On the Tasks pane search, type “Core”, then enter. Make sure that your cursor is under the steps: Select Use .NET Core, then click Add.

Image 13

Image 14

On the Tasks assistant, select .NET Core, make sure the Command is set to build.

Select .NET Core again, then change the Command to test

Select .NET Core again, then change the Command to publish.

Now search for the Publish build Artifacts task, then Add.

Check the YAML code, then make sure it’s similar with the code as follows:

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
- master

pool:
  vmImage: 'windows-latest'
  demands: npm

variables:
  RestoreBuildProjects: '**/*.csproj'
  TestProjects: '**/*[Tt]ests/*.csproj'
  ArtifactName: 'ProductAppSample'

steps:
  - task: UseDotNet@2
    displayName: Use .Net Core 3.1.x SDK
    inputs:
      packageType: 'sdk'
      version: '3.1.x'

  - task: DotNetCoreCLI@2
    displayName: Restore
    inputs:
      command: 'restore'
      projects: '$(RestoreBuildProjects)'
      feedsToUse: 'select'
 
  - task: Npm@1
    displayName: 'npm install'
    inputs:
      workingDir: ProductAppSample/ClientApp
      verbose: false

  - task: DotNetCoreCLI@2
    displayName: Build
    inputs:
      projects: '$(RestoreBuildProjects)'
      arguments: '--configuration $(BuildConfiguration)'

  - task: DotNetCoreCLI@2
    displayName: Test
    inputs:
      command: test
      projects: '$(TestProjects)'
      arguments: '--configuration $(BuildConfiguration)'

  - task: VSBuild@1
    displayName: 'Build Database Project'
    inputs:
      solution: ProductAppSampleDB/ProductAppSampleDB.sqlproj
      platform: 'Any CPU'
      configuration: '$(BuildConfiguration)'

  - task: CopyFiles@2
    displayName: 'Copy ProductAppSampleDB dacpac to release'
    inputs:
      SourceFolder: ProductAppSampleDB\bin\Output\
      Contents: '*'
      TargetFolder: '$(build.artifactstagingdirectory)\ProductAppSampleDB'
  
  - task: CopyFiles@2
    displayName: 'Copy ARM Templates to release'
    inputs:
      SourceFolder: ARMTemplates
      Contents: '*'
      TargetFolder: '$(build.artifactstagingdirectory)\ARMTemplates'

  - task: DotNetCoreCLI@2
    displayName: "Publish"
    inputs:
      command: 'publish'
      publishWebProjects: true
      arguments: '-r linux-x64 --configuration $(BuildConfiguration) 
                  --output $(Build.ArtifactStagingDirectory)'
      zipAfterPublish: true
    
  - task: PublishBuildArtifacts@1
    displayName: 'Publish Artifact'
    inputs:
      PathtoPublish: '$(build.artifactstagingdirectory)'
      ArtifactName: '$(ArtifactName)'

Now click Save and run to test the build

If the Build is successful, it will produce an Artifact where the software/web package will be stored.

Go to the Pipelines by clicking the Jet icon, then select Pipelines. Then click on the ProductAppSample pipeline.

 

Image 15

It will load list of runs page which shows the Description of the commit as well as the branch and commit id.

Image 16

Click on the description to go to show the Build Summary, Code Coverage and Test Results.

Image 17

Click on the 1 published link to see the Published Artifacts.

Image 18

Click the back arrow button to go back to the Build Summary, then click on Job to show the Job run results. This will also show the Job step and tasks defined on the YAML file.

Image 19

Release

Now we will create a Release pipeline to release the package as an Azure App Service.

Click on Pipelines>Releases, then click New pipeline button.

Image 20

In the New release pipeline page, you will notice that it there are two sections, Artifacts and Stages. It will also prompt you to select a template. For now, select Empty Job.

Image 21

On the Stage form, change the Stage name to Test. Then click Save. Then enter a Comment, click OK.

Image 22

Click + Add on the Artifacts, then select the Build as the Source type, then ProductAppSample on the Source (build pipeline).

Image 23

Click on the Thunder button, then Enable Continuous deployment trigger to create a release every time a new build is available. Click Save. Enter a comment then click OK.

Image 24

On the Stages section, click on 1 job, 0 task link to open the Stages page.

Image 25

Click on Agent Job to see the details about the Agent. Change the Agent Specification to the windows-2019 to use the latest version of the agent specifications.

Image 26

Before we add the task, we will create Variables and assign values needed for the Tasks.

Click on the Variables tab, then create the variables below. You would need to change the values of the variables according to your Azure Subscription and account details. Most importantly, you would need to specifically change the values of the HostingPlanName, SqlServerName and WebsiteName.

Image 27

Go back to the Task tab. It will now show the list of tasks, for this tutorial, we will be creating three tasks as shown from the following figure:

Image 28

Click on the +Plus button beside the Agent job, then search for ARM template, select the ARM template deployment, then click Add.

Image 29

Set the values of the ARM template deployment as follows, you would need to create a service connection to be able to connect to your subscription. You can find more details in creating a service connection from the Microsoft document to configure your service connection

You can also create a Service connection first by clicking the Manage link.

Image 30

You will be redirected to the Service connections page. Click on New service connection on the upper right.

 

Image 31

Choose Azure Resource Manager then click Next.

Image 32

Choose Service principal (automatic), then click Next.

Image 33

It will prompt you to login using your Azure portal subscription account.

Once logged in, select the Subscription you want to use, then enter a Service connection name. Then click Save.

Image 34

You may now select the Azure Resource Manager connection. Set the values of the task fields similar to the image below. Notice that the we have used the variable we have defined earlier for ResourceGroup and Location. This way, you can dynamically change the values of the ARM template. You would also need to select the correct location of the template.json and parameters.json file. These files are already part of the source downloaded from Git and can be found on the ARMTemplates folder.

We will also override the template parameters and use the values from the variables. Copy the parameters below and paste it on the Override template parameters textbox.

-subscriptionId "$(SubscriptionId)" -websiteName "$(WebsiteName)" -location "$(Location)" 
-hostingPlanName "$(HostingPlanName)" -serverFarmResourceGroup "$(ServerFarmResourceGroup)" 
-sku "$(Sku)" -skuCode "$(SkuCode)" -sqlServerName "$(SqlServerName)" -sqlDBName "$(SqlDBName)" 
-administratorLogin "$(AdministratorLogin)" 
-administratorLoginPassword "$(AdministratorLoginPassword)"

The ARM template deployment will automatically create the resource group, database and web app service in Azure. Notice that the Action is set to Create or update resource group.

Image 35

Image 36

Add another task and search for Azure SQL Dacpac task.

 

Image 37

Set the values of the fields from the following figure. Notice that the SQL Database Authentication Type is set to Connection String and the Connection String value is set with the variable we have defined earlier. This way, we can make the values consistent to the ARM template values.

Make sure to change the value and use the correct path for the DACPAC File.

Image 38

Add another task, on the search field, enter Azure App Service Deploy, then select and click Add.

Image 39

Set the values of the Azure App Service Deploy task same as the values from following figure. The value of the App Service name is set to the variable we have defined earlier. Change the value of the Package or folder zip file based on your current working directory. The App settings value has also been set to use the variable we have defined earlier. The -ConnectionStrings__TestConnection will automatically be set in Azure and update the value of the Connection String on the appSettings.json file.

Image 40

Image 41

Click Save. You are now ready to release the application. You can create a release manually or make a change on your code, then push the changes then it will automatically run your build and release.

To demonstrate the continuous and delivery pipeline, make a change to the source.

Open Visual Studio then edit the index.html file, add your name on the title as seen below:

Image 42

In Visual Studio Team Explorer, commit your change. Then sync and push.

Check the Build pipeline. It should automatically be triggered.

Once the Build finished successfully, check the Release Pipeline, it should create a new release automatically, then also run the job and tasks.

Once deployed successfully, check the website, https://{yourwebappname}.azurewebsites.net

Fill out the form, then click Submit.

It should display the records on the right of the page.

Image 43

Common Mistakes on Setting up a Build and Release Pipelines

  1. Poor build and release planning
  2. Incorrect build and release tasks
  3. Incorrect Source Paths mappings
  4. Mismatch versions from source files and Agent job tasks
  5. Not Encrypting sensitive/confidential variable values

History

  • 18th November, 2020: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)